aboutsummaryrefslogtreecommitdiff
path: root/src/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'src/parisc')
-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;