[OpenBIOS] [PATCH 10/11] libopenbios: add PReP boot partition loader for PPC

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Sat May 26 21:29:55 CEST 2018


Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 config/examples/ppc_config.xml  |   1 +
 forth/debugging/client.fs       |   1 +
 include/libopenbios/prep_load.h |  24 +++++++++
 libopenbios/build.xml           |   1 +
 libopenbios/initprogram.c       |   8 +++
 libopenbios/load.c              |  11 +++++
 libopenbios/prep_load.c         | 106 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 152 insertions(+)
 create mode 100644 include/libopenbios/prep_load.h
 create mode 100644 libopenbios/prep_load.c

diff --git a/config/examples/ppc_config.xml b/config/examples/ppc_config.xml
index 0ac3817..3112ea5 100644
--- a/config/examples/ppc_config.xml
+++ b/config/examples/ppc_config.xml
@@ -32,6 +32,7 @@
   <option name="CONFIG_LOADER_ELF" type="boolean" value="true"/>
   <option name="CONFIG_LOADER_FCODE" type="boolean" value="false"/>
   <option name="CONFIG_LOADER_FORTH" type="boolean" value="false"/>
+  <option name="CONFIG_LOADER_PREP" type="boolean" value="true"/>
   <option name="CONFIG_LOADER_XCOFF" type="boolean" value="true"/>
 
   <!-- Filesystem Configuration -->
diff --git a/forth/debugging/client.fs b/forth/debugging/client.fs
index c8cd5b6..5ee6003 100644
--- a/forth/debugging/client.fs
+++ b/forth/debugging/client.fs
@@ -51,6 +51,7 @@ variable file-size
 10 constant fcode
 11 constant forth
 12 constant bootcode
+13 constant prep
 
 
 : init-program    ( -- )
diff --git a/include/libopenbios/prep_load.h b/include/libopenbios/prep_load.h
new file mode 100644
index 0000000..ed1882e
--- /dev/null
+++ b/include/libopenbios/prep_load.h
@@ -0,0 +1,24 @@
+/*
+ *   Creation Date: <2010/03/22 18:00:00 mcayland>
+ *   Time-stamp: <2010/03/22 18:00:00 mcayland>
+ *
+ *   <prep_load.h>
+ *
+ *   PReP boot partition loader
+ *
+ *   Copyright (C) 2018 Mark Cave-Ayland (mark.cave-ayland at 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_PREPLOAD
+#define _H_PREPLOAD
+
+extern int prep_load(ihandle_t dev);
+int is_prep(char *addr);
+void prep_init_program(void);
+
+#endif   /* _H_PREPLOAD */
diff --git a/libopenbios/build.xml b/libopenbios/build.xml
index feb8f6c..0c89110 100644
--- a/libopenbios/build.xml
+++ b/libopenbios/build.xml
@@ -19,6 +19,7 @@
   <object source="load.c"/>
   <object source="linuxbios_info.c" condition="LINUXBIOS"/>
   <object source="ofmem_common.c" condition="OFMEM"/>
+  <object source="prep_load.c" condition="LOADER_PREP"/>
   <object source="xcoff_load.c" condition="LOADER_XCOFF"/>
   <object source="video_common.c"/>
  </library>
diff --git a/libopenbios/initprogram.c b/libopenbios/initprogram.c
index ffd3254..3213378 100644
--- a/libopenbios/initprogram.c
+++ b/libopenbios/initprogram.c
@@ -29,6 +29,7 @@
 #include "libopenbios/elf_load.h"
 #include "libopenbios/fcode_load.h"
 #include "libopenbios/forth_load.h"
+#include "libopenbios/prep_load.h"
 #include "libopenbios/xcoff_load.h"
 
 
@@ -90,6 +91,13 @@ void init_program(void)
 	}
 #endif
 
+#ifdef CONFIG_LOADER_PREP
+	if (is_prep((char *)cell2pointer(addr))) {
+		prep_init_program();
+		return;
+	}
+#endif
+
 }
 
 void init_fcode_context(void)
diff --git a/libopenbios/load.c b/libopenbios/load.c
index 174d221..16dc74a 100644
--- a/libopenbios/load.c
+++ b/libopenbios/load.c
@@ -45,6 +45,10 @@
 #include "libopenbios/bootcode_load.h"
 #endif
 
+#ifdef CONFIG_LOADER_PREP
+#include "libopenbios/prep_load.h"
+#endif
+
 
 struct sys_info sys_info;
 void *elf_boot_notes = NULL;
@@ -113,6 +117,13 @@ void load(ihandle_t dev)
         }
 #endif
 
+#ifdef CONFIG_LOADER_PREP
+	if (prep_load(dev) != LOADER_NOT_SUPPORT) {
+            feval("load-state >ls.file-size @");
+            return;
+        }
+#endif
+
         /* Didn't load anything, so return zero size */
         PUSH(0);
 }
diff --git a/libopenbios/prep_load.c b/libopenbios/prep_load.c
new file mode 100644
index 0000000..7942804
--- /dev/null
+++ b/libopenbios/prep_load.c
@@ -0,0 +1,106 @@
+/*
+ * PReP boot partition loader
+ * Written by Mark Cave-Ayland 2018
+ */
+
+#include "config.h"
+#include "kernel/kernel.h"
+#include "libopenbios/bindings.h"
+#include "libopenbios/prep_load.h"
+#include "libopenbios/initprogram.h"
+#include "libopenbios/sys_info.h"
+#include "libc/byteorder.h"
+#include "libc/diskio.h"
+#include "drivers/drivers.h"
+#define printf printk
+#define debug printk
+
+
+int
+prep_load(ihandle_t dev)
+{
+    int retval = LOADER_NOT_SUPPORT, fd, count, size;
+    ucell *loadbase;
+    unsigned char *image;
+    uint32_t entry_point_offset, load_image_length;
+    unsigned long entry;
+
+    /* 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 = cell2pointer(POP());
+
+    /* Read block 2 containing the boot info */
+    seek_io(fd, 512);
+    count = read_io(fd, (void *)loadbase, 512);
+    if (count != 512) {
+        goto out;
+    }
+
+    entry_point_offset = __le32_to_cpu(loadbase[0]);
+    load_image_length = __le32_to_cpu(loadbase[1]);
+
+    /* Load the entire image */
+    size = 0;
+    image = (unsigned char *)loadbase;
+    entry = (uintptr_t)loadbase + entry_point_offset;
+
+    seek_io(fd, 0);
+    while (size < load_image_length) {
+        count = read_io(fd, (void *)image, 512);
+        if (count == -1) {
+            break;
+        }
+
+        size += count;
+        image += count;
+    }
+
+    /* If we didn't read anything, something went wrong */
+    if (!size) {
+        goto out;
+    }
+
+    /* Set correct size */
+    size = load_image_length;
+
+    /* Initialise load-state */
+    PUSH(entry);
+    feval("load-state >ls.entry !");
+    PUSH(size);
+    feval("load-state >ls.file-size !");
+    feval("prep load-state >ls.file-type !");
+
+out:
+    close_io(fd);
+    return retval;
+}
+
+int
+is_prep(char *addr)
+{
+    /* PReP bootloaders are executed directly. So we'll say that something is
+     * PReP if the loader detected the PReP type sucessfully */
+    ucell filetype;
+
+    feval("load-state >ls.file-type @");
+    filetype = POP();
+
+    return (filetype == 0x13);
+}
+
+void
+prep_init_program(void)
+{
+    /* Entry point is already set, just need to setup the context */
+    arch_init_program();
+
+    feval("-1 state-valid !");
+}
-- 
2.11.0




More information about the OpenBIOS mailing list