mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
hierarchy is correct, we can simply pass an ihandle into the loader and it will work correctly regardless of whether it is being invoked on an entire disk, partition or individual file. In order to test the new code, start by switching the Fcode loader over to the new infrastructure for testing on SPARC64. Note this patch also contains a correction to load-base on SPARC which was being set to a value other than 0x4000 which is the documented default. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@798 f158a5a8-5612-0410-a976-696ce0be7e32
110 lines
2.3 KiB
C
110 lines
2.3 KiB
C
/*
|
|
* FCode boot loader
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "kernel/kernel.h"
|
|
#include "libopenbios/bindings.h"
|
|
#include "libopenbios/fcode_load.h"
|
|
#include "libopenbios/sys_info.h"
|
|
#include "libc/diskio.h"
|
|
#define printf printk
|
|
#define debug printk
|
|
|
|
static int fd;
|
|
|
|
int
|
|
is_fcode(unsigned char *fcode)
|
|
{
|
|
return (fcode[0] == 0xf0 // start0
|
|
|| fcode[0] == 0xf1 // start1
|
|
|| fcode[0] == 0xf2 // start2
|
|
|| fcode[0] == 0xf3 // start4
|
|
|| fcode[0] == 0xfd); // version1
|
|
}
|
|
|
|
int
|
|
fcode_load(ihandle_t dev)
|
|
{
|
|
int retval = -1;
|
|
uint8_t fcode_header[8];
|
|
unsigned long start, size;
|
|
unsigned int offset;
|
|
|
|
/* Mark the saved-program-state as invalid */
|
|
feval("0 state-valid !");
|
|
|
|
fd = open_ih(dev);
|
|
if (!fd)
|
|
goto out;
|
|
|
|
for (offset = 0; offset < 16 * 512; offset += 512) {
|
|
seek_io(fd, offset);
|
|
if (read_io(fd, &fcode_header, sizeof(fcode_header))
|
|
!= sizeof(fcode_header)) {
|
|
debug("Can't read FCode header from ihandle " FMT_ucellx "\n", dev);
|
|
retval = LOADER_NOT_SUPPORT;
|
|
goto out;
|
|
}
|
|
|
|
if (is_fcode(fcode_header))
|
|
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];
|
|
|
|
fword("load-base");
|
|
start = POP();
|
|
|
|
printf("\nLoading FCode image...\n");
|
|
|
|
seek_io(fd, offset);
|
|
|
|
if ((size_t)read_io(fd, (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);
|
|
|
|
// Initialise saved-program-state
|
|
PUSH(start);
|
|
feval("saved-program-state >sps.entry !");
|
|
PUSH(size);
|
|
feval("saved-program-state >sps.file-size !");
|
|
feval("fcode saved-program-state >sps.file-type !");
|
|
|
|
feval("-1 state-valid !");
|
|
|
|
out:
|
|
close_io(fd);
|
|
return retval;
|
|
}
|
|
|
|
void
|
|
fcode_init_program(void)
|
|
{
|
|
/* If the payload is Fcode then we execute it immediately */
|
|
ucell address;
|
|
uint8_t fcode_header[8];
|
|
|
|
fword("load-base");
|
|
address = POP();
|
|
|
|
if (!is_fcode((unsigned char *)address)) {
|
|
debug("Not a valid Fcode memory image\n");
|
|
return;
|
|
}
|
|
|
|
PUSH(address + sizeof(fcode_header));
|
|
PUSH(1);
|
|
fword("byte-load");
|
|
}
|