aboutsummaryrefslogtreecommitdiffstats
path: root/roms/openbios/libopenbios/prep_load.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/openbios/libopenbios/prep_load.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/openbios/libopenbios/prep_load.c')
-rw-r--r--roms/openbios/libopenbios/prep_load.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/roms/openbios/libopenbios/prep_load.c b/roms/openbios/libopenbios/prep_load.c
new file mode 100644
index 000000000..7942804bf
--- /dev/null
+++ b/roms/openbios/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 !");
+}