Author: nwhitehorn
Date: Sat Jan 31 19:42:08 2015
New Revision: 277997
URL: https://svnweb.freebsd.org/changeset/base/277997

Log:
  Relocate kernel to high address space (a static + 64 MB for now) to avoid
  conflicts with the Linux host kernel. This lets you kexec an unmodified
  GENERIC64.

Modified:
  head/sys/boot/powerpc/kboot/conf.c
  head/sys/boot/powerpc/kboot/kerneltramp.S
  head/sys/boot/powerpc/kboot/main.c
  head/sys/boot/powerpc/kboot/ppc64_elf_freebsd.c

Modified: head/sys/boot/powerpc/kboot/conf.c
==============================================================================
--- head/sys/boot/powerpc/kboot/conf.c  Sat Jan 31 19:32:14 2015        
(r277996)
+++ head/sys/boot/powerpc/kboot/conf.c  Sat Jan 31 19:42:08 2015        
(r277997)
@@ -115,7 +115,3 @@ struct console *consoles[] = {
     NULL
 };
 
-/*
- * reloc - our load address
- */
-vm_offset_t    reloc = RELOC;

Modified: head/sys/boot/powerpc/kboot/kerneltramp.S
==============================================================================
--- head/sys/boot/powerpc/kboot/kerneltramp.S   Sat Jan 31 19:32:14 2015        
(r277996)
+++ head/sys/boot/powerpc/kboot/kerneltramp.S   Sat Jan 31 19:42:08 2015        
(r277997)
@@ -9,6 +9,7 @@
  * to the absolute address 0x60. Here we implement a loop waiting on the 
release
  * of a lock by the kernel at 0x40.
  * 
+ * $FreeBSD$
  */
 
 #include <machine/asm.h>
@@ -39,7 +40,6 @@ CNAME(kerneltramp):
        mflr    %r8
        mtlr    %r9
        lwz     %r3,0(%r8)
-       ld      %r3,0(%r3)      /* Resolve function descriptor */
        mtctr   %r3
        lwz     %r3,4(%r8)
        lwz     %r4,8(%r8)

Modified: head/sys/boot/powerpc/kboot/main.c
==============================================================================
--- head/sys/boot/powerpc/kboot/main.c  Sat Jan 31 19:32:14 2015        
(r277996)
+++ head/sys/boot/powerpc/kboot/main.c  Sat Jan 31 19:42:08 2015        
(r277997)
@@ -48,6 +48,7 @@ ssize_t kboot_copyin(const void *src, vm
 ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len);
 ssize_t kboot_readin(const int fd, vm_offset_t dest, const size_t len);
 int kboot_autoload(void);
+uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr);
 int kboot_setcurrdev(struct env_var *ev, int flags, const void *value);
 
 extern int command_fdt_internal(int argc, char *argv[]);
@@ -116,6 +117,7 @@ main(int argc, const char **argv)
        archsw.arch_copyout = kboot_copyout;
        archsw.arch_readin = kboot_readin;
        archsw.arch_autoload = kboot_autoload;
+       archsw.arch_loadaddr = kboot_loadaddr;
 
        printf("\n");
        printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
@@ -282,6 +284,22 @@ kboot_autoload(void)
        return (0);
 }
 
+uint64_t
+kboot_loadaddr(u_int type, void *data, uint64_t addr)
+{
+       /*
+        * Need to stay out of the way of Linux. /chosen/linux,kernel-end does
+        * a better job here, but use a fixed offset for now.
+        */
+
+       if (type == LOAD_ELF)
+               addr = roundup(addr, PAGE_SIZE);
+       else
+               addr += 64*1024*1024; /* Stay out of the way of Linux */
+
+       return (addr);
+}
+
 void
 _start(int argc, const char **argv, char **env)
 {

Modified: head/sys/boot/powerpc/kboot/ppc64_elf_freebsd.c
==============================================================================
--- head/sys/boot/powerpc/kboot/ppc64_elf_freebsd.c     Sat Jan 31 19:32:14 
2015        (r277996)
+++ head/sys/boot/powerpc/kboot/ppc64_elf_freebsd.c     Sat Jan 31 19:42:08 
2015        (r277997)
@@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
 #include "host_syscall.h"
 
 extern char            end[];
-extern vm_offset_t     reloc;  /* From <arch>/conf.c */
 extern void            *kerneltramp;
 extern size_t          szkerneltramp;
 extern int             nkexec_segments;
@@ -68,17 +67,22 @@ ppc64_elf_exec(struct preloaded_file *fp
        Elf_Ehdr                *e;
        int                     error;
        uint32_t                *trampoline;
-       vm_offset_t             trampolinebase = 96*1024*1024; /* XXX */
+       uint64_t                entry;
+       vm_offset_t             trampolinebase;
 
        if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
                return(EFTYPE);
        }
        e = (Elf_Ehdr *)&fmp->md_data;
+
+       /* Figure out where to put it */
+       trampolinebase = archsw.arch_loadaddr(LOAD_RAW, NULL, 0);
        
-       /* Handle function descriptor */
+       /* Set up interesting values in function descriptor */
        trampoline = malloc(szkerneltramp);
        memcpy(trampoline, &kerneltramp, szkerneltramp);
-       trampoline[2] = e->e_entry;
+       archsw.arch_copyout(e->e_entry + elf64_relocation_offset, &entry, 8);
+       trampoline[2] = entry + elf64_relocation_offset;
        trampoline[4] = 0; /* Phys. mem offset */
        trampoline[5] = 0; /* OF entry point */
 
@@ -88,7 +92,8 @@ ppc64_elf_exec(struct preloaded_file *fp
        trampoline[3] = dtb;
        trampoline[6] = mdp;
        trampoline[7] = sizeof(mdp);
-       printf("Kernel entry at %#jx ...\n", e->e_entry);
+       printf("Kernel entry at %#jx (%#x) ...\n", e->e_entry, trampoline[2]);
+       printf("DTB at %#x, mdp at %#x\n", dtb, mdp);
 
        dev_cleanup();
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to