diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-03-09 02:57:34 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-03-09 02:57:34 +0000 |
commit | 59b9a761ea0182492ad248ce6e5bf3818917516e (patch) | |
tree | 7505cbe441793d041a3962f06c5b0d486f29d738 /sys/boot/ofw | |
parent | cf77261296a7c87dfb75318e9e0aff9f2693ea91 (diff) | |
download | FreeBSD-src-59b9a761ea0182492ad248ce6e5bf3818917516e.zip FreeBSD-src-59b9a761ea0182492ad248ce6e5bf3818917516e.tar.gz |
Provide a shim layer in loader to condense the Open Firmware device tree to
an FDT. This is how Linux and OS X boot and can avoid some issues with
using Open Firmware at runtime. The code is highly experimental and disabled
by default; it can be turned on by setting the loader environment variable
"usefdt" to a non-NULL value.
Diffstat (limited to 'sys/boot/ofw')
-rw-r--r-- | sys/boot/ofw/common/main.c | 2 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/elf_freebsd.c | 14 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/openfirm.c | 14 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/openfirm.h | 1 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ppc64_elf_freebsd.c | 14 |
5 files changed, 36 insertions, 9 deletions
diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c index eb8ae0c..0913f0c 100644 --- a/sys/boot/ofw/common/main.c +++ b/sys/boot/ofw/common/main.c @@ -45,7 +45,7 @@ u_int32_t acells, scells; static char bootargs[128]; -#define HEAP_SIZE 0x80000 +#define HEAP_SIZE 0x100000 #define OF_puts(fd, text) OF_write(fd, text, strlen(text)) diff --git a/sys/boot/ofw/libofw/elf_freebsd.c b/sys/boot/ofw/libofw/elf_freebsd.c index 50fd8a6..80ece7e 100644 --- a/sys/boot/ofw/libofw/elf_freebsd.c +++ b/sys/boot/ofw/libofw/elf_freebsd.c @@ -67,7 +67,7 @@ int __elfN(ofw_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; - vm_offset_t mdp; + vm_offset_t mdp, dtbp; Elf_Ehdr *e; int error; intptr_t entry; @@ -78,15 +78,21 @@ __elfN(ofw_exec)(struct preloaded_file *fp) e = (Elf_Ehdr *)&fmp->md_data; entry = e->e_entry; - if ((error = md_load(fp->f_args, &mdp)) != 0) + if ((error = md_load(fp->f_args, &mdp, &dtbp)) != 0) return (error); printf("Kernel entry at 0x%lx ...\n", e->e_entry); dev_cleanup(); ofw_release_heap(); - OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, - (void *)mdp, sizeof(mdp)); + if (dtbp != 0) { + OF_quiesce(); + ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, + mdp, sizeof(mdp)); + } else { + OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, + (void *)mdp, sizeof(mdp)); + } panic("exec returned"); } diff --git a/sys/boot/ofw/libofw/openfirm.c b/sys/boot/ofw/libofw/openfirm.c index d4eb9d6..a8626cc 100644 --- a/sys/boot/ofw/libofw/openfirm.c +++ b/sys/boot/ofw/libofw/openfirm.c @@ -729,6 +729,20 @@ OF_exit() ; } +void +OF_quiesce() +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + } args = { + (cell_t)"quiesce", + }; + + openfirmware(&args); +} + /* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ #if 0 void diff --git a/sys/boot/ofw/libofw/openfirm.h b/sys/boot/ofw/libofw/openfirm.h index c70c2e9..ecb1f32 100644 --- a/sys/boot/ofw/libofw/openfirm.h +++ b/sys/boot/ofw/libofw/openfirm.h @@ -82,6 +82,7 @@ void OF_init(int (*openfirm)(void *)); /* Generic functions */ int OF_test(char *); +void OF_quiesce(); /* Disable firmware */ /* Device tree functions */ phandle_t OF_peer(phandle_t); diff --git a/sys/boot/ofw/libofw/ppc64_elf_freebsd.c b/sys/boot/ofw/libofw/ppc64_elf_freebsd.c index 84ea406..f85a77a 100644 --- a/sys/boot/ofw/libofw/ppc64_elf_freebsd.c +++ b/sys/boot/ofw/libofw/ppc64_elf_freebsd.c @@ -67,7 +67,7 @@ int ppc64_ofw_elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; - vm_offset_t mdp; + vm_offset_t mdp, dtbp; Elf_Ehdr *e; int error; intptr_t entry; @@ -80,7 +80,7 @@ ppc64_ofw_elf_exec(struct preloaded_file *fp) /* Handle function descriptor */ entry = *(uint64_t *)e->e_entry; - if ((error = md_load64(fp->f_args, &mdp)) != 0) + if ((error = md_load64(fp->f_args, &mdp, &dtbp)) != 0) return (error); printf("Kernel entry at 0x%lx ...\n", entry); @@ -88,8 +88,14 @@ ppc64_ofw_elf_exec(struct preloaded_file *fp) dev_cleanup(); ofw_release_heap(); - OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, - (void *)mdp, sizeof(mdp)); + if (dtbp != 0) { + OF_quiesce(); + ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, + mdp, sizeof(mdp)); + } else { + OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, + (void *)mdp, sizeof(mdp)); + } panic("exec returned"); } |