Date: Fri, 6 Apr 2018 20:27:55 +0000 (UTC) From: Kyle Evans <kevans@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r332152 - in stable/11/stand: ofw/common ofw/libofw powerpc/ofw Message-ID: <201804062027.w36KRtZk058743@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kevans Date: Fri Apr 6 20:27:55 2018 New Revision: 332152 URL: https://svnweb.freebsd.org/changeset/base/332152 Log: MFC r330365, r330371: OFW changes r330365: Move "common" Open Firmware parts of the loader used only on PowerPC to the powerpc/ subdirectory. These have never used by SPARC and we have no other (and almost certainly will have no other) Open Firmware platforms. This makes the directory structure simpler and lets us avoid some cargo-cult MI patterns on code that is, and always was, architecture-specific. r330371: Where we can, pass the kernel an FDT facsimile of the OF device tree rather than a pointer to Open Firmware by default. This eliminates a number of potentially unsafe calls to firmware from the kernel and provides better performance. This feature is meant to be expanded until it is on by default unconditionally and, ideally, we can then garbage-collect the nightmare pile of hacks required to call into Open Firmware from a live kernel. Added: stable/11/stand/powerpc/ofw/elf_freebsd.c - copied unchanged from r330365, head/stand/powerpc/ofw/elf_freebsd.c stable/11/stand/powerpc/ofw/main.c - copied, changed from r330365, head/stand/powerpc/ofw/main.c stable/11/stand/powerpc/ofw/ppc64_elf_freebsd.c - copied unchanged from r330365, head/stand/powerpc/ofw/ppc64_elf_freebsd.c Deleted: stable/11/stand/ofw/common/ stable/11/stand/ofw/libofw/elf_freebsd.c stable/11/stand/ofw/libofw/ppc64_elf_freebsd.c Modified: stable/11/stand/ofw/libofw/Makefile stable/11/stand/ofw/libofw/libofw.h stable/11/stand/powerpc/ofw/Makefile stable/11/stand/powerpc/ofw/conf.c Directory Properties: stable/11/ (props changed) Modified: stable/11/stand/ofw/libofw/Makefile ============================================================================== --- stable/11/stand/ofw/libofw/Makefile Fri Apr 6 20:26:56 2018 (r332151) +++ stable/11/stand/ofw/libofw/Makefile Fri Apr 6 20:27:55 2018 (r332152) @@ -4,7 +4,7 @@ LIB= ofw -SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \ +SRCS= devicename.c ofw_console.c ofw_copy.c ofw_disk.c \ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ ofw_time.c openfirm.c .PATH: ${ZFSSRC} @@ -12,10 +12,6 @@ SRCS+= devicename_stubs.c # Pick up the bootstrap header for some interface items CFLAGS+= -I${LDRSRC} - -.if ${MACHINE_CPUARCH} == "powerpc" -SRCS+= ppc64_elf_freebsd.c -.endif .ifdef(BOOT_DISK_DEBUG) # Make the disk code more talkative Modified: stable/11/stand/ofw/libofw/libofw.h ============================================================================== --- stable/11/stand/ofw/libofw/libofw.h Fri Apr 6 20:26:56 2018 (r332151) +++ stable/11/stand/ofw/libofw/libofw.h Fri Apr 6 20:27:55 2018 (r332152) @@ -62,17 +62,9 @@ void ofw_memmap(int); struct preloaded_file; struct file_format; -int ofw_elf_loadfile(char *, vm_offset_t, struct preloaded_file **); -int ofw_elf_exec(struct preloaded_file *); - /* MD code implementing MI interfaces */ vm_offset_t md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb); vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); - -extern struct file_format ofw_elf; -#ifdef __powerpc__ -extern struct file_format ofw_elf64; -#endif extern void reboot(void); Modified: stable/11/stand/powerpc/ofw/Makefile ============================================================================== --- stable/11/stand/powerpc/ofw/Makefile Fri Apr 6 20:26:56 2018 (r332151) +++ stable/11/stand/powerpc/ofw/Makefile Fri Apr 6 20:27:55 2018 (r332152) @@ -17,7 +17,7 @@ NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH} INSTALLFLAGS= -b # Architecture-specific loader code -SRCS= conf.c vers.c start.c +SRCS= conf.c vers.c main.c elf_freebsd.c ppc64_elf_freebsd.c start.c SRCS+= ucmpdi2.c .include "${BOOTSRC}/fdt.mk" @@ -37,10 +37,6 @@ RELOC?= 0x1C00000 CFLAGS+= -DRELOC=${RELOC} LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc - -# Pull in common loader code -.PATH: ${BOOTSRC}/ofw/common -.include "${BOOTSRC}/ofw/common/Makefile.inc" # Open Firmware standalone support library LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a Modified: stable/11/stand/powerpc/ofw/conf.c ============================================================================== --- stable/11/stand/powerpc/ofw/conf.c Fri Apr 6 20:26:56 2018 (r332151) +++ stable/11/stand/powerpc/ofw/conf.c Fri Apr 6 20:27:55 2018 (r332152) @@ -97,6 +97,9 @@ struct netif_driver *netif_drivers[] = { * rather than reading the file go first. */ +struct file_format ofw_elf; +struct file_format ofw_elf64; + struct file_format *file_formats[] = { &ofw_elf, &ofw_elf64, Copied: stable/11/stand/powerpc/ofw/elf_freebsd.c (from r330365, head/stand/powerpc/ofw/elf_freebsd.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/11/stand/powerpc/ofw/elf_freebsd.c Fri Apr 6 20:27:55 2018 (r332152, copy of r330365, head/stand/powerpc/ofw/elf_freebsd.c) @@ -0,0 +1,106 @@ +/*- + * 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$"); + +#include <sys/param.h> +#include <sys/linker.h> + +#include <machine/metadata.h> +#include <machine/elf.h> +#if defined(__powerpc__) +#include <machine/md_var.h> +#endif + +#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 +__elfN(ofw_loadfile)(char *filename, u_int64_t dest, + struct preloaded_file **result) +{ + int r; + + r = __elfN(loadfile)(filename, dest, result); + if (r != 0) + return (r); + +#if defined(__powerpc__) + /* + * 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); +#endif + return (0); +} + +int +__elfN(ofw_exec)(struct preloaded_file *fp) +{ + struct file_metadata *fmp; + vm_offset_t mdp, dtbp; + Elf_Ehdr *e; + int error; + intptr_t entry; + + if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { + return(EFTYPE); + } + e = (Elf_Ehdr *)&fmp->md_data; + entry = e->e_entry; + + if ((error = md_load(fp->f_args, &mdp, &dtbp)) != 0) + return (error); + + printf("Kernel entry at 0x%lx ...\n", e->e_entry); + + dev_cleanup(); + if (dtbp != 0) { + OF_quiesce(); + ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, + 0, 0, (void *)mdp, 0xfb5d104d); + } else { + OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, + (void *)mdp, 0xfb5d104d); + } + + panic("exec returned"); +} + +struct file_format ofw_elf = +{ + __elfN(ofw_loadfile), + __elfN(ofw_exec) +}; Copied and modified: stable/11/stand/powerpc/ofw/main.c (from r330365, head/stand/powerpc/ofw/main.c) ============================================================================== --- head/stand/powerpc/ofw/main.c Sat Mar 3 23:39:07 2018 (r330365, copy source) +++ stable/11/stand/powerpc/ofw/main.c Fri Apr 6 20:27:55 2018 (r332152) @@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$"); #include "libofw.h" #include "bootstrap.h" +#include <machine/psl.h> + struct arch_switch archsw; /* MI/MD interface boundary */ extern char end[]; @@ -47,6 +49,16 @@ static char heap[HEAP_SIZE]; // In BSS, so uses no spa #define OF_puts(fd, text) OF_write(fd, text, strlen(text)) +static __inline register_t +mfmsr(void) +{ + register_t value; + + __asm __volatile ("mfmsr %0" : "=r"(value)); + + return (value); +} + void init_heap(void) { @@ -144,6 +156,15 @@ main(int (*openfirm)(void *)) env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); setenv("LINES", "24", 1); /* optional */ + + /* + * On non-Apple hardware, where it works reliably, pass flattened + * device trees to the kernel by default instead of OF CI pointers. + * Apple hardware is the only virtual-mode OF implementation in + * existence, so far as I am aware, so use that as a flag. + */ + if (!(mfmsr() & PSL_DR)) + setenv("usefdt", "1", 1); archsw.arch_getdev = ofw_getdev; archsw.arch_copyin = ofw_copyin; Copied: stable/11/stand/powerpc/ofw/ppc64_elf_freebsd.c (from r330365, head/stand/powerpc/ofw/ppc64_elf_freebsd.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/11/stand/powerpc/ofw/ppc64_elf_freebsd.c Fri Apr 6 20:27:55 2018 (r332152, copy of r330365, head/stand/powerpc/ofw/ppc64_elf_freebsd.c) @@ -0,0 +1,110 @@ +/*- + * 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 <machine/md_var.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, dtbp; + 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 for ELFv1 kernels */ + if ((e->e_flags & 3) == 2) + entry = e->e_entry; + else + entry = *(uint64_t *)(intptr_t)e->e_entry; + + if ((error = md_load64(fp->f_args, &mdp, &dtbp)) != 0) + return (error); + + printf("Kernel entry at 0x%lx ...\n", entry); + + dev_cleanup(); + + if (dtbp != 0) { + OF_quiesce(); + ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, + 0, 0, (void *)mdp, 0xfb5d104d); + } else { + OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, + (void *)mdp, 0xfb5d104d); + } + + panic("exec returned"); +} + +struct file_format ofw_elf64 = +{ + ppc64_ofw_elf_loadfile, + ppc64_ofw_elf_exec +};
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804062027.w36KRtZk058743>