From owner-svn-src-user@FreeBSD.ORG  Tue Dec 30 20:22:45 2014
Return-Path: <owner-svn-src-user@FreeBSD.ORG>
Delivered-To: svn-src-user@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org
 [IPv6:2001:1900:2254:206a::19:1])
 (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
 (No client certificate requested)
 by hub.freebsd.org (Postfix) with ESMTPS id 09EBE2FD;
 Tue, 30 Dec 2014 20:22:45 +0000 (UTC)
Received: from svn.freebsd.org (svn.freebsd.org
 [IPv6:2001:1900:2254:2068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id E99571E9E;
 Tue, 30 Dec 2014 20:22:44 +0000 (UTC)
Received: from svn.freebsd.org ([127.0.1.70])
 by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sBUKMi7m038780;
 Tue, 30 Dec 2014 20:22:44 GMT (envelope-from nwhitehorn@FreeBSD.org)
Received: (from nwhitehorn@localhost)
 by svn.freebsd.org (8.14.9/8.14.9/Submit) id sBUKMhMN038773;
 Tue, 30 Dec 2014 20:22:43 GMT (envelope-from nwhitehorn@FreeBSD.org)
Message-Id: <201412302022.sBUKMhMN038773@svn.freebsd.org>
X-Authentication-Warning: svn.freebsd.org: nwhitehorn set sender to
 nwhitehorn@FreeBSD.org using -f
From: Nathan Whitehorn <nwhitehorn@FreeBSD.org>
Date: Tue, 30 Dec 2014 20:22:43 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-user@freebsd.org
Subject: svn commit: r276420 - user/nwhitehorn/kboot/powerpc/kboot
X-SVN-Group: user
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-user@freebsd.org
X-Mailman-Version: 2.1.18-1
Precedence: list
List-Id: "SVN commit messages for the experimental &quot; user&quot;
 src tree" <svn-src-user.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-user>,
 <mailto:svn-src-user-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-user/>
List-Post: <mailto:svn-src-user@freebsd.org>
List-Help: <mailto:svn-src-user-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-user>,
 <mailto:svn-src-user-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Tue, 30 Dec 2014 20:22:45 -0000

Author: nwhitehorn
Date: Tue Dec 30 20:22:43 2014
New Revision: 276420
URL: https://svnweb.freebsd.org/changeset/base/276420

Log:
  Get FreeBSD kexec'ing. The trampoline needs to relocate the kernel back to
  where it is supposed to be (on top of Linux, usually) for this to actually
  do anything useful, but we're now getting much closer.

Modified:
  user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S
  user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
  user/nwhitehorn/kboot/powerpc/kboot/main.c
  user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c

Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S	Tue Dec 30 20:22:43 2014	(r276420)
@@ -44,3 +44,19 @@ ENTRY(host_select)
 	sc
 	blr
 
+ENTRY(kexec_load)
+	lis	%r4,nkexec_segments@ha
+	ori	%r4,%r4,nkexec_segments@l
+	lwz	%r4,0(%r4)
+	lis	%r5,loaded_segments@ha
+	ori	%r5,%r5,loaded_segments@l
+	lis	%r6,21	# KEXEC_ARCH_PPC64
+	li	%r0,268 # __NR_kexec_load
+	sc
+	blr
+
+ENTRY(host_reboot)
+	li %r0,88 # SYS_reboot
+	sc
+	blr
+

Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h	Tue Dec 30 20:22:43 2014	(r276420)
@@ -44,5 +44,7 @@ struct host_timeval {
 int host_gettimeofday(struct host_timeval *a, void *b);
 int host_select(int nfds, long *readfds, long *writefds, long *exceptfds,
     struct host_timeval *timeout);
+int kexec_load(vm_offset_t start);
+int host_reboot(int, int, int, void *);
 
 #endif

Modified: user/nwhitehorn/kboot/powerpc/kboot/main.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/main.c	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/main.c	Tue Dec 30 20:22:43 2014	(r276420)
@@ -181,6 +181,7 @@ get_phys_buffer(vm_offset_t dest, const 
 {
 	int i = 0;
 	const size_t segsize = 2*1024*1024;
+	dest += 32*1024*1024; /* XXX Make nonoverlapping somehow */
 
 	for (i = 0; i < nkexec_segments; i++) {
 		if (dest >= (vm_offset_t)loaded_segments[i].mem &&

Modified: user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Tue Dec 30 20:22:43 2014	(r276420)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <stand.h>
 
 #include "bootstrap.h"
+#include "host_syscall.h"
 
 extern char		end[];
 extern vm_offset_t	reloc;	/* From <arch>/conf.c */
@@ -65,6 +66,7 @@ ppc64_elf_exec(struct preloaded_file *fp
 	Elf_Ehdr		*e;
 	int			error;
 	uint32_t		*trampoline;
+	vm_offset_t		trampolinebase = 32*1024*1024; /* XXX */
 
 	if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
 		return(EFTYPE);
@@ -84,12 +86,21 @@ ppc64_elf_exec(struct preloaded_file *fp
 
 	trampoline[6] = mdp;
 	trampoline[7] = sizeof(mdp);
-	printf("Kernel entry at %#x ...\n", e->e_entry);
+	printf("Kernel entry at %#jx ...\n", e->e_entry);
 
 	dev_cleanup();
 
-	archsw.arch_copyin(trampoline, 0 /* XXX */, szkerneltramp);
-	/* XXX kexec_load, reboot */
+	archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp);
+	free(trampoline);
+
+	error = kexec_load(trampolinebase);
+	if (error != 0)
+		panic("kexec_load returned error: %d", error);
+	error = host_reboot(0xfee1dead, 672274793,
+	    0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, NULL);
+	if (error != 0)
+		panic("reboot returned error: %d", error);
+	while (1) {}
 
 	panic("exec returned");
 }