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 */