libopenbios: add PReP boot partition loader for PPC
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
parent
853b59f901
commit
ce43b60d61
|
@ -32,6 +32,7 @@
|
||||||
<option name="CONFIG_LOADER_ELF" type="boolean" value="true"/>
|
<option name="CONFIG_LOADER_ELF" type="boolean" value="true"/>
|
||||||
<option name="CONFIG_LOADER_FCODE" type="boolean" value="false"/>
|
<option name="CONFIG_LOADER_FCODE" type="boolean" value="false"/>
|
||||||
<option name="CONFIG_LOADER_FORTH" 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"/>
|
<option name="CONFIG_LOADER_XCOFF" type="boolean" value="true"/>
|
||||||
|
|
||||||
<!-- Filesystem Configuration -->
|
<!-- Filesystem Configuration -->
|
||||||
|
|
|
@ -51,6 +51,7 @@ variable file-size
|
||||||
10 constant fcode
|
10 constant fcode
|
||||||
11 constant forth
|
11 constant forth
|
||||||
12 constant bootcode
|
12 constant bootcode
|
||||||
|
13 constant prep
|
||||||
|
|
||||||
|
|
||||||
: init-program ( -- )
|
: init-program ( -- )
|
||||||
|
|
|
@ -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@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 */
|
|
@ -19,6 +19,7 @@
|
||||||
<object source="load.c"/>
|
<object source="load.c"/>
|
||||||
<object source="linuxbios_info.c" condition="LINUXBIOS"/>
|
<object source="linuxbios_info.c" condition="LINUXBIOS"/>
|
||||||
<object source="ofmem_common.c" condition="OFMEM"/>
|
<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="xcoff_load.c" condition="LOADER_XCOFF"/>
|
||||||
<object source="video_common.c"/>
|
<object source="video_common.c"/>
|
||||||
</library>
|
</library>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "libopenbios/elf_load.h"
|
#include "libopenbios/elf_load.h"
|
||||||
#include "libopenbios/fcode_load.h"
|
#include "libopenbios/fcode_load.h"
|
||||||
#include "libopenbios/forth_load.h"
|
#include "libopenbios/forth_load.h"
|
||||||
|
#include "libopenbios/prep_load.h"
|
||||||
#include "libopenbios/xcoff_load.h"
|
#include "libopenbios/xcoff_load.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,6 +91,13 @@ void init_program(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOADER_PREP
|
||||||
|
if (is_prep((char *)cell2pointer(addr))) {
|
||||||
|
prep_init_program();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_fcode_context(void)
|
void init_fcode_context(void)
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
#include "libopenbios/bootcode_load.h"
|
#include "libopenbios/bootcode_load.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOADER_PREP
|
||||||
|
#include "libopenbios/prep_load.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct sys_info sys_info;
|
struct sys_info sys_info;
|
||||||
void *elf_boot_notes = NULL;
|
void *elf_boot_notes = NULL;
|
||||||
|
@ -113,6 +117,13 @@ void load(ihandle_t dev)
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
/* Didn't load anything, so return zero size */
|
||||||
PUSH(0);
|
PUSH(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 !");
|
||||||
|
}
|
Loading…
Reference in New Issue