diff options
author | Helge Deller <deller@gmx.de> | 2022-03-25 10:27:27 +0100 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2022-03-25 10:27:27 +0100 |
commit | 5cec13f11d3917cf3bceaf68ce23e9fa5f206a35 (patch) | |
tree | 7a9c74b26b24d8c3fce51e622f920dd597cc661f /src/parisc | |
parent | bf3404006fd2c832857eb57e6f853862f97dacea (diff) | |
download | seabios-hppa-5cec13f11d3917cf3bceaf68ce23e9fa5f206a35.zip seabios-hppa-5cec13f11d3917cf3bceaf68ce23e9fa5f206a35.tar.gz seabios-hppa-5cec13f11d3917cf3bceaf68ce23e9fa5f206a35.tar.bz2 |
parisc: Fix CPU hotplug rendenzvous code
Fix the PDC rendenzvous code to clear all pending external intrrupts
before entering the waiting loop.
Without clearing them before, the CPU was waken up immediately again.
This fixes the CPU hotplug on Linux, which can be run with
chcpu -d 2 # to disable CPU2
chcpu -e 2 # to wake up CPU2
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'src/parisc')
-rw-r--r-- | src/parisc/head.S | 21 | ||||
-rw-r--r-- | src/parisc/parisc.c | 5 |
2 files changed, 22 insertions, 4 deletions
diff --git a/src/parisc/head.S b/src/parisc/head.S index b4f54a5..eec378b 100644 --- a/src/parisc/head.S +++ b/src/parisc/head.S @@ -122,6 +122,16 @@ ENTRY(enter_smp_idle_loop) /* IDLE LOOP for SMP CPUs - wait for rendenzvous. */ mfctl CPU_HPA_CR_REG, %r25 /* get CPU HPA from cr7 */ +#define PSW_I 1 + rsm PSW_I, %r0 /* disable local irqs */ + + /* EIRR : clear all pending external intr */ +#define CR_EIRR 23 + load32 -1,%r1 + mtctl %r1, CR_EIRR + mfctl CR_EIRR, %r0 + mtctl %r0, CR_EIRR + /* Load IVT for SMT tiny loop exit */ #define CR_IVA 14 load32 BOOTADDR(smp_ivt),%r1 @@ -129,10 +139,9 @@ ENTRY(enter_smp_idle_loop) /* enable CPU local interrupts */ #define CR_EIEM 15 -#define PSW_I 1 load32 1<<31, %r1 /* allow IRQ0 (Timer) */ mtctl %r1, CR_EIEM - ssm PSW_I, %r9 + ssm PSW_I, %r0 /* enable local irqs */ /* endless idle loop, exits to $smp_exit_loop by IRQ only */ $smp_idle_loop: @@ -141,6 +150,10 @@ $smp_idle_loop: $smp_exit_loop: mtctl %r0, CR_EIEM + rsm PSW_I, %r0 /* disable local irqs */ + + /* tell QEMU to drop all local TLB entries. */ + pdtlbe %r0(%sr1,%r0) /* on 64bit: Address of PDCE_PROC for each non-monarch processor in GR26. */ load32 BOOTADDR(pdc_entry), %r26 @@ -148,8 +161,8 @@ $smp_exit_loop: /* jump to rendevouz */ ldw 0x10(%r0),%r3 /* MEM_RENDEZ */ /* ldw 0x28(%r0),%r0 MEM_RENDEZ_HI - assume addr < 4GB */ - bv 0(%r3) - copy %r0,%r2 + load32 enter_smp_idle_loop, %rp + bv,n 0(%r3) $is_monarch_cpu: diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index e135920..9d96986 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -1195,6 +1195,11 @@ static int pdc_proc(unsigned int *arg) case 1: if (ARG2 != 0) return PDC_BAD_PROC; + if (pdc_debug & DEBUG_PDC) + printf("\nSeaBIOS: CPU%d enters rendenzvous loop.\n", + index_of_CPU_HPA(mfctl(CPU_HPA_CR_REG))); + /* wait until all outstanding timer irqs arrived. */ + msleep(500); /* let the current CPU sleep until rendenzvous. */ enter_smp_idle_loop(); return PDC_OK; |