From 82ea8a8b1e659aed3fb4aaee69391f4868b12187 Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Wed, 28 Nov 2007 22:50:00 +0000 Subject: [PATCH] Consolidate all multiple segment handling into lib/lar.c:load_file_segments() and greatly simplify arch/x86/stage1.c code as a result. While I'm at it, improve the LAR segmentation abstraction. Stage 1 code should not have to care about internal representation of segments, that knowledge belongs into lib/lar.c. Constification of most function parameters in lib/lar.c led to a few other now obvious code removals. Build tested and runtime tested in Qemu. Signed-off-by: Carl-Daniel Hailfinger Acked-by: Ronald G. Minnich git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@530 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- arch/x86/stage1.c | 29 ++----------- include/lar.h | 11 ++--- lib/lar.c | 104 ++++++++++++++++++++++++---------------------- 3 files changed, 65 insertions(+), 79 deletions(-) diff --git a/arch/x86/stage1.c b/arch/x86/stage1.c index 752cdcb5aa..e28aa38d5a 100644 --- a/arch/x86/stage1.c +++ b/arch/x86/stage1.c @@ -77,7 +77,6 @@ void __attribute__((stdcall)) stage1_main(u32 bist) struct mem_file archive, result; int elfboot_mem(struct lb_memory *mem, void *where, int size); void *entry; - int i; /* we can't statically init this hack. */ unsigned char faker[64]; @@ -161,11 +160,9 @@ void __attribute__((stdcall)) stage1_main(u32 bist) /* Turn off Cache-As-Ram */ disable_car(); - entry = load_file(&archive, "normal/stage2.o/segment0"); + entry = load_file_segments(&archive, "normal/stage2.o"); if (entry == (void *)-1) - die("FATAL: Failed loading stage2 segment0."); - if (load_file(&archive, "normal/stage2.o/segment1") == (void *)-1) - die("FATAL: Failed loading stage2 segment1."); + die("FATAL: Failed loading stage2."); ret = run_address(entry); if (ret) die("FATAL: Failed in stage2 code."); @@ -176,26 +173,8 @@ void __attribute__((stdcall)) stage1_main(u32 bist) if (! ret) legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem); - - /* new style lar boot. Install all the files in memory. - * By convention we take the entry point from the first - * one. Look for a cmdline as well. - */ - for(i = 0, entry = (void *)0; ;i++) { - char filename[64]; - void *newentry; - sprintf(filename, "normal/payload/segment%d", i); - archive.len = *(u32 *)0xfffffff4; - archive.start =(void *)(0UL-archive.len); - newentry = load_file(&archive, filename); - printk(BIOS_SPEW, "newentry is %p\n", newentry); - if (newentry == (void *)-1) - break; - if (! entry) - entry = newentry; - } - printk(BIOS_SPEW, "all loaded, entry %p\n", entry); - if (entry) + entry = load_file_segments(&archive, "normal/payload"); + if (entry != (void*)-1) run_address(entry); die("FATAL: No usable payload found.\n"); diff --git a/include/lar.h b/include/lar.h index b311d1ac0b..84f00aaf8f 100644 --- a/include/lar.h +++ b/include/lar.h @@ -82,10 +82,11 @@ struct mem_file { }; /* Prototypes. */ -int find_file(struct mem_file *archive, const char *filename, struct mem_file *result); -int copy_file(struct mem_file *archive, const char *filename, void *where); -int run_file(struct mem_file *archive, const char *filename, void *where); -int execute_in_place(struct mem_file *archive, const char *filename); +int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result); +int copy_file(const struct mem_file *archive, const char *filename, void *where); +int run_file(const struct mem_file *archive, const char *filename, void *where); +int execute_in_place(const struct mem_file *archive, const char *filename); int run_address(void *f); -void *load_file(struct mem_file *archive, const char *filename); +void *load_file(const struct mem_file *archive, const char *filename); +void *load_file_segments(const struct mem_file *archive, const char *filename); #endif /* LAR_H */ diff --git a/lib/lar.c b/lib/lar.c index a9c0a4f2c5..98e5ce9ed5 100644 --- a/lib/lar.c +++ b/lib/lar.c @@ -56,7 +56,7 @@ int run_address(void *f) * returns 0 on success, -1 otherwise */ -int find_file(struct mem_file *archive, const char *filename, struct mem_file *result) +int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result) { char *walk, *fullname; struct lar_header *header; @@ -145,7 +145,7 @@ int find_file(struct mem_file *archive, const char *filename, struct mem_file *r return 1; } -static int process_file(struct mem_file *archive, void *where) +static int process_file(const struct mem_file *archive, void *where) { printk(BIOS_SPEW, "LAR: Compression algorithm #%i used\n", archive->compression); /* no compression */ @@ -174,6 +174,37 @@ static int process_file(struct mem_file *archive, void *where) 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. @@ -182,7 +213,7 @@ static int process_file(struct mem_file *archive, void *where) * returns entry on success, (void*)-1 otherwise */ -void *load_file(struct mem_file *archive, const char *filename) +void *load_file(const struct mem_file *archive, const char *filename) { int ret; struct mem_file result; @@ -212,7 +243,7 @@ void *load_file(struct mem_file *archive, const char *filename) * @param where pointer to where to load the data * returns 0 on success, -1 otherwise */ -int copy_file(struct mem_file *archive, const char *filename, void *where) +int copy_file(const struct mem_file *archive, const char *filename, void *where) { int ret; struct mem_file result; @@ -228,56 +259,31 @@ int copy_file(struct mem_file *archive, const char *filename, void *where) } -/** - * Given a file name in the LAR , search for it, and load it into memory, - * using the passed-in pointer as the address; jump to the file. - * If the passed-in pointer is (void *)-1, then execute the file in place. - * @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 run_file(struct mem_file *archive, const char *filename, void *where) -{ - struct mem_file result; - int ret; - - if ((u32) where != 0xFFFFFFFF) { - if (copy_file(archive, filename, where)) { - printk(BIOS_INFO, - "LAR: Run file %s failed: No such file.\n", - filename); - return 1; - } - } else { /* XIP */ - 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; -} - /** * 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(struct mem_file *archive, const char *filename) +int execute_in_place(const struct mem_file *archive, const char *filename) { - return run_file(archive, filename, (void *) 0xFFFFFFFF); + 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; }