Files
openbios/arch/sparc64/boot.c
Mark Cave-Ayland 6dd0574272 Switch the loaders for x86, sparc64 and sparc32 over to use the new saved-program-state in boot() rather than try to execute the
device payload directly. This is the first stage in isolating the OF "load" and "go" words, and in preparation for moving the 
majority of the loaders into libopenbios.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@709 f158a5a8-5612-0410-a976-696ce0be7e32
2010-03-26 22:33:50 +00:00

166 lines
3.7 KiB
C

/*
*
*/
#undef BOOTSTRAP
#include "config.h"
#include "libopenbios/bindings.h"
#include "arch/common/nvram.h"
#include "libc/diskio.h"
#include "libc/vsprintf.h"
#include "libopenbios/sys_info.h"
#include "boot.h"
struct sys_info sys_info;
uint64_t kernel_image;
uint64_t kernel_size;
uint64_t qemu_cmdline;
uint64_t cmdline_size;
char boot_device;
extern int sparc64_of_client_interface( int *params );
static int try_path(const char *path, char *param)
{
void *boot_notes = NULL;
ucell valid, address, type, size;
int image_retval = 0;
/* ELF Boot loader */
elf_load(&sys_info, path, param);
feval("state-valid @");
valid = POP();
if (valid)
goto start_image;
/* Linux loader (not using Forth) */
linux_load(&sys_info, path, param);
/* a.out loader */
aout_load(&sys_info, path);
feval("state-valid @");
valid = POP();
if (valid)
goto start_image;
/* Fcode loader */
fcode_load(path);
feval("state-valid @");
valid = POP();
if (valid)
goto start_image;
return 0;
start_image:
/* Get the entry point and the type (see forth/debugging/client.fs) */
feval("saved-program-state >sps.entry @");
address = POP();
feval("saved-program-state >sps.file-type @");
type = POP();
feval("saved-program-state >sps.file-size @");
size = POP();
printk("Jumping to entry point " FMT_ucellx " for type " FMT_ucellx "...\n", address, type);
switch (type) {
case 0x0:
/* Start ELF boot image */
image_retval = start_elf(address, (uint64_t)boot_notes);
break;
case 0x5:
/* Start a.out image */
image_retval = start_client_image(address, (uint64_t)&sparc64_of_client_interface);
break;
case 0x10:
/* Start Fcode image */
printk("Evaluating FCode...\n");
PUSH(address);
PUSH(1);
fword("byte-load");
image_retval = 0;
break;
}
printk("Image returned with return value %#x\n", image_retval);
return -1;
}
void boot(void)
{
char *path=pop_fstr_copy(), *param;
char altpath[256];
int result;
if (kernel_size) {
void (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5);;
printk("[sparc64] Kernel already loaded\n");
entry = (void *) (unsigned long)kernel_image;
entry(0, 0, 0, 0, (unsigned long)&sparc64_of_client_interface);
}
if(!path) {
push_str("boot-device");
push_str("/options");
fword("(find-dev)");
POP();
fword("get-package-property");
if (!POP()) {
path = pop_fstr_copy();
} else {
switch (boot_device) {
case 'a':
path = strdup("/obio/SUNW,fdtwo");
break;
case 'c':
path = strdup("disk");
break;
default:
case 'd':
path = strdup("cdrom");
break;
case 'n':
path = strdup("net");
break;
}
}
}
param = strchr(path, ' ');
if(param) {
*param = '\0';
param++;
} else if (cmdline_size) {
param = (char *)qemu_cmdline;
} else {
push_str("boot-args");
push_str("/options");
fword("(find-dev)");
POP();
fword("get-package-property");
POP();
param = pop_fstr_copy();
}
printk("[sparc64] Booting file '%s' ", path);
if (param)
printk("with parameters '%s'\n", param);
else
printk("without parameters.\n");
result = try_path(path, param);
if (!result) {
snprintf(altpath, sizeof(altpath), "%s:f", path);
try_path(altpath, param);
}
printk("Unsupported image format\n");
free(path);
}