X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fopenbios%2Farch%2Fppc%2Fpearpc%2Fmain.c;fp=qemu%2Froms%2Fopenbios%2Farch%2Fppc%2Fpearpc%2Fmain.c;h=085494e564c071e049908234588d8ef11d36c14a;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/openbios/arch/ppc/pearpc/main.c b/qemu/roms/openbios/arch/ppc/pearpc/main.c new file mode 100644 index 000000000..085494e56 --- /dev/null +++ b/qemu/roms/openbios/arch/ppc/pearpc/main.c @@ -0,0 +1,145 @@ +/* + * Creation Date: <2004/08/28 18:38:22 greg> + * Time-stamp: <2004/08/28 18:38:22 greg> + * + * + * + * Copyright (C) 2004 Greg Watson + * + * Based on MOL specific code which is + * Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) + * + * 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 + * + */ + + +#include "config.h" +#include "libopenbios/bindings.h" +#include "libopenbios/elfload.h" +#include "arch/common/nvram.h" +#include "libc/diskio.h" +#include "libc/vsprintf.h" +#include "pearpc/pearpc.h" +#include "libopenbios/ofmem.h" + +static void +transfer_control_to_elf( unsigned long entry ) +{ + extern void call_elf( unsigned long entry ); + printk("Starting ELF image at 0x%08lX\n", entry); + call_elf( 0x400000 ); + //call_elf( entry ); + + fatal_error("call_elf returned unexpectedly\n"); +} + +static int +load_elf_rom( unsigned long *entry, int fd ) +{ + int i, lszz_offs, elf_offs; + char buf[128], *addr; + Elf_ehdr ehdr; + Elf_phdr *phdr; + size_t s; + + printk("Loading '%s'\n", get_file_path(fd)); + + /* the ELF-image (usually) starts at offset 0x4000 */ + if( (elf_offs=find_elf(fd)) < 0 ) { + printk("----> %s is not an ELF image\n", buf ); + exit(1); + } + if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) + fatal_error("elf_readhdrs failed\n"); + + *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= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { + patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); + newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); + } +#endif + flush_icache_range( addr, addr+s ); + + /*printk("ELF ROM-section loaded at %08lX (size %08lX)\n", + (unsigned long)phdr[i].p_vaddr, (unsigned long)phdr[i].p_memsz );*/ + } + free( phdr ); + return lszz_offs; +} + + +static void +encode_bootpath( const char *spec, const char *args ) +{ + phandle_t chosen_ph = find_dev("/chosen"); + set_property( chosen_ph, "bootpath", spec, strlen(spec)+1 ); + set_property( chosen_ph, "bootargs", args, strlen(args)+1 ); +} + +/************************************************************************/ +/* pearpc booting */ +/************************************************************************/ + +static void +pearpc_startup( void ) +{ + const char *paths[] = { "hd:0,\\zImage.chrp", NULL }; + const char *args[] = { "root=/dev/hda2 console=ttyS0,115200", NULL }; + unsigned long entry; + int i, fd; + + for( i=0; paths[i]; i++ ) { + if( (fd=open_io(paths[i])) == -1 ) + continue; + (void) load_elf_rom( &entry, fd ); + close_io( fd ); + encode_bootpath( paths[i], args[i] ); + + update_nvram(); + transfer_control_to_elf( entry ); + /* won't come here */ + } + printk("*** Boot failure! No secondary bootloader specified ***\n"); +} + + +/************************************************************************/ +/* entry */ +/************************************************************************/ + +void +boot( void ) +{ + fword("update-chosen"); + pearpc_startup(); +}