aboutsummaryrefslogtreecommitdiff
path: root/src/parisc/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/parisc/head.S')
-rw-r--r--src/parisc/head.S93
1 files changed, 53 insertions, 40 deletions
diff --git a/src/parisc/head.S b/src/parisc/head.S
index 891ec9a..900ec48 100644
--- a/src/parisc/head.S
+++ b/src/parisc/head.S
@@ -67,6 +67,15 @@ name:
#define INT_LEN 4
#endif
+/* various control register and irq bits */
+#define PSW_I 1
+#define PSW_Q 8
+#define CR_EIRR 23
+#define CR_IVA 14
+#define CR_EIEM 15
+#define PSW_W_SM 0x200
+#define PSW_W_BIT 36
+
.import $global$
.section ".head.text","ax"
.level 1.1
@@ -91,6 +100,8 @@ marker:
.align 0x80
ENTRY(startup)
+ rsm PSW_I, %r0 /* disable local irqs */
+
/* Make sure space registers are set to zero */
mtsp %r0,%sr0
mtsp %r0,%sr1
@@ -101,14 +112,34 @@ ENTRY(startup)
mtsp %r0,%sr6
mtsp %r0,%sr7
-#define PSW_W_SM 0x200
-#define PSW_W_BIT 36
-
;! nuke the W bit
.level 2.0
rsm PSW_W_SM, %r0
.level 1.1
+ /* If CPU HPA is already set in CPU_HPA_CR_REG then the
+ * CPU is already initialized and the machine was only reset */
+ mfctl CPU_HPA_CR_REG, %r1
+ comib,= 0,%r1,$startup_fresh_booted
+ nop
+
+$startup_just_rebooted:
+ /* Get current CPU HPA. It was stored there at initial bootup. */
+ mfctl CPU_HPA_CR_REG, %r5
+
+ /* branch if this is the monarch cpu */
+ load32 CPU_HPA, %r1
+ comb,= %r5,%r1,$is_monarch_cpu_reboot
+ nop
+
+ /* we assume the monarch CPU is in idle loop. wake it up. */
+ ldi -1, %r3 /* trigger IRQ0 (Timer) */
+ stw %r3, 0(%r1)
+ b,n enter_smp_idle_loop
+
+$startup_fresh_booted:
+ /* Here the machine was booted from scratch: */
+
/* Save CPU HPA in cr7, hopefully HP-UX will not use that register. */
mtctl %r5, CPU_HPA_CR_REG /* store CPU HPA */
@@ -121,38 +152,32 @@ 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 */
+ rsm PSW_I | PSW_Q, %r0 /* disable local irqs */
+ mtctl %r0, CR_EIEM /* disable all external 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
mtctl %r1, CR_IVA
/* enable CPU local interrupts */
-#define CR_EIEM 15
load32 1<<31, %r1 /* allow IRQ0 (Timer) */
mtctl %r1, CR_EIEM
ssm PSW_I, %r0 /* enable local irqs */
- /* endless idle loop, exits to $smp_exit_loop by IRQ only */
+ /* endless idle loop for secondary CPUs. Exits to $smp_exit_loop by IRQ only */
$smp_idle_loop:
b $smp_idle_loop
- or %r10,%r10,%r10
+ or %r10,%r10,%r10 /* qemu sleep instruction */
$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)
+ mtctl %r0, CR_EIEM
/* on 64bit: Address of PDCE_PROC for each non-monarch processor in GR26. */
load32 BOOTADDR(pdc_entry), %r26
@@ -160,11 +185,23 @@ $smp_exit_loop:
/* jump to rendevouz */
ldw 0x10(%r0),%r3 /* MEM_RENDEZ */
/* ldw 0x28(%r0),%r0 MEM_RENDEZ_HI - assume addr < 4GB */
- load32 enter_smp_idle_loop, %rp
+ cmpb,=,n %r0,%r3,startup /* branch to startup if not yet initialized */
+ load32 startup, %rp
bv,n 0(%r3)
-
$is_monarch_cpu:
+ /* Save boot_args. Only monarch CPU does this once. */
+ load32 BOOTADDR(0x040 + 10*4),%r1
+ stw,ma %r26,4(%r1)
+ stw,ma %r25,4(%r1)
+ stw,ma %r24,4(%r1)
+ stw,ma %r23,4(%r1)
+ stw,ma %r22,4(%r1)
+ stw,ma %r21,4(%r1)
+ stw,ma %r20,4(%r1)
+ stw,ma %r19,4(%r1)
+
+$is_monarch_cpu_reboot:
/* Initialize stack pointer */
load32 BOOTADDR(parisc_stack),%r1
ldo FRAME_SIZE(%r1),%sp
@@ -182,23 +219,11 @@ $bss_loop:
cmpb,<<,n %r3,%r4,$bss_loop
stw,ma %r0,4(%r3)
- /* Save boot args */
- load32 BOOTADDR(boot_args),%r1
- stw,ma %r26,4(%r1)
- stw,ma %r25,4(%r1)
- stw,ma %r24,4(%r1)
- stw,ma %r23,4(%r1)
- stw,ma %r22,4(%r1)
- stw,ma %r21,4(%r1)
- stw,ma %r20,4(%r1)
- stw,ma %r19,4(%r1)
-
load32 BOOTADDR(start_parisc_firmware),%r3
bv 0(%r3)
copy %r0,%r2
END(startup)
-
/*******************************************************
TOC handler
Write all GRs, CRs, SRs and the iaoq_back and iasq_back registers (in
@@ -381,18 +406,6 @@ ENTRY(iodc_entry)
ldw -32(%sp),%dp
END(iodc_entry)
- .data
-ENTRY(boot_args)
- .word 0 /* r26: ramsize */
- .word 0 /* r25: kernel entry point */
- .word 0 /* r24: cmdline */
- .word 0 /* r23: initrd_start */
- .word 0 /* r22: initrd_end */
- .word 0 /* r21: num CPUs */
- .word 0 /* r20: pdc_debug */
- .word 0 /* r19: fw_cfg port */
-END(boot_args)
-
/****************************************************************
* Rom Header for VGA / STI
****************************************************************/