diff --git a/config/examples/ppc_config.xml b/config/examples/ppc_config.xml
index ccb616d..5bb789f 100644
--- a/config/examples/ppc_config.xml
+++ b/config/examples/ppc_config.xml
@@ -26,6 +26,7 @@
+
diff --git a/forth/debugging/client.fs b/forth/debugging/client.fs
index 24b1ec7..9da9b33 100644
--- a/forth/debugging/client.fs
+++ b/forth/debugging/client.fs
@@ -27,6 +27,9 @@ create saved-program-state saved-program-state.size allot
variable state-valid
0 state-valid !
+variable want-bootcode
+0 want-bootcode !
+
variable file-size
: !load-size file-size ! ;
@@ -44,6 +47,7 @@ variable file-size
5 constant aout
10 constant fcode
11 constant forth
+12 constant bootcode
: init-program ( -- )
diff --git a/include/libopenbios/bootcode_load.h b/include/libopenbios/bootcode_load.h
new file mode 100644
index 0000000..147783a
--- /dev/null
+++ b/include/libopenbios/bootcode_load.h
@@ -0,0 +1,22 @@
+/*
+ * Creation Date: <2010/03/22 18:00:00 mcayland>
+ * Time-stamp: <2010/03/22 18:00:00 mcayland>
+ *
+ *
+ *
+ * Raw bootcode (%BOOT) loader
+ *
+ * Copyright (C) 2013 Mark Cave-Ayland (mark.cave-ayland@ilande.co.uk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ */
+
+#ifndef _H_BOOTCODELOAD
+#define _H_BOOTCODELOAD
+
+extern int bootcode_load(ihandle_t dev);
+
+#endif /* _H__H_BOOTCODELOAD */
diff --git a/libopenbios/bootcode_load.c b/libopenbios/bootcode_load.c
new file mode 100644
index 0000000..3644997
--- /dev/null
+++ b/libopenbios/bootcode_load.c
@@ -0,0 +1,71 @@
+/*
+ * Raw bootcode loader (CHRP/Apple %BOOT)
+ * Written by Mark Cave-Ayland 2013
+ */
+
+#include "config.h"
+#include "kernel/kernel.h"
+#include "libopenbios/bindings.h"
+#include "libopenbios/bootcode_load.h"
+#include "libc/diskio.h"
+#include "drivers/drivers.h"
+#define printf printk
+#define debug printk
+
+#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000)
+
+int
+bootcode_load(ihandle_t dev)
+{
+ int retval = -1, count = 0, fd;
+ unsigned long bootcode, loadbase, offset;
+
+ /* Mark the saved-program-state as invalid */
+ feval("0 state-valid !");
+
+ fd = open_ih(dev);
+ if (fd == -1) {
+ goto out;
+ }
+
+ /* Default to loading at load-base */
+ fword("load-base");
+ loadbase = POP();
+
+#ifdef CONFIG_PPC
+ /* However Old World Macs need to load to a different address */
+ if (is_oldworld()) {
+ loadbase = OLDWORLD_BOOTCODE_BASEADDR;
+ }
+#endif
+
+ bootcode = loadbase;
+ offset = 0;
+
+ while(1) {
+ if (seek_io(fd, offset) == -1)
+ break;
+ count = read_io(fd, (void *)bootcode, 512);
+ offset += count;
+ bootcode += count;
+ }
+
+ /* If we didn't read anything then exit */
+ if (!count) {
+ goto out;
+ }
+
+ /* Initialise saved-program-state */
+ PUSH(loadbase);
+ feval("saved-program-state >sps.entry !");
+ PUSH(offset);
+ feval("saved-program-state >sps.file-size !");
+ feval("bootcode saved-program-state >sps.file-type !");
+
+ feval("-1 state-valid !");
+
+out:
+ close_io(fd);
+ return retval;
+}
+
diff --git a/libopenbios/build.xml b/libopenbios/build.xml
index 04e3800..8c1fe3f 100644
--- a/libopenbios/build.xml
+++ b/libopenbios/build.xml
@@ -3,6 +3,7 @@
+
diff --git a/libopenbios/load.c b/libopenbios/load.c
index 2a2a7f9..1d50a82 100644
--- a/libopenbios/load.c
+++ b/libopenbios/load.c
@@ -36,6 +36,10 @@
#include "libopenbios/forth_load.h"
#endif
+#ifdef CONFIG_LOADER_BOOTCODE
+#include "libopenbios/bootcode_load.h"
+#endif
+
struct sys_info sys_info;
void *elf_boot_notes = NULL;
@@ -92,4 +96,13 @@ void load(ihandle_t dev)
}
#endif
+#ifdef CONFIG_LOADER_BOOTCODE
+ /* Check for a "raw" %BOOT bootcode payload */
+ feval("want-bootcode @");
+ valid = POP();
+ if (valid) {
+ bootcode_load(dev);
+ }
+#endif
+
}
diff --git a/packages/mac-parts.c b/packages/mac-parts.c
index 85d53f8..c29b554 100644
--- a/packages/mac-parts.c
+++ b/packages/mac-parts.c
@@ -89,8 +89,12 @@ macparts_open( macparts_info_t *di )
parnum = atol(parstr);
/* Detect if we are looking for the bootcode */
- if (strcmp(argstr, "%BOOT") == 0)
+ if (strcmp(argstr, "%BOOT") == 0) {
want_bootcode = 1;
+ feval("1 want-bootcode !");
+ } else {
+ feval("0 want-bootcode !");
+ }
}
DPRINTF("parstr: %s argstr: %s parnum: %d\n", parstr, argstr, parnum);
@@ -285,16 +289,10 @@ macparts_open( macparts_info_t *di )
set_property(chosen_ph, "bootpath", bootpath, strlen(bootpath) + 1);
}
-
- /* If the filename was %BOOT then it's not a real filename, so clear argstr before
- attempting interpose */
- if (want_bootcode) {
- argstr = strdup("");
- }
-
+
/* If we have been asked to open a particular file, interpose the filesystem package with
the passed filename as an argument */
- if (strlen(argstr)) {
+ if (!want_bootcode && strlen(argstr)) {
push_str( argstr );
PUSH_ph( ph );
fword("interpose");