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 <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>


git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@530 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Carl-Daniel Hailfinger 2007-11-28 22:50:00 +00:00
parent 210463d65c
commit 82ea8a8b1e
3 changed files with 65 additions and 79 deletions

View file

@ -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");

View file

@ -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 */

104
lib/lar.c
View file

@ -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;
}