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 <be...@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 <be...@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
+};
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to