Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Jan 2015 19:42:09 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r277997 - head/sys/boot/powerpc/kboot
Message-ID:  <201501311942.t0VJg9iV057342@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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();
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501311942.t0VJg9iV057342>