diff --git a/arch/sparc64/boot.c b/arch/sparc64/boot.c
index 4835cbf..84cafaf 100644
--- a/arch/sparc64/boot.c
+++ b/arch/sparc64/boot.c
@@ -68,15 +68,22 @@ void boot(void)
if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
- if (aout_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) {
+ if (aout_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
+ if (fcode_load(&sys_info, path, param)
+ == LOADER_NOT_SUPPORT) {
- sprintf(altpath, "%s:d", path);
+ sprintf(altpath, "%s:d", path);
- if (elf_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
- if (linux_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
- if (aout_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
- printk("Unsupported image format\n");
- }
+ if (elf_load(&sys_info, altpath, param)
+ == LOADER_NOT_SUPPORT)
+ if (linux_load(&sys_info, altpath, param)
+ == LOADER_NOT_SUPPORT)
+ if (aout_load(&sys_info, altpath, param)
+ == LOADER_NOT_SUPPORT)
+ if (fcode_load(&sys_info, path, param)
+ == LOADER_NOT_SUPPORT)
+ printk("Unsupported image format\n");
+ }
free(path);
}
diff --git a/arch/sparc64/boot.h b/arch/sparc64/boot.h
index 612dea7..0c1519c 100644
--- a/arch/sparc64/boot.h
+++ b/arch/sparc64/boot.h
@@ -10,6 +10,8 @@ int forth_load(struct sys_info *info, const char *filename, const char *cmdline)
int elf_load(struct sys_info *info, const char *filename, const char *cmdline);
int linux_load(struct sys_info *info, const char *file, const char *cmdline);
int aout_load(struct sys_info *info, const char *filename, const char *cmdline);
+int fcode_load(struct sys_info *info, const char *filename,
+ const char *cmdline);
uint64_t start_elf(uint64_t entry_point, uint64_t param);
diff --git a/arch/sparc64/build.xml b/arch/sparc64/build.xml
index c4a7b68..b6c21db 100644
--- a/arch/sparc64/build.xml
+++ b/arch/sparc64/build.xml
@@ -17,6 +17,7 @@
+
diff --git a/arch/sparc64/fcodeload.c b/arch/sparc64/fcodeload.c
new file mode 100644
index 0000000..ed39fe3
--- /dev/null
+++ b/arch/sparc64/fcodeload.c
@@ -0,0 +1,76 @@
+/*
+ * FCode boot loader
+ */
+
+#include "openbios/config.h"
+#include "openbios/kernel.h"
+#include "openbios/bindings.h"
+#include "sys_info.h"
+#include "loadfs.h"
+#include "boot.h"
+#define printf printk
+#define debug printk
+
+int fcode_load(struct sys_info *info, const char *filename,
+ const char *cmdline)
+{
+ int retval = -1;
+ uint8_t fcode_header[8];
+ unsigned long start, size;
+ unsigned int offset;
+
+ if (!file_open(filename))
+ goto out;
+
+ for (offset = 0; offset < 16 * 512; offset += 512) {
+ file_seek(offset);
+ if (lfile_read(&fcode_header, sizeof(fcode_header))
+ != sizeof(fcode_header)) {
+ debug("Can't read FCode header from file %s\n", filename);
+ retval = LOADER_NOT_SUPPORT;
+ goto out;
+ }
+ switch (fcode_header[0]) {
+ case 0xf0: // start0
+ case 0xf1: // start1
+ case 0xf2: // start2
+ case 0xf3: // start4
+ case 0xfd: // version1
+ goto found;
+ }
+ }
+
+ debug("Not a bootable FCode image\n");
+ retval = LOADER_NOT_SUPPORT;
+ goto out;
+
+ found:
+ size = (fcode_header[4] << 24) | (fcode_header[5] << 16) |
+ (fcode_header[6] << 8) | fcode_header[7];
+
+ start = 0x4000;
+
+ printf("Loading FCode image...\n");
+
+ file_seek(offset + sizeof(fcode_header));
+
+ if ((unsigned long)lfile_read((void *)start, size) != size) {
+ printf("Can't read file (size 0x%lx)\n", size);
+ goto out;
+ }
+
+ debug("Loaded %lu bytes\n", size);
+
+ debug("entry point is %#lx\n", start);
+ printf("Evaluating FCode...\n");
+
+ PUSH(start);
+ PUSH(1);
+ fword("byte-load");
+
+ retval = 0;
+
+out:
+ file_close();
+ return retval;
+}