diff mbox series

[2/2] ppc/shutdown: Implement machine_{halt,restart}()

Message ID 20240705182311.1968790-3-andrew.cooper3@citrix.com (mailing list archive)
State New
Headers show
Series ppc/shutdown: Implement machine_{halt,restart}() | expand

Commit Message

Andrew Cooper July 5, 2024, 6:23 p.m. UTC
OPAL has easy APIs for shutdown/reboot, so wire them up.

Then, use machine_halt() rather than an infinite loop at the end of
start_xen().  This avoids the Qemu smoke test needing to wait for the full
timeout in order to succeed.

  (XEN) 8e011600000000c0 is the result of PTE map
  Enabled radix in LPCR
  Flushed TLB
  Hello, ppc64le!
  [    6.341897656,5] OPAL: Shutdown request type 0x0...

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Shawn Anastasio <sanastasio@raptorengineering.com>
CC: Oleksii Kurochko <oleksii.kurochko@gmail.com>
CC: Jan Beulich <JBeulich@suse.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>

I got bored testing fixes to the containers...
---
 xen/arch/ppc/Makefile           |  1 +
 xen/arch/ppc/ppc64/opal-calls.S |  4 +++
 xen/arch/ppc/setup.c            |  8 +++---
 xen/arch/ppc/shutdown.c         | 43 +++++++++++++++++++++++++++++++++
 xen/arch/ppc/stubs.c            | 12 ---------
 5 files changed, 51 insertions(+), 17 deletions(-)
 create mode 100644 xen/arch/ppc/shutdown.c

Comments

Shawn Anastasio July 8, 2024, 9:21 p.m. UTC | #1
Hi Andrew,

Overall this looks good, I just have one comment.

On 7/5/24 1:23 PM, Andrew Cooper wrote:
> diff --git a/xen/arch/ppc/shutdown.c b/xen/arch/ppc/shutdown.c
> new file mode 100644
> index 000000000000..c4b00e57b13a
> --- /dev/null
> +++ b/xen/arch/ppc/shutdown.c
> @@ -0,0 +1,43 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#include <xen/shutdown.h>
> +
> +#include <asm/opal-api.h>
> +
> +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;
> +

Before the opal_cec_{power_down,reboot} calls are made, any interupts
reserved for OPAL to handle need to be masked off.

Since we don't have any set up at this point, I would just add a TODO
comment like:

/* 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: mdelay(delay_millisecs); */
> +

Ditto.

> +    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);
> +}
> +

Other than that, looks great.

Reviewed-by: Shawn Anastasio <sanastasio@raptorengineering.com>

Thanks,
Shawn
diff mbox series

Patch

diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile
index 71feb5e2c41f..655d212f6687 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 cc5de75c8af4..69d07909d108 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 7fe06aa4bfb0..5fb5ab64e323 100644
--- a/xen/arch/ppc/setup.c
+++ b/xen/arch/ppc/setup.c
@@ -2,6 +2,8 @@ 
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/shutdown.h>
+
 #include <public/version.h>
 #include <asm/boot.h>
 #include <asm/early_printk.h>
@@ -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 000000000000..c4b00e57b13a
--- /dev/null
+++ b/xen/arch/ppc/shutdown.c
@@ -0,0 +1,43 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <xen/shutdown.h>
+
+#include <asm/opal-api.h>
+
+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;
+
+    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: 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 923f0e7b2095..41e7a7d2130b 100644
--- a/xen/arch/ppc/stubs.c
+++ b/xen/arch/ppc/stubs.c
@@ -59,18 +59,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)