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