Date: Fri, 16 Jun 2017 12:17:41 -0400 From: Ed Maste <emaste@freebsd.org> To: Andrew Turner <andrew@freebsd.org> Cc: "src-committers@freebsd.org" <src-committers@freebsd.org>, "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>, "svn-src-head@freebsd.org" <svn-src-head@freebsd.org> Subject: Re: svn commit: r281466 - in head/sys: arm/conf conf dev/psci Message-ID: <CAPyFy2BGm6LSxYs7-ipcd8578izVrn_4wToFAEKigmfDHhDA8w@mail.gmail.com> In-Reply-To: <201504121300.t3CD0xk7083878@svn.freebsd.org> References: <201504121300.t3CD0xk7083878@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 12 April 2015 at 09:00, Andrew Turner <andrew@freebsd.org> wrote: > Author: andrew > Date: Sun Apr 12 13:00:58 2015 > New Revision: 281466 > URL: https://svnweb.freebsd.org/changeset/base/281466 > > Log: > Add a driver for the ARM Power State Coordination Interface (PSCI). This > handles versions 0.1 and 0.2 of the standard on 32-bit ARM. Building armv6 with the clang500-import branch now reports psci_arm.S:45:2: error: instruction requres: TrustZone smc #0 ^ > > With this driver we can shutdown in QEMU. Further work is needed to > turn secondary cores on on boot and to support later revisions of the > specification. > > Submitted by: Robin Randhawa <Robin.Randhawa at ARM.com> > Sponsored by: The FreeBSD Foundation > > Added: > head/sys/dev/psci/ > head/sys/dev/psci/psci.c (contents, props changed) > head/sys/dev/psci/psci.h (contents, props changed) > head/sys/dev/psci/psci_arm.S (contents, props changed) > Modified: > head/sys/arm/conf/VIRT > head/sys/conf/files.arm > > Modified: head/sys/arm/conf/VIRT > ============================================================================== > --- head/sys/arm/conf/VIRT Sun Apr 12 12:31:19 2015 (r281465) > +++ head/sys/arm/conf/VIRT Sun Apr 12 13:00:58 2015 (r281466) > @@ -82,6 +82,7 @@ device uart > device pty > device snp > device pl011 > +device psci > > device virtio > device virtio_mmio > > Modified: head/sys/conf/files.arm > ============================================================================== > --- head/sys/conf/files.arm Sun Apr 12 12:31:19 2015 (r281465) > +++ head/sys/conf/files.arm Sun Apr 12 13:00:58 2015 (r281466) > @@ -85,6 +85,8 @@ dev/fdt/fdt_arm_platform.c optional plat > dev/hwpmc/hwpmc_arm.c optional hwpmc > dev/hwpmc/hwpmc_armv7.c optional hwpmc armv6 > dev/kbd/kbd.c optional sc | vt > +dev/psci/psci.c optional psci > +dev/psci/psci_arm.S optional psci > dev/syscons/scgfbrndr.c optional sc > dev/syscons/scterm-teken.c optional sc > dev/syscons/scvtb.c optional sc > > Added: head/sys/dev/psci/psci.c > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/dev/psci/psci.c Sun Apr 12 13:00:58 2015 (r281466) > @@ -0,0 +1,286 @@ > +/*- > + * Copyright (c) 2014 Robin Randhawa > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + * > + */ > + > +/* > + * This implements support for ARM's Power State Co-ordination Interface > + * [PSCI]. The implementation adheres to version 0.2 of the PSCI specification > + * but also supports v0.1. PSCI standardizes operations such as system reset, CPU > + * on/off/suspend. PSCI requires a compliant firmware implementation. > + * > + * The PSCI specification used for this implementation is available at: > + * > + * <http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0022b/index.html>. > + * > + * TODO: > + * - Add support for remaining PSCI calls [this implementation only > + * supports get_version, system_reset and cpu_on]. > + */ > + > +#include <sys/cdefs.h> > +__FBSDID("$FreeBSD$"); > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/bus.h> > +#include <sys/eventhandler.h> > +#include <sys/kernel.h> > +#include <sys/module.h> > +#include <sys/reboot.h> > + > +#include <machine/bus.h> > + > +#include <dev/fdt/fdt_common.h> > +#include <dev/ofw/openfirm.h> > +#include <dev/ofw/ofw_bus.h> > +#include <dev/ofw/ofw_bus_subr.h> > + > +#include <dev/psci/psci.h> > + > +struct psci_softc { > + device_t dev; > + > + psci_callfn_t psci_call; > + uint32_t psci_fnids[PSCI_FN_MAX]; > +}; > + > +static int psci_v0_1_init(device_t dev); > +static int psci_v0_2_init(device_t dev); > + > +struct psci_softc *psci_softc = NULL; > + > +static struct ofw_compat_data compat_data[] = { > + {"arm,psci-0.2", (uintptr_t)psci_v0_2_init}, > + {"arm,psci", (uintptr_t)psci_v0_1_init}, > + {NULL, 0} > +}; > + > +static int psci_probe(device_t dev); > +static int psci_attach(device_t dev); > +static void psci_shutdown(void *, int); > + > +static device_method_t psci_methods[] = { > + DEVMETHOD(device_probe, psci_probe), > + DEVMETHOD(device_attach, psci_attach), > + > + DEVMETHOD_END > +}; > + > +static driver_t psci_driver = { > + "psci", > + psci_methods, > + sizeof(struct psci_softc), > +}; > + > +static devclass_t psci_devclass; > + > +EARLY_DRIVER_MODULE(psci, simplebus, psci_driver, psci_devclass, 0, 0, > + BUS_PASS_CPU + BUS_PASS_ORDER_FIRST); > +EARLY_DRIVER_MODULE(psci, ofwbus, psci_driver, psci_devclass, 0, 0, > + BUS_PASS_CPU + BUS_PASS_ORDER_FIRST); > + > +static int > +psci_probe(device_t dev) > +{ > + const struct ofw_compat_data *ocd; > + > + if (!ofw_bus_status_okay(dev)) > + return (ENXIO); > + > + ocd = ofw_bus_search_compatible(dev, compat_data); > + if (ocd->ocd_str == NULL) > + return (ENXIO); > + > + device_set_desc(dev, "ARM Power State Co-ordination Interface Driver"); > + > + return (BUS_PROBE_SPECIFIC); > +} > + > +static int > +psci_attach(device_t dev) > +{ > + struct psci_softc *sc = device_get_softc(dev); > + const struct ofw_compat_data *ocd; > + psci_initfn_t psci_init; > + phandle_t node; > + char method[16]; > + > + if (psci_softc != NULL) > + return (ENXIO); > + > + ocd = ofw_bus_search_compatible(dev, compat_data); > + psci_init = (psci_initfn_t)ocd->ocd_data; > + KASSERT(psci_init != NULL, ("PSCI init function cannot be NULL")); > + > + node = ofw_bus_get_node(dev); > + if ((OF_getprop(node, "method", method, sizeof(method))) > 0) { > + if (strcmp(method, "hvc") == 0) > + sc->psci_call = psci_hvc_despatch; > + else if (strcmp(method, "smc") == 0) > + sc->psci_call = psci_smc_despatch; > + else { > + device_printf(dev, > + "psci_attach: PSCI conduit \"%s\" invalid\n", > + method); > + return (ENXIO); > + } > + } else { > + device_printf(dev, > + "psci_attach: PSCI conduit not supplied in the DT\n"); > + return (ENXIO); > + } > + > + if (psci_init(dev)) > + return (ENXIO); > + > + psci_softc = sc; > + > + return (0); > +} > + > +static int > +psci_get_version(struct psci_softc *sc) > +{ > + uint32_t fnid; > + > + /* PSCI version wasn't supported in v0.1. */ > + fnid = sc->psci_fnids[PSCI_FN_VERSION]; > + if (fnid) > + return (sc->psci_call(fnid, 0, 0, 0)); > + > + return (PSCI_RETVAL_NOT_SUPPORTED); > +} > + > +int > +psci_cpu_on(unsigned long cpu, unsigned long entry, unsigned long context_id) > +{ > + > + /* PSCI v0.1 and v0.2 both support cpu_on. */ > + return(psci_softc->psci_call(psci_softc->psci_fnids[PSCI_FN_CPU_ON], cpu, > + entry, context_id)); > +} > + > +static void > +psci_shutdown(void *xsc, int howto) > +{ > + uint32_t fn = 0; > + > + /* PSCI system_off and system_reset werent't supported in v0.1. */ > + if ((howto & RB_POWEROFF) != 0) > + fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_OFF]; > + else if ((howto & RB_HALT) == 0) > + fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_RESET]; > + > + if (fn) > + psci_softc->psci_call(fn, 0, 0, 0); > + > + /* System reset and off do not return. */ > +} > + > +static int > +psci_v0_1_init(device_t dev) > +{ > + struct psci_softc *sc = device_get_softc(dev); > + int psci_fn; > + uint32_t psci_fnid; > + phandle_t node; > + int len; > + > + > + /* Zero out the function ID table - Is this needed ? */ > + for (psci_fn = PSCI_FN_VERSION, psci_fnid = PSCI_FNID_VERSION; > + psci_fn < PSCI_FN_MAX; psci_fn++, psci_fnid++) > + sc->psci_fnids[psci_fn] = 0; > + > + /* PSCI v0.1 doesn't specify function IDs. Get them from DT */ > + node = ofw_bus_get_node(dev); > + > + if ((len = OF_getproplen(node, "cpu_suspend")) > 0) { > + OF_getencprop(node, "cpu_suspend", &psci_fnid, len); > + sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = psci_fnid; > + } > + > + if ((len = OF_getproplen(node, "cpu_on")) > 0) { > + OF_getencprop(node, "cpu_on", &psci_fnid, len); > + sc->psci_fnids[PSCI_FN_CPU_ON] = psci_fnid; > + } > + > + if ((len = OF_getproplen(node, "cpu_off")) > 0) { > + OF_getencprop(node, "cpu_off", &psci_fnid, len); > + sc->psci_fnids[PSCI_FN_CPU_OFF] = psci_fnid; > + } > + > + if ((len = OF_getproplen(node, "migrate")) > 0) { > + OF_getencprop(node, "migrate", &psci_fnid, len); > + sc->psci_fnids[PSCI_FN_MIGRATE] = psci_fnid; > + } > + > + if (bootverbose) > + device_printf(dev, "PSCI version 0.1 available\n"); > + > + return(0); > +} > + > +static int > +psci_v0_2_init(device_t dev) > +{ > + struct psci_softc *sc = device_get_softc(dev); > + int version; > + > + /* PSCI v0.2 specifies explicit function IDs. */ > + sc->psci_fnids[PSCI_FN_VERSION] = PSCI_FNID_VERSION; > + sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = PSCI_FNID_CPU_SUSPEND; > + sc->psci_fnids[PSCI_FN_CPU_OFF] = PSCI_FNID_CPU_OFF; > + sc->psci_fnids[PSCI_FN_CPU_ON] = PSCI_FNID_CPU_ON; > + sc->psci_fnids[PSCI_FN_AFFINITY_INFO] = PSCI_FNID_AFFINITY_INFO; > + sc->psci_fnids[PSCI_FN_MIGRATE] = PSCI_FNID_MIGRATE; > + sc->psci_fnids[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_FNID_MIGRATE_INFO_TYPE; > + sc->psci_fnids[PSCI_FN_MIGRATE_INFO_UP_CPU] = PSCI_FNID_MIGRATE_INFO_UP_CPU; > + sc->psci_fnids[PSCI_FN_SYSTEM_OFF] = PSCI_FNID_SYSTEM_OFF; > + sc->psci_fnids[PSCI_FN_SYSTEM_RESET] = PSCI_FNID_SYSTEM_RESET; > + > + version = psci_get_version(sc); > + > + if (version == PSCI_RETVAL_NOT_SUPPORTED) > + return (1); > + > + if ((PSCI_VER_MAJOR(version) != 0) && (PSCI_VER_MINOR(version) != 2)) { > + device_printf(dev, "PSCI version number mismatched with DT\n"); > + return (1); > + } > + > + if (bootverbose) > + device_printf(dev, "PSCI version 0.2 available\n"); > + > + /* > + * We only register this for v0.2 since v0.1 doesn't support > + * system_reset. > + */ > + EVENTHANDLER_REGISTER(shutdown_final, psci_shutdown, sc, > + SHUTDOWN_PRI_LAST); > + > + return (0); > +} > > Added: head/sys/dev/psci/psci.h > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/dev/psci/psci.h Sun Apr 12 13:00:58 2015 (r281466) > @@ -0,0 +1,102 @@ > +/*- > + * Copyright (c) 2013, 2014 Robin Randhawa > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#ifndef _MACHINE_PSCI_H_ > +#define _MACHINE_PSCI_H_ > + > +#include <sys/types.h> > + > +typedef int (*psci_initfn_t)(device_t dev); > +typedef int (*psci_callfn_t)(register_t, register_t, register_t, register_t); > + > +extern int psci_present; > + > +void psci_system_reset(void); > +int psci_cpu_on(unsigned long, unsigned long, unsigned long); > +int psci_hvc_despatch(register_t, register_t, register_t, register_t); > +int psci_smc_despatch(register_t, register_t, register_t, register_t); > + > + > +/* > + * PSCI return codes. > + */ > +#define PSCI_RETVAL_SUCCESS 0 > +#define PSCI_RETVAL_NOT_SUPPORTED -1 > +#define PSCI_RETVAL_INVALID_PARAMS -2 > +#define PSCI_RETVAL_DENIED -3 > +#define PSCI_RETVAL_ALREADY_ON -4 > +#define PSCI_RETVAL_ON_PENDING -5 > +#define PSCI_RETVAL_INTERNAL_FAILURE -6 > +#define PSCI_RETVAL_NOT_PRESENT -7 > +#define PSCI_RETVAL_DISABLED -8 > + > +/* > + * PSCI function codes (as per PSCI v0.2). > + */ > +#ifdef __aarch64__ > +#define PSCI_FNID_VERSION 0x84000000 > +#define PSCI_FNID_CPU_SUSPEND 0xc4000001 > +#define PSCI_FNID_CPU_OFF 0x84000002 > +#define PSCI_FNID_CPU_ON 0xc4000003 > +#define PSCI_FNID_AFFINITY_INFO 0xc4000004 > +#define PSCI_FNID_MIGRATE 0xc4000005 > +#define PSCI_FNID_MIGRATE_INFO_TYPE 0x84000006 > +#define PSCI_FNID_MIGRATE_INFO_UP_CPU 0xc4000007 > +#define PSCI_FNID_SYSTEM_OFF 0x84000008 > +#define PSCI_FNID_SYSTEM_RESET 0x84000009 > +#else > +#define PSCI_FNID_VERSION 0x84000000 > +#define PSCI_FNID_CPU_SUSPEND 0x84000001 > +#define PSCI_FNID_CPU_OFF 0x84000002 > +#define PSCI_FNID_CPU_ON 0x84000003 > +#define PSCI_FNID_AFFINITY_INFO 0x84000004 > +#define PSCI_FNID_MIGRATE 0x84000005 > +#define PSCI_FNID_MIGRATE_INFO_TYPE 0x84000006 > +#define PSCI_FNID_MIGRATE_INFO_UP_CPU 0x84000007 > +#define PSCI_FNID_SYSTEM_OFF 0x84000008 > +#define PSCI_FNID_SYSTEM_RESET 0x84000009 > +#endif > + > +#define PSCI_VER_MAJOR(v) (((v) >> 16) & 0xFF) > +#define PSCI_VER_MINOR(v) ((v) & 0xFF) > + > +enum psci_fn { > + PSCI_FN_VERSION, > + PSCI_FN_CPU_SUSPEND, > + PSCI_FN_CPU_OFF, > + PSCI_FN_CPU_ON, > + PSCI_FN_AFFINITY_INFO, > + PSCI_FN_MIGRATE, > + PSCI_FN_MIGRATE_INFO_TYPE, > + PSCI_FN_MIGRATE_INFO_UP_CPU, > + PSCI_FN_SYSTEM_OFF, > + PSCI_FN_SYSTEM_RESET, > + PSCI_FN_MAX > +}; > + > +#endif /* _MACHINE_PSCI_H_ */ > > Added: head/sys/dev/psci/psci_arm.S > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/dev/psci/psci_arm.S Sun Apr 12 13:00:58 2015 (r281466) > @@ -0,0 +1,47 @@ > +/*- > + * Copyright (c) 2015 Andrew Turner > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + * > + */ > + > +#include <machine/asm.h> > +__FBSDID("$FreeBSD$"); > + > +.arch_extension virt /* For hvc */ > + > +/* > + * int psci_hvc_despatch(register_t psci_fnid, register_t...) > + */ > +ENTRY(psci_hvc_despatch) > + hvc #0 > + RET > +END(psci_hvc_despatch) > + > +/* > + * int psci_smc_despatch(register_t psci_fnid, register_t...) > + */ > +ENTRY(psci_smc_despatch) > + smc #0 > + RET > +END(psci_hvc_despatch) >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPyFy2BGm6LSxYs7-ipcd8578izVrn_4wToFAEKigmfDHhDA8w>