mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
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:
parent
210463d65c
commit
82ea8a8b1e
3 changed files with 65 additions and 79 deletions
|
@ -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");
|
||||
|
|
|
@ -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
104
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue