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;
|
struct mem_file archive, result;
|
||||||
int elfboot_mem(struct lb_memory *mem, void *where, int size);
|
int elfboot_mem(struct lb_memory *mem, void *where, int size);
|
||||||
void *entry;
|
void *entry;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* we can't statically init this hack. */
|
/* we can't statically init this hack. */
|
||||||
unsigned char faker[64];
|
unsigned char faker[64];
|
||||||
|
@ -161,11 +160,9 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
|
||||||
/* Turn off Cache-As-Ram */
|
/* Turn off Cache-As-Ram */
|
||||||
disable_car();
|
disable_car();
|
||||||
|
|
||||||
entry = load_file(&archive, "normal/stage2.o/segment0");
|
entry = load_file_segments(&archive, "normal/stage2.o");
|
||||||
if (entry == (void *)-1)
|
if (entry == (void *)-1)
|
||||||
die("FATAL: Failed loading stage2 segment0.");
|
die("FATAL: Failed loading stage2.");
|
||||||
if (load_file(&archive, "normal/stage2.o/segment1") == (void *)-1)
|
|
||||||
die("FATAL: Failed loading stage2 segment1.");
|
|
||||||
ret = run_address(entry);
|
ret = run_address(entry);
|
||||||
if (ret)
|
if (ret)
|
||||||
die("FATAL: Failed in stage2 code.");
|
die("FATAL: Failed in stage2 code.");
|
||||||
|
@ -176,26 +173,8 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
|
||||||
if (! ret)
|
if (! ret)
|
||||||
legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem);
|
legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem);
|
||||||
|
|
||||||
|
entry = load_file_segments(&archive, "normal/payload");
|
||||||
/* new style lar boot. Install all the files in memory.
|
if (entry != (void*)-1)
|
||||||
* 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)
|
|
||||||
run_address(entry);
|
run_address(entry);
|
||||||
|
|
||||||
die("FATAL: No usable payload found.\n");
|
die("FATAL: No usable payload found.\n");
|
||||||
|
|
|
@ -82,10 +82,11 @@ struct mem_file {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
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);
|
||||||
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 run_file(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(struct mem_file *archive, const char *filename);
|
int execute_in_place(const struct mem_file *archive, const char *filename);
|
||||||
int run_address(void *f);
|
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 */
|
#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
|
* 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;
|
char *walk, *fullname;
|
||||||
struct lar_header *header;
|
struct lar_header *header;
|
||||||
|
@ -145,7 +145,7 @@ int find_file(struct mem_file *archive, const char *filename, struct mem_file *r
|
||||||
return 1;
|
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);
|
printk(BIOS_SPEW, "LAR: Compression algorithm #%i used\n", archive->compression);
|
||||||
/* no compression */
|
/* no compression */
|
||||||
|
@ -174,6 +174,37 @@ static int process_file(struct mem_file *archive, void *where)
|
||||||
return -1;
|
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
|
* Given a file name in the LAR , search for it, and load it into memory, using
|
||||||
* the loadaddress pointer in the mem_file struct.
|
* 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
|
* 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;
|
int ret;
|
||||||
struct mem_file result;
|
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
|
* @param where pointer to where to load the data
|
||||||
* returns 0 on success, -1 otherwise
|
* 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;
|
int ret;
|
||||||
struct mem_file result;
|
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.
|
* Given a file name in the LAR , search for it, and execute it in place.
|
||||||
* @param archive A descriptor for current archive.
|
* @param archive A descriptor for current archive.
|
||||||
* @param filename filename to find
|
* @param filename filename to find
|
||||||
* returns 0 on success, -1 otherwise
|
* 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