diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 71feb5e2c4..655d212f66 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o obj-y += mm-radix.o obj-y += opal.o obj-y += setup.o +obj-y += shutdown.o obj-y += stubs.o obj-y += tlb-radix.o diff --git a/xen/arch/ppc/ppc64/opal-calls.S b/xen/arch/ppc/ppc64/opal-calls.S index cc5de75c8a..69d07909d1 100644 --- a/xen/arch/ppc/ppc64/opal-calls.S +++ b/xen/arch/ppc/ppc64/opal-calls.S @@ -79,3 +79,7 @@ opal_return_mmu: OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE) OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH) OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS) + +OPAL_CALL(opal_cec_power_down, OPAL_CEC_POWER_DOWN) +OPAL_CALL(opal_cec_reboot, OPAL_CEC_REBOOT) +OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS) diff --git a/xen/arch/ppc/setup.c b/xen/arch/ppc/setup.c index 7fe06aa4bf..5fb5ab64e3 100644 --- a/xen/arch/ppc/setup.c +++ b/xen/arch/ppc/setup.c @@ -2,6 +2,8 @@ #include #include #include +#include + #include #include #include @@ -43,11 +45,7 @@ void __init noreturn start_xen(unsigned long r3, unsigned long r4, early_printk("Hello, ppc64le!\n"); - for ( ; ; ) - /* Set current hardware thread to very low priority */ - HMT_very_low(); - - unreachable(); + machine_halt(); } void arch_get_xen_caps(xen_capabilities_info_t *info) diff --git a/xen/arch/ppc/shutdown.c b/xen/arch/ppc/shutdown.c new file mode 100644 index 0000000000..6e49a095d8 --- /dev/null +++ b/xen/arch/ppc/shutdown.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include + +#include + +int64_t opal_cec_power_down(uint64_t request); +int64_t opal_cec_reboot(void); +int64_t opal_poll_events(uint64_t *outstanding_event_mask); + +void machine_halt(void) +{ + int rc; + + /* TODO: mask any OPAL IRQs before shutting down */ + + do { + rc = opal_cec_power_down(0); + + if ( rc == OPAL_BUSY_EVENT ) + opal_poll_events(NULL); + + } while ( rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT ); + + for ( ;; ) + opal_poll_events(NULL); +} + +void machine_restart(unsigned int delay_millisecs) +{ + int rc; + + /* + * TODO: mask any OPAL IRQs before shutting down + * TODO: mdelay(delay_millisecs); + */ + + do { + rc = opal_cec_reboot(); + + if ( rc == OPAL_BUSY_EVENT ) + opal_poll_events(NULL); + + } while ( rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT ); + + for ( ;; ) + opal_poll_events(NULL); +} + diff --git a/xen/arch/ppc/stubs.c b/xen/arch/ppc/stubs.c index e743a86710..50e54d61c0 100644 --- a/xen/arch/ppc/stubs.c +++ b/xen/arch/ppc/stubs.c @@ -60,18 +60,6 @@ void vcpu_show_execution_state(struct vcpu *v) BUG_ON("unimplemented"); } -/* shutdown.c */ - -void machine_restart(unsigned int delay_millisecs) -{ - BUG_ON("unimplemented"); -} - -void machine_halt(void) -{ - BUG_ON("unimplemented"); -} - /* vm_event.c */ void vm_event_fill_regs(vm_event_request_t *req)