Author: mcayland Date: Mon Mar 29 01:47:36 2010 New Revision: 720 URL: http://tracker.coreboot.org/trac/openbios/changeset/720
Log: Move the *_init_program() functions into the main loader source files so that everything is in one place. Part of this involves taking the existing parts of the XCOFF loader and putting them into a new loader file xcoff_load.c. Also fix a dependency order change these changes introduce when building openbios-unix.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk
Added: trunk/openbios-devel/include/libopenbios/xcoff_load.h trunk/openbios-devel/libopenbios/xcoff_load.c Modified: trunk/openbios-devel/arch/unix/build.xml trunk/openbios-devel/arch/unix/unix.c trunk/openbios-devel/include/libopenbios/aout_load.h trunk/openbios-devel/include/libopenbios/elf_load.h trunk/openbios-devel/include/libopenbios/fcode_load.h trunk/openbios-devel/include/libopenbios/forth_load.h trunk/openbios-devel/libopenbios/aout_load.c trunk/openbios-devel/libopenbios/build.xml trunk/openbios-devel/libopenbios/elf_load.c trunk/openbios-devel/libopenbios/fcode_load.c trunk/openbios-devel/libopenbios/forth_load.c trunk/openbios-devel/packages/elf-loader.c trunk/openbios-devel/packages/xcoff-loader.c
Modified: trunk/openbios-devel/arch/unix/build.xml ============================================================================== --- trunk/openbios-devel/arch/unix/build.xml Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/arch/unix/build.xml Mon Mar 29 01:47:36 2010 (r720) @@ -13,8 +13,8 @@ <object source="blk.c" flags="-DBOOTSTRAP"/> <object source="plugins.c" flags="-DBOOTSTRAP" condition="PLUGINS"/> <external-object source="libbootstrap.a"/> - <external-object source="libopenbios.a"/> <external-object source="libpackages.a"/> + <external-object source="libopenbios.a"/> <external-object source="libdrivers.a"/> <external-object source="libfs.a"/> <external-object source="liblibc.a"/>
Modified: trunk/openbios-devel/arch/unix/unix.c ============================================================================== --- trunk/openbios-devel/arch/unix/unix.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/arch/unix/unix.c Mon Mar 29 01:47:36 2010 (r720) @@ -51,6 +51,8 @@ static void exit_terminal(void); void boot(void);
+unsigned long virt_offset = 0; + /* local variables */
static ucell *memory;
Modified: trunk/openbios-devel/include/libopenbios/aout_load.h ============================================================================== --- trunk/openbios-devel/include/libopenbios/aout_load.h Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/include/libopenbios/aout_load.h Mon Mar 29 01:47:36 2010 (r720) @@ -22,5 +22,6 @@
extern int is_aout(struct exec *ehdr); extern int aout_load(struct sys_info *info, const char *filename); +extern void aout_init_program(void);
#endif /* _H_AOUTLOAD */
Modified: trunk/openbios-devel/include/libopenbios/elf_load.h ============================================================================== --- trunk/openbios-devel/include/libopenbios/elf_load.h Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/include/libopenbios/elf_load.h Mon Mar 29 01:47:36 2010 (r720) @@ -22,6 +22,7 @@ #include "libopenbios/sys_info.h"
extern int elf_load(struct sys_info *info, const char *filename, const char *cmdline, void **boot_notes); +extern void elf_init_program(void); extern int is_elf(Elf_ehdr *ehdr); extern int find_elf(Elf_ehdr *ehdr);
Modified: trunk/openbios-devel/include/libopenbios/fcode_load.h ============================================================================== --- trunk/openbios-devel/include/libopenbios/fcode_load.h Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/include/libopenbios/fcode_load.h Mon Mar 29 01:47:36 2010 (r720) @@ -19,5 +19,6 @@
extern int is_fcode(unsigned char *fcode); extern int fcode_load(const char *filename); +extern void fcode_init_program(void);
#endif /* _H_FCODELOAD */
Modified: trunk/openbios-devel/include/libopenbios/forth_load.h ============================================================================== --- trunk/openbios-devel/include/libopenbios/forth_load.h Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/include/libopenbios/forth_load.h Mon Mar 29 01:47:36 2010 (r720) @@ -19,5 +19,6 @@
extern int is_forth(char *forth); extern int forth_load(const char *filename); +extern void forth_init_program(void);
#endif /* _H_FORTHLOAD */
Added: trunk/openbios-devel/include/libopenbios/xcoff_load.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/openbios-devel/include/libopenbios/xcoff_load.h Mon Mar 29 01:47:36 2010 (r720) @@ -0,0 +1,27 @@ +/* + * Creation Date: <2010/03/22 18:00:00 mcayland> + * Time-stamp: <2010/03/22 18:00:00 mcayland> + * + * <xcoff_load.h> + * + * XCOFF loader + * + * Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland@siriusit.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_XCOFFLOAD +#define _H_XCOFFLOAD + +#include "arch/common/xcoff.h" +#include "libopenbios/sys_info.h" + +extern int is_xcoff(COFF_filehdr_t *fhdr); +extern int xcoff_load(struct sys_info *info, const char *filename); +extern void xcoff_init_program(void); + +#endif /* _H_XCOFFLOAD */
Modified: trunk/openbios-devel/libopenbios/aout_load.c ============================================================================== --- trunk/openbios-devel/libopenbios/aout_load.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/libopenbios/aout_load.c Mon Mar 29 01:47:36 2010 (r720) @@ -23,7 +23,8 @@ static char *image_name, *image_version; static int fd;
-static int check_mem_ranges(struct sys_info *info, +static int +check_mem_ranges(struct sys_info *info, unsigned long start, unsigned long size) { @@ -58,16 +59,17 @@ return 0; }
-int is_aout(struct exec *ehdr) +int +is_aout(struct exec *ehdr) { return ((ehdr->a_info & 0xffff) == OMAGIC || (ehdr->a_info & 0xffff) == NMAGIC || (ehdr->a_info & 0xffff) == ZMAGIC || (ehdr->a_info & 0xffff) == QMAGIC); - }
-int aout_load(struct sys_info *info, const char *filename) +int +aout_load(struct sys_info *info, const char *filename) { int retval = -1; struct exec ehdr; @@ -154,3 +156,10 @@ close_io(fd); return retval; } + +void +aout_init_program(void) +{ + // Currently not implemented + feval("0 state-valid !"); +}
Modified: trunk/openbios-devel/libopenbios/build.xml ============================================================================== --- trunk/openbios-devel/libopenbios/build.xml Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/libopenbios/build.xml Mon Mar 29 01:47:36 2010 (r720) @@ -14,6 +14,7 @@ <object source="ipchecksum.c"/> <object source="linuxbios_info.c" condition="LINUXBIOS"/> <object source="ofmem_common.c" condition="OFMEM"/> + <object source="xcoff_load.c" condition="LOADER_XCOFF"/> </library>
<dictionary name="openbios" target="forth">
Modified: trunk/openbios-devel/libopenbios/elf_load.c ============================================================================== --- trunk/openbios-devel/libopenbios/elf_load.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/libopenbios/elf_load.c Mon Mar 29 01:47:36 2010 (r720) @@ -19,6 +19,10 @@ #define MAX_HEADERS 0x20 #define BS 0x100 /* smallest step used when looking for the ELF header */
+#ifdef CONFIG_PPC +extern void flush_icache_range( char *start, char *stop ); +#endif + /* FreeBSD and possibly others mask the high 8 bits */ #define addr_fixup(addr) ((addr) & 0x00ffffff)
@@ -362,7 +366,8 @@ return phdr; }
-int elf_load(struct sys_info *info, const char *filename, const char *cmdline, void **boot_notes) +int +elf_load(struct sys_info *info, const char *filename, const char *cmdline, void **boot_notes) { Elf_ehdr ehdr; Elf_phdr *phdr = NULL; @@ -460,3 +465,55 @@ free(image_version); return retval; } + +void +elf_init_program(void) +{ + char *base; + int i; + Elf_ehdr *ehdr; + Elf_phdr *phdr; + size_t size; + char *addr; + cell tmp; + + /* TODO: manage ELF notes section */ + feval("0 state-valid !"); + feval("load-base"); + base = (char*)POP(); + + ehdr = (Elf_ehdr *)base; + phdr = (Elf_phdr *)(base + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; i++) { + +#if DEBUG + debug("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 ); +#endif + + size = MIN(phdr[i].p_filesz, phdr[i].p_memsz); + if (!size) + continue; +#if 0 + if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) { + printk("Claim failed!\n"); + return; + } +#endif + /* Workaround for archs where sizeof(int) != pointer size */ + tmp = phdr[i].p_vaddr; + addr = (char *)tmp; + + memcpy(addr, base + phdr[i].p_offset, size); +#ifdef CONFIG_PPC + flush_icache_range( addr, addr + size ); +#endif + } + /* FIXME: should initialize saved-program-state. */ + PUSH(ehdr->e_entry); + feval("elf-entry !"); + feval("-1 state-valid !"); +}
Modified: trunk/openbios-devel/libopenbios/fcode_load.c ============================================================================== --- trunk/openbios-devel/libopenbios/fcode_load.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/libopenbios/fcode_load.c Mon Mar 29 01:47:36 2010 (r720) @@ -13,16 +13,18 @@
static int fd;
-int is_fcode(unsigned char *fcode) +int +is_fcode(unsigned char *fcode) { - return (fcode[0] == 0xf0 // start0 + return (fcode[0] == 0xf0 // start0 || fcode[0] == 0xf1 // start1 || fcode[0] == 0xf2 // start2 || fcode[0] == 0xf3 // start4 || fcode[0] == 0xfd); // version1 }
-int fcode_load(const char *filename) +int +fcode_load(const char *filename) { int retval = -1; uint8_t fcode_header[8]; @@ -84,3 +86,16 @@ close_io(fd); return retval; } + +void +fcode_init_program(void) +{ + /* If the payload is Fcode then we execute it immediately */ + ucell address; + + fword("load-base"); + address = POP(); + PUSH(address); + PUSH(1); + fword("byte-load"); +}
Modified: trunk/openbios-devel/libopenbios/forth_load.c ============================================================================== --- trunk/openbios-devel/libopenbios/forth_load.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/libopenbios/forth_load.c Mon Mar 29 01:47:36 2010 (r720) @@ -78,3 +78,10 @@ // free(forthtext); return retval; } + +void +forth_init_program(void) +{ + // Currently not implemented + feval("0 state-valid !"); +}
Added: trunk/openbios-devel/libopenbios/xcoff_load.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/openbios-devel/libopenbios/xcoff_load.c Mon Mar 29 01:47:36 2010 (r720) @@ -0,0 +1,141 @@ +/* + * + * <xcoff_load.c> + * + * XCOFF file loader + * + * Copyright (C) 2009 Laurent Vivier (Laurent@vivier.eu) + * + * from original XCOFF loader by Steven Noonan steven@uplinklabs.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 + * + */ + +#include "config.h" +#include "libopenbios/bindings.h" +#include "libopenbios/xcoff_load.h" + +#include "arch/common/xcoff.h" + +#ifdef CONFIG_PPC +extern void flush_icache_range( char *start, char *stop ); +#endif + +//#define DEBUG_XCOFF + +#ifdef DEBUG_XCOFF +#define DPRINTF(fmt, args...) \ + do { printk("%s: " fmt, __func__ , ##args); } while (0) +#else +#define DPRINTF(fmt, args...) \ + do { } while (0) +#endif + +int +is_xcoff(COFF_filehdr_t *fhdr) +{ + return (fhdr->f_magic == U802WRMAGIC + || fhdr->f_magic == U802ROMAGIC + || fhdr->f_magic == U802TOCMAGIC + || fhdr->f_magic == U802TOMAGIC); +} + +int +xcoff_load(struct sys_info *info, const char *filename) +{ + // Currently not implemented + return LOADER_NOT_SUPPORT; +} + +void +xcoff_init_program(void) +{ + char *base; + COFF_filehdr_t *fhdr; + COFF_aouthdr_t *ahdr; + COFF_scnhdr_t *shdr; + uint32_t offset; + int i; + + feval("0 state-valid !"); + + feval("load-base"); + base = (char*)POP(); + + fhdr = (COFF_filehdr_t*)base; + + /* Is it an XCOFF file ? */ + if (!is_xcoff(fhdr)) { + DPRINTF("Not a XCOFF file %02x\n", fhdr->f_magic); + return; + } + + /* Is it executable ? */ + if (fhdr->f_magic != 0x01DF && + (fhdr->f_flags & COFF_F_EXEC) == 0) { + DPRINTF("Not an executable XCOFF file %02x\n", fhdr->f_flags); + return; + } + + /* Optional header is a.out ? */ + if (fhdr->f_opthdr != sizeof(COFF_aouthdr_t)) { + DPRINTF("AOUT optional error size mismatch in XCOFF file\n"); + return; + } + + ahdr = (COFF_aouthdr_t*)(base + sizeof(COFF_filehdr_t)); + + /* check a.out magic number */ + if (ahdr->magic != AOUT_MAGIC) { + DPRINTF("Invalid AOUT optional header\n"); + return; + } + + offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t); + + DPRINTF("XCOFF file with %d sections\n", fhdr->f_nscns); + + for (i = 0; i < fhdr->f_nscns; i++) { + + DPRINTF("Read header at offset %0x\n", offset); + + shdr = (COFF_scnhdr_t*)(base + offset); + + DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n", + shdr->s_name, offset, shdr->s_scnptr, + shdr->s_vaddr, shdr->s_size); + + if (strcmp(shdr->s_name, ".text") == 0) { + + memcpy((char*)shdr->s_vaddr, base + shdr->s_scnptr, + shdr->s_size); +#ifdef CONFIG_PPC + flush_icache_range((char*)shdr->s_vaddr, + (char*)(shdr->s_vaddr + shdr->s_size)); +#endif + } else if (strcmp(shdr->s_name, ".data") == 0) { + + memcpy((char*)shdr->s_vaddr, base + shdr->s_scnptr, + shdr->s_size); + + } else if (strcmp(shdr->s_name, ".bss") == 0) { + + memset((void *)shdr->s_vaddr, 0, shdr->s_size); + + } else { + DPRINTF(" Skip '%s' section\n", shdr->s_name); + } + offset += sizeof(COFF_scnhdr_t); + } + + /* FIXME: should initialize saved-program-state. */ + + DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr->entry); + PUSH(*(uint32_t*)ahdr->entry); + feval("xcoff-entry !"); + + feval("-1 state-valid !"); +}
Modified: trunk/openbios-devel/packages/elf-loader.c ============================================================================== --- trunk/openbios-devel/packages/elf-loader.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/packages/elf-loader.c Mon Mar 29 01:47:36 2010 (r720) @@ -16,81 +16,13 @@
#include "config.h" #include "libopenbios/bindings.h" +#include "libopenbios/elf_load.h" #include "packages.h" -#include "libopenbios/ofmem.h" - -#include "arch/common/elf.h" -#include "asm/elf.h" - -/* TODO: manage ELF notes section */ - -//#define DEBUG_ELF - -#ifdef DEBUG_ELF -#define DPRINTF(fmt, args...) \ - do { printk("%s: " fmt, __func__ , ##args); } while (0) -#else -#define DPRINTF(fmt, args...) \ - do { } while (0) -#endif
DECLARE_NODE(elf_loader, INSTALL_OPEN, 0, "+/packages/elf-loader" );
-#ifdef CONFIG_PPC -extern void flush_icache_range( char *start, char *stop ); -#endif - -static void -elf_loader_init_program( void *dummy ) -{ - char *base; - int i; - Elf_ehdr *ehdr; - Elf_phdr *phdr; - size_t size; - char *addr; - cell tmp; - - feval("0 state-valid !"); - - feval("load-base"); - base = (char*)POP(); - - ehdr = (Elf_ehdr *)base; - phdr = (Elf_phdr *)(base + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; i++) { - 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 ); - - size = MIN(phdr[i].p_filesz, phdr[i].p_memsz); - if (!size) - continue; -#if 0 - if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) { - printk("Claim failed!\n"); - return; - } -#endif - /* Workaround for archs where sizeof(int) != pointer size */ - tmp = phdr[i].p_vaddr; - addr = (char *)tmp; - - memcpy(addr, base + phdr[i].p_offset, size); -#ifdef CONFIG_PPC - flush_icache_range( addr, addr + size ); -#endif - } - /* FIXME: should initialize saved-program-state. */ - PUSH(ehdr->e_entry); - feval("elf-entry !"); - feval("-1 state-valid !"); -} - NODE_METHODS( elf_loader ) = { - { "init-program", elf_loader_init_program }, + { "init-program", elf_init_program }, };
void elf_loader_init( void )
Modified: trunk/openbios-devel/packages/xcoff-loader.c ============================================================================== --- trunk/openbios-devel/packages/xcoff-loader.c Sun Mar 28 22:55:10 2010 (r719) +++ trunk/openbios-devel/packages/xcoff-loader.c Mon Mar 29 01:47:36 2010 (r720) @@ -16,126 +16,13 @@
#include "config.h" #include "libopenbios/bindings.h" +#include "libopenbios/xcoff_load.h" #include "packages.h" -#include "libopenbios/ofmem.h" - -#include "arch/common/xcoff.h" - -//#define DEBUG_XCOFF - -#ifdef DEBUG_XCOFF -#define DPRINTF(fmt, args...) \ - do { printk("%s: " fmt, __func__ , ##args); } while (0) -#else -#define DPRINTF(fmt, args...) \ - do { } while (0) -#endif
DECLARE_NODE(xcoff_loader, INSTALL_OPEN, 0, "+/packages/xcoff-loader" );
-#ifdef CONFIG_PPC -extern void flush_icache_range( char *start, char *stop ); -#endif - -static void -xcoff_loader_init_program( void *dummy ) -{ - char *base; - COFF_filehdr_t *fhdr; - COFF_aouthdr_t *ahdr; - COFF_scnhdr_t *shdr; - uint32_t offset; - int i; - - feval("0 state-valid !"); - - feval("load-base"); - base = (char*)POP(); - - fhdr = (COFF_filehdr_t*)base; - - /* Is it an XCOFF file ? */ - - if (fhdr->f_magic != U802WRMAGIC && - fhdr->f_magic != U802ROMAGIC && - fhdr->f_magic != U802TOCMAGIC && - fhdr->f_magic != U802TOMAGIC) { - DPRINTF("Not a XCOFF file %02x\n", fhdr->f_magic); - return; - } - - /* Is it executable ? */ - - if (fhdr->f_magic != 0x01DF && - (fhdr->f_flags & COFF_F_EXEC) == 0) { - DPRINTF("Not an executable XCOFF file %02x\n", fhdr->f_flags); - return; - } - - /* Optional header is a.out ? */ - - if (fhdr->f_opthdr != sizeof(COFF_aouthdr_t)) { - DPRINTF("AOUT optional error size mismatch in XCOFF file\n"); - return; - } - - ahdr = (COFF_aouthdr_t*)(base + sizeof(COFF_filehdr_t)); - - /* check a.out magic number */ - - if (ahdr->magic != AOUT_MAGIC) { - DPRINTF("Invalid AOUT optional header\n"); - return; - } - - offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t); - - DPRINTF("XCOFF file with %d sections\n", fhdr->f_nscns); - - for (i = 0; i < fhdr->f_nscns; i++) { - - DPRINTF("Read header at offset %0x\n", offset); - - shdr = (COFF_scnhdr_t*)(base + offset); - - DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n", - shdr->s_name, offset, shdr->s_scnptr, - shdr->s_vaddr, shdr->s_size); - - if (strcmp(shdr->s_name, ".text") == 0) { - - memcpy((char*)shdr->s_vaddr, base + shdr->s_scnptr, - shdr->s_size); -#ifdef CONFIG_PPC - flush_icache_range((char*)shdr->s_vaddr, - (char*)(shdr->s_vaddr + shdr->s_size)); -#endif - } else if (strcmp(shdr->s_name, ".data") == 0) { - - memcpy((char*)shdr->s_vaddr, base + shdr->s_scnptr, - shdr->s_size); - - } else if (strcmp(shdr->s_name, ".bss") == 0) { - - memset((void *)shdr->s_vaddr, 0, shdr->s_size); - - } else { - DPRINTF(" Skip '%s' section\n", shdr->s_name); - } - offset += sizeof(COFF_scnhdr_t); - } - - /* FIXME: should initialize saved-program-state. */ - - DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr->entry); - PUSH(*(uint32_t*)ahdr->entry); - feval("xcoff-entry !"); - - feval("-1 state-valid !"); -} - NODE_METHODS( xcoff_loader ) = { - { "init-program", xcoff_loader_init_program }, + { "init-program", xcoff_init_program }, };
void xcoff_loader_init( void )