aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2024-01-18 17:42:10 +0100
committerHelge Deller <deller@gmx.de>2024-01-18 17:42:10 +0100
commit156124bf2e92f261ac5f96ae35c3e233c8fcf97f (patch)
treeee43fe555a3b6d3de74338ddb3340255f6dad2f8
parent68a51aac78186ef9c86b5657cfde3336609d69ce (diff)
downloadseabios-hppa-156124bf2e92f261ac5f96ae35c3e233c8fcf97f.zip
seabios-hppa-156124bf2e92f261ac5f96ae35c3e233c8fcf97f.tar.gz
seabios-hppa-156124bf2e92f261ac5f96ae35c3e233c8fcf97f.tar.bz2
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>
-rw-r--r--src/parisc/head.S13
-rw-r--r--src/parisc/parisc.c17
2 files changed, 21 insertions, 9 deletions
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 @@ $bss_loop:
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 @@ ENTRY(smp_ivt)
.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 @@ unsigned long romfile_loadstring_to_int(const char *name, unsigned long defval)
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 @@ void __VISIBLE start_parisc_firmware(void)
/* 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 */