Date: Mon, 7 Sep 2009 20:39:04 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: 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 Message-ID: <200909072039.n87Kd4Fh026295@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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@ha std 5,openfirmware_entry@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@ha + ld 2,tocbase@l(2) + + /* Switch to 64-bit mode */ + mfmsr 9 + li 8,1 + insrdi 9,8,1,0 + mtmsrd 9 + mfmsr 0 lis 9,ofmsr@ha - stwu 0,ofmsr@l(9) + stdu 0,ofmsr@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@ha + ld 4,openfirmware_entry@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909072039.n87Kd4Fh026295>