mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
ppc: simplify boot by using load and go.
Signed-off-by: Laurent Vivier <Laurent@vivier.eu> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@589 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -39,81 +39,16 @@
|
|||||||
#define NEWWORLD_DPRINTF(fmt, args...) SUBSYS_DPRINTF("NEWWORLD", fmt, ##args)
|
#define NEWWORLD_DPRINTF(fmt, args...) SUBSYS_DPRINTF("NEWWORLD", fmt, ##args)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load(const char *path)
|
load(const char *path, const char *param)
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
if (param)
|
||||||
|
sprintf(buffer, "load %s %s", path, param);
|
||||||
|
else
|
||||||
sprintf(buffer, "load %s", path);
|
sprintf(buffer, "load %s", path);
|
||||||
feval(buffer);
|
feval(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
transfer_control_to_elf( ulong elf_entry )
|
|
||||||
{
|
|
||||||
ELF_DPRINTF("Starting ELF boot loader\n");
|
|
||||||
call_elf( 0, 0, elf_entry );
|
|
||||||
|
|
||||||
fatal_error("call_elf returned unexpectedly\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
load_elf_rom( ulong *elf_entry, int fd )
|
|
||||||
{
|
|
||||||
int i, lszz_offs, elf_offs;
|
|
||||||
char *addr;
|
|
||||||
Elf_ehdr ehdr;
|
|
||||||
Elf_phdr *phdr;
|
|
||||||
size_t s;
|
|
||||||
|
|
||||||
ELF_DPRINTF("Loading '%s' from '%s'\n", get_file_path(fd),
|
|
||||||
get_volume_name(fd) );
|
|
||||||
|
|
||||||
/* the ELF-image (usually) starts at offset 0x4000 */
|
|
||||||
if( (elf_offs=find_elf(fd)) < 0 ) {
|
|
||||||
ELF_DPRINTF("----> %s is not an ELF image\n", get_file_path(fd));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) {
|
|
||||||
ELF_DPRINTF("elf_readhdrs failed\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*elf_entry = ehdr.e_entry;
|
|
||||||
|
|
||||||
/* load segments. Compressed ROM-image assumed to be located immediately
|
|
||||||
* after the last segment */
|
|
||||||
lszz_offs = elf_offs;
|
|
||||||
for( i=0; i<ehdr.e_phnum; i++ ) {
|
|
||||||
/* p_memsz, p_flags */
|
|
||||||
s = MIN( phdr[i].p_filesz, phdr[i].p_memsz );
|
|
||||||
seek_io( fd, elf_offs + phdr[i].p_offset );
|
|
||||||
|
|
||||||
ELF_DPRINTF("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n",
|
|
||||||
(ulong)phdr[i].p_filesz, (ulong)phdr[i].p_memsz, (ulong)phdr[i].p_offset,
|
|
||||||
(ulong)phdr[i].p_vaddr );
|
|
||||||
|
|
||||||
if( phdr[i].p_vaddr != phdr[i].p_paddr )
|
|
||||||
ELF_DPRINTF("WARNING: ELF segment virtual addr != physical addr\n");
|
|
||||||
lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz );
|
|
||||||
if( !s )
|
|
||||||
continue;
|
|
||||||
if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 )
|
|
||||||
fatal_error("Claim failed!\n");
|
|
||||||
|
|
||||||
addr = (char*)phdr[i].p_vaddr;
|
|
||||||
if( read_io(fd, addr, s) != s ) {
|
|
||||||
ELF_DPRINTF("read failed\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_icache_range( addr, addr+s );
|
|
||||||
|
|
||||||
ELF_DPRINTF("ELF ROM-section loaded at %08lX (size %08lX)\n",
|
|
||||||
(ulong)phdr[i].p_vaddr, (ulong)phdr[i].p_memsz );
|
|
||||||
}
|
|
||||||
free( phdr );
|
|
||||||
return lszz_offs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_device( const char *path )
|
get_device( const char *path )
|
||||||
{
|
{
|
||||||
@@ -206,60 +141,21 @@ encode_bootpath( const char *spec, const char *args )
|
|||||||
/* qemu booting */
|
/* qemu booting */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
static void
|
static void
|
||||||
try_path(const char *path, const char *param)
|
try_path(const char *device, const char* filename, const char *param)
|
||||||
{
|
{
|
||||||
ulong elf_entry;
|
char path[1024];
|
||||||
int fd, ret;
|
|
||||||
|
if (filename)
|
||||||
|
snprintf(path, sizeof(path), "%s%s", device, filename);
|
||||||
|
else
|
||||||
|
snprintf(path, sizeof(path), "%s", device);
|
||||||
|
|
||||||
ELF_DPRINTF("Trying %s %s\n", path, param);
|
ELF_DPRINTF("Trying %s %s\n", path, param);
|
||||||
if ((fd = open_io(path)) == -1) {
|
|
||||||
ELF_DPRINTF("Can't open %s\n", path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ret = load_elf_rom( &elf_entry, fd );
|
|
||||||
if (ret < 0)
|
|
||||||
return;
|
|
||||||
close_io( fd );
|
|
||||||
encode_bootpath( path, param );
|
|
||||||
|
|
||||||
|
load(path, param);
|
||||||
update_nvram();
|
update_nvram();
|
||||||
ELF_DPRINTF("Transfering control to %s %s\n",
|
ELF_DPRINTF("Transfering control to %s %s\n",
|
||||||
path, param);
|
path, param);
|
||||||
transfer_control_to_elf( elf_entry );
|
|
||||||
/* won't come here */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
try_chrp_script(const char *of_path, const char *param, const char *script_path)
|
|
||||||
{
|
|
||||||
char path[1024];
|
|
||||||
char *device, *filename, *directory;
|
|
||||||
int partition;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
device = get_device(of_path);
|
|
||||||
partition = get_partition(of_path);
|
|
||||||
filename = get_filename(of_path, &directory);
|
|
||||||
|
|
||||||
CHRP_DPRINTF("device %s partition %d filename %s\n", device, partition, filename);
|
|
||||||
|
|
||||||
/* read boot script */
|
|
||||||
|
|
||||||
if (partition == -1)
|
|
||||||
snprintf(path, sizeof(path), "%s:,%s",
|
|
||||||
device, script_path);
|
|
||||||
else
|
|
||||||
snprintf(path, sizeof(path), "%s:%d,%s",
|
|
||||||
device, partition, script_path);
|
|
||||||
|
|
||||||
CHRP_DPRINTF("Trying %s\n", path);
|
|
||||||
load(path);
|
|
||||||
feval("load-size");
|
|
||||||
size = POP();
|
|
||||||
if (size == 0) {
|
|
||||||
ELF_DPRINTF("Can't open %s\n", of_path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
feval("go");
|
feval("go");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,8 +236,8 @@ newworld_boot( void )
|
|||||||
POP();
|
POP();
|
||||||
param = pop_fstr_copy();
|
param = pop_fstr_copy();
|
||||||
}
|
}
|
||||||
try_path(path, param);
|
try_path(path, NULL, param);
|
||||||
try_chrp_script(path, param, chrp_path);
|
try_path(path, chrp_path, param);
|
||||||
} else {
|
} else {
|
||||||
uint16_t boot_device = fw_cfg_read_i16(FW_CFG_BOOT_DEVICE);
|
uint16_t boot_device = fw_cfg_read_i16(FW_CFG_BOOT_DEVICE);
|
||||||
switch (boot_device) {
|
switch (boot_device) {
|
||||||
@@ -353,12 +249,12 @@ newworld_boot( void )
|
|||||||
path = strdup("cd:");
|
path = strdup("cd:");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try_chrp_script(path, param, chrp_path);
|
try_path(path, chrp_path, param);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NEWWORLD_DPRINTF("Entering boot, path %s\n", path);
|
NEWWORLD_DPRINTF("Entering boot, path %s\n", path);
|
||||||
try_path(path, param);
|
try_path(path, NULL, param);
|
||||||
try_chrp_script(path, param, chrp_path);
|
try_path(path, chrp_path, param);
|
||||||
}
|
}
|
||||||
printk("*** Boot failure! No secondary bootloader specified ***\n");
|
printk("*** Boot failure! No secondary bootloader specified ***\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user