parisc/parisc64: Allow booting 64-bit kernel up into start_parisc
Add minimal code to allow booting up into C-function start_parisc.
Console output is not working yet.
Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/src/parisc/head.S b/src/parisc/head.S
index c9b96b7..b951f42 100644
--- a/src/parisc/head.S
+++ b/src/parisc/head.S
@@ -19,6 +19,13 @@
#endif
.endm
+ /* set upper 32-bits of firmware address */
+ .macro load_fw_upper32 reg
+#ifdef CONFIG_64BIT
+ depdi FIRMWARE_HIGH, 31, 32, \reg
+#endif
+ .endm
+
;! set the W bit
#define set_PSW_W .level 2.0 ! ssm PSW_W_SM, %r0 ! .level LEVEL
@@ -41,7 +48,9 @@
.macro loadgp
#ifdef CONFIG_64BIT
- copy %r0, %r27
+ ldil L%__gp, %r27
+ ldo R%__gp(%r27), %r27
+ load_fw_upper32 %r27
#else
ldil L%$global$, %r27
ldo R%$global$(%r27), %r27
@@ -127,8 +136,28 @@
cmpib,<>,n 0,%r1,1f
.word 0xfffdead0 /* immediately halt the emulator */
1:
- // set_PSW_W
+ /* we now know we run on a 64-bit CPU. */
+ /* next step: turn on the PSW.W flag (enable 64-bit mode) */
+ load32 2f,%r11
+ load_fw_upper32 %r11
+
+ mtctl %r0,%cr17 /* Clear IIASQ tail */
+ mtctl %r0,%cr17 /* Clear IIASQ head */
+
+ /* Load RFI target into PC queue */
+ mtctl %r11,%cr18 /* IIAOQ head */
+ ldo 4(%r11),%r11
+ mtctl %r11,%cr18 /* IIAOQ tail */
+
+ load32 (0x08000000 | PSW_Q),%r10 /* PSW.W=1 */
+ mtctl %r10,%ipsw
+
+ /* Jump through hyperspace to enable PSW.W */
+ rfi
+ nop
+2:
#else
+ /* clear any PSW.W on 32-bit firmware */
clear_PSW_W
#endif
@@ -209,6 +238,7 @@
cmpb,=,n %r0,%r3,enter_smp_idle_loop
nop /* failed backward branch is nullified */
load32 startup, %rp
+ load_fw_upper32 %rp
bv,n 0(%r3)
$is_monarch_cpu:
@@ -226,6 +256,7 @@
$is_monarch_cpu_reboot:
/* Initialize stack pointer */
load32 BOOTADDR(parisc_stack),%r1
+ load_fw_upper32 %r1
ldo FRAME_SIZE(%r1),%sp
/* Initialize the global data pointer */
@@ -242,6 +273,7 @@
STREGM %r0,WORD_LEN(%r3)
load32 BOOTADDR(start_parisc_firmware),%r3
+ load_fw_upper32 %r3
bv 0(%r3)
copy %r0,%r2
END(startup)
diff --git a/src/parisc/hppa_hardware.h b/src/parisc/hppa_hardware.h
index 78554af..acafda4 100644
--- a/src/parisc/hppa_hardware.h
+++ b/src/parisc/hppa_hardware.h
@@ -6,6 +6,7 @@
#define FIRMWARE_START 0xf0000000
#define FIRMWARE_END 0xf0800000
+#define FIRMWARE_HIGH 0xfffffff0 /* upper 32-bits of 64-bit firmware address */
#define MEM_PDC_ENTRY 0x4800 /* PDC entry address */
diff --git a/src/parisc/pafirmware.lds.S b/src/parisc/pafirmware.lds.S
index 4af3865..c31ac83 100644
--- a/src/parisc/pafirmware.lds.S
+++ b/src/parisc/pafirmware.lds.S
@@ -11,7 +11,8 @@
SECTIONS
{
#if BITS == 64
- . = 0xfffffff000000000 + FIRMWARE_START;
+ /* limit firmware high bits to physical addresses to allow debug info */
+ . = ((FIRMWARE_HIGH & 0x3ffffff0) << 32) + FIRMWARE_START;
#else
. = FIRMWARE_START;
#endif
@@ -47,6 +48,21 @@
_sti_rom_end = .;
}
+#if BITS == 64
+ . = ALIGN(16);
+ .opd : {
+ __start_opd = .;
+ *(.opd)
+ __end_opd = .;
+ } PROVIDE (__gp = .);
+ .plt : {
+ *(.plt)
+ }
+ .dlt : {
+ *(.dlt)
+ }
+#endif
+
. = ALIGN(8);
.rodata : {
_rodata = . ;