From owner-svn-src-head@freebsd.org Tue Sep 3 14:06:09 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5A30DDC2BD; Tue, 3 Sep 2019 14:06:04 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2610:1c1:1:6074::16:84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46N7yz3jjqz4P86; Tue, 3 Sep 2019 14:06:03 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 1452) id 772781A05E; Tue, 3 Sep 2019 14:05:56 +0000 (UTC) X-Original-To: yuripv@localmail.freebsd.org Delivered-To: yuripv@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [96.47.72.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id D7F3A1AE58; Tue, 2 Apr 2019 04:00:06 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2610:1c1:1:6074::16:84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 51FE370966; Tue, 2 Apr 2019 04:00:06 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 538) id 3448F1AE56; Tue, 2 Apr 2019 04:00:06 +0000 (UTC) Delivered-To: src-committers@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [96.47.72.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id 4A8DE1AE53 for ; Tue, 2 Apr 2019 04:00:03 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 7DDB97095A; Tue, 2 Apr 2019 04:00:02 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1E75A2083B; Tue, 2 Apr 2019 04:00:02 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x32402tO076809; Tue, 2 Apr 2019 04:00:02 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x32401O8076808; Tue, 2 Apr 2019 04:00:01 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201904020400.x32401O8076808@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r345789 - head/sys/powerpc/powernv X-SVN-Group: head X-SVN-Commit-Author: jhibbits X-SVN-Commit-Paths: head/sys/powerpc/powernv X-SVN-Commit-Revision: 345789 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk X-Loop: FreeBSD.org Sender: owner-src-committers@freebsd.org X-Rspamd-Queue-Id: 51FE370966 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.94 / 15.00]; local_wl_from(0.00)[freebsd.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_SHORT(-0.94)[-0.943,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] Status: O X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Date: Tue, 03 Sep 2019 14:06:09 -0000 X-Original-Date: Tue, 2 Apr 2019 04:00:01 +0000 (UTC) X-List-Received-Date: Tue, 03 Sep 2019 14:06:09 -0000 Author: jhibbits Date: Tue Apr 2 04:00:01 2019 New Revision: 345789 URL: https://svnweb.freebsd.org/changeset/base/345789 Log: powerpc/powernv: Add OPAL heartbeat thread Summary: OPAL needs to be kicked periodically in order for the firmware to make progress on its tasks. To do so, create a heartbeat thread to perform this task every N milliseconds, defined by the device tree. This task is also a central location to handle all messages received from OPAL. Reviewed By: luporl Differential Revision: https://reviews.freebsd.org/D19743 Modified: head/sys/powerpc/powernv/opal.h head/sys/powerpc/powernv/opal_dev.c Modified: head/sys/powerpc/powernv/opal.h ============================================================================== --- head/sys/powerpc/powernv/opal.h Mon Apr 1 23:37:21 2019 (r345788) +++ head/sys/powerpc/powernv/opal.h Tue Apr 2 04:00:01 2019 (r345789) @@ -31,6 +31,7 @@ #include #include +#include /* Check if OPAL is correctly instantiated. Will try to instantiate it. */ int opal_check(void); @@ -72,6 +73,7 @@ int opal_call(uint64_t token, ...); #define OPAL_RETURN_CPU 69 #define OPAL_REINIT_CPUS 70 #define OPAL_CHECK_TOKEN 80 +#define OPAL_GET_MSG 85 #define OPAL_CHECK_ASYNC_COMPLETION 86 #define OPAL_SENSOR_READ 88 #define OPAL_HANDLE_HMI 98 @@ -140,6 +142,19 @@ int opal_call(uint64_t token, ...); #define OPAL_TOKEN_ABSENT 0 #define OPAL_TOKEN_PRESENT 1 +#define OPAL_EVENT_OPAL_INTERNAL 0x1 +#define OPAL_EVENT_NVRAM 0x2 +#define OPAL_EVENT_RTC 0x4 +#define OPAL_EVENT_CONSOLE_INPUT 0x8 +#define OPAL_EVENT_CONSOLE_OUTPUT 0x10 +#define OPAL_EVENT_ERROR_LOG_AVAIL 0x20 +#define OPAL_EVENT_ERROR_LOG 0x40 +#define OPAL_EVENT_EPOW 0x80 +#define OPAL_EVENT_LED_STATUS 0x100 +#define OPAL_EVENT_PCI_ERROR 0x200 +#define OPAL_EVENT_DUMP_AVAIL 0x400 +#define OPAL_EVENT_MSG_PENDING 0x800 + #define OPAL_HMI_FLAGS_TB_RESYNC (1ull << 0) #define OPAL_HMI_FLAGS_DEC_LOST (1ull << 1) #define OPAL_HMI_FLAGS_HDEC_LOST (1ull << 2) @@ -188,4 +203,17 @@ int opal_alloc_async_token(void); void opal_free_async_token(int); int opal_wait_completion(void *, uint64_t, uint64_t); +typedef void (*opal_msg_handler_fn)(void *, struct opal_msg *); +EVENTHANDLER_DECLARE(OPAL_ASYNC_COMP, opal_msg_handler_fn); +EVENTHANDLER_DECLARE(OPAL_EPOW, opal_msg_handler_fn); +EVENTHANDLER_DECLARE(OPAL_SHUTDOWN, opal_msg_handler_fn); +EVENTHANDLER_DECLARE(OPAL_HMI_EVT, opal_msg_handler_fn); +EVENTHANDLER_DECLARE(OPAL_DPO, opal_msg_handler_fn); +EVENTHANDLER_DECLARE(OPAL_OCC, opal_msg_handler_fn); +EVENTHANDLER_LIST_DECLARE(OPAL_ASYNC_COMP); +EVENTHANDLER_LIST_DECLARE(OPAL_EPOW); +EVENTHANDLER_LIST_DECLARE(OPAL_SHUTDOWN); +EVENTHANDLER_LIST_DECLARE(OPAL_HMI_EVT); +EVENTHANDLER_LIST_DECLARE(OPAL_DPO); +EVENTHANDLER_LIST_DECLARE(OPAL_OCC); #endif Modified: head/sys/powerpc/powernv/opal_dev.c ============================================================================== --- head/sys/powerpc/powernv/opal_dev.c Mon Apr 1 23:37:21 2019 (r345788) +++ head/sys/powerpc/powernv/opal_dev.c Tue Apr 2 04:00:01 2019 (r345789) @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -59,6 +60,8 @@ static const struct ofw_bus_devinfo *opaldev_get_devin device_t child); static void opal_shutdown(void *arg, int howto); +static void opal_handle_shutdown_message(void *unused, + struct opal_msg *msg); static void opal_intr(void *); static device_method_t opaldev_methods[] = { @@ -94,6 +97,49 @@ static devclass_t opaldev_devclass; DRIVER_MODULE(opaldev, ofwbus, opaldev_driver, opaldev_devclass, 0, 0); +static void opal_heartbeat(void); +static void opal_handle_messages(void); + +static struct proc *opal_hb_proc; +static struct kproc_desc opal_heartbeat_kp = { + "opal_heartbeat", + opal_heartbeat, + &opal_hb_proc +}; + +SYSINIT(opal_heartbeat_setup, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, kproc_start, + &opal_heartbeat_kp); + +static int opal_heartbeat_ms; +EVENTHANDLER_LIST_DEFINE(OPAL_ASYNC_COMP); +EVENTHANDLER_LIST_DEFINE(OPAL_EPOW); +EVENTHANDLER_LIST_DEFINE(OPAL_SHUTDOWN); +EVENTHANDLER_LIST_DEFINE(OPAL_HMI_EVT); +EVENTHANDLER_LIST_DEFINE(OPAL_DPO); +EVENTHANDLER_LIST_DEFINE(OPAL_OCC); + +#define OPAL_SOFT_OFF 0 +#define OPAL_SOFT_REBOOT 1 + +static void +opal_heartbeat(void) +{ + uint64_t events; + + if (opal_heartbeat_ms == 0) + kproc_exit(0); + + while (1) { + events = 0; + /* Turn the OPAL state crank */ + opal_call(OPAL_POLL_EVENTS, vtophys(&events)); + if (events & OPAL_EVENT_MSG_PENDING) + opal_handle_messages(); + tsleep(opal_hb_proc, 0, "opal", + MSEC_2_TICKS(opal_heartbeat_ms)); + } +} + static int opaldev_probe(device_t dev) { @@ -150,9 +196,13 @@ opaldev_attach(device_t dev) if (rv == OPAL_SUCCESS) clock_register(dev, 2000); + EVENTHANDLER_REGISTER(OPAL_SHUTDOWN, opal_handle_shutdown_message, + NULL, EVENTHANDLER_PRI_ANY); EVENTHANDLER_REGISTER(shutdown_final, opal_shutdown, NULL, SHUTDOWN_PRI_LAST); + OF_getencprop(ofw_bus_get_node(dev), "ibm,heartbeat-ms", + &opal_heartbeat_ms, sizeof(opal_heartbeat_ms)); /* Bind to interrupts */ for (i = 0; (irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_ACTIVE)) != NULL; i++) @@ -306,13 +356,68 @@ opal_shutdown(void *arg, int howto) } static void +opal_handle_shutdown_message(void *unused, struct opal_msg *msg) +{ + int howto; + + switch (be64toh(msg->params[0])) { + case OPAL_SOFT_OFF: + howto = RB_POWEROFF; + break; + case OPAL_SOFT_REBOOT: + howto = RB_REROOT; + break; + } + shutdown_nice(howto); +} + +static void +opal_handle_messages(void) +{ + static struct opal_msg msg; + uint64_t rv; + uint32_t type; + + rv = opal_call(OPAL_GET_MSG, vtophys(&msg), sizeof(msg)); + + if (rv != OPAL_SUCCESS) + return; + + type = be32toh(msg.msg_type); + switch (type) { + case OPAL_MSG_ASYNC_COMP: + EVENTHANDLER_DIRECT_INVOKE(OPAL_ASYNC_COMP, &msg); + break; + case OPAL_MSG_EPOW: + EVENTHANDLER_DIRECT_INVOKE(OPAL_EPOW, &msg); + break; + case OPAL_MSG_SHUTDOWN: + EVENTHANDLER_DIRECT_INVOKE(OPAL_SHUTDOWN, &msg); + break; + case OPAL_MSG_HMI_EVT: + EVENTHANDLER_DIRECT_INVOKE(OPAL_HMI_EVT, &msg); + break; + case OPAL_MSG_DPO: + EVENTHANDLER_DIRECT_INVOKE(OPAL_DPO, &msg); + break; + case OPAL_MSG_OCC: + EVENTHANDLER_DIRECT_INVOKE(OPAL_OCC, &msg); + break; + default: + printf("Unknown OPAL message type %d\n", type); + } +} + +static void opal_intr(void *xintr) { uint64_t events = 0; opal_call(OPAL_HANDLE_INTERRUPT, (uint32_t)(uint64_t)xintr, vtophys(&events)); - /* XXX: do something useful with this information */ + /* Wake up the heartbeat, if it's been setup. */ + if (events != 0 && opal_hb_proc != NULL) + wakeup(opal_hb_proc); }