smp: Use wfi and put idle CPUs in deep sleep

This allows a single active P-Core to boost to 3.2GHz.

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-09-17 00:15:52 +09:00
parent 77fbb05623
commit b1bc4023dc
3 changed files with 42 additions and 2 deletions

View file

@ -2,6 +2,7 @@
#include "smp.h"
#include "adt.h"
#include "cpu_regs.h"
#include "string.h"
#include "types.h"
#include "utils.h"
@ -42,9 +43,11 @@ void smp_secondary_entry(void)
me->flag = 1;
sysop("dmb sy");
u64 target;
while (1) {
while (!(target = me->target)) {
sysop("wfe");
deep_wfi();
msr(SYS_IMP_APL_IPI_SR_EL1, 1);
}
sysop("dmb sy");
me->flag++;
@ -173,7 +176,9 @@ void smp_call4(int cpu, void *func, u64 arg0, u64 arg1, u64 arg2, u64 arg3)
sysop("dmb sy");
target->target = (u64)func;
sysop("dmb sy");
sysop("sev");
msr(SYS_IMP_APL_IPI_RR_GLOBAL_EL1, spin_table[cpu].mpidr);
while (target->flag == flag)
sysop("dmb sy");
}

View file

@ -406,4 +406,6 @@ struct vector_args {
extern struct vector_args next_stage;
void deep_wfi(void);
#endif

View file

@ -1,5 +1,7 @@
/* SPDX-License-Identifier: MIT */
#include "cpu_regs.h"
.text
.globl memcpy64
@ -135,3 +137,34 @@ put_simd_state:
ldp q28, q29, [x0], #32
ldp q30, q31, [x0], #32
ret
.globl deep_wfi
.type deep_wfi, @function
deep_wfi:
str x30, [sp, #-16]!
stp x28, x29, [sp, #-16]!
stp x26, x27, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x20, x21, [sp, #-16]!
stp x18, x19, [sp, #-16]!
mrs x0, SYS_IMP_APL_CYC_OVRD
orr x0, x0, #(3L << 24)
msr SYS_IMP_APL_CYC_OVRD, x0
wfi
mrs x0, SYS_IMP_APL_CYC_OVRD
bic x0, x0, #(1L << 24)
msr SYS_IMP_APL_CYC_OVRD, x0
ldp x18, x19, [sp], #16
ldp x20, x21, [sp], #16
ldp x22, x23, [sp], #16
ldp x24, x25, [sp], #16
ldp x26, x27, [sp], #16
ldp x28, x29, [sp], #16
ldr x30, [sp], #16
ret