On Tue, Mar 07, 2017 at 02:28:06AM -0500, Dale Rahn wrote: > > Updated diff, this has changed a bit since the psci driver has changed. > > diff --git a/sys/dev/fdt/psci.c b/sys/dev/fdt/psci.c > index b24613a275c..2ba500ea718 100644 > --- a/sys/dev/fdt/psci.c > +++ b/sys/dev/fdt/psci.c > @@ -29,14 +29,18 @@ > extern void (*cpuresetfn)(void); > extern void (*powerdownfn)(void); > > +extern int (*cpu_on_fn)(uint64_t, uint64_t) __attribute__((weak)) ; > + > #define SYSTEM_OFF 0x84000008 > #define SYSTEM_RESET 0x84000009 > +#define SYSTEM_CPU_ON64 0xC4000003 > > struct psci_softc { > struct device sc_dev; > - void (*callfn)(uint32_t, uint32_t, uint32_t, > uint32_t); > + int (*callfn)(uint32_t, uint32_t, uint32_t, > uint32_t); > int sc_system_off; > int sc_system_reset; > + int sc_system_on;
This should be sc_cpu_on > }; > > struct psci_softc *psci_sc; > @@ -45,9 +49,10 @@ int psci_match(struct device *, void *, void *); > void psci_attach(struct device *, struct device *, void *); > void psci_reset(void); > void psci_powerdown(void); > +int psci_cpu_on(uint64_t, uint64_t); > > -extern void hvc_call(uint32_t, uint32_t, uint32_t, uint32_t); > -extern void smc_call(uint32_t, uint32_t, uint32_t, uint32_t); > +extern int hvc_call(uint32_t, uint32_t, uint32_t, uint32_t); > +extern int smc_call(uint32_t, uint32_t, uint32_t, uint32_t); > > struct cfattach psci_ca = { > sizeof(struct psci_softc), psci_match, psci_attach > @@ -90,11 +95,13 @@ psci_attach(struct device *parent, struct device *self, > void *aux) > OF_is_compatible(faa->fa_node, "arm,psci-1.0")) { > sc->sc_system_off = SYSTEM_OFF; > sc->sc_system_reset = SYSTEM_RESET; > + sc->sc_system_on = OF_getpropint(faa->fa_node, "cpu_on", 0); If psci-0.2 or psci-1.0 is claimed the properties are supposed to be ignored according to the device tree binding documentation. "Function IDs are not required and should be ignored by an OS with PSCI 0.2 support, but are permitted to be present for compatibility with existing software when "arm,psci" is later in the compatible list" It is clear this extends to cpu_on when looking at examples like arm64/boot/dts/broadcom/ns2.dtsi cpus { #address-cells = <2>; #size-cells = <0>; A57_0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a57", "arm,armv8"; reg = <0 0>; enable-method = "psci"; next-level-cache = <&CLUSTER0_L2>; }; ... psci { compatible = "arm,psci-1.0"; method = "smc"; }; > } else if (OF_is_compatible(faa->fa_node, "arm,psci")) { > sc->sc_system_off = OF_getpropint(faa->fa_node, > "system_off", 0); > sc->sc_system_reset = OF_getpropint(faa->fa_node, > "system_reset", 0); > + sc->sc_system_on = OF_getpropint(faa->fa_node, "cpu_on", 0); > } > > printf("\n"); > @@ -104,6 +111,10 @@ psci_attach(struct device *parent, struct device *self, > void *aux) > powerdownfn = psci_powerdown; > if (sc->sc_system_reset != 0) > cpuresetfn = psci_reset; > + > + if ((&cpu_on_fn != NULL) && (sc->sc_system_on == SYSTEM_CPU_ON64)) { Isn't the address of a global going to always be non-NULL? > + cpu_on_fn = psci_cpu_on; > + } > } > > void > @@ -121,3 +132,12 @@ psci_powerdown(void) > if (sc->callfn) > (*sc->callfn)(sc->sc_system_off, 0, 0, 0); > } > + > +int > +psci_cpu_on(uint64_t mpidr, uint64_t pc) > +{ > + struct psci_softc *sc = psci_sc; > + if (sc->callfn) > + return (*sc->callfn)(sc->sc_system_on, mpidr, pc, 0); > + return -1; > +} > > > Dale Rahn dr...@dalerahn.com >