Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Dec 2014 17:30:48 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r276413 - user/nwhitehorn/kboot/powerpc/kboot
Message-ID:  <201412301730.sBUHUmmo048771@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Tue Dec 30 17:30:47 2014
New Revision: 276413
URL: https://svnweb.freebsd.org/changeset/base/276413

Log:
  Lay out first steps for launch trampoline.

Added:
  user/nwhitehorn/kboot/powerpc/kboot/kerneltramp.S   (contents, props changed)
Modified:
  user/nwhitehorn/kboot/powerpc/kboot/Makefile
  user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c

Modified: user/nwhitehorn/kboot/powerpc/kboot/Makefile
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/Makefile	Tue Dec 30 16:55:53 2014	(r276412)
+++ user/nwhitehorn/kboot/powerpc/kboot/Makefile	Tue Dec 30 17:30:47 2014	(r276413)
@@ -10,7 +10,7 @@ INSTALLFLAGS=	-b
 
 # Architecture-specific loader code
 SRCS=		conf.c metadata.c vers.c main.c ppc64_elf_freebsd.c
-SRCS+=		host_syscall.S hostcons.c hostdisk.c
+SRCS+=		host_syscall.S hostcons.c hostdisk.c kerneltramp.S
 SRCS+=		ucmpdi2.c
 
 LOADER_DISK_SUPPORT?=	yes

Added: user/nwhitehorn/kboot/powerpc/kboot/kerneltramp.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/nwhitehorn/kboot/powerpc/kboot/kerneltramp.S	Tue Dec 30 17:30:47 2014	(r276413)
@@ -0,0 +1,38 @@
+/*
+ * This is the analog to the kexec "purgatory" code
+ *
+ * The goal here is to call the actual kernel entry point with the arguments it
+ * expects when kexec calls into it with no arguments. The value of the kernel
+ * entry point and arguments r3-r7 are copied into the trampoline text (which can
+ * be executed from any address) at bytes 8-32.
+ * 
+ * TODO:
+ * - This may or may not need to relocate the kernel before executing it
+ * - kexec enters at address 0x60 for all APs. We need to catch these and hold
+ *   them.
+ */
+
+#include <machine/asm.h>
+
+        .globl  CNAME(kerneltramp),CNAME(szkerneltramp)
+CNAME(kerneltramp):
+	mflr %r9
+	bl 1f
+	.space 24	/* branch address, r3-r7 */
+1:
+	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)
+	lwz	%r5,12(%r8)
+	lwz	%r6,16(%r8)
+	lwz	%r7,20(%r8)
+	bctr
+endkerneltramp:
+
+	.data
+CNAME(szkerneltramp):
+	.long endkerneltramp - CNAME(kerneltramp)

Modified: user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Tue Dec 30 16:55:53 2014	(r276412)
+++ user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Tue Dec 30 17:30:47 2014	(r276413)
@@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
 
 extern char		end[];
 extern vm_offset_t	reloc;	/* From <arch>/conf.c */
+extern void		*kerneltramp;
+extern size_t		szkerneltramp;
 
 int
 ppc64_elf_loadfile(char *filename, u_int64_t dest,
@@ -62,7 +64,7 @@ ppc64_elf_exec(struct preloaded_file *fp
 	vm_offset_t		mdp;
 	Elf_Ehdr		*e;
 	int			error;
-	int (*entry)(u_long, u_long, u_long, void *, u_long);
+	uint32_t		*trampoline;
 
 	if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
 		return(EFTYPE);
@@ -70,17 +72,24 @@ ppc64_elf_exec(struct preloaded_file *fp
 	e = (Elf_Ehdr *)&fmp->md_data;
 	
 	/* Handle function descriptor */
-	entry = (void *)(uintptr_t)(*(uint64_t *)e->e_entry);
+	trampoline = malloc(szkerneltramp);
+	memcpy(trampoline, &kerneltramp, szkerneltramp);
+	trampoline[2] = e->e_entry;
+	trampoline[3] = 0; /* FDT */
+	trampoline[4] = 0; /* Phys. mem offset */
+	trampoline[5] = 0; /* OF entry point */
 
 	if ((error = md_load64(fp->f_args, &mdp)) != 0)
 		return (error);
 
-	printf("Kernel entry at %p ...\n", entry);
+	trampoline[6] = mdp;
+	trampoline[7] = sizeof(mdp);
+	printf("Kernel entry at %#x ...\n", e->e_entry);
 
 	dev_cleanup();
 
-	entry(0 /* FDT */, 0 /* Phys. mem offset */, 0 /* OF entry */,
-	     (void *)mdp, sizeof(mdp));
+	archsw.arch_copyin(trampoline, 0 /* XXX */, szkerneltramp);
+	/* XXX kexec_load, reboot */
 
 	panic("exec returned");
 }



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