aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2022-03-25 10:27:27 +0100
committerHelge Deller <deller@gmx.de>2022-03-25 10:27:27 +0100
commit5cec13f11d3917cf3bceaf68ce23e9fa5f206a35 (patch)
tree7a9c74b26b24d8c3fce51e622f920dd597cc661f
parentbf3404006fd2c832857eb57e6f853862f97dacea (diff)
downloadseabios-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>
-rw-r--r--src/parisc/head.S21
-rw-r--r--src/parisc/parisc.c5
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;