Signed-off-by: <[email protected]>
Index: coreboot-v3/include/romfs.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ coreboot-v3/include/romfs.h 2008-12-19 15:09:23.000000000 -0700 @@ -0,0 +1,173 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Jordan Crouse <[email protected]> + * + * This file is dual-licensed. You can choose between: + * - The GNU GPL, version 2, as published by the Free Software Foundation + * - The revised BSD license (without advertising clause) + * + * --------------------------------------------------------------------------- + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + * --------------------------------------------------------------------------- + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * --------------------------------------------------------------------------- + */ + +#ifndef _ROMFS_H_ +#define _ROMFS_H_ + +/** These are standard values for the known compression + alogrithms that coreboot knows about for stages and + payloads. Of course, other LAR users can use whatever + values they want, as long as they understand them. */ + +#define ROMFS_COMPRESS_NONE 0 +#define ROMFS_COMPRESS_LZMA 1 +#define ROMFS_COMPRESS_NRV2B 2 + +/** These are standard component types for well known + components (i.e - those that coreboot needs to consume. + Users are welcome to use any other value for their + components */ + +#define ROMFS_TYPE_STAGE 0x10 +#define ROMFS_TYPE_PAYLOAD 0x20 +#define ROMFS_TYPE_OPTIONROM 0x30 + +/** this is the master romfs header - it need to be + located somewhere in the bootblock. Where it + actually lives is up to coreboot. A pointer to + this header will live at 0xFFFFFFF4, so we can + easily find it. */ + +#define ROMFS_HEADER_MAGIC 0x4F524243 +#define ROMFS_HEADPTR_ADDR 0xFFFFFFF4 + +struct romfs_header { + u32 magic; + u32 size; + u32 align; + u32 offset; +} __attribute__((packed)); + +/** This is a component header - every entry in the ROMFS + will have this header. + + This is how the component is arranged in the ROM: + + -------------- <- 0 + component header + -------------- <- sizeof(struct component) + component name + -------------- <- offset + data + ... + -------------- <- offset + len +*/ + +#define ROMFS_FILE_MAGIC "LARCHIVE" + +struct romfs_file { + char magic[8]; + u32 len; + u32 type; + u32 checksum; + u32 offset; +} __attribute__((packed)); + +/*** Component sub-headers ***/ + +/* Following are component sub-headers for the "standard" + component types */ + +/** This is the sub-header for stage components. Stages are + loaded by coreboot during the normal boot process */ + +struct romfs_stage { + u32 compression; /** Compression type */ + u64 entry; /** entry point */ + u64 load; /** Where to load in memory */ + u32 len; /** length of data to load */ + u32 memlen; /** total length of object in memory */ +} __attribute__((packed)); + +/** this is the sub-header for payload components. Payloads + are loaded by coreboot at the end of the boot process */ + +struct romfs_payload_segment { + u32 type; + u32 compression; + u32 offset; + u64 load_addr; + u32 len; + u32 mem_len; +} __attribute__((packed)); + +struct romfs_payload { + struct romfs_payload_segment segments; +}; + +#define PAYLOAD_SEGMENT_CODE 0x45444F43 +#define PAYLOAD_SEGMENT_DATA 0x41544144 +#define PAYLOAD_SEGMENT_BSS 0x20535342 +#define PAYLOAD_SEGMENT_PARAMS 0x41524150 +#define PAYLOAD_SEGMENT_ENTRY 0x52544E45 + +struct romfs_optionrom { + u32 compression; + u32 len; +} __attribute__((packed)); + +#define ROMFS_NAME(_c) (((char *) (_c)) + sizeof(struct romfs_file)) +#define ROMFS_SUBHEADER(_p) ( (void *) ((((u8 *) (_p)) + (_p)->offset)) ) + +void * romfs_load_payload(const char *name); +void * romfs_load_stage(const char *name); +int romfs_execute_stage(const char *name); +void * romfs_get_file(const char *name); +int romfs_load_optionrom(const char *name, u32 dest); + +EXPORT_SYMBOL(romfs_execute_stage); +EXPORT_SYMBOL(romfs_load_stage); +EXPORT_SYMBOL(romfs_load_payload); +EXPORT_SYMBOL(romfs_get_file); +EXPORT_SYMBOL(romfs_load_optionrom); + +int run_address(void *f); +EXPORT_SYMBOL(run_address); + +#endif + Index: coreboot-v3/lib/romfs.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ coreboot-v3/lib/romfs.c 2008-12-19 15:09:50.000000000 -0700 @@ -0,0 +1,246 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008, Jordan Crouse <[email protected]> + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#include <types.h> +#include <string.h> +#include <romfs.h> +#include <console.h> + +#ifndef CONFIG_BIG_ENDIAN +#define ntohl(x) ( ((x&0xff)<<24) | ((x&0xff00)<<8) | \ + ((x&0xff0000) >> 8) | ((x&0xff000000) >> 24) ) +#else +#define ntohl(x) (x) +#endif + +int run_address(void *f); + +int romfs_decompress(int algo, void *src, void *dst, int len) +{ + switch(algo) { + case ROMFS_COMPRESS_NONE: + memcpy(dst, src, len); + return 0; + +#ifdef CONFIG_COMPRESSION_LZMA + + case ROMFS_COMPRESS_LZMA: { + unsigned long ulzma(unsigned char *src, unsigned char *dst); + ulzma(src, dst); + } + return 0; +#endif + +#ifdef CONFIG_COMPRESSION_NRV2B + case ROMFS_COMPRESS_NRV2B: { + unsigned long unrv2b(u8 *src, u8 *dst, unsigned long *ilen_p); + unsigned long tmp; + + unrv2b(src, dst, &tmp); + } + return 0; +#endif + default: + printk(BIOS_INFO, "ROMFS: Unknown compresion type %d\n", + algo); + return -1; + } +} + +int romfs_check_magic(struct romfs_file *file) +{ + return !strcmp(file->magic, ROMFS_FILE_MAGIC) ? 1 : 0; +} + +struct romfs_header *romfs_master_header(void) +{ + struct romfs_header *header; + + unsigned long ptr = *((unsigned long *) ROMFS_HEADPTR_ADDR); + header = (struct romfs_header *) ptr; + + if (ntohl(header->magic) != ROMFS_HEADER_MAGIC) + return NULL; + + return header; +} + +struct romfs_file *romfs_find(const char *name) +{ + struct romfs_header *header = romfs_master_header(); + unsigned long offset; + + if (header == NULL) + return NULL; + + offset = 0xFFFFFFFF - ntohl(header->size) + ntohl(header->offset); + + while(1) { + struct romfs_file *file = (struct romfs_file *) offset; + + if (romfs_check_magic(file) && + !strcmp(ROMFS_NAME(file), name)) + return file; + + offset += ntohl(header->align); + + if (offset < 0xFFFFFFFF - ntohl(header->size)) + return NULL; + } +} + +struct romfs_stage *romfs_find_file(const char *name, int type) +{ + struct romfs_file *file = romfs_find(name); + + if (file == NULL) { + printk(BIOS_INFO, "ROMFS: Could not find file %s\n", + name); + return NULL; + } + + if (ntohl(file->type) != type) { + printk(BIOS_INFO, "ROMFS: File %s is of type %x instead of" + "type %x\n", name, file->type, type); + + return NULL; + } + + return (void *) ROMFS_SUBHEADER(file); +} + +int romfs_load_optionrom(const char *name, u32 dest) +{ + struct romfs_optionrom *orom = (struct romfs_optionrom *) + romfs_find_file(name, ROMFS_TYPE_OPTIONROM); + + if (orom == NULL) + return -1; + + if (romfs_decompress(ntohl(orom->compression), + ((unsigned char *) orom) + + sizeof(struct romfs_optionrom), + (void *) dest, + ntohl(orom->len))) + return -1; + + return 0; +} + +void * romfs_load_payload(const char *name) +{ + struct romfs_payload *payload = (struct romfs_payload *) + romfs_find_file(name, ROMFS_TYPE_PAYLOAD); + + struct romfs_payload_segment *segment; + + if (payload == NULL) + return (void *) -1; + + segment = &payload->segments; + + while(1) { + switch(segment->type) { + case PAYLOAD_SEGMENT_CODE: + case PAYLOAD_SEGMENT_DATA: + memset((void *) ntohl((u32) segment->load_addr), + 0, ntohl(segment->mem_len)); + + if (romfs_decompress(ntohl(segment->compression), + ((unsigned char *) segment) + + ntohl(segment->offset), + (void *) + ntohl((u32) segment->load_addr), + ntohl(segment->len))) + goto err; + break; + case PAYLOAD_SEGMENT_BSS: + memset((void *) ntohl((u32) segment->load_addr), + 0, ntohl(segment->mem_len)); + break; + + case PAYLOAD_SEGMENT_ENTRY: + return (void *) ntohl((u32) segment->load_addr); + } + } + +err: + printk(BIOS_INFO, "ROMFS: Unable to load payload %s\n", + name); + + return (void *) -1; +} + +void * romfs_load_stage(const char *name) +{ + struct romfs_stage *stage = (struct romfs_stage *) + romfs_find_file(name, ROMFS_TYPE_STAGE); + + if (stage == NULL) + return (void *) -1; + + memset((void *) ntohl((u32) stage->load), 0, ntohl(stage->memlen)); + + if (romfs_decompress(ntohl(stage->compression), + ((unsigned char *) stage) + + sizeof(struct romfs_stage), + (void *) ntohl((u32) stage->load), + ntohl(stage->len))) + return (void *) -1; + + return (void *) ntohl((u32) stage->entry); +} + +void * romfs_get_file(const char *name) +{ + return romfs_find(name); +} + +int romfs_execute_stage(const char *name) +{ + struct romfs_stage *stage = (struct romfs_stage *) + romfs_find_file(name, ROMFS_TYPE_STAGE); + + if (stage == NULL) + return 1; + + if (ntohl(stage->compression) != ROMFS_COMPRESS_NONE) { + printk(BIOS_INFO, "ROMFS: Unable to run %s: Compressed file" + "Not supported for in-place execution\n", name); + return 1; + } + + /* FIXME: This isn't right */ + return run_address((void *) ntohl((u32) stage->entry)); +} + +/** + * * run_address is passed the address of a function taking no parameters and + * * jumps to it, returning the result. + * * @param f the address to call as a function. + * * returns value returned by the function. + * */ + +int run_address(void *f) +{ + int (*v) (void); + v = f; + return v(); +} + Index: coreboot-v3/arch/x86/stage1.c =================================================================== --- coreboot-v3.orig/arch/x86/stage1.c 2008-12-18 10:49:05.000000000 -0700 +++ coreboot-v3/arch/x86/stage1.c 2008-12-19 15:09:27.000000000 -0700 @@ -23,7 +23,7 @@ #include <console.h> #include <cpu.h> #include <globalvars.h> -#include <lar.h> +#include <romfs.h> #include <string.h> #include <tables.h> #include <lib.h> @@ -52,22 +52,6 @@ post_code(POST_STAGE1_ENABLE_ROM); } -void init_archive(struct mem_file *archive) -{ - // FIXME this should be defined in the VPD area - // but NOT IN THE CODE. - - /* The len field starts behind the reset vector on x86. - * The start is not correct for all platforms. sc520 will - * need some hands on here. - */ - archive->len = *(u32 *)0xfffffff4; - archive->start =(void *)(0UL-archive->len); - - // FIXME check integrity - -} - /* * The name is slightly misleading because this is the initial stack pointer, * not the address of the first element on the stack. @@ -191,7 +175,6 @@ { struct global_vars globvars; int ret; - struct mem_file archive; post_code(POST_STAGE1_MAIN); @@ -228,24 +211,21 @@ // enable rom enable_rom(); - // location and size of image. - - init_archive(&archive); - // find first initram if (check_normal_boot_flag()) { printk(BIOS_DEBUG, "Choosing normal boot.\n"); - ret = execute_in_place(&archive, "normal/initram/segment0"); + ret = romfs_execute_stage("normal/initram"); } else { printk(BIOS_DEBUG, "Choosing fallback boot.\n"); - ret = execute_in_place(&archive, "fallback/initram/segment0"); - /* Try a normal boot if fallback doesn't exist in the lar. + ret = romfs_execute_stage("fallback/initram"); + + /* Try a normal boot if fallback doesn't exist in the ROM. * TODO: There are other ways to do this. * It could be ifdef or the boot flag could be forced. */ if (ret) { printk(BIOS_DEBUG, "Fallback failed. Try normal boot\n"); - ret = execute_in_place(&archive, "normal/initram/segment0"); + ret = romfs_execute_stage("normal/initram"); } } @@ -309,7 +289,6 @@ void __attribute__((stdcall)) stage1_phase3(void) { void *entry; - struct mem_file archive; struct multiboot_info *mbi; #ifdef CONFIG_PAYLOAD_ELF_LOADER @@ -332,13 +311,13 @@ /* Provide an easy way to check whether RAM is available. */ global_vars()->ram_available = 1; - // location and size of image. - init_archive(&archive); + entry = romfs_load_stage("normal/stage2"); - entry = load_file_segments(&archive, "normal/stage2"); if (entry == (void *)-1) die("FATAL: Failed loading stage2."); + mbi = (struct multiboot_info*) run_address(entry); + if (! mbi) die("FATAL: Failed in stage2 code."); @@ -350,7 +329,8 @@ legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem); #endif /* CONFIG_PAYLOAD_ELF_LOADER */ - entry = load_file_segments(&archive, "normal/payload"); + entry = romfs_load_payload("normal/payload"); + #ifdef CONFIG_CHECK_STACK_USAGE printk(BIOS_DEBUG, "Before handoff to payload, lowest stack is %p\n", global_vars()->loweststack); Index: coreboot-v3/arch/x86/mc146818rtc.c =================================================================== --- coreboot-v3.orig/arch/x86/mc146818rtc.c 2008-12-18 10:49:05.000000000 -0700 +++ coreboot-v3/arch/x86/mc146818rtc.c 2008-12-19 15:09:27.000000000 -0700 @@ -26,7 +26,7 @@ #include <tables.h> #include <mc146818rtc.h> #include <string.h> -#include <lar.h> +#include <romfs.h> /* * Why is this not a function? I assume the two io @@ -180,18 +180,12 @@ struct cmos_option_table *get_option_table(void) { - struct mem_file result, archive; - int ret; - - init_archive(&archive); - - ret = find_file(&archive, "normal/option_table", &result); - if (ret) { + void *ret = romfs_get_file("normal/option_table"); + if (ret == NULL) printk(BIOS_ERR, "No such file '%s'.\n", "normal/option_table"); - return (struct cmos_option_table *)NULL; - } - return (struct cmos_option_table *) result.start; + + return (struct cmos_option_table *) ret; } int get_option(void *dest, char *name) Index: coreboot-v3/device/pci_rom.c =================================================================== --- coreboot-v3.orig/device/pci_rom.c 2008-12-18 10:49:04.000000000 -0700 +++ coreboot-v3/device/pci_rom.c 2008-12-19 15:09:45.000000000 -0700 @@ -27,7 +27,7 @@ #include <device/pci_ids.h> #include <device/pci_ops.h> #include <string.h> -#include <lar.h> +#include <romfs.h> struct rom_header *pci_rom_probe(struct device *dev) { @@ -36,7 +36,6 @@ struct pci_data *rom_data; unsigned int i; unsigned char sum = 0, *rom_bytes; - struct mem_file archive, result; if (dev->on_mainboard) { int ret; @@ -44,20 +43,14 @@ /* In case some device PCI_ROM_ADDRESS can not be set * or readonly. */ - init_archive(&archive); sprintf(pcifile, "pci%04x,%04x.rom", dev->id.pci.vendor, dev->id.pci.device); - ret = find_file(&archive, pcifile, &result); - if (ret) { + if (romfs_load_optionrom(pcifile, 0xc0000)) { printk(BIOS_INFO, "No option rom for onboard device.\n"); return NULL; } - /* FIXME hardcode to 0xc0000 for now because we can only init - * VGA anyways. - */ - process_file(&result, (void *)0xc0000); rom_address = 0xc0000; } else { Index: coreboot-v3/arch/x86/Makefile =================================================================== --- coreboot-v3.orig/arch/x86/Makefile 2008-12-18 10:49:05.000000000 -0700 +++ coreboot-v3/arch/x86/Makefile 2008-12-19 15:10:37.000000000 -0700 @@ -27,37 +27,25 @@ SILENT := >/dev/null 2>&1 -# -# Build the ROM Image / LAR archive -# -# coreboot v3 is completely modular. One module, the bootblock (stage0), -# is mandatory. All modules are packed together in a LAR archive. -# The LAR archive may contain any number of stages, payloads and option ROMs. -# -ROM_SIZE := $(shell expr $(CONFIG_COREBOOT_ROMSIZE_KB) \* 1024) +# Build the ROM Image + +$(obj)/coreboot.rom: $(obj)/coreboot.bootblock $(obj)/coreboot.initram $(obj)/coreboot.stage2 $(obj)/option_table $(SMM) + $(Q)printf " ROM $(subst $(shell pwd)/,,$(@))\n" + $(Q)rm -f $@ + + $(Q)./util/romtool/romtool $@ create \ + $(CONFIG_COREBOOT_ROMSIZE_KB)K $(obj)/coreboot.bootblock + + $(Q)./util/romtool/romtool $@ add-stage \ + $(obj)/coreboot.initram normal/initram -LARFILES_NOCOMPRESS := coreboot.initram:normal/initram option_table:normal/option_table -LARFILES_COMPRESSIBLE := coreboot.stage2:normal/stage2 + $(Q)./util/romtool/romtool $@ add \ + $(obj)/option_table normal/option_table + + $(Q)./util/romtool/romtool $@ add-stage \ + $(obj)/coreboot.stage2 normal/stage2 -COMPRESSFLAG := -ifeq ($(CONFIG_DEFAULT_COMPRESSION_LZMA),y) -COMPRESSFLAG := -C lzma -endif -ifeq ($(CONFIG_DEFAULT_COMPRESSION_NRV2B),y) -COMPRESSFLAG := -C nrv2b -endif - -$(obj)/coreboot.rom $(obj)/coreboot.map: $(obj)/coreboot.bootblock $(obj)/util/lar/lar lzma nrv2b $(obj)/coreboot.initram $(obj)/coreboot.stage2 $(obj)/option_table $(SMM) - $(Q)printf " LAR $(subst $(shell pwd)/,,$(@))\n" - $(Q)rm -f $(obj)/coreboot.rom - $(Q)cd $(obj) && \ - ./util/lar/lar -e -c coreboot.rom \ - -s $(ROM_SIZE) -b coreboot.bootblock \ - $(LARFILES_NOCOMPRESS) - $(Q)cd $(obj) && \ - ./util/lar/lar -e $(COMPRESSFLAG) -a coreboot.rom \ - $(LARFILES_COMPRESSIBLE) ifeq ($(CONFIG_PAYLOAD_NONE),y) $(Q)printf " PAYLOAD none (as specified by user)\n" else @@ -67,13 +55,11 @@ printf "Error: payload file '$(CONFIG_PAYLOAD_FILE)' not found.\n"; \ exit 1; \ fi - $(Q)$(obj)/util/lar/lar $(PARSEELF) $(COMPRESSFLAG) -a \ - $(obj)/coreboot.rom $(CONFIG_PAYLOAD_FILE):normal/payload; -endif -ifeq ($(CONFIG_ZERO_AFTER_PAYLOAD),y) - $(Q)printf " ZEROING lar -z ./coreboot.rom\n" - $(Q)cd $(obj) && ./util/lar/lar -z ./coreboot.rom + + $(Q)./util/romtool/romtool $@ add-payload \ + $(CONFIG_PAYLOAD_FILE) normal/payload endif + ifeq ($(CONFIG_SMM),y) $(Q)printf " Adding smm.elf\n" $(Q)cd $(obj) && ./util/lar/lar -e $(COMPRESSFLAG) -a $(obj)/coreboot.rom $(SMM):normal/smm; @@ -82,8 +68,10 @@ $(Q)# Run "qemu -L build/ -serial stdio -hda /dev/zero". $(Q)printf " CP $(subst $(shell pwd)/,,$(obj)/bios.bin)\n" $(Q)cp $@ $(obj)/bios.bin + +$(obj)/coreboot.map: $(obj)/coreboot.rom $(Q)echo "Coreboot ROM Image:" > $(obj)/coreboot.map - $(Q)$(obj)/util/lar/lar -l $(obj)/coreboot.rom >> $(obj)/coreboot.map + $(Q)$(obj)/util/romtool/romtool $(obj)/coreboot.rom print >> $(obj)/coreboot.map $(Q)(echo; echo "Stage 0/1 Map:") >> $(obj)/coreboot.map $(Q)cat $(obj)/stage0.init.map >> $(obj)/coreboot.map $(Q)(echo; echo "Stage Initram Map:") >> $(obj)/coreboot.map @@ -91,7 +79,6 @@ $(Q)(echo; echo "Stage 2 Map:") >> $(obj)/coreboot.map $(Q)cat $(obj)/coreboot.stage2.map >> $(obj)/coreboot.map - $(obj)/coreboot.bootblock: $(obj)/coreboot.vpd $(obj)/stage0.init $(Q)printf " BUILD $(subst $(shell pwd)/,,$(@))\n" $(Q)cat $^ > $@ @@ -103,7 +90,7 @@ # -STAGE0_LIB_SRC = uart8250.c mem.c lar.c romfs.c delay.c vtxprintf.c \ +STAGE0_LIB_SRC = uart8250.c mem.c romfs.c delay.c vtxprintf.c \ vsprintf.c console.c string.c $(DECOMPRESSORS) STAGE0_ARCH_X86_SRC = stage1.c serial.c \ udelay_io.c mc146818rtc.c post_code.c \ Index: coreboot-v3/include/lar.h =================================================================== --- coreboot-v3.orig/include/lar.h 2008-12-18 10:48:39.000000000 -0700 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006 coresystems GmbH - * (Written by Stefan Reinauer <[email protected]> for coresystems GmbH) - * - * This file is dual-licensed. You can choose between: - * - The GNU GPL, version 2, as published by the Free Software Foundation - * - The revised BSD license (without advertising clause) - * - * --------------------------------------------------------------------------- - * 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - * --------------------------------------------------------------------------- - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * --------------------------------------------------------------------------- - */ - -#ifndef LAR_H -#define LAR_H - -#include <types.h> -#include <shared.h> - -#define MAGIC "LARCHIVE" -#define MAX_PATHLEN 1024 -/* NOTE -- This and the user-mode lar.h may NOT be in sync. Be careful. */ -struct lar_header { - char magic[8]; - u32 len; - u32 reallen; - u32 checksum; - u32 compchecksum; - u32 offset; - /* Compression: - * 0 = no compression - * 1 = lzma - * 2 = nrv2b - * 3 = zeroes - */ - u32 compression; - u64 entry; - u64 loadaddress; -}; - -enum compalgo { - ALGO_NONE = 0, - ALGO_LZMA = 1, - ALGO_NRV2B = 2, - ALGO_ZEROES = 3, - /* invalid should always be the last entry. */ - ALGO_INVALID -}; - -struct mem_file { - void *start; - int len; - u32 reallen; - u32 compression; - void *entry; - void *loadaddress; -}; - -/* Prototypes. */ -/* architecture-defined */ -void init_archive(struct mem_file *); -EXPORT_SYMBOL(init_archive); -/* architecture-independent */ -int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result); -EXPORT_SYMBOL(find_file); -int copy_file(const struct mem_file *archive, const char *filename, void *where); -EXPORT_SYMBOL(copy_file); -int run_file(const struct mem_file *archive, const char *filename, void *where); -EXPORT_SYMBOL(run_file); -int execute_in_place(const struct mem_file *archive, const char *filename); -EXPORT_SYMBOL(execute_in_place); -int run_address(void *f); -EXPORT_SYMBOL(run_address); -void * load_file(const struct mem_file *archive, const char *filename); -EXPORT_SYMBOL(load_file); -void * load_file_segments(const struct mem_file *archive, const char *filename); -EXPORT_SYMBOL(load_file_segments); -int process_file(const struct mem_file *archive, void *where); -EXPORT_SYMBOL(process_file); -#endif /* LAR_H */ Index: coreboot-v3/lib/lar.c =================================================================== --- coreboot-v3.orig/lib/lar.c 2008-12-18 10:48:39.000000000 -0700 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,309 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006-2007 coresystems GmbH - * (Written by Stefan Reinauer <[email protected]> for coresystems GmbH) - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include <types.h> -#include <string.h> -#include <lar.h> -#include <console.h> - -#ifndef CONFIG_BIG_ENDIAN -#define ntohl(x) ( ((x&0xff)<<24) | ((x&0xff00)<<8) | \ - ((x&0xff0000) >> 8) | ((x&0xff000000) >> 24) ) -#else -#define ntohl(x) (x) -#endif - -static const char * const algo_name[] = { - "none", - "lzma", - "nrv2b", - "zeroes", - /* invalid should always be the last entry. */ - "invalid" -}; - -/** - * run_address is passed the address of a function taking no parameters and - * jumps to it, returning the result. - * @param f the address to call as a function. - * returns value returned by the function. - */ - -int run_address(void *f) -{ - int (*v) (void); - v = f; - return v(); -} - -/** - * Given a file name in the LAR , search for it, and fill out a return struct with the - * result. - * @param archive A descriptor for current archive. This is actually a mem_file type, - * which is a machine-dependent representation of the actual archive. In particular, - * things like u32 are void * in the mem_file struct. - * @param filename filename to find - * @param result pointer to mem_file struct which is filled in if the file is found - * returns 0 on success, -1 otherwise - */ - -int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result) -{ - char *walk, *fullname; - struct lar_header *header; - - printk(BIOS_INFO, "LAR: Attempting to open '%s'.\n", filename); - printk(BIOS_SPEW, "LAR: Start %p len 0x%x\n", archive->start, - archive->len); - - /* Why check for sizeof(struct lar_header) + 1? The code below expects - * a filename to follow directly after the LAR header and will - * dereference the address directly after the header. However, if - * archive->len == sizeof(struct lar_header), printing the filename - * will dereference memory outside the archive. Without looking at the - * filename, the only thing we can check is that there is at least room - * for an empty filename (only the terminating \0). - */ - if (archive->len < sizeof(struct lar_header) + 1) - printk(BIOS_ERR, "Error: truncated archive (%d bytes); minimum" - " possible size is %d bytes\n", - archive->len, sizeof(struct lar_header) + 1); - - /* Getting this for loop right is harder than it looks. All quantities - * are unsigned. The LAR stretches from (e.g.) 0xfff0000 for 0x100000 - * bytes, i.e. to address ZERO. - * As a result, 'walk', can wrap to zero and keep going (this has been - * seen in practice). Recall that these are unsigned; walk can - * wrap to zero; so, question, when is walk less than any of these: - * archive->start - * Answer: once walk wraps to zero, it is < archive->start - * archive->start + archive->len - * archive->start + archive->len - 1 - * Answer: In the case that archive->start + archive->len == 0, ALWAYS! - * A lot of expressions have been tried and all have been wrong. - * So what would work? Simple: - * test for walk < archive->start + archive->len - sizeof(lar_header) - * to cover the case that the archive does NOT occupy ALL of the - * top of memory and wrap to zero; RESIST the temptation to change - * that comparison to <= because if a header did terminate the - * archive, the filename (stored directly after the header) would - * be outside the archive and you'd get a nice NULL pointer for - * the filename - * and test for walk >= archive->start, - * to cover the case that you wrapped to zero. - * Unsigned pointer arithmetic that wraps to zero can be messy. - */ - for (walk = archive->start; - (walk < (char *)(archive->start + archive->len - sizeof(struct lar_header))) && - (walk >= (char *)archive->start); walk += 16) { - if (strncmp(walk, MAGIC, sizeof(header->magic)) != 0) - continue; - - header = (struct lar_header *)walk; - fullname = walk + sizeof(struct lar_header); - - printk(BIOS_SPEW, "LAR: seen member %...@%p, size %d\n", - fullname, header, ntohl(header->len)); - // FIXME: check checksum - - if (strcmp(fullname, filename) == 0) { - printk(BIOS_SPEW, "LAR: CHECK %s @ %p\n", fullname, header); - result->start = walk + ntohl(header->offset); - result->len = ntohl(header->len); - result->reallen = ntohl(header->reallen); - result->compression = ntohl(header->compression); - result->entry = (void *)ntohl((u32)header->entry); - result->loadaddress = (void *)ntohl((u32)header->loadaddress); - printk(BIOS_SPEW, - "start %p len %d reallen %d compression %x entry %p loadaddress %p\n", - result->start, result->len, result->reallen, - result->compression, result->entry, result->loadaddress); - return 0; - } - /* skip file: - * The next iteration of the for loop will add 16 to walk, so - * we now add offset (from header start to data start) and len - * (member length), subtract 1 (to get the address of the last - * byte of the member) and round this down to the next 16 byte - * boundary. - * In the case of consecutive archive members with header- - * before-member structure, the next iteration of the loop will - * start exactly at the beginning of the next header. - */ - walk += (ntohl(header->offset) + ntohl(header->len) - 1) - & 0xfffffff0; - } - printk(BIOS_SPEW, "LAR: File not found!\n"); - return 1; -} - -int process_file(const struct mem_file *archive, void *where) -{ - const char *algoname = algo_name[(archive->compression >= ALGO_INVALID) - ? ALGO_INVALID : archive->compression]; - printk(BIOS_SPEW, "LAR: Compression algorithm #%i (%s) used\n", - archive->compression, algoname); - switch (archive->compression) { - /* no compression */ - case ALGO_NONE: - memcpy(where, archive->start, archive->len); - return 0; -#ifdef CONFIG_COMPRESSION_LZMA - /* lzma */ - case ALGO_LZMA: { - unsigned long ulzma(unsigned char *src, unsigned char *dst); - ulzma(archive->start, where); - return 0; - } -#endif -#ifdef CONFIG_COMPRESSION_NRV2B - /* nrv2b */ - case ALGO_NRV2B: { - unsigned long unrv2b(u8 *src, u8 *dst, unsigned long *ilen_p); - unsigned long tmp; - unrv2b(archive->start, where, &tmp); - return 0; - } -#endif - /* zeroes */ - case ALGO_ZEROES: - memset(where, 0, archive->reallen); - return 0; - default: - printk(BIOS_INFO, "LAR: Compression algorithm #%i (%s) not" - " supported!\n", archive->compression, algoname); - return -1; - } -} - -/** - * Given a file name, search the LAR for all segments of it, and load them - * into memory, using the loadaddress pointer in the mem_file struct. - * @param archive A descriptor for current archive. - * @param filename filename to find - * returns entry on success, (void*)-1 otherwise - * FIXME: Look for a cmdline as well. - */ -void *load_file_segments(const struct mem_file *archive, const char *filename) -{ - void *entry = NULL; - void *newentry; - int i; - char tmpname[64]; - - for(i = 0, entry = (void *)0; ;i++) { - sprintf(tmpname, "%s/segment%d", filename, i); - newentry = load_file(archive, tmpname); - if (newentry == (void *)-1) - break; - if (!entry) - entry = newentry; - } - if (!entry) { - printk(BIOS_INFO, "LAR: load_file_segments: Failed for %s\n", filename); - return (void *)-1; - } - printk(BIOS_SPEW, "LAR: load_file_segments: All loaded, entry %p\n", entry); - return entry; -} - -/** - * Given a file name in the LAR , search for it, and load it into memory, using - * the loadaddress pointer in the mem_file struct. - * @param archive A descriptor for current archive. - * @param filename filename to find - * returns entry on success, (void*)-1 otherwise - */ - -void *load_file(const struct mem_file *archive, const char *filename) -{ - int ret; - struct mem_file result; - void *where; - void *entry; - - ret = find_file(archive, filename, &result); - if (ret) { - printk(BIOS_INFO, "LAR: load_file: No such file '%s'\n", - filename); - return (void *)-1; - } - entry = result.entry; - where = result.loadaddress; - - if (process_file(&result, where) == 0) - return entry; - - return (void *)-1; -} - -/** - * Given a file name in the LAR , search for it, and load it into memory, - * using the passed-in pointer as the address - * @param archive A descriptor for current archive. - * @param filename filename to find - * @param where pointer to where to load the data - * returns 0 on success, -1 otherwise - */ -int copy_file(const struct mem_file *archive, const char *filename, void *where) -{ - int ret; - struct mem_file result; - - ret = find_file(archive, filename, &result); - if (ret) { - printk(BIOS_INFO, "LAR: copy_file: No such file '%s'\n", - filename); - return 1; - } - - return process_file(&result, where); -} - - -/** - * Given a file name in the LAR , search for it, and execute it in place. - * @param archive A descriptor for current archive. - * @param filename filename to find - * returns 0 on success, -1 otherwise - */ -int execute_in_place(const struct mem_file *archive, const char *filename) -{ - struct mem_file result; - int ret; - void *where; - - if (find_file(archive, filename, &result)) { - printk(BIOS_INFO, "LAR: Run file %s failed: No such file.\n", - filename); - return 1; - } - if (result.compression != 0) { - printk(BIOS_INFO, "LAR: Run file %s failed: Compressed file" - " not supported for in-place execution\n", filename); - return 1; - } - where = result.start + (u32)result.entry; - printk(BIOS_SPEW, "Entry point is %p\n", where); - ret = run_address(where); - printk(BIOS_SPEW, "run_file returns with %d\n", ret); - return ret; -} Index: coreboot-v3/lib/stage2.c =================================================================== --- coreboot-v3.orig/lib/stage2.c 2008-12-18 10:48:40.000000000 -0700 +++ coreboot-v3/lib/stage2.c 2008-12-19 15:09:50.000000000 -0700 @@ -23,7 +23,6 @@ #include <types.h> #include <string.h> -#include <lar.h> #include <console.h> #include <device/device.h> #include <tables.h>
-- coreboot mailing list: [email protected] http://www.coreboot.org/mailman/listinfo/coreboot

