svn commit: r196951 - in projects/ppc64/sys: boot boot/common
boot/ofw/libofw boot/powerpc boot/powerpc/ofw
boot/powerpc/uboot powerpc/aim powerpc/aim64 powerpc/include
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Mon Sep 7 20:39:04 UTC 2009
Author: nwhitehorn
Date: Mon Sep 7 20:39:04 2009
New Revision: 196951
URL: http://svn.freebsd.org/changeset/base/196951
Log:
Fix up some bugs in virtual mode Open Firmware and add support to the
PowerPC loader to load 64-bit executables. This provides the first
64-bit PowerPC boot on real hardware, which then crashes bringing up
the VM due to remaining missing features.
Added:
projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c (contents, props changed)
Modified:
projects/ppc64/sys/boot/Makefile
projects/ppc64/sys/boot/common/Makefile.inc
projects/ppc64/sys/boot/ofw/libofw/Makefile
projects/ppc64/sys/boot/ofw/libofw/libofw.h
projects/ppc64/sys/boot/powerpc/Makefile.inc
projects/ppc64/sys/boot/powerpc/ofw/Makefile
projects/ppc64/sys/boot/powerpc/ofw/conf.c
projects/ppc64/sys/boot/powerpc/uboot/Makefile
projects/ppc64/sys/powerpc/aim/ofw_machdep.c
projects/ppc64/sys/powerpc/aim64/locore.S
projects/ppc64/sys/powerpc/include/elf.h
Modified: projects/ppc64/sys/boot/Makefile
==============================================================================
--- projects/ppc64/sys/boot/Makefile Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/Makefile Mon Sep 7 20:39:04 2009 (r196951)
@@ -13,12 +13,12 @@ SUBDIR+= efi
.endif
# Build Open Firmware library.
-.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "sparc64"
+.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "sparc64"
SUBDIR+= ofw
.endif
# Build U-Boot library.
-.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "arm"
+.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "arm"
SUBDIR+= uboot
.endif
Modified: projects/ppc64/sys/boot/common/Makefile.inc
==============================================================================
--- projects/ppc64/sys/boot/common/Makefile.inc Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/common/Makefile.inc Mon Sep 7 20:39:04 2009 (r196951)
@@ -9,8 +9,11 @@ SRCS+= load_elf32.c load_elf32_obj.c rel
SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.c
.elif ${MACHINE} == "pc98"
SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
-.elif ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "arm"
+.elif ${MACHINE_ARCH} == "arm"
SRCS+= load_elf32.c reloc_elf32.c
+.elif ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
+SRCS+= load_elf32.c reloc_elf32.c
+SRCS+= load_elf64.c reloc_elf64.c
.elif ${MACHINE_ARCH} == "sparc64" || ${MACHINE_ARCH} == "ia64"
SRCS+= load_elf64.c reloc_elf64.c
.endif
Modified: projects/ppc64/sys/boot/ofw/libofw/Makefile
==============================================================================
--- projects/ppc64/sys/boot/ofw/libofw/Makefile Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/ofw/libofw/Makefile Mon Sep 7 20:39:04 2009 (r196951)
@@ -13,8 +13,9 @@ CFLAGS+= -I${.CURDIR}/../../../../lib/li
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
CFLAGS+= -ffreestanding
-.if ${MACHINE_ARCH} == "powerpc"
+.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
CFLAGS+= -msoft-float
+SRCS+= ppc64_elf_freebsd.c
.endif
.ifdef(BOOT_DISK_DEBUG)
Modified: projects/ppc64/sys/boot/ofw/libofw/libofw.h
==============================================================================
--- projects/ppc64/sys/boot/ofw/libofw/libofw.h Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/ofw/libofw/libofw.h Mon Sep 7 20:39:04 2009 (r196951)
@@ -62,6 +62,9 @@ int ofw_elf_loadfile(char *, vm_offset_t
int ofw_elf_exec(struct preloaded_file *);
extern struct file_format ofw_elf;
+#ifdef __powerpc__
+extern struct file_format ofw_elf64;
+#endif
extern void reboot(void);
Added: projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c Mon Sep 7 20:39:04 2009 (r196951)
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+#include "openfirm.h"
+
+extern char end[];
+extern vm_offset_t reloc; /* From <arch>/conf.c */
+
+int
+ppc64_ofw_elf_loadfile(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ int r;
+
+ r = __elfN(loadfile)(filename, dest, result);
+ if (r != 0)
+ return (r);
+
+ /*
+ * No need to sync the icache for modules: this will
+ * be done by the kernel after relocation.
+ */
+ if (!strcmp((*result)->f_type, "elf kernel"))
+ __syncicache((void *) (*result)->f_addr, (*result)->f_size);
+ return (0);
+}
+
+int
+ppc64_ofw_elf_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t mdp;
+ Elf_Ehdr *e;
+ int error;
+ intptr_t entry;
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
+ return(EFTYPE);
+ }
+ e = (Elf_Ehdr *)&fmp->md_data;
+
+ /* Handle function descriptor */
+ entry = *(uint64_t *)e->e_entry;
+
+ if ((error = md_load(fp->f_args, &mdp)) != 0)
+ return (error);
+
+ printf("Kernel entry at 0x%lx ...\n", entry);
+
+ dev_cleanup();
+ ofw_release_heap();
+
+ OF_chain((void *)reloc, end - (char *)reloc, (void *)entry,
+ (void *)mdp, sizeof(mdp));
+
+ panic("exec returned");
+}
+
+struct file_format ofw_elf64 =
+{
+ ppc64_ofw_elf_loadfile,
+ ppc64_ofw_elf_exec
+};
Modified: projects/ppc64/sys/boot/powerpc/Makefile.inc
==============================================================================
--- projects/ppc64/sys/boot/powerpc/Makefile.inc Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/powerpc/Makefile.inc Mon Sep 7 20:39:04 2009 (r196951)
@@ -1,3 +1,9 @@
# $FreeBSD$
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32 -mcpu=powerpc
+LDFLAGS+= -m elf32-powerpc
+AFLAGS+= --32
+.endif
+
.include "../Makefile.inc"
Modified: projects/ppc64/sys/boot/powerpc/ofw/Makefile
==============================================================================
--- projects/ppc64/sys/boot/powerpc/ofw/Makefile Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/powerpc/ofw/Makefile Mon Sep 7 20:39:04 2009 (r196951)
@@ -10,6 +10,7 @@ INSTALLFLAGS= -b
# Architecture-specific loader code
SRCS= conf.c metadata.c vers.c start.c
+SRCS+= ucmpdi2.c
LOADER_DISK_SUPPORT?= yes
LOADER_UFS_SUPPORT?= yes
@@ -57,9 +58,9 @@ LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
# Always add MI sources
-.PATH: ${.CURDIR}/../../common
+.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern
.include "${.CURDIR}/../../common/Makefile.inc"
-CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../..
CFLAGS+= -I.
CLEANFILES+= vers.c loader.help
Modified: projects/ppc64/sys/boot/powerpc/ofw/conf.c
==============================================================================
--- projects/ppc64/sys/boot/powerpc/ofw/conf.c Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/powerpc/ofw/conf.c Mon Sep 7 20:39:04 2009 (r196951)
@@ -96,6 +96,7 @@ struct netif_driver *netif_drivers[] = {
struct file_format *file_formats[] = {
&ofw_elf,
+ &ofw_elf64,
NULL
};
Modified: projects/ppc64/sys/boot/powerpc/uboot/Makefile
==============================================================================
--- projects/ppc64/sys/boot/powerpc/uboot/Makefile Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/boot/powerpc/uboot/Makefile Mon Sep 7 20:39:04 2009 (r196951)
@@ -8,6 +8,7 @@ NO_MAN=
# Architecture-specific loader code
SRCS= start.S conf.c vers.c
+SRCS+= ucmpdi2.c
LOADER_DISK_SUPPORT?= no
LOADER_UFS_SUPPORT?= no
@@ -55,9 +56,9 @@ LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
# Always add MI sources
-.PATH: ${.CURDIR}/../../common
+.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern
.include "${.CURDIR}/../../common/Makefile.inc"
-CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../..
CFLAGS+= -I.
CLEANFILES+= vers.c ${PROG}.help
Modified: projects/ppc64/sys/powerpc/aim/ofw_machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/ofw_machdep.c Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/powerpc/aim/ofw_machdep.c Mon Sep 7 20:39:04 2009 (r196951)
@@ -68,16 +68,8 @@ static int (*ofwcall)(void *);
static void *fdt;
int ofw_real_mode;
-#ifdef __powerpc64__
-/* Handle PPC64 ABI brain damage */
-struct {
- int (*funcptr)(void *);
- uintptr_t toc;
- uintptr_t env;
-} ofwcall_funcdesc;
-#endif
-
int ofw_real_mode_entry(void *);
+int ofw_32bit_mode_entry(void *);
static int openfirmware(void *args);
/*
@@ -329,22 +321,21 @@ OF_initial_setup(void *fdt_ptr, void *ju
else
ofw_real_mode = 1;
+ ofwcall = NULL;
+
#ifdef __powerpc64__
/*
- * For PPC64, we need to hack up a function descriptor object
- * to be able to call a memory address.
+ * For PPC64, we need to use some hand-written
+ * asm trampolines to get to OF.
*/
- if (ofw_real_mode) {
+ if (ofw_real_mode && openfirm != NULL)
ofwcall = ofw_real_mode_entry;
- } else {
- ofwcall_funcdesc.funcptr = openfirm;
- ofwcall_funcdesc.toc = 0;
- ofwcall_funcdesc.env = 0;
- ofwcall = (int (*)(void *))&ofwcall_funcdesc;
- }
+ else
+ ofwcall = ofw_32bit_mode_entry;
#else
ofwcall = openfirm;
#endif
+
fdt = fdt_ptr;
}
Modified: projects/ppc64/sys/powerpc/aim64/locore.S
==============================================================================
--- projects/ppc64/sys/powerpc/aim64/locore.S Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/powerpc/aim64/locore.S Mon Sep 7 20:39:04 2009 (r196951)
@@ -87,10 +87,10 @@
GLOBAL(tmpstk)
.space TMPSTKSZ
GLOBAL(esym)
- .long 0 /* end of symbol table */
+ .llong 0 /* end of symbol table */
GLOBAL(ofmsr)
- .long 0, 0, 0, 0, 0 /* msr/sprg0-3 used in Open Firmware */
+ .llong 0, 0, 0, 0, 0 /* msr/sprg0-3 used in Open Firmware */
#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */
GLOBAL(intrnames)
@@ -105,11 +105,11 @@ GLOBAL(eintrcnt)
* File-scope for locore.S
*/
idle_u:
- .long 0 /* fake uarea during idle after exit */
+ .llong 0 /* fake uarea during idle after exit */
openfirmware_entry:
- .long 0 /* Open Firmware entry point */
+ .llong 0 /* Open Firmware entry point */
srsave:
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .llong 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.text
.globl btext
@@ -146,21 +146,32 @@ ASENTRY(__start)
lis 8,openfirmware_entry at ha
std 5,openfirmware_entry at l(8) /* save client interface handler */
+ /* Set up the stack pointer */
lis 1,(tmpstk+TMPSTKSZ-16)@ha
addi 1,1,(tmpstk+TMPSTKSZ-16)@l
+ /* Set up the TOC pointer */
+ lis 2,tocbase at ha
+ ld 2,tocbase at l(2)
+
+ /* Switch to 64-bit mode */
+ mfmsr 9
+ li 8,1
+ insrdi 9,8,1,0
+ mtmsrd 9
+
mfmsr 0
lis 9,ofmsr at ha
- stwu 0,ofmsr at l(9)
+ stdu 0,ofmsr at l(9)
mfsprg0 0 /* save SPRG0-3 */
- stw 0,4(9) /* ofmsr[1] = sprg0 */
+ std 0,8(9) /* ofmsr[1] = sprg0 */
mfsprg1 0
- stw 0,8(9) /* ofmsr[2] = sprg1 */
+ std 0,16(9) /* ofmsr[2] = sprg1 */
mfsprg2 0
- stw 0,12(9) /* ofmsr[3] = sprg2 */
+ std 0,24(9) /* ofmsr[3] = sprg2 */
mfsprg3 0
- stw 0,16(9) /* ofmsr[4] = sprg3 */
+ std 0,32(9) /* ofmsr[4] = sprg3 */
bl .OF_initial_setup
nop
@@ -217,6 +228,31 @@ ASENTRY(ofw_real_mode_entry)
mtlr 0
blr
+ASENTRY(ofw_32bit_mode_entry)
+ mflr 4
+ mtsprg1 4
+
+ lis 4,openfirmware_entry at ha
+ ld 4,openfirmware_entry at l(4) /* read client interface handler */
+
+ /* Set up a 32-bit MSR in r5 */
+ mfmsr 5
+ mtsprg2 5
+ clrldi 5,5,1
+
+ /* Set MSR, branch to OF, and come back */
+ mtmsrd 5
+ isync
+ mtctr 4
+ bctrl
+ mfsprg2 5
+ mtmsrd 5
+ isync
+
+ mfsprg1 4
+ mtlr 4
+ blr
+
/*
* int setfault()
*
Modified: projects/ppc64/sys/powerpc/include/elf.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/elf.h Mon Sep 7 20:10:33 2009 (r196950)
+++ projects/ppc64/sys/powerpc/include/elf.h Mon Sep 7 20:39:04 2009 (r196951)
@@ -36,17 +36,19 @@
* [ppc-eabi-1995-01.pdf] for details.
*/
+#ifndef __ELF_WORD_SIZE
#ifdef __powerpc64__
#define __ELF_WORD_SIZE 64 /* Used by <sys/elf_generic.h> */
#else
#define __ELF_WORD_SIZE 32 /* Used by <sys/elf_generic.h> */
#endif
+#endif
#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
#include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */
#include <sys/elf_generic.h>
-#ifdef __powerpc64__
+#if __ELF_WORD_SIZE == 64
#define ELF_ARCH EM_PPC64
#define ELF_MACHINE_OK(x) ((x) == EM_PPC64)
#else
@@ -70,7 +72,6 @@ typedef struct { /* Auxiliary vector ent
} a_un;
} Elf32_Auxinfo;
-#ifdef __powerpc64__
/* XXX: check ABI */
typedef struct { /* Auxiliary vector entry on initial stack */
int a_type; /* Entry type. */
@@ -80,7 +81,6 @@ typedef struct { /* Auxiliary vector ent
void (*a_fcn)(void); /* Function pointer (not used). */
} a_un;
} Elf64_Auxinfo;
-#endif
__ElfType(Auxinfo);
@@ -112,7 +112,7 @@ __ElfType(Auxinfo);
#define R_PPC_EMB_COUNT (R_PPC_EMB_RELSDA - R_PPC_EMB_NADDR32 + 1)
/* Define "machine" characteristics */
-#ifdef __powerpc64__
+#if __ELF_WORD_SIZE == 64
#define ELF_TARG_CLASS ELFCLASS64
#define ELF_TARG_DATA ELFDATA2MSB
#define ELF_TARG_MACH EM_PPC64
More information about the svn-src-projects
mailing list