summaryrefslogtreecommitdiffstats
path: root/sys/boot/ofw
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2015-03-09 02:57:34 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2015-03-09 02:57:34 +0000
commit59b9a761ea0182492ad248ce6e5bf3818917516e (patch)
tree7505cbe441793d041a3962f06c5b0d486f29d738 /sys/boot/ofw
parentcf77261296a7c87dfb75318e9e0aff9f2693ea91 (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/boot/ofw/libofw/elf_freebsd.c14
-rw-r--r--sys/boot/ofw/libofw/openfirm.c14
-rw-r--r--sys/boot/ofw/libofw/openfirm.h1
-rw-r--r--sys/boot/ofw/libofw/ppc64_elf_freebsd.c14
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");
}
OpenPOWER on IntegriCloud