From 1d33aa0ec0766f38359fe43a93e44de34c72e417 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Mon, 15 May 2006 08:17:51 +0000 Subject: [PATCH] sparc32 merge git-svn-id: svn://coreboot.org/openbios/openbios-devel@18 f158a5a8-5612-0410-a976-696ce0be7e32 --- arch/sparc32/aoutload.c | 133 +++++++++++ arch/sparc32/boot.c | 6 +- arch/sparc32/build.xml | 1 + arch/sparc32/elfload.c | 2 +- arch/sparc32/romvec.c | 28 ++- arch/sparc32/tree.fs | 4 + config/examples/cross-sparc32_config.xml | 1 + config/examples/sparc32_config.xml | 1 + include/a.out.h | 268 +++++++++++++++++++++++ include/sparc32/a.out.h | 98 +++++++++ 10 files changed, 532 insertions(+), 10 deletions(-) create mode 100644 arch/sparc32/aoutload.c create mode 100644 include/a.out.h create mode 100644 include/sparc32/a.out.h diff --git a/arch/sparc32/aoutload.c b/arch/sparc32/aoutload.c new file mode 100644 index 0000000..e4d931a --- /dev/null +++ b/arch/sparc32/aoutload.c @@ -0,0 +1,133 @@ +/* a.out boot loader + * As we have seek, this implementation can be straightforward. + * 2003-07 by SONE Takeshi + */ + +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "a.out.h" +#include "sys_info.h" +#include "loadfs.h" +#define printf printk +#define debug printk + +#define addr_fixup(addr) ((addr) & 0x00ffffff) + +static char *image_name, *image_version; +const char *program_name, *program_version; + +static int check_mem_ranges(struct sys_info *info, + unsigned long start, + unsigned long size) +{ + int j; + unsigned long end; + unsigned long prog_start, prog_end; + struct memrange *mem; + + prog_start = virt_to_phys(&_start); + prog_end = virt_to_phys(&_end); + + end = start + size; + + if (start < prog_start && end > prog_start) + goto conflict; + if (start < prog_end && end > prog_end) + goto conflict; + mem = info->memrange; + for (j = 0; j < info->n_memranges; j++) { + if (mem[j].base <= start && mem[j].base + mem[j].size >= end) + break; + } + if (j >= info->n_memranges) + goto badseg; + return 1; + + conflict: + printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end); + + badseg: + printf("A.out file [%#lx-%#lx] doesn't fit into memory\n", start, end - 1); + return 0; +} + +int aout_load(struct sys_info *info, const char *filename, const char *cmdline) +{ + int retval = -1; + int image_retval; + struct exec ehdr; + unsigned long start, size; + + image_name = image_version = 0; + + if (!file_open(filename)) + goto out; + + if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) { + debug("Can't read a.out header\n"); + retval = LOADER_NOT_SUPPORT; + goto out; + } + + if (N_BADMAG(ehdr)) { + debug("Not a bootable a.out image\n"); + retval = LOADER_NOT_SUPPORT; + goto out; + } + + if (N_MAGIC(ehdr) == NMAGIC) { + size = N_DATADDR(ehdr) + ehdr.a_data; + } else { + size = ehdr.a_text + ehdr.a_data; + } + + start = 0x4000; // N_TXTADDR(ehdr); + + if (!check_mem_ranges(info, start, size)) + goto out; + + printf("Loading a.out %s...\n", image_name ? image_name : "image"); + + file_seek(N_TXTOFF(ehdr)); + + if (N_MAGIC(ehdr) == NMAGIC) { + if (lfile_read(start, ehdr.a_text) != ehdr.a_text) { + printf("Can't read program text segment (size 0x%x)\n", ehdr.a_text); + goto out; + } + if (lfile_read(start + N_DATADDR(ehdr), ehdr.a_data) != ehdr.a_data) { + printf("Can't read program data segment (size 0x%x)\n", ehdr.a_data); + goto out; + } + } else { + if (lfile_read(start, size) != size) { + printf("Can't read program (size 0x%x)\n", size); + goto out; + } + } + + debug("Loaded %lu bytes\n", size); + + debug("entry point is %#x\n", start); + printf("Jumping to entry point...\n"); + +#if 1 + { + extern unsigned int qemu_mem_size; + void *init_openprom(unsigned long memsize, const char *cmdline, char boot_device); + + int (*entry)(const void *romvec, int p2, int p3, int p4, int p5); + const void *romvec; + + romvec = init_openprom(qemu_mem_size, cmdline, 'c'); + entry = (void *) addr_fixup(start); + image_retval = entry(romvec, 0, 0, 0, 0); + } +#endif + + printf("Image returned with return value %#x\n", image_retval); + retval = 0; + +out: + return retval; +} diff --git a/arch/sparc32/boot.c b/arch/sparc32/boot.c index 79578c7..8c27199 100644 --- a/arch/sparc32/boot.c +++ b/arch/sparc32/boot.c @@ -10,6 +10,7 @@ #include "sys_info.h" int elf_load(struct sys_info *, const char *filename, const char *cmdline); +int aout_load(struct sys_info *, const char *filename, const char *cmdline); int linux_load(struct sys_info *, const char *filename, const char *cmdline); void boot(void); @@ -37,8 +38,9 @@ void boot(void) printk("[sparc] Booting file '%s' with parameters '%s'\n",path, param); if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) - if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) - printk("Unsupported image format\n"); + if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) + if (aout_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) + printk("Unsupported image format\n"); free(path); } diff --git a/arch/sparc32/build.xml b/arch/sparc32/build.xml index 74820ff..82855a3 100644 --- a/arch/sparc32/build.xml +++ b/arch/sparc32/build.xml @@ -18,6 +18,7 @@ + diff --git a/arch/sparc32/elfload.c b/arch/sparc32/elfload.c index ca6bce5..1b0ab77 100644 --- a/arch/sparc32/elfload.c +++ b/arch/sparc32/elfload.c @@ -378,7 +378,7 @@ int elf_load(struct sys_info *info, const char *filename, const char *cmdline) int (*entry)(const void *romvec, int p2, int p3, int p4, int p5); const void *romvec; - romvec = init_openprom(qemu_mem_size, NULL, 'c'); + romvec = init_openprom(qemu_mem_size, cmdline, 'c'); entry = (void *) addr_fixup(ehdr.e_entry); image_retval = entry(romvec, 0, 0, 0, 0); } diff --git a/arch/sparc32/romvec.c b/arch/sparc32/romvec.c index ef6ba17..6958618 100644 --- a/arch/sparc32/romvec.c +++ b/arch/sparc32/romvec.c @@ -17,9 +17,7 @@ #include "openbios/kernel.h" #include "openbios/sysinclude.h" -//#define DEBUG_OBP - -#ifdef DEBUG_OBP +#ifdef CONFIG_DEBUG_OBP #define DPRINTF(fmt, args...) \ do { printk(fmt , ##args); } while (0) #else @@ -181,7 +179,7 @@ static const char *obp_nextprop(int node, char *name) static int obp_nbgetchar(void) { - return 0; + return getchar(); } static int obp_nbputchar(int ch) @@ -214,9 +212,15 @@ static void obp_halt() static int obp_devopen(char *str) { + int ret; + DPRINTF("obp_devopen(%s)\n", str); - return 0; + push_str(str); + fword("open-dev"); + ret = POP(); + + return ret; } static int obp_devclose(__attribute__((unused)) int dev_desc) @@ -228,9 +232,19 @@ static int obp_devclose(__attribute__((unused)) int dev_desc) static int obp_rdblkdev(int dev_desc, int num_blks, int offset, char *buf) { - DPRINTF("obp_rdblkdev: fd %x, num_blks %d, offset %d, buf 0x%x\n", dev_desc, num_blks, offset, buf); + int ret; - return 0; + DPRINTF("obp_rdblkdev: fd %x, num_blks %d, offset %d, buf 0x%x\n", dev_desc, num_blks, offset, (int)buf); + + PUSH((int)buf); + PUSH(offset); + PUSH(num_blks); + push_str("read-blocks"); + PUSH(dev_desc); + fword("$call-method"); + ret = POP(); + + return ret; } static char *obp_dumb_mmap(char *va, __attribute__((unused)) int which_io, diff --git a/arch/sparc32/tree.fs b/arch/sparc32/tree.fs index 79c587c..252e7b4 100644 --- a/arch/sparc32/tree.fs +++ b/arch/sparc32/tree.fs @@ -247,3 +247,7 @@ new-device 0 encode-int " slave" property h# 2c encode-int 0 encode-int encode+ " intr" property finish-device + +" /options" find-device + " disk" encode-string " boot-from" property + diff --git a/config/examples/cross-sparc32_config.xml b/config/examples/cross-sparc32_config.xml index 657ffd5..946c031 100644 --- a/config/examples/cross-sparc32_config.xml +++ b/config/examples/cross-sparc32_config.xml @@ -28,6 +28,7 @@