From patchwork Sat May 2 11:36:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281665 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49Dq905s6Wz9sSr for ; Sat, 2 May 2020 23:05:08 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=ls+Xq1le; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49Dq8z410fzDqrm for ; Sat, 2 May 2020 23:05:07 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::642; helo=mail-pl1-x642.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=ls+Xq1le; dkim-atps=neutral Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnCz4wbQzDr0y for ; Sat, 2 May 2020 21:37:35 +1000 (AEST) Received: by mail-pl1-x642.google.com with SMTP id h11so4687751plr.11 for ; Sat, 02 May 2020 04:37:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=d0yMouDCBTEEPg0weg9ZjhqHXGPx8hUGQs2D7GlfE+w=; b=ls+Xq1leUxHhKEzR0wSqjhX3rZM3OCrIHjgs81EbnSEq+Liz8jiIa6quuyzf2pC5MN 6dLBrt1kttpvLLTEsYTkcvU1iCYFHLCqZkGPo30TuYYd9j384iE7NlYc00n1MS5sSf+x wGrKeO9UrVVPyfYDsb0c6a+RhM2C+jecf6MefNVovxWcpcM+ASRk7dmbQ5WEmSlW9/j5 Ta9VV4ceOO4sVVYK03iAcMlFEntNGRZYEPjP2s9/IFCXlzObOXYRCe6JxCri14z5EmCf eT4CYLm0w6Uc5TFbuRpR77vKY2AMvMwFiys41hshvfkNMfpdYw1RTWOl1JHti7/Qay9H 33rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=d0yMouDCBTEEPg0weg9ZjhqHXGPx8hUGQs2D7GlfE+w=; b=ZP/jz1aHpvtHVdTSG9yQvxAouxx7+xuA/ZRri25zaKwZI+IQh2O9yhGX2SzaDf8NLO hTnCu0MLKhxxiheqiaBAbPvE/1Wyi+OFRjd/cJx/KX6Tl3g+5oOW57OW3Crkhs4OTDfK W58q7F5T9xFR6vKVTTjBwCjd9/52zFRYMZiGOCmOt2mXYYNgipcMCMxpZPmtT4FL7h0j YYYCvPEH37x12j4n4lSdRNKQtPX3P5+UCW1fXiFpq+q+gszFTAme6BXOwoV3FE/2u7sg 79zw3vko6avnJTzln3+H9BkNjzdaDeBvaEtGXg84hfTl0FtOvcw2Vi8ZZVJo2ARkfO2g ymtg== X-Gm-Message-State: AGi0PuZSJ8ruGwZKyLSyEdFt9OFAEwbv7bv6m9gj3yrbPU4O1OmbdAWu 3uC3G0bwNjg7CVZ6vjOgYC8M+TA4 X-Google-Smtp-Source: APiQypIDhm0v2k5k8BcILP19+cyOSa368ujCD9wN724JfdhBwY5p2SQh8Mg+P3J23nBq1WvpUl0ZgQ== X-Received: by 2002:a17:90a:bf08:: with SMTP id c8mr5443227pjs.20.1588419451357; Sat, 02 May 2020 04:37:31 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:30 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:41 +1000 Message-Id: <20200502113649.176329-2-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 1/9] Build skiboot little-endian by default X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" LE is the way to go. Significantly smaller, less stack, faster, can avoid endian flips when called from an LE OS, subsequent patches are adding some LE specific features. They aren't exclusvely LE, but I haven't implemented for BE yet. Signed-off-by: Nicholas Piggin --- Makefile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d236df9ec..6e5b91d84 100644 --- a/Makefile +++ b/Makefile @@ -48,12 +48,18 @@ KERNEL ?= # STACK_CHECK ?= $(DEBUG) +BIG_ENDIAN ?= 0 +ifeq ($(BIG_ENDIAN),1) +LITTLE_ENDIAN = 0 +else +LITTLE_ENDIAN ?= 1 +endif + # # Experimental (unsupported) build options # -# Little-endian does not yet build. Include it here to set ELF ABI. -LITTLE_ENDIAN ?= 0 -# ELF v2 ABI is more efficient and compact +# ELF v2 ABI is more efficient and compact. +# This can be set for big-endian builds. Clearing it for LE probably won't work. ELF_ABI_v2 ?= $(LITTLE_ENDIAN) # Discard unreferenced code and data at link-time DEAD_CODE_ELIMINATION ?= 0 From patchwork Sat May 2 11:36:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281666 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49Dq9M4y38z9sRf for ; Sat, 2 May 2020 23:05:27 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=RZVuIFfM; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49Dq9M47L8zDqpJ for ; Sat, 2 May 2020 23:05:27 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1044; helo=mail-pj1-x1044.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=RZVuIFfM; dkim-atps=neutral Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnD122RxzDqXX for ; Sat, 2 May 2020 21:37:37 +1000 (AEST) Received: by mail-pj1-x1044.google.com with SMTP id hi11so1172024pjb.3 for ; Sat, 02 May 2020 04:37:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NHVEXHPClpU9a1Q3zo+wN2H8+/Ug5/QPoqZTGDgy86M=; b=RZVuIFfMy8wmuujaa3UqcMIfmQ3Sp9W1QXKnBkFB6kcdLhQLzAoW0/+drFaLWsF6N7 Av6+AlVabcrwu0mpurRVQwBSOoYMCNwfixoI9C8TMwOnHW8OdFSezs14GbJtKu9dKf6y n45p3oPw60hQBWyUZ8+XVB1xZqvHN/+dQ2N1FAffPOLSMamtEf3DfouBg/kxxl8FbS+e gZ/DZqbniGOucpexKXyTBppjswwKK5kMs0v2wxm+gXA1ZKXfvG71ZmJ7hRcf5KL4vbrq aCn2IBhOws3jpHve/kuuAwR6LNKppGfg9GcfR0D14YBU3mkpBCpkNKioI0NUd4KWGt8G ka5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NHVEXHPClpU9a1Q3zo+wN2H8+/Ug5/QPoqZTGDgy86M=; b=JSo8DLap89Spz/jxO2NFXBxqvXFmIyAiBTH2264UXYnWhI5z89sJh6ATaZVMnOTad7 LsZg74r8OgWTiuAogHEgISV9gdSuevmyyNM9VokWBCwN0n1XHgiC1KuCPZRbq8zLDZZm XDu7j8np9R8H6D9uzuE8RLnqLqjekA0QKNjVaDqJGlWwlAAvNe9+qqmghVN6nVypY+tn I9SoMd7WJ+ozc260uCf3jAEeuzq0QNQmGH/vg7p+95sffoBcmPfnEVHrKu+f/dFWjCyy vdKpcKO8oXd/JlgLTymBkLbkWwmdHWdQbSeXsap3Hh8krJUuPM0Oy8iOtkqJHfRikKCw TJow== X-Gm-Message-State: AGi0PuZ6etNyEDiA7EkPpaQKToGniRhAdqomY5qlT8jhUoaEFkgT68xj 7IqgUznmAIEZaVGWRiWT+1zqtlY2 X-Google-Smtp-Source: APiQypIwkJOX7GTpJofDg+vzN6N7UaGtiuEaNY+Sj20Nxu1odTXOjgzOlAjoc6jMSsE1EoHfrhkoUQ== X-Received: by 2002:a17:90a:33c5:: with SMTP id n63mr5128149pjb.4.1588419454658; Sat, 02 May 2020 04:37:34 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:34 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:42 +1000 Message-Id: <20200502113649.176329-3-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 2/9] Add OPAL_SYM_TO_ADDR and OPAL_ADDR_TO_SYM X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" These calls can be used by Linux to annotate BUG addresses with symbols, look up symbol addresses in xmon, etc. This is preferable over having Linux parse the OPAL symbol map itself, because OPAL's parsing code already exists for its own symbol printing, and it can support other code regions than the skiboot symbols, e.g., the wake-up code in the HOMER (where CPUs have been seen to get stuck). Signed-off-by: Nicholas Piggin --- core/opal.c | 2 + core/utils.c | 102 ++++++++++++++++++++++-- doc/opal-api/opal-get-symbol-181.rst | 42 ++++++++++ doc/opal-api/opal-lookup-symbol-182.rst | 35 ++++++++ include/opal-api.h | 4 +- 5 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 doc/opal-api/opal-get-symbol-181.rst create mode 100644 doc/opal-api/opal-lookup-symbol-182.rst diff --git a/core/opal.c b/core/opal.c index 97b5f89a8..864c244cc 100644 --- a/core/opal.c +++ b/core/opal.c @@ -162,6 +162,8 @@ int64_t opal_entry_check(struct stack_frame *eframe) case OPAL_CEC_REBOOT: case OPAL_CEC_REBOOT2: case OPAL_SIGNAL_SYSTEM_RESET: + case OPAL_ADDR_TO_SYM: + case OPAL_SYM_TO_ADDR: break; default: printf("CPU ATTEMPT TO RE-ENTER FIRMWARE! PIR=%04lx cpu @%p -> pir=%04x token=%llu\n", diff --git a/core/utils.c b/core/utils.c index d778fcdff..d53bcf374 100644 --- a/core/utils.c +++ b/core/utils.c @@ -52,40 +52,128 @@ char __attrconst tohex(uint8_t nibble) return __tohex[nibble]; } -static unsigned long get_symbol(unsigned long addr, char **sym, char **sym_end) +static unsigned long addr_to_sym(unsigned long addr, char **sym, char **sym_end, unsigned long *size) { - unsigned long prev = 0, next; + unsigned long prev = 0, next = 0; char *psym = NULL, *p = __sym_map_start; *sym = *sym_end = NULL; - while(p < __sym_map_end) { + + while (p < __sym_map_end) { next = strtoul(p, &p, 16) | SKIBOOT_BASE; if (next > addr && prev <= addr) { - p = psym + 3;; + if (!psym) + return 0; + p = psym + 3; if (p >= __sym_map_end) return 0; *sym = p; - while(p < __sym_map_end && *p != 10) + while (p < __sym_map_end && *p != '\n') p++; *sym_end = p; + *size = next - prev; + return prev; } + prev = next; psym = p; - while(p < __sym_map_end && *p != 10) + while (p < __sym_map_end && *p != '\n') + p++; + p++; + } + + return 0; +} + +static unsigned long sym_to_addr(const char *name, unsigned long *size) +{ + size_t len = strlen(name); + unsigned long addr = 0; + char *sym; + char *p = __sym_map_start; + + while (p < __sym_map_end) { + addr = strtoul(p, &p, 16) | SKIBOOT_BASE; + p += 3; + if (p >= __sym_map_end) + return 0; + + if (*(p + len) == '\n' && !strncmp(name, p, len)) { + char *sym_end; + + /* Now get the size */ + if (addr_to_sym(addr, &sym, &sym_end, size) == 0) { + if (strcmp(name, "_end")) + printf("sym_to_addr: name=%s p=%p addr=%lx addr_to_sym failed\n", name, p, addr); + *size = 0; + } + + /* + * May be more than one symbol at this address but + * symbol length calculation should still work in + * that case. + */ + + return addr; + } + + while (p < __sym_map_end && *p != '\n') p++; p++; } return 0; } +static int64_t opal_addr_to_sym(uint64_t addr, __be64 *symaddr, __be64 *symsize, char *namebuf, uint64_t buflen) +{ + unsigned long saddr; + unsigned long ssize; + char *sym, *sym_end; + size_t l; + + saddr = addr_to_sym(addr, &sym, &sym_end, &ssize); + if (!saddr) + return OPAL_RESOURCE; + + if (buflen > sym_end - sym) + l = sym_end - sym; + else + l = buflen - 1; + memcpy(namebuf, sym, l); + namebuf[l] = '\0'; + + *symaddr = cpu_to_be64(saddr); + *symsize = cpu_to_be64(ssize); + + return OPAL_SUCCESS; +} +opal_call(OPAL_ADDR_TO_SYM, opal_addr_to_sym, 5); + +static int64_t opal_sym_to_addr(const char *name, __be64 *symaddr, __be64 *symsize) +{ + unsigned long saddr; + unsigned long ssize; + + saddr = sym_to_addr(name, &ssize); + if (!saddr) + return OPAL_RESOURCE; + + *symaddr = cpu_to_be64(saddr); + *symsize = cpu_to_be64(ssize); + + return OPAL_SUCCESS; +} +opal_call(OPAL_SYM_TO_ADDR, opal_sym_to_addr, 3); + size_t snprintf_symbol(char *buf, size_t len, uint64_t addr) { unsigned long saddr; + unsigned long ssize; char *sym, *sym_end; size_t l; - saddr = get_symbol(addr, &sym, &sym_end); + saddr = addr_to_sym(addr, &sym, &sym_end, &ssize); if (!saddr) return 0; diff --git a/doc/opal-api/opal-get-symbol-181.rst b/doc/opal-api/opal-get-symbol-181.rst new file mode 100644 index 000000000..00ff18431 --- /dev/null +++ b/doc/opal-api/opal-get-symbol-181.rst @@ -0,0 +1,42 @@ +.. _OPAL_ADDR_TO_SYM: + +OPAL_ADDR_TO_SYM +================ + +.. code-block:: c + + #define OPAL_ADDR_TO_SYM 181 + + static int64_t opal_addr_to_sym(uint64_t addr, __be64 *symaddr, __be64 *symsize, char *namebuf, uint64_t buflen); + +This OPAL call looks up a firmware code address for symbol information. + +Arguments +--------- + + ``addr`` + Contains address to be looked up. + + ``symaddr`` + Returns the start address of the symbol for the object which + contains addr or immediately precedes addr. + + ``symsize`` + Returns the size of the object, or the number of bytes until the + next symbol. + + ``namebuf`` + Contains a buffer for the symbol name to be copied into, as a NUL + terminated string. + + ``buflen`` + Contains the length of the bufer that may be used. + + +Returns +------- + +:ref:`OPAL_SUCCESS` + Found a symbol. +:ref:`OPAL_RESOURCE` + Did not find a symbol. diff --git a/doc/opal-api/opal-lookup-symbol-182.rst b/doc/opal-api/opal-lookup-symbol-182.rst new file mode 100644 index 000000000..06ab4baff --- /dev/null +++ b/doc/opal-api/opal-lookup-symbol-182.rst @@ -0,0 +1,35 @@ +.. _OPAL_SYM_TO_ADDR: + +OPAL_SYM_TO_ADDR +================ + +.. code-block:: c + + #define OPAL_SYM_TO_ADDR 182 + + static int64_t opal_sym_to_addr(const char *name, __be64 *symaddr, __be64 *symsize); + +This OPAL call looks up a firmware symbol name for its address. + +Arguments +--------- + + ``name`` + Contains a pointer to NUL terminated symbol name to be looked up. + + ``symaddr`` + Returns the start address of the symbol for the object which + contains addr or immediately precedes addr. + + ``symsize`` + Returns the size of the object, or the number of bytes until the + next symbol. + + +Returns +------- + +:ref:`OPAL_SUCCESS` + Found a symbol. +:ref:`OPAL_RESOURCE` + Did not find a symbol. diff --git a/include/opal-api.h b/include/opal-api.h index e90cab1e9..ab8fc721f 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -227,7 +227,9 @@ #define OPAL_SECVAR_ENQUEUE_UPDATE 178 #define OPAL_PHB_SET_OPTION 179 #define OPAL_PHB_GET_OPTION 180 -#define OPAL_LAST 180 +#define OPAL_ADDR_TO_SYM 181 +#define OPAL_SYM_TO_ADDR 182 +#define OPAL_LAST 182 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ From patchwork Sat May 2 11:36:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281667 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49Dq9q0VyKz9sRf for ; Sat, 2 May 2020 23:05:51 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=iEsm7620; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49Dq9p55S5zDrQq for ; Sat, 2 May 2020 23:05:50 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1042; helo=mail-pj1-x1042.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=iEsm7620; dkim-atps=neutral Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnD41st9zDqWL for ; Sat, 2 May 2020 21:37:40 +1000 (AEST) Received: by mail-pj1-x1042.google.com with SMTP id a32so1166815pje.5 for ; Sat, 02 May 2020 04:37:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gZYGXpeVs5B7m2moPBY2pbUXuHmuNfaeZQ3sEEec0PI=; b=iEsm7620Vfub4c7MDnHa+/C5i+RzAuU9PDBkVucd7hhB7vK2/bQoYjFvR6S9Dcpvlw JNtrzlTStbMfKVT8OCNuWRCnGKCRnWpto5IXPEZ9+7b3LKXWUuhlo4xvsLlsdP4dA7ti YbViqvGf/K05AI1cGRklAhYq2e7CMVS5SEzR3IiEJAbH2f45uCI4XGeAe00+aTllq5DN ng/MnH2r/1zq42v6NVu7u57fQBLVldyko4ZXgQV+9S1KDIhZ2WlZlrkXspkLu85smTl7 ErKS9Cc/B8k2hHs28z8MO13yg2830IDriQ1cALSfqKYhLFmuaYoMbJEjEs93MoLzmUqM oWTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gZYGXpeVs5B7m2moPBY2pbUXuHmuNfaeZQ3sEEec0PI=; b=sH7xMcyBOfAkB7sD11++FgPCpud64fMvc8+vdlhZQQnX1OvD81/u14kdV+HqITQMwl 5lslLv36KLo8B7iCTI2p/zAakpglxnXVKeit7Ih13hPpQpKniGdnPvyOY7DZBQqSyoHK fiOfNQBKYNNNjk2us7jHj49MUuZd1d8TfFGiJ7aC2iwsbCVMcSFsHkCilMbljmL7AUdf Ts/q8dcSlrtshIchI7JLeyNxxQdB6zB8yVBZMbyDyROS3o0ZN+Lk7RCfsqtVYBPv27cm ky5mqbBSapDTopgkIgsdRlF0vtj/pdZ+tojHNR0u1gNHg/kFojITPsU9bUjcMa1oor7M MDvQ== X-Gm-Message-State: AGi0PuYZ8vRKqAhihffl1RlxrKfAfy5dGY7hLBZ0APBmAlDmjqeClLbD G2s2Nl1sCpP3PnGqE5Uz4qlCZuiz X-Google-Smtp-Source: APiQypJPy6akT9/m/osWpz/L6fYs60+nNNO/DXDX/fYRGywUgWqJeONnGOJ5IJNmsitKy5MxC1dBcA== X-Received: by 2002:a17:902:aa94:: with SMTP id d20mr8530519plr.15.1588419457707; Sat, 02 May 2020 04:37:37 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:37 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:43 +1000 Message-Id: <20200502113649.176329-4-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 3/9] Add OPAL_REPORT_TRAP interface X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" If the OS takes over OPAL's assert trap interrupts, it needs a way to report them and get metadata. This API leaves room for a WARN type of assertion without actually implementing one yet. The changes behaviour of OPAL asserts when the OS is running. They don't get put into an infinite loop, but rather try to kill the calling process. Not sure if this is quite the best way to go yet, it's possible we should be more recoverable like Linux BUG(), but there may be other issues with that. There is a way to ask for a panic, but that's also not used yet. Again the benefit of trap over the inline assertion is (aside from the above killing the process and attempting to continue), that a more precise snapshot of registers can be reported, and the current stack is not required (OS can use an alternative stack if it chooses). Signed-off-by: Nicholas Piggin --- core/utils.c | 22 ++++++++++++++++++++++ include/opal-api.h | 7 ++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/core/utils.c b/core/utils.c index d53bcf374..2ec11255d 100644 --- a/core/utils.c +++ b/core/utils.c @@ -166,6 +166,28 @@ static int64_t opal_sym_to_addr(const char *name, __be64 *symaddr, __be64 *symsi } opal_call(OPAL_SYM_TO_ADDR, opal_sym_to_addr, 3); +static int64_t opal_report_trap(uint64_t nip) +{ + struct trap_table_entry *tte; + + for (tte = __trap_table_start; tte < __trap_table_end; tte++) { + if (tte->address == nip) { + prerror("< %s >\n", tte->message); + prerror(" .\n"); + prerror(" .\n"); + prerror(" .\n"); + prerror(" OO__)\n"); + prerror(" <\"__/\n"); + prerror(" ^ ^\n"); + + return OPAL_TRAP_FATAL; + } + } + + return OPAL_EMPTY; +} +opal_call(OPAL_REPORT_TRAP, opal_report_trap, 1); + size_t snprintf_symbol(char *buf, size_t len, uint64_t addr) { unsigned long saddr; diff --git a/include/opal-api.h b/include/opal-api.h index ab8fc721f..76d751c75 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -229,7 +229,8 @@ #define OPAL_PHB_GET_OPTION 180 #define OPAL_ADDR_TO_SYM 181 #define OPAL_SYM_TO_ADDR 182 -#define OPAL_LAST 182 +#define OPAL_REPORT_TRAP 183 +#define OPAL_LAST 183 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ @@ -1257,6 +1258,10 @@ struct opal_mpipl_fadump { struct opal_mpipl_region region[]; }; +#define OPAL_TRAP_FATAL 1 +#define OPAL_TRAP_WARN 2 +#define OPAL_TRAP_PANIC 3 + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ From patchwork Sat May 2 11:36:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281668 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqBD3jwZz9sRf for ; Sat, 2 May 2020 23:06:12 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=BjJ6kTHX; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqBD1znKzDrQg for ; Sat, 2 May 2020 23:06:12 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::542; helo=mail-pg1-x542.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=BjJ6kTHX; dkim-atps=neutral Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnD813JlzDr4d for ; Sat, 2 May 2020 21:37:44 +1000 (AEST) Received: by mail-pg1-x542.google.com with SMTP id d17so5897035pgo.0 for ; Sat, 02 May 2020 04:37:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AQ7LH06q27s36eZ3/yedRcPqvQ7td1+GTSbYDGqi3jA=; b=BjJ6kTHX47ijJlhrVHWi3UsUwgYTl4Ad1QfvKE9HZab+IM+ibk9bntpRwLzwuFnIPm PLNZ15RwaLxq3OHMbXvirt9XXiY42Zzar8kW9ZK7hbXXSNT+VUyI8oBPtY5JmV8fXSwG R41jMLV07WCSUu/9hLfcv+Nv6N0ELEsN3xXEaK3QpWTbkXKIL/vr+EwYW5+xru0nIJLU myyVJIgo3DRszD5TKUHsUNqGvLhq06dJyl3hjIhfUw0E2nTmJ7vh2e6l7M1roELraD5I gEYN1+D8fi661yBmYEdKJ+kVxFuhzJjW8IMtNRwH6tpWP0xUC+o+kiQuYWsYYwJYyqvj SGRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AQ7LH06q27s36eZ3/yedRcPqvQ7td1+GTSbYDGqi3jA=; b=nnBe0ClFyfpk0YI7ni61odQZuS5P1nAsayE8fRCJqKPc8UIbzLl4sFvy6laN0bAZqg O7MUI4TcvoBuFVZueaZCn2EAUeKUaZ486m4X7K4+BmKxdQCNgJBt2oPQmctWOhI7ODzG 1AXgXU8KO9lbzrlyGL7Y0u2ic4WMaixWGTG77VdPSQOKv4H7YFKKUIykOpbanu/WLjEZ Nu0jCzPCpDoWqKzS7mFTeoX74BGzpe1lxwQ/MRumEeZ8dunyB/Dab8VFw39UNEWARVLv 3d/RL6K77AZpG7lY6V4BF6/8ARhvbqcHrXwEndiqa0OTUf3JF7nOY7Dei2kFQMNoZCJh iCkQ== X-Gm-Message-State: AGi0PubQ56k0p0kGKk/liQGavSMYSuXEm36hcOIGuEJeWZvysbgMDplv s4Petibke23/KHIeC+EP7m08iq1K X-Google-Smtp-Source: APiQypKEAWcFABnwVKwqqhNUcLva93ep/AXXXoOrjjM0pcW2KCxgja0/LwwTTW5vAr7Bc2JF0DTT+g== X-Received: by 2002:a62:15d8:: with SMTP id 207mr8090274pfv.140.1588419460878; Sat, 02 May 2020 04:37:40 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:40 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:44 +1000 Message-Id: <20200502113649.176329-5-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 4/9] opal: provide a "raw" console mode X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This allows the console drivers to be switched to a "raw" mode (maybe OS mode is a better name) which exposes the console hardware driver directly via the OPAL APIs, and does not allow OPAL to use it. This is not used until a subsequent patch, but it allows the OS to own the console rather than be arbitrated via the OPAL console layer. The OS then provides console services to OPAL. This can not really be achieved by advertising the UART to the OS in the DT at boot, because there is no way to coordinate the switch to the OS owning the console. Signed-off-by: Nicholas Piggin --- core/console.c | 83 +++++++++++++++++++++++++++++++++------ hw/lpc-uart.c | 83 +++++++++++++++++++++++++++++++++++++++ include/console.h | 3 ++ platforms/mambo/console.c | 60 ++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+), 12 deletions(-) diff --git a/core/console.c b/core/console.c index 2a1509025..336dda7a1 100644 --- a/core/console.c +++ b/core/console.c @@ -19,12 +19,15 @@ static char *con_buf = (char *)INMEM_CON_START; static size_t con_in; static size_t con_out; static bool con_wrapped; +static bool con_raw; /* Internal console driver ops */ static struct con_ops *con_driver; /* External (OPAL) console driver ops */ static struct opal_con_ops *opal_con_driver = &dummy_opal_con; +static struct opal_con_ops *opal_raw_con_driver = NULL; +static struct opal_con_ops *opal_cooked_con_driver = &dummy_opal_con; static struct lock con_lock = LOCK_UNLOCKED; @@ -167,6 +170,9 @@ bool flush_console(void) { bool ret; + if (!con_driver) + return false; + lock(&con_lock); ret = __flush_console(true, true); unlock(&con_lock); @@ -232,9 +238,12 @@ ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count) /* We use recursive locking here as we can get called * from fairly deep debug path */ - bool need_unlock = lock_recursive(&con_lock); + bool need_unlock; const char *cbuf = buf; + assert(!con_raw); + need_unlock = lock_recursive(&con_lock); + while(count--) { char c = *(cbuf++); if (c == '\n') @@ -260,6 +269,8 @@ ssize_t read(int fd __unused, void *buf, size_t req_count) bool need_unlock = lock_recursive(&con_lock); size_t count = 0; + assert(!con_raw); + if (con_driver && con_driver->read) count = con_driver->read(buf, req_count); if (!count) @@ -272,17 +283,22 @@ ssize_t read(int fd __unused, void *buf, size_t req_count) /* Helper function to perform a full synchronous flush */ void console_complete_flush(void) { - /* - * Using term 0 here is a dumb hack that works because the UART - * only has term 0 and the FSP doesn't have an explicit flush method. - */ - int64_t ret = opal_con_driver->flush(0); - - if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER) - return; - - while (ret != OPAL_SUCCESS) { - ret = opal_con_driver->flush(0); + if (con_raw) { + opal_raw_con_driver->flush(0); + } else { + /* + * Using term 0 here is a dumb hack that works because the UART + * only has term 0 and the FSP doesn't have an explicit flush + * method. + */ + int64_t ret = opal_con_driver->flush(0); + + if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER) + return; + + while (ret != OPAL_SUCCESS) { + ret = opal_con_driver->flush(0); + } } } @@ -311,9 +327,51 @@ static bool opal_cons_init = false; void set_opal_console(struct opal_con_ops *driver) { assert(!opal_cons_init); + opal_cooked_con_driver = driver; opal_con_driver = driver; } +void set_opal_raw_console(struct opal_con_ops *driver) +{ + assert(!opal_cons_init); + opal_raw_con_driver = driver; +} + +void set_opal_console_to_raw(void) +{ + if (!opal_raw_con_driver) + return; + + console_complete_flush(); + + opal_con_driver = opal_raw_con_driver; + if (opal_cons_init) { + opal_register(OPAL_CONSOLE_READ, opal_con_driver->read, 3); + opal_register(OPAL_CONSOLE_WRITE, opal_con_driver->write, 3); + opal_register(OPAL_CONSOLE_FLUSH, opal_con_driver->flush, 1); + opal_register(OPAL_CONSOLE_WRITE_BUFFER_SPACE, + opal_con_driver->space, 2); + } + + opal_con_driver = NULL; + con_raw = true; +} + +void set_opal_console_to_cooked(void) +{ + console_complete_flush(); + + opal_con_driver = opal_cooked_con_driver; + if (opal_cons_init) { + opal_register(OPAL_CONSOLE_READ, opal_con_driver->read, 3); + opal_register(OPAL_CONSOLE_WRITE, opal_con_driver->write, 3); + opal_register(OPAL_CONSOLE_FLUSH, opal_con_driver->flush, 1); + opal_register(OPAL_CONSOLE_WRITE_BUFFER_SPACE, + opal_con_driver->space, 2); + } + con_raw = false; +} + void init_opal_console(void) { assert(!opal_cons_init); @@ -324,6 +382,7 @@ void init_opal_console(void) opal_con_driver->name); opal_con_driver = &dummy_opal_con; + opal_cooked_con_driver = &dummy_opal_con; } prlog(PR_INFO, "OPAL: Using %s\n", opal_con_driver->name); diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c index 898fc4b1c..549aad49f 100644 --- a/hw/lpc-uart.c +++ b/hw/lpc-uart.c @@ -183,6 +183,89 @@ static struct con_ops uart_con_driver = { * OPAL console driver */ +static int64_t uart_opal_raw_write(int64_t term_number, __be64 *__length, + const uint8_t *buffer) +{ + size_t written = 0, len = be64_to_cpu(*__length); + + if (term_number != 0) + return OPAL_PARAMETER; + + if (!lpc_ok() && !mmio_uart_base) + return OPAL_HARDWARE; + + while (written < len) { + if (tx_room == 0) { + uart_check_tx_room(); + if (tx_room == 0) + break; + } + uart_write(REG_THR, buffer[written++]); + tx_room--; + } + + *__length = cpu_to_be64(written); + + return OPAL_SUCCESS; +} + +static int64_t uart_opal_raw_write_buffer_space(int64_t term_number, + __be64 *__length) +{ + if (term_number != 0) + return OPAL_PARAMETER; + + uart_check_tx_room(); + *__length = cpu_to_be64(tx_room); + + return OPAL_SUCCESS; +} + +static int64_t uart_opal_raw_read(int64_t term_number, __be64 *__length, + uint8_t *buffer) +{ + size_t req_count = be64_to_cpu(*__length), read_cnt = 0; + uint8_t lsr = 0; + + if (term_number != 0) + return OPAL_PARAMETER; + + while (req_count) { + lsr = uart_read(REG_LSR); + if ((lsr & LSR_DR) == 0) + break; + buffer[read_cnt++] = uart_read(REG_RBR); + req_count--; + } + + *__length = cpu_to_be64(read_cnt); + return OPAL_SUCCESS; +} + +static int64_t uart_opal_raw_flush(int64_t term_number) +{ + if (term_number != 0) + return OPAL_PARAMETER; + + while (tx_room != 16) + uart_check_tx_room(); + + return OPAL_SUCCESS; +} + +static void uart_init_opal_raw_console(void) +{ +} + +struct opal_con_ops uart_opal_raw_con = { + .name = "OPAL UART raw console", + .init = uart_init_opal_raw_console, + .read = uart_opal_raw_read, + .write = uart_opal_raw_write, + .space = uart_opal_raw_write_buffer_space, + .flush = uart_opal_raw_flush, +}; + /* * We implement a simple buffer to buffer input data as some bugs in * Linux make it fail to read fast enough after we get an interrupt. diff --git a/include/console.h b/include/console.h index 02fc7a4b6..54ddd6718 100644 --- a/include/console.h +++ b/include/console.h @@ -65,6 +65,9 @@ extern bool flush_console(void); extern void set_console(struct con_ops *driver); extern void set_opal_console(struct opal_con_ops *driver); +extern void set_opal_raw_console(struct opal_con_ops *driver); +extern void set_opal_console_to_raw(void); +extern void set_opal_console_to_cooked(void); extern void init_opal_console(void); extern void console_complete_flush(void); diff --git a/platforms/mambo/console.c b/platforms/mambo/console.c index 6d5b20b56..f2a0ad675 100644 --- a/platforms/mambo/console.c +++ b/platforms/mambo/console.c @@ -3,6 +3,7 @@ #include #include +#include #include "mambo.h" @@ -48,10 +49,69 @@ static struct con_ops mambo_con_driver = { .write = mambo_console_write, }; +static int64_t mambo_opal_raw_write(int64_t term_number, __be64 *__length, + const uint8_t *buffer) +{ + size_t len = be64_to_cpu(*__length); + + if (term_number != 0) + return OPAL_PARAMETER; + + mambo_console_write(buffer, len); + + return OPAL_SUCCESS; +} + +static int64_t mambo_opal_raw_write_buffer_space(int64_t term_number, + __be64 *__length) +{ + if (term_number != 0) + return OPAL_PARAMETER; + + *__length = cpu_to_be64(256); + + return OPAL_SUCCESS; +} + +static int64_t mambo_opal_raw_read(int64_t term_number, __be64 *__length, + uint8_t *buffer) +{ + size_t req_count = be64_to_cpu(*__length), read_cnt = 0; + + if (term_number != 0) + return OPAL_PARAMETER; + + read_cnt = mambo_console_read(buffer, req_count); + *__length = cpu_to_be64(read_cnt); + + return OPAL_SUCCESS; +} + +static int64_t mambo_opal_raw_flush(int64_t term_number) +{ + if (term_number != 0) + return OPAL_PARAMETER; + return OPAL_SUCCESS; +} + +static void mambo_init_opal_raw_console(void) +{ +} + +struct opal_con_ops mambo_opal_raw_con = { + .name = "OPAL Mambo raw console", + .init = mambo_init_opal_raw_console, + .read = mambo_opal_raw_read, + .write = mambo_opal_raw_write, + .space = mambo_opal_raw_write_buffer_space, + .flush = mambo_opal_raw_flush, +}; + void enable_mambo_console(void) { prlog(PR_NOTICE, "Enabling Mambo console\n"); set_console(&mambo_con_driver); + set_opal_raw_console(&mambo_opal_raw_con); } /* From patchwork Sat May 2 11:36:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqBc2TVzz9sRf for ; Sat, 2 May 2020 23:06:32 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=tp792zty; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqBb74vGzDqlr for ; Sat, 2 May 2020 23:06:31 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::644; helo=mail-pl1-x644.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=tp792zty; dkim-atps=neutral Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnDC0ksFzDr40 for ; Sat, 2 May 2020 21:37:46 +1000 (AEST) Received: by mail-pl1-x644.google.com with SMTP id s20so4698313plp.6 for ; Sat, 02 May 2020 04:37:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CnOhVdEye9idIsqnGO1FnqjEqRoJuXxrDmU2UCqRVUY=; b=tp792ztyXryJIIU3o7ipDhdiHF+ue3WEULQLzzaELxzQ31L2IaVIO2yx2sEzsmYyyU bpy0v8e3NBjTuwwqkzUqx8ObGG6mu5t1JFIGY1ITf2ML8zUYxT9gvdjnNdJr0idsJ3Pw 1AHKNq23DZpJ6jhqfAuMzwyrcQeor9NeFcG4o0LLwLYIn9hCjpVvwHWnOqiAU+USTbsP 9CeuKqk0BYBnr1oGR47LbyMHncGGsCkhKCn1YZNBS2JaWnLXGezWSxfO5BzYdaF9A8Ub dUrHSXBZDOjmr3XPPzghmpR2DYqsOoyeMbDJXcC+HElBaI99uVK2eMlNdWkXIuH8i2gR GhIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CnOhVdEye9idIsqnGO1FnqjEqRoJuXxrDmU2UCqRVUY=; b=PZaUp5qxgrmSo7hPBf4ZJ6i+ZVZSxZ9QoUNi/M6pOeKdMj+FwQNGSXuKeMsQwHAdyu e9/Sij93EgtjSztS74t6gYRIQ/7OeJyYg4jyq19Hk0rC158sXFZuBExRsFzaLx+o9JAB +yYoMf/XsmxuDpJY97rqeOQHM2ZMvUkYPLfqzzrZVxHkbLgSIIZkFcjsKb0QcO1Nzroi hv0ZVFvcQnxV4s6KYydiRWEtHNc0MImp7n7mHwVeFaprANqAcfGljKptWODr5cH5ygCB EV64n+EvuEh+/E3ST8umh/oq6UzDMywSYYKttNlIbszyI7JPBiOtQyuUCj3MJkhwdCuQ Zgkg== X-Gm-Message-State: AGi0PuZueFAPxJs9g0pnaWNL5QUA53qbEos0QKht17pfk4iO4noTrczd r0+Q3XGDVRpNZhGVEFThGwqY7cTi X-Google-Smtp-Source: APiQypKEKUMUqCaONITxqiYjgMQeYavHuqM4ojpFths3hk0iPQfZQ7i8mroiR9fMuptzol+9K6LnGQ== X-Received: by 2002:a17:902:9306:: with SMTP id bc6mr8881551plb.255.1588419464256; Sat, 02 May 2020 04:37:44 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:43 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:45 +1000 Message-Id: <20200502113649.176329-6-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 5/9] Add OPAL_FIND_VM_AREA X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This interface allows the OS to query the virtual mappings that were set up at the time OPAL initiated the OS. This allows the OS to set up its own virtual memory environment to call OPAL in. Signed-off-by: Nicholas Piggin --- core/vm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/opal-api.h | 15 ++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/core/vm.c b/core/vm.c index 3f910d0d6..236a0e70b 100644 --- a/core/vm.c +++ b/core/vm.c @@ -257,6 +257,22 @@ static void htab_remove(unsigned long va, int local) } } +static uint64_t vmm_os_map_flags(struct vm_map *vmm) +{ + uint64_t flags = 0; + + if (vmm->readable) + flags |= OS_VM_FLAG_READ; + if (vmm->writeable) + flags |= OS_VM_FLAG_WRITE; + if (vmm->executable) + flags |= OS_VM_FLAG_EXECUTE; + if (vmm->ci) + flags |= OS_VM_FLAG_CI; + + return flags; +} + /* * Try to fix problems in callers if !strict. */ @@ -934,3 +950,29 @@ void vm_destroy(void) free(prtab); prtab = NULL; } + +static int64_t opal_find_vm_area(uint64_t addr, struct opal_vm_area *opal_vm_area) +{ + struct vm_map *vmm; + + /* OS takes over control of providing VM mappings */ + list_for_each(&vm_maps, vmm, list) { + uint64_t flags; + + if (addr >= vmm->address + vmm->length) + continue; + + flags = vmm_os_map_flags(vmm); + opal_vm_area->address = cpu_to_be64(vmm->address); + opal_vm_area->length = cpu_to_be64(vmm->length); + opal_vm_area->pa = cpu_to_be64(vmm->pa); + opal_vm_area->vm_flags = cpu_to_be64(flags); + + printf("0x%016llx-0x%016llx flags=%llx (%s)\n", vmm->address, vmm->address + vmm->length, flags, vmm->name); + + return OPAL_SUCCESS; + } + + return OPAL_EMPTY; +} +opal_call(OPAL_FIND_VM_AREA, opal_find_vm_area, 2); diff --git a/include/opal-api.h b/include/opal-api.h index 76d751c75..e5142f121 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -230,7 +230,8 @@ #define OPAL_ADDR_TO_SYM 181 #define OPAL_SYM_TO_ADDR 182 #define OPAL_REPORT_TRAP 183 -#define OPAL_LAST 183 +#define OPAL_FIND_VM_AREA 184 +#define OPAL_LAST 184 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ @@ -1262,6 +1263,18 @@ struct opal_mpipl_fadump { #define OPAL_TRAP_WARN 2 #define OPAL_TRAP_PANIC 3 +#define OS_VM_FLAG_READ 0x1 +#define OS_VM_FLAG_WRITE 0x2 +#define OS_VM_FLAG_EXECUTE 0x4 +#define OS_VM_FLAG_CI 0x8 + +struct opal_vm_area { + __be64 address; + __be64 length; + __be64 pa; + __be64 vm_flags; +}; + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ From patchwork Sat May 2 11:36:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281670 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqC26G6bz9sRf for ; Sat, 2 May 2020 23:06:54 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=MToUS3Bw; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqC25Y0XzDqxF for ; Sat, 2 May 2020 23:06:54 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1043; helo=mail-pj1-x1043.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=MToUS3Bw; dkim-atps=neutral Received: from mail-pj1-x1043.google.com (mail-pj1-x1043.google.com [IPv6:2607:f8b0:4864:20::1043]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnDG3SzZzDqdm for ; Sat, 2 May 2020 21:37:50 +1000 (AEST) Received: by mail-pj1-x1043.google.com with SMTP id y6so1174701pjc.4 for ; Sat, 02 May 2020 04:37:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vHOqG1FApgoMKCRpDt6F+rH+krpzCj61gROqg6Gby6o=; b=MToUS3BwJcoo6Am3FhScWIyj4KmIktn/2wicCbXg2JwrvL/UC46qQJ8k4eUgCCiyhL 9Atz45mgjxy0SVJCxHdwbjjIMIp/dk/OeQP5olGxS9DGVegVPEuyes565/O1XtSD88Kj PPs3yXe93VizDmSY0G2r/lQXR/v3vZZYin0aD8edW4p9Ykd+gd0DccQdISJ0J4P1x1r8 fU10kEaYTvIbs8+pxH+1q/lme8dDwSytpT+e5e8Thm4F1pZomnz/cqFJ1yCrv8dk4ggn ovzeLp+AQO0dfSxL5xwFyVWeW8drEZZ7UD0xseWy76Dy3LKIvfwQ0Ti/OMMpmCT6g/iP uYhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vHOqG1FApgoMKCRpDt6F+rH+krpzCj61gROqg6Gby6o=; b=fQyfOz6/A/J5Zx95SH+o9mwnx5o6d/eZctNlDCkHrEcGLGMWHeHafaWaofIvIOWMSZ s6+MgA+43PBZbE4aBdauQKx9zF12eC8/r1yGgcqz0RlojTY2hMYCJFm39NjK1Xz7ywZJ SYWz+KJAhVGrnwZ1/+XDhWkchwd0gmbV+E+uOgF/WS9P7I1TdLlbTmfmcuq8uTy/U/Ty M6HQD4dNPZ/PgEE5rQcjoZxTEz/tGFygGRrn62qJsv+epkHZhMWwIz8nhkRGY1dbv1bn VhJLnTRfYJ/gu241GQCsVW67vVp/K0lkJHzG6aKw4iNZoH6133IMTkOKD+unv9wu3OUI actA== X-Gm-Message-State: AGi0PuY/hByQbfHycvai3HyXSdAzpKKgKn+xqun1e0gPj+hLAj7f+JNp P8e8l6CoNe9SVVUFh5EyUF74P7xV X-Google-Smtp-Source: APiQypJICdzCSAngS17OSnkcl/kq6pLG+yJm0qvWv1A7bQeu8UjpJzsusi+0vgmxeYb8CKJ+SwAINA== X-Received: by 2002:a17:902:ac8d:: with SMTP id h13mr9068234plr.267.1588419467460; Sat, 02 May 2020 04:37:47 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:47 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:46 +1000 Message-Id: <20200502113649.176329-7-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 6/9] OPAL V4 calling convention X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This is a new calling convention, currently implemented only a LE entry point for LE skiboot builds. It is simply called as an indirect function, with the first argument selecting the opal call token, and the subsequent arguments are the opal call args. The caller's stack is used by OPAL! Linux tries very hard to ensure the stack is re-entrant across interrupts including non-maskable ones. We've currently hacked around this in skiboot by using a different part of the skiboot stack if OPAL is re-entered, but this is fragile and error prone. This makes it much more simple to add a machine check handling OPAL API, for example. This API may be called with MMU enabled! If the OS sets up a virtual memory environment described by OPAL_FIND_VM_AREA, it may call this API with MSR[IR] and MSR[DR] enabled, or may call in real mode. Currently skiboot immediately drops to real mode to make the call, and back to virtual mode to return. Signed-off-by: Nicholas Piggin --- core/cpu.c | 9 +----- core/opal.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++-- include/cpu.h | 9 ++++++ 3 files changed, 93 insertions(+), 10 deletions(-) diff --git a/core/cpu.c b/core/cpu.c index 30f9c6e70..3cf43ab1c 100644 --- a/core/cpu.c +++ b/core/cpu.c @@ -23,14 +23,7 @@ /* The cpu_threads array is static and indexed by PIR in * order to speed up lookup from asm entry points */ -struct cpu_stack { - union { - uint8_t stack[STACK_SIZE]; - struct cpu_thread cpu; - }; -} __align(STACK_SIZE); - -static struct cpu_stack * const cpu_stacks = (struct cpu_stack *)CPU_STACKS_BASE; +struct cpu_stack * const cpu_stacks = (struct cpu_stack *)CPU_STACKS_BASE; unsigned int cpu_thread_count; unsigned int cpu_max_pir; struct cpu_thread *boot_cpu; diff --git a/core/opal.c b/core/opal.c index 864c244cc..27ce7a375 100644 --- a/core/opal.c +++ b/core/opal.c @@ -388,6 +388,79 @@ static void add_opal_firmware_node(void) add_opal_firmware_exports_node(firmware); } +typedef int64_t (*opal_call_fn)(uint64_t r3, uint64_t r4, uint64_t r5, + uint64_t r6, uint64_t r7, uint64_t r8, + uint64_t r9); + +static int64_t opal_v4_le_entry(uint64_t token, uint64_t r4, uint64_t r5, + uint64_t r6, uint64_t r7, uint64_t r8, + uint64_t r9, uint64_t r10) +{ + struct cpu_thread *cpu; + opal_call_fn *fn; + uint64_t msr; + uint32_t pir; + uint64_t r16; + uint64_t ret; + + msr = mfmsr(); + assert(!(msr & MSR_EE)); + + if (msr & (MSR_IR|MSR_DR)) + mtmsrd(msr & ~(MSR_IR|MSR_DR), 0); + + pir = mfspr(SPR_PIR); + r16 = (uint64_t)__this_cpu; + __this_cpu = &cpu_stacks[pir].cpu; + cpu = this_cpu(); + + cpu->in_opal_call++; + if (cpu->in_opal_call == 1) { + cpu->current_token = token; + cpu->entered_opal_call_at = mftb(); + } + + if (!opal_check_token(token)) { + ret = opal_bad_token(token); + goto out; + } + + fn = (opal_call_fn *)(&opal_branch_table[token]); + + ret = (*fn)(r4, r5, r6, r7, r8, r9, r10); + +out: + if (!list_empty(&cpu->locks_held)) { + prlog(PR_ERR, "OPAL exiting with locks held, pir=%04x token=%llu retval=%lld\n", + pir, token, ret); + drop_my_locks(true); + } + + if (token != OPAL_RESYNC_TIMEBASE) { + uint64_t call_time; + + call_time = tb_to_msecs(mftb() - cpu->entered_opal_call_at); + if (call_time > 100) { + prlog((call_time < 1000) ? PR_DEBUG : PR_WARNING, + "Spent %llu msecs in OPAL call %llu!\n", + call_time, token); + } + } + + if (cpu->in_opal_call == 1) { + cpu->current_token = 0; + } + assert(cpu->in_opal_call > 0); + cpu->in_opal_call--; + + if (msr != mfmsr()) + mtmsrd(msr, 0); + + __this_cpu = (struct cpu_thread *)r16; + + return ret; +} + void add_opal_node(void) { uint64_t base, entry, size; @@ -412,16 +485,24 @@ void add_opal_node(void) dt_add_property_cells(opal_node, "#address-cells", 0); dt_add_property_cells(opal_node, "#size-cells", 0); - if (proc_gen < proc_gen_p9) + if (proc_gen < proc_gen_p9) { dt_add_property_strings(opal_node, "compatible", "ibm,opal-v2", "ibm,opal-v3"); - else + } else if (HAVE_LITTLE_ENDIAN) { + dt_add_property_strings(opal_node, "compatible", "ibm,opal-v3", + "ibm,opal-v4"); + } else { dt_add_property_strings(opal_node, "compatible", "ibm,opal-v3"); + } dt_add_property_cells(opal_node, "opal-msg-async-num", OPAL_MAX_ASYNC_COMP); dt_add_property_cells(opal_node, "opal-msg-size", OPAL_MSG_SIZE); dt_add_property_u64(opal_node, "opal-base-address", base); dt_add_property_u64(opal_node, "opal-entry-address", entry); + if (HAVE_LITTLE_ENDIAN) { + dt_add_property_u64(opal_node, "opal-v4-le-entry-address", + (uint64_t)&opal_v4_le_entry); + } dt_add_property_u64(opal_node, "opal-boot-address", (uint64_t)&boot_entry); dt_add_property_u64(opal_node, "opal-runtime-size", size); diff --git a/include/cpu.h b/include/cpu.h index 5e8acbf6a..b769024d1 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -234,6 +234,15 @@ extern u8 get_available_nr_cores_in_chip(u32 chip_id); for (core = first_available_core_in_chip(chip_id); core; \ core = next_available_core_in_chip(core, chip_id)) +struct cpu_stack { + union { + uint8_t stack[STACK_SIZE]; + struct cpu_thread cpu; + }; +} __align(STACK_SIZE); + +extern struct cpu_stack * const cpu_stacks; + /* Return the caller CPU (only after init_cpu_threads) */ register struct cpu_thread *__this_cpu asm("r16"); static inline __nomcount struct cpu_thread *this_cpu(void) From patchwork Sat May 2 11:36:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281671 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqCP5txDz9sRf for ; Sat, 2 May 2020 23:07:13 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Z83qApVU; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqCP4MmzzDrKh for ; Sat, 2 May 2020 23:07:13 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1042; helo=mail-pj1-x1042.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Z83qApVU; dkim-atps=neutral Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnDM0mtBzDqXX for ; Sat, 2 May 2020 21:37:55 +1000 (AEST) Received: by mail-pj1-x1042.google.com with SMTP id y6so1174744pjc.4 for ; Sat, 02 May 2020 04:37:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8CbCTGoKulhknpMM4/rxzAfwQwKGJTesi/bshjkXojI=; b=Z83qApVUBKCtbtkzywHgfxWapn9K75r0LnWcETRTkUQp8/SMhXukt6U16nji5bh2OR AdOrwpvkUlookCMIUJxLR6WAJRKIhOSQepmcZdRk4xSHSCKvXd6A5iTyxil6h1+YzwCJ bXFGghowCAZh56M/PS7/iQiZxhH0PJsnXveLY87rccPRL55MzRNIQFVZPVzmMRh2pf9t 1ZWRUJxzyVVdPX7KIUWulzZ7SCJpy0stHF28Vb7fSX+i7WM5HBGsZiTx9+2gCURphv04 9dkWbvfkwg56RL977hTSrMcJ+ZH8Oxc3vn/DuEk/Dcz9Z3eCPOzU32Tuchp4OI/hNwoi s16A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8CbCTGoKulhknpMM4/rxzAfwQwKGJTesi/bshjkXojI=; b=lZGNqtJxGChXtqJqse6O+zhPE0MbRP5CPp2W45n2Er9nljGWCw9tNQ8sD0ctPNpTg0 ++uoT+lC3eIE88hYpy0yZy7Jvomp+YPP/hVjGitgxAmoYS+v3kCyrPJUnWPbksg1BLjc F2MmDJjBTm8pmMQQdtavBYXk2RfGJUlzxuqcYpG9owLde57BhrBoSUc6ETScDqj118JE 36Yf7+ywpg8yorvnmxLaZJImC48IarwhSZKteTxln8AHnBY37PwlgugUX06UvnT+dOs1 EzAFKZrf7rH8euMzIwCVGgEozwDFNHuLPG0t1pZ3gKlnVoeuP8jPxh/ixFrIDnaDlp3r yLNA== X-Gm-Message-State: AGi0PuY7Kgolqw9WMMDO3sARL9O4ysw8pc+35LXu3qB0I7dIvoH0J8tS Pr07rDgdYvliRE71PA3YXzhroAoS X-Google-Smtp-Source: APiQypJPfe90ACuZ0Kp3uPSdTl5M+4frhtDjL1cKVnuoRqn6sXQBRtgwucc8UdklFbHXfbOnCCFgvw== X-Received: by 2002:a17:902:50d:: with SMTP id 13mr8853339plf.170.1588419470865; Sat, 02 May 2020 04:37:50 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:50 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:47 +1000 Message-Id: <20200502113649.176329-8-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 7/9] Runtime virtual memory for OPAL V4 X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch removes the real-mode switch from the V4 entry, and allows skiboot to run in virtual mode. When vm_map is used to access addresses outside the global mappings, MSR[DR] is disabled, although MSR[IR] remains on (is this wise? It's not a common configuration for Linux). Signed-off-by: Nicholas Piggin --- core/mem_region.c | 35 +++++++++++++++++++++++++---------- core/opal.c | 20 +++++++++++++++----- core/vm.c | 24 +++++++++++++++++++----- include/cpu.h | 1 + 4 files changed, 60 insertions(+), 20 deletions(-) diff --git a/core/mem_region.c b/core/mem_region.c index 69f24d630..c7a689255 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -168,16 +168,20 @@ static void mem_poison(struct free_hdr *f) unsigned long start = (unsigned long)(f + 1); unsigned long *t = tailer(f); size_t poison_size = (unsigned long)t - start; - void *mem; /* We only poison up to a limit, as otherwise boot is * kinda slow */ if (poison_size > POISON_MEM_REGION_LIMIT) poison_size = POISON_MEM_REGION_LIMIT; - mem = vm_map(start, poison_size, true); - memset(mem, POISON_MEM_REGION_WITH, poison_size); - vm_unmap(start, poison_size); + if (cpu_in_os()) { + memset((void *)start, POISON_MEM_REGION_WITH, poison_size); + } else { + void *mem; + mem = vm_map(start, poison_size, true); + memset(mem, POISON_MEM_REGION_WITH, poison_size); + vm_unmap(start, poison_size); + } } #endif @@ -211,9 +215,14 @@ static void init_allocatable_region(struct mem_region *region) f->hdr.prev_free = false; list_add(®ion->free_list, &f->list); - t = vm_map((unsigned long)tailer(f), sizeof(long), true); - *t = num_longs; - vm_unmap((unsigned long)tailer(f), sizeof(long)); + if (cpu_in_os()) { + t = tailer(f); + *t = num_longs; + } else { + t = vm_map((unsigned long)tailer(f), sizeof(long), true); + *t = num_longs; + vm_unmap((unsigned long)tailer(f), sizeof(long)); + } #if POISON_MEM_REGION == 1 mem_poison(f); @@ -277,9 +286,15 @@ static void make_free(struct mem_region *region, struct free_hdr *f, no_unmap: /* Fix up tailer. */ - t = vm_map((unsigned long)tailer(f), sizeof(long), true); - *t = f->hdr.num_longs; - vm_unmap((unsigned long)tailer(f), sizeof(long)); + if (cpu_in_os()) { + t = tailer(f); + *t = f->hdr.num_longs; + } else { + t = vm_map((unsigned long)tailer(f), sizeof(long), true); + *t = f->hdr.num_longs; + vm_unmap((unsigned long)tailer(f), sizeof(long)); + } + } /* Can we fit this many longs with this alignment in this free block? */ diff --git a/core/opal.c b/core/opal.c index 27ce7a375..7fb4fae86 100644 --- a/core/opal.c +++ b/core/opal.c @@ -398,6 +398,8 @@ static int64_t opal_v4_le_entry(uint64_t token, uint64_t r4, uint64_t r5, { struct cpu_thread *cpu; opal_call_fn *fn; + bool was_vm_setup; + uint64_t old_opal_call_msr; uint64_t msr; uint32_t pir; uint64_t r16; @@ -406,14 +408,20 @@ static int64_t opal_v4_le_entry(uint64_t token, uint64_t r4, uint64_t r5, msr = mfmsr(); assert(!(msr & MSR_EE)); - if (msr & (MSR_IR|MSR_DR)) - mtmsrd(msr & ~(MSR_IR|MSR_DR), 0); - pir = mfspr(SPR_PIR); r16 = (uint64_t)__this_cpu; __this_cpu = &cpu_stacks[pir].cpu; cpu = this_cpu(); + old_opal_call_msr = cpu->opal_call_msr; + cpu->opal_call_msr = msr; + + was_vm_setup = this_cpu()->vm_setup; + if (msr & (MSR_IR|MSR_DR)) + this_cpu()->vm_setup = true; + else + this_cpu()->vm_setup = false; + cpu->in_opal_call++; if (cpu->in_opal_call == 1) { cpu->current_token = token; @@ -453,11 +461,13 @@ out: assert(cpu->in_opal_call > 0); cpu->in_opal_call--; - if (msr != mfmsr()) - mtmsrd(msr, 0); + this_cpu()->vm_setup = was_vm_setup; + cpu->opal_call_msr = old_opal_call_msr; __this_cpu = (struct cpu_thread *)r16; + assert(mfmsr() == msr); + return ret; } diff --git a/core/vm.c b/core/vm.c index 236a0e70b..b2830fccf 100644 --- a/core/vm.c +++ b/core/vm.c @@ -491,9 +491,18 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) assert(!c->vm_local_map_inuse); c->vm_local_map_inuse = true; - if (c->vm_setup) { + if (cpu_in_os() && c->vm_setup) { + assert(c->opal_call_msr & (MSR_IR|MSR_DR)); + newaddr = addr; + mtmsr(c->opal_call_msr & ~MSR_DR); + c->vm_setup = false; + } else if (!c->vm_setup) { + newaddr = addr; + } else { struct vm_map *new = &c->vm_local_map; + assert(!cpu_in_os()); + newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; new->name = "local"; @@ -504,9 +513,6 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) new->writeable = rw; new->executable = false; new->ci = false; - - } else { - newaddr = addr; } return (void *)newaddr + offset; @@ -527,10 +533,18 @@ void vm_unmap(unsigned long addr, unsigned long len) assert(c->vm_local_map_inuse); c->vm_local_map_inuse = false; - if (c->vm_setup) { + if (cpu_in_os() && (c->opal_call_msr & (MSR_IR|MSR_DR))) { + assert(!c->vm_setup); + c->vm_setup = true; + mtmsr(c->opal_call_msr); + } else if (!c->vm_setup) { + return; + } else { struct vm_map *vmm; unsigned long ea; + assert(!cpu_in_os()); + newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; vmm = &c->vm_local_map; diff --git a/include/cpu.h b/include/cpu.h index b769024d1..bbfbf7ca9 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -59,6 +59,7 @@ struct cpu_thread { enum cpu_thread_state state; struct dt_node *node; struct trace_info *trace; + uint64_t opal_call_msr; uint64_t save_r1; void *icp_regs; uint32_t in_opal_call; From patchwork Sat May 2 11:36:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281672 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqCp4hmPz9sRf for ; Sat, 2 May 2020 23:07:34 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=kDLwqCka; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqCp4FyLzDrQq for ; Sat, 2 May 2020 23:07:34 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::644; helo=mail-pl1-x644.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=kDLwqCka; dkim-atps=neutral Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnDN5r4jzDqdD for ; Sat, 2 May 2020 21:37:56 +1000 (AEST) Received: by mail-pl1-x644.google.com with SMTP id h11so4687949plr.11 for ; Sat, 02 May 2020 04:37:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rCEP6BldxdY7MuZwwOakf10oUACekkVw92GMpNbqPtg=; b=kDLwqCkaqvon7bau4xQpsvP2L9SDPv2QyRJTXz80zmFCiZwpqKQ0q8TQa560cd9AGO GxXWMRU5V1VoIXAskBc01ic9BfAy4DxWJ5NqK8Zk/NHfzGlDa8WxhLROKXCRxWC4OBsg o79LbP4/quJeYq0JZH2Pwizs3gjDxGmVMDFp9kro9rS6juDqH9eTxZoVpWdBWo4N69SX AoY7GcRzvpEoxWHm1eZPLx1ICsvLnEUv5RzIOe7vGp5Tz4CtlRaq6yMB21YBmmC0nSEi mNoHROW3Y5HGD81NUpXOfyE1rePJJDyjplSkLkSav8BRbyhN74qoNNwRIy5Fb1YAAmX5 Crag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rCEP6BldxdY7MuZwwOakf10oUACekkVw92GMpNbqPtg=; b=P1CAs+1/kHSruNZjPDJ3/FERvsjpgVBqyvYCq2FkCpxtZyi9lD+UtrDyuulBTMk4Vo 7FggXNpa9N1tL01K9Q75cdibQLIVPtRU7O+brJp7D6gi0SKUfl5t6rPO4k1qdgAlHg7n TcwXeXZFnpHdZGVBQMooEiblqffSRfMH+xt1xceJZuKqrmg7QF1/42LS35AeGy56iA4C LQXBkctKEt8D67YJuKQgcRNFT8T6T//3DlsIr961pItbkw97CjsSMn2GRpwnVsfCuJJ3 ZaYpybdLc0b9Ea2Zcg92szobogHz7vJvw1CMEpLgxj+rNN2i8LlTTm2ifK/RmZqZC5kX Faog== X-Gm-Message-State: AGi0Pubh/L8b0AFnzYKzaXtXdzhvecFOUJP+RGpv1n+2rRe+kA2LS8iP FB0tQv1q5axsYawl7JyfBJAfDDOZ X-Google-Smtp-Source: APiQypL8vE9FOFkyniqulBfvOEFofFMTDT3AbJdt5GipABQfEhhLVDOnM9KOdml5eN3w0QvWq2w2VQ== X-Received: by 2002:a17:90a:df8b:: with SMTP id p11mr5233288pjv.137.1588419474086; Sat, 02 May 2020 04:37:54 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:53 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:48 +1000 Message-Id: <20200502113649.176329-9-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 8/9] OPAL V4: initial OS-operations (traps, printf) X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This completes OPAL V4, where the OS can provide servies to OPAL. To start with for this patch, the OS is to provide printf console and logging support, and trap handling and decoding. When the OS calls OPAL_REGISTER_OS_OPS, skiboot patches its traps back in, for the OS to handle. It sets the console to raw mode (introduced in an earlier patch) and no longer uses its console facilities. It calls the OS to log messages. Other services may be added to the size-versioned structure. The benefit of this is that 1) OPAL messages get into kernel log facilities, and 2) Linux's path to the console is much shorter, with no locks or buffering between the kernel and the uart MMIO. Things like xmon and BUG printing are careful to be as reliable as possible, I've encountered times when the skiboot console code trips us up here. Other OS facilities that may be useful: - Sleep facilities, which could abstract away highly implementation specific idle sleep, and expose calls for a simple generic OPAL driver. - ftrace and/or kprobes facilities. - perf interrupts. - Lockup watchdog interrupts. - Timer facilities. Skiboot could request an OS timer is scheduled which then makes an OPAL call with an opaque pointer which skiboot can then use to run functions asynchronously, for example. - Interrupt enable... possibly not, we'd rather keep calls as short as possible. Except perhaps for watchog and perf interrupts. Signed-off-by: Nicholas Piggin --- core/console-log.c | 9 ++++++++ core/console.c | 11 ++++++++++ core/fast-reboot.c | 7 +++++- core/init.c | 4 +--- core/opal.c | 48 +++++++++++++++++++++++++++++++++++++++++ include/mem_region.h | 1 + include/opal-api.h | 7 +++++- include/opal-internal.h | 9 ++++++++ 8 files changed, 91 insertions(+), 5 deletions(-) diff --git a/core/console-log.c b/core/console-log.c index 21a1442bd..d73913894 100644 --- a/core/console-log.c +++ b/core/console-log.c @@ -8,6 +8,7 @@ * Copyright 2013-2018 IBM Corp. */ +#include #include "skiboot.h" #include "unistd.h" #include "stdio.h" @@ -15,6 +16,8 @@ #include "timebase.h" #include +extern void os_printf(uint32_t log_level, const char *str); + static int vprlog(int log_level, const char *fmt, va_list ap) { int count; @@ -32,6 +35,12 @@ static int vprlog(int log_level, const char *fmt, va_list ap) if (log_level > (debug_descriptor.console_log_levels >> 4)) return 0; + if (opal_v4_os) { + count = vsnprintf(buffer, sizeof(buffer), fmt, ap); + os_printf(log_level, buffer); + return count; + } + count = snprintf(buffer, sizeof(buffer), "[%5lu.%09lu,%d] ", tb_to_secs(tb), tb_remaining_nsecs(tb), log_level); count+= vsnprintf(buffer+count, sizeof(buffer)-count, fmt, ap); diff --git a/core/console.c b/core/console.c index 336dda7a1..9c882c6a4 100644 --- a/core/console.c +++ b/core/console.c @@ -259,8 +259,19 @@ ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count) return count; } +extern void os_printf(uint32_t log_level, const char *str); + ssize_t write(int fd __unused, const void *buf, size_t count) { + if (opal_v4_os) { + char *b = malloc(count+1); + memcpy(b, buf, count); + b[count] = '\0'; + os_printf(4, b); + free(b); + return count; + } + return console_write(true, buf, count); } diff --git a/core/fast-reboot.c b/core/fast-reboot.c index e7f3b5c67..fc5dd8bf4 100644 --- a/core/fast-reboot.c +++ b/core/fast-reboot.c @@ -334,7 +334,12 @@ void __noreturn fast_reboot_entry(void) /* Restore skiboot vectors */ copy_exception_vectors(); copy_sreset_vector(); - patch_traps(true); + if (opal_v4_os) { + set_opal_console_to_cooked(); + opal_v4_os = false; + } else { + patch_traps(true); + } } /* Must wait for others to because shared SPRs like HID0 are only set diff --git a/core/init.c b/core/init.c index 95c0339cf..81672b0d4 100644 --- a/core/init.c +++ b/core/init.c @@ -86,8 +86,6 @@ struct debug_descriptor debug_descriptor = { #endif }; -static void checksum_romem(void); - static bool try_load_elf64_le(struct elf_hdr *header) { struct elf64le_hdr *kh = (struct elf64le_hdr *)header; @@ -1028,7 +1026,7 @@ static uint32_t mem_csum(void *_p, void *_e) static uint32_t romem_csum; -static void checksum_romem(void) +void checksum_romem(void) { uint32_t csum; diff --git a/core/opal.c b/core/opal.c index 7fb4fae86..5454cac67 100644 --- a/core/opal.c +++ b/core/opal.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Pending events to signal via opal_poll_events */ uint64_t opal_pending_events; @@ -471,6 +472,53 @@ out: return ret; } +bool opal_v4_os = false; +struct os_ops os_ops; + +static int64_t opal_register_os_ops(struct opal_os_ops *ops, uint64_t size) +{ + struct cpu_thread *cpu; + + if (size < 8) + return OPAL_PARAMETER; + + for_each_cpu(cpu) { + if (cpu == this_cpu()) + continue; + if (cpu->state == cpu_state_os) + return OPAL_BUSY; + } + + if (opal_v4_os) + return OPAL_WRONG_STATE; + + if (!verify_romem()) { + prlog(PR_NOTICE, "OPAL checksums did not match\n"); + disable_fast_reboot("Inconsistent firmware romem checksum"); + return OPAL_WRONG_STATE; + } + + /* v4 must handle OPAL traps */ + patch_traps(true); + + if (size >= 8) { + os_ops.os_printf = (void *)be64_to_cpu(ops->os_printf); + set_opal_console_to_raw(); + } + + checksum_romem(); + + opal_v4_os = true; + + return OPAL_SUCCESS; +} +opal_call(OPAL_REGISTER_OS_OPS, opal_register_os_ops, 2); + +void os_printf(uint32_t log_level, const char *str) +{ + os_ops.os_printf(log_level, str); +} + void add_opal_node(void) { uint64_t base, entry, size; diff --git a/include/mem_region.h b/include/mem_region.h index 47c3bd70c..f56eef2d8 100644 --- a/include/mem_region.h +++ b/include/mem_region.h @@ -73,6 +73,7 @@ struct mem_region *find_mem_region(const char *name); bool mem_range_is_reserved(uint64_t start, uint64_t size); /* Read-only memory checksum */ +void checksum_romem(void); bool verify_romem(void); #endif /* __MEMORY_REGION */ diff --git a/include/opal-api.h b/include/opal-api.h index e5142f121..139dc1d43 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -231,7 +231,8 @@ #define OPAL_SYM_TO_ADDR 182 #define OPAL_REPORT_TRAP 183 #define OPAL_FIND_VM_AREA 184 -#define OPAL_LAST 184 +#define OPAL_REGISTER_OS_OPS 185 +#define OPAL_LAST 185 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ @@ -1275,6 +1276,10 @@ struct opal_vm_area { __be64 vm_flags; }; +struct opal_os_ops { + __be64 os_printf; /* void printf(int32_t level, const char *str) */ +}; + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/include/opal-internal.h b/include/opal-internal.h index f6ca7ac32..64f372489 100644 --- a/include/opal-internal.h +++ b/include/opal-internal.h @@ -18,6 +18,15 @@ struct opal_table_entry { u32 nargs; }; +struct os_ops { + void (*os_printf)(uint32_t log_level, const char *str); +}; + +extern bool opal_v4_os; +extern struct os_ops os_ops; + +extern void os_printf(uint32_t log_level, const char *str); + #ifdef __CHECKER__ #define __opal_func_test_arg(__func, __nargs) 0 #else From patchwork Sat May 2 11:36:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281673 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqD922cxz9sRf for ; Sat, 2 May 2020 23:07:53 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=CyJDezAF; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqD84cXWzDrQg for ; Sat, 2 May 2020 23:07:52 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::643; helo=mail-pl1-x643.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=CyJDezAF; dkim-atps=neutral Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnDS2QSKzDr7J for ; Sat, 2 May 2020 21:38:00 +1000 (AEST) Received: by mail-pl1-x643.google.com with SMTP id w3so4698988plz.5 for ; Sat, 02 May 2020 04:37:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=grxRJ5s6YFHViXGJBy85nlsQKAZLuxpSCvzZfi/LTi0=; b=CyJDezAFm10KQPKiB4OEjk1n04soqOge496rBQX3YUh4iNIX96J/ye7aVbNXvClKPt R6dYhWUHvC8QMNyGnigaU00vSNpkxyMVtamFM7hs84t7yRNcWeqI1bTCSyptI8Rky0D6 s2YMxjppv8n9GwK38A0tx0dHjtnnsaSeCe6jGH0mVyi50EaiWDrOL97jF4zUogMu12Wj Jl0qqS9YsnyXGEgKF4G79PBt5KXSDQZBMS1Jj1b8S6NmnZzZRY4lyi7IlEI8igwouREF VacZaeJdBJHpHFa5L9qNq0evEjGbccM3Eavdl5ULCRreY9LsidXy/llyn2kI2MeS+8RY gFhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=grxRJ5s6YFHViXGJBy85nlsQKAZLuxpSCvzZfi/LTi0=; b=CQj+JpbdBuMphRBmCQAAinxK89WlkFT38ltYIfBLvvYXUHO0W/JDQBO76KXEsxlfNC dkp1/Fx+PUwN6+j5UG6oF0ii8mBBzSeOqLrZRMyjjs4CeLHgWnJYItkr7NVfQeMANwq0 OPklfw2Dxe8elNc9Qeew4ya3mDnfA+atCOS1QCL7Vy5a/cwv7JHDclP4n9QTIh18dcjQ aYjzZg4TkFYcOX5gTGI9CG2mAHRd4r9Ziw+2+Xsedltq9yiZr6xDB/pEbLbFyC/Gedxk VaebdmDelOgX5AOq6eIJUqpJ9j6wOPsH1GoLbzQFILODpug2cojTtm9JRomPzLPrpbOa Npzw== X-Gm-Message-State: AGi0PuZi4o+ku6KosQO24gG6Bpw7Ed1xJlgTzdjdYdgN2wYmyQ8bb4Ac XKyopgCwPM1H3qnKCYJewfvG5FRQ X-Google-Smtp-Source: APiQypKxLr+e7FvJ69BM3Zf0fzkcIWyVoeCAzFVHXX1zZqQ2Yeal28f0ptqC71mgNs+lQQXs+/d/1w== X-Received: by 2002:a17:90a:1998:: with SMTP id 24mr5588429pji.0.1588419476994; Sat, 02 May 2020 04:37:56 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:56 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:49 +1000 Message-Id: <20200502113649.176329-10-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 9/9] OPAL V4: local vm_map/unmap operations X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This implements vm_map/unmap API that an OS can provide. The per-CPU areas are advertised by OPAL_FIND_VM_AREA so page tables can be allocated ahead of time. The ops must not sleep or cause IPIs. This allows skiboot to run entirely in virtual mode and not have to drop to real mode to cope with vm_map(). Signed-off-by: Nicholas Piggin --- core/console-log.c | 2 +- core/opal.c | 37 ++++++++++++++++++++++ core/vm.c | 70 ++++++++++++++++++++++++++++++++++------- include/config.h | 1 + include/opal-api.h | 3 ++ include/opal-internal.h | 4 +++ include/skiboot.h | 1 + 7 files changed, 105 insertions(+), 13 deletions(-) diff --git a/core/console-log.c b/core/console-log.c index d73913894..2899c1c56 100644 --- a/core/console-log.c +++ b/core/console-log.c @@ -35,7 +35,7 @@ static int vprlog(int log_level, const char *fmt, va_list ap) if (log_level > (debug_descriptor.console_log_levels >> 4)) return 0; - if (opal_v4_os) { + if (os_ops.os_printf) { count = vsnprintf(buffer, sizeof(buffer), fmt, ap); os_printf(log_level, buffer); return count; diff --git a/core/opal.c b/core/opal.c index 5454cac67..bb71ac374 100644 --- a/core/opal.c +++ b/core/opal.c @@ -506,6 +506,12 @@ static int64_t opal_register_os_ops(struct opal_os_ops *ops, uint64_t size) set_opal_console_to_raw(); } + if (size >= 24) { + os_ops.os_vm_map = (void *)be64_to_cpu(ops->os_vm_map); + os_ops.os_vm_unmap = (void *)be64_to_cpu(ops->os_vm_unmap); + vm_resurrect(); + } + checksum_romem(); opal_v4_os = true; @@ -519,6 +525,37 @@ void os_printf(uint32_t log_level, const char *str) os_ops.os_printf(log_level, str); } +int64_t os_vm_map(uint64_t ea, uint64_t pa, uint64_t flags) +{ + struct cpu_thread *cpu = this_cpu(); + uint64_t msr = mfmsr(); + int64_t ret; + + if (msr != cpu->opal_call_msr) + mtmsrd(cpu->opal_call_msr, 0); + + ret = os_ops.os_vm_map(ea, pa, flags); + + if (msr != cpu->opal_call_msr) + mtmsrd(cpu->opal_call_msr, 0); + + return ret; +} + +void os_vm_unmap(uint64_t ea) +{ + struct cpu_thread *cpu = this_cpu(); + uint64_t msr = mfmsr(); + + if (msr != cpu->opal_call_msr) + mtmsrd(cpu->opal_call_msr, 0); + + os_ops.os_vm_unmap(ea); + + if (msr != cpu->opal_call_msr) + mtmsrd(cpu->opal_call_msr, 0); +} + void add_opal_node(void) { uint64_t base, entry, size; diff --git a/core/vm.c b/core/vm.c index b2830fccf..2ecfaeb44 100644 --- a/core/vm.c +++ b/core/vm.c @@ -35,6 +35,7 @@ static bool vm_globals_allocated = false; #define LOCAL_SLB_BASE GLOBAL_SLB_NR #define LOCAL_EA_PERCPU (SLB_SZ) +#define OS_LOCAL_EA_PERCPU (2ULL*1024*1024) #define LOCAL_EA_BEGIN 0x0008000000000000ULL #define LOCAL_EA_END 0x0009000000000000ULL @@ -485,13 +486,16 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) addr &= ~(PAGE_SIZE - 1); len = end - addr; - assert(len <= LOCAL_EA_PERCPU); + if (cpu_in_os()) + assert(len <= OS_LOCAL_EA_PERCPU); + else + assert(len <= LOCAL_EA_PERCPU); /* Can't do nested mappings */ assert(!c->vm_local_map_inuse); c->vm_local_map_inuse = true; - if (cpu_in_os() && c->vm_setup) { + if (cpu_in_os() && c->vm_setup && !os_ops.os_vm_map) { assert(c->opal_call_msr & (MSR_IR|MSR_DR)); newaddr = addr; mtmsr(c->opal_call_msr & ~MSR_DR); @@ -501,9 +505,10 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) } else { struct vm_map *new = &c->vm_local_map; - assert(!cpu_in_os()); - - newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; + if (cpu_in_os()) + newaddr = LOCAL_EA_BEGIN + OS_LOCAL_EA_PERCPU * c->pir; + else + newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; new->name = "local"; new->address = newaddr; @@ -513,6 +518,20 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) new->writeable = rw; new->executable = false; new->ci = false; + + if (cpu_in_os()) { + uint64_t ea, pa, flags; + + flags = vmm_os_map_flags(new); + + pa = new->pa; + ea = newaddr; + while (ea < newaddr + len) { + os_vm_map(ea, pa, flags); + ea += OS_PAGE_SIZE; + pa += OS_PAGE_SIZE; + } + } } return (void *)newaddr + offset; @@ -528,12 +547,15 @@ void vm_unmap(unsigned long addr, unsigned long len) addr &= ~(PAGE_SIZE - 1); len = end - addr; - assert(len <= LOCAL_EA_PERCPU); + if (cpu_in_os()) + assert(len <= OS_LOCAL_EA_PERCPU); + else + assert(len <= LOCAL_EA_PERCPU); assert(c->vm_local_map_inuse); c->vm_local_map_inuse = false; - if (cpu_in_os() && (c->opal_call_msr & (MSR_IR|MSR_DR))) { + if (cpu_in_os() && (c->opal_call_msr & (MSR_IR|MSR_DR)) && !os_ops.os_vm_map) { assert(!c->vm_setup); c->vm_setup = true; mtmsr(c->opal_call_msr); @@ -543,9 +565,10 @@ void vm_unmap(unsigned long addr, unsigned long len) struct vm_map *vmm; unsigned long ea; - assert(!cpu_in_os()); - - newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; + if (cpu_in_os()) + newaddr = LOCAL_EA_BEGIN + OS_LOCAL_EA_PERCPU * c->pir; + else + newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; vmm = &c->vm_local_map; assert(newaddr == vmm->address); @@ -554,8 +577,13 @@ void vm_unmap(unsigned long addr, unsigned long len) ea = newaddr; while (ea < newaddr + len) { - htab_remove(ea, true); - ea += PAGE_SIZE; + if (cpu_in_os()) { + os_vm_unmap(ea); + ea += OS_PAGE_SIZE; + } else { + htab_remove(ea, true); + ea += PAGE_SIZE; + } } } } @@ -987,6 +1015,24 @@ static int64_t opal_find_vm_area(uint64_t addr, struct opal_vm_area *opal_vm_are return OPAL_SUCCESS; } + if (addr < LOCAL_EA_BEGIN) { + opal_vm_area->address = cpu_to_be64(LOCAL_EA_BEGIN); + opal_vm_area->length = cpu_to_be64(cpu_max_pir * OS_LOCAL_EA_PERCPU); + opal_vm_area->pa = 0; + opal_vm_area->vm_flags = 0; + + printf("0x%016llx-0x%016llx flags=0 (per-cpu maps)\n", LOCAL_EA_BEGIN, LOCAL_EA_BEGIN + cpu_max_pir * OS_LOCAL_EA_PERCPU); + + return OPAL_SUCCESS; + } + return OPAL_EMPTY; } opal_call(OPAL_FIND_VM_AREA, opal_find_vm_area, 2); + +void vm_resurrect(void) +{ + /* OS takes over control of providing VM mappings */ + prlog(PR_NOTICE, "VMM: Rise from your grave!\n"); + print_maps(); +} diff --git a/include/config.h b/include/config.h index fd9521fa2..70608d120 100644 --- a/include/config.h +++ b/include/config.h @@ -6,6 +6,7 @@ /* Alignment to which skiboot lays out memory. */ #define PAGE_SIZE 0x10000 +#define OS_PAGE_SIZE 0x10000 #define HAVE_TYPEOF 1 #define HAVE_BUILTIN_TYPES_COMPATIBLE_P 1 diff --git a/include/opal-api.h b/include/opal-api.h index 139dc1d43..3c630f02e 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -1278,6 +1278,9 @@ struct opal_vm_area { struct opal_os_ops { __be64 os_printf; /* void printf(int32_t level, const char *str) */ + __be64 os_vm_map; /* void os_vm_map(uint64_t ea, uint64_t pa, uint64_t flags) */ + __be64 os_vm_unmap; /* static void os_vm_unmap(uint64_t ea) */ + }; #endif /* __ASSEMBLY__ */ diff --git a/include/opal-internal.h b/include/opal-internal.h index 64f372489..af5216639 100644 --- a/include/opal-internal.h +++ b/include/opal-internal.h @@ -20,12 +20,16 @@ struct opal_table_entry { struct os_ops { void (*os_printf)(uint32_t log_level, const char *str); + int64_t (*os_vm_map)(uint64_t ea, uint64_t pa, uint64_t flags); + void (*os_vm_unmap)(uint64_t ea); }; extern bool opal_v4_os; extern struct os_ops os_ops; extern void os_printf(uint32_t log_level, const char *str); +extern int64_t os_vm_map(uint64_t ea, uint64_t pa, uint64_t flags); +extern void os_vm_unmap(uint64_t ea); #ifdef __CHECKER__ #define __opal_func_test_arg(__func, __nargs) 0 diff --git a/include/skiboot.h b/include/skiboot.h index aacb425f7..5f0e3e0f7 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -362,5 +362,6 @@ bool vm_dslb(uint64_t nia, uint64_t dar); bool vm_islb(uint64_t nia); bool vm_dsi(uint64_t nia, uint64_t dar, uint32_t dsisr); bool vm_isi(uint64_t nia); +void vm_resurrect(void); #endif /* __SKIBOOT_H */