parisc: Add start_kernel() function
On 64-bit kernels avoid using the PLT and implement an own start_kernel()
function which jumps to the address given in the 5th parameter.
Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/src/parisc/head.S b/src/parisc/head.S
index f35301d..6bad420 100644
--- a/src/parisc/head.S
+++ b/src/parisc/head.S
@@ -278,6 +278,18 @@
copy %r0,%r2
END(startup)
+/*******************************************************/
+
+ENTRY(start_kernel)
+#ifdef CONFIG_64BIT
+ bv 0(%r22)
+ clear_PSW_W /* clear PSW before we start the kernel! */
+#else
+ ldw -0x34(%sp),%r1
+ bv,n 0(%r1)
+#endif
+END(start_kernel)
+
/*******************************************************
TOC handler
Write all GRs, CRs, SRs and the iaoq_back and iasq_back registers (in
@@ -399,7 +411,6 @@
.endr
END(smp_ivt)
-
/*******************************************************
PDC and IODC entry
*******************************************************/
diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c
index 1922f8d..52a8148 100644
--- a/src/parisc/parisc.c
+++ b/src/parisc/parisc.c
@@ -2965,6 +2965,10 @@
return defval;
}
+extern void start_kernel(unsigned long mem_free, unsigned long cline,
+ unsigned long rdstart, unsigned long rdend,
+ unsigned long kernel_start_address);
+
void __VISIBLE start_parisc_firmware(void)
{
unsigned int i, cpu_hz;
@@ -3301,29 +3305,26 @@
/* directly start Linux kernel if it was given on qemu command line. */
if (linux_kernel_entry > 1) {
- void (*start_kernel)(unsigned long mem_free, unsigned long cline,
- unsigned long rdstart, unsigned long rdend);
+ unsigned long kernel_entry = linux_kernel_entry;
printf("Autobooting Linux kernel which was loaded by qemu...\n\n");
- start_kernel = (void *) linux_kernel_entry;
/* zero out kernel entry point in case we reset the machine: */
linux_kernel_entry = 0;
- start_kernel(PAGE0->mem_free, cmdline, initrd_start, initrd_end);
+ start_kernel(PAGE0->mem_free, cmdline, initrd_start, initrd_end,
+ kernel_entry);
hlt(); /* this ends the emulator */
}
/* check for bootable drives, and load and start IPL bootloader if possible */
if (parisc_boot_menu(&iplstart, &iplend, bootdrive)) {
- void (*start_ipl)(long interactive, long iplend);
-
PAGE0->mem_boot.dp.layers[0] = boot_drive->target;
PAGE0->mem_boot.dp.layers[1] = boot_drive->lun;
printf("\nBooting...\n"
"Boot IO Dependent Code (IODC) revision 153\n\n"
"%s Booted.\n", PAGE0->imm_soft_boot ? "SOFT":"HARD");
- start_ipl = (void *) iplstart;
- start_ipl(interact_ipl, iplend);
+ /* actually: start_ipl(interact_ipl, iplend); */
+ start_kernel(interact_ipl, iplend, 0, 0, iplstart);
}
hlt(); /* this ends the emulator */