From aa08aab774dbcd6ea6c1c1a9c137f951e7876d28 Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 27 Jan 2023 23:11:59 +0000 Subject: [PATCH] Only use the CPU_OFF PSCI call if SYSTEM_SUSPEND is supported. This means that secondary CPUs will get parked in a WFI loop like we already do on Apple Silicon systems. This requires some small changes in agintc(4) to make sure we ack the "halt" IPI such that we can send a "wakeup" IPI later. ok patrick@ --- sys/arch/arm64/arm64/cpu.c | 10 ++++++---- sys/arch/arm64/dev/agintc.c | 12 +++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index daef07d3ea6..e40634efb58 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.80 2023/01/26 13:09:18 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.81 2023/01/27 23:11:59 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -1064,17 +1064,19 @@ cpu_halt(void) { struct cpu_info *ci = curcpu(); int count = 0; + u_long psw; KERNEL_ASSERT_UNLOCKED(); SCHED_ASSERT_UNLOCKED(); - intr_disable(); + psw = intr_disable(); atomic_clearbits_int(&ci->ci_flags, CPUF_RUNNING | CPUF_PRESENT | CPUF_GO); #if NPSCI > 0 - psci_cpu_off(); + if (psci_can_suspend()) + psci_cpu_off(); #endif /* @@ -1097,7 +1099,7 @@ cpu_halt(void) atomic_setbits_int(&ci->ci_flags, CPUF_RUNNING); __asm volatile("dsb sy; sev" ::: "memory"); - intr_enable(); + intr_restore(psw); /* Unmask clock interrupts. */ WRITE_SPECIALREG(cntv_ctl_el0, diff --git a/sys/arch/arm64/dev/agintc.c b/sys/arch/arm64/dev/agintc.c index 02989a4e94f..905b5118c70 100644 --- a/sys/arch/arm64/dev/agintc.c +++ b/sys/arch/arm64/dev/agintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agintc.c,v 1.46 2022/12/21 23:18:09 patrick Exp $ */ +/* $OpenBSD: agintc.c,v 1.47 2023/01/27 23:11:59 kettenis Exp $ */ /* * Copyright (c) 2007, 2009, 2011, 2017 Dale Rahn * Copyright (c) 2018 Mark Kettenis @@ -1396,7 +1396,17 @@ agintc_ipi_ddb(void *v) int agintc_ipi_halt(void *v) { + struct agintc_softc *sc = v; + int old = curcpu()->ci_cpl; + + intr_disable(); + agintc_eoi(sc->sc_ipi_num[ARM_IPI_HALT]); + agintc_setipl(IPL_NONE); + cpu_halt(); + + agintc_setipl(old); + intr_enable(); return 1; } -- 2.20.1