program loading: unify on struct prog
Instead of having different structures for loading ramstage and payload align to using struct prog. This also removes arch_payload_run() in favor of the prog_run() interface. Change-Id: I31483096094eacc713a7433811cd69cc5621c43e Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/8849 Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marc.jones@se-eng.com>
This commit is contained in:
parent
b3847e6424
commit
ce9efe061a
|
@ -29,8 +29,3 @@ void arch_prog_run(struct prog *prog)
|
||||||
doit = prog_entry(prog);
|
doit = prog_entry(prog);
|
||||||
doit(prog_entry_arg(prog));
|
doit(prog_entry_arg(prog));
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_payload_run(struct payload *payload)
|
|
||||||
{
|
|
||||||
arch_prog_run(&payload->prog);
|
|
||||||
}
|
|
||||||
|
|
|
@ -77,8 +77,3 @@ void arch_prog_run(struct prog *prog)
|
||||||
|
|
||||||
doit(prog_entry_arg(prog));
|
doit(prog_entry_arg(prog));
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_payload_run(struct payload *payload)
|
|
||||||
{
|
|
||||||
arch_prog_run(&payload->prog);
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,8 +24,3 @@ void arch_prog_run(struct prog *prog)
|
||||||
{
|
{
|
||||||
stage_exit(prog_entry(prog));
|
stage_exit(prog_entry(prog));
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_payload_run(struct payload *payload)
|
|
||||||
{
|
|
||||||
arch_prog_run(&payload->prog);
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,8 +26,3 @@ void arch_prog_run(struct prog *prog)
|
||||||
doit = prog_entry(prog);
|
doit = prog_entry(prog);
|
||||||
doit(prog_entry_arg(prog));
|
doit(prog_entry_arg(prog));
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_payload_run(struct payload *payload)
|
|
||||||
{
|
|
||||||
arch_prog_run(&payload->prog);
|
|
||||||
}
|
|
||||||
|
|
|
@ -123,18 +123,22 @@ static void jmp_payload(void *entry, unsigned long buffer, unsigned long size)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_payload_run(struct payload *payload)
|
static void try_payload(struct prog *prog)
|
||||||
{
|
{
|
||||||
|
if (prog->type == PROG_PAYLOAD) {
|
||||||
if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE))
|
if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE))
|
||||||
jmp_payload_no_bounce_buffer(prog_entry(&payload->prog));
|
jmp_payload_no_bounce_buffer(prog_entry(prog));
|
||||||
else
|
else
|
||||||
jmp_payload(prog_entry(&payload->prog),
|
jmp_payload(prog_entry(prog),
|
||||||
(uintptr_t)payload->bounce.data,
|
(uintptr_t)prog_start(prog),
|
||||||
payload->bounce.size);
|
prog_size(prog));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_prog_run(struct prog *prog)
|
void arch_prog_run(struct prog *prog)
|
||||||
{
|
{
|
||||||
|
if (ENV_RAMSTAGE)
|
||||||
|
try_payload(prog);
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"jmp *%%edi\n"
|
"jmp *%%edi\n"
|
||||||
:: "D"(prog_entry(prog))
|
:: "D"(prog_entry(prog))
|
||||||
|
|
|
@ -50,7 +50,8 @@ struct prog {
|
||||||
const char *name;
|
const char *name;
|
||||||
/* The area can mean different things depending on what type the
|
/* The area can mean different things depending on what type the
|
||||||
* program is. e.g. a payload prog uses this field for the backing
|
* program is. e.g. a payload prog uses this field for the backing
|
||||||
* store of the payload_segments and data. */
|
* store of the payload_segments and data. After loading the segments
|
||||||
|
* area is updated to reflect the bounce buffer used. */
|
||||||
struct buffer_area area;
|
struct buffer_area area;
|
||||||
/* Entry to program with optional argument. It's up to the architecture
|
/* Entry to program with optional argument. It's up to the architecture
|
||||||
* to decide if argument is passed. */
|
* to decide if argument is passed. */
|
||||||
|
@ -100,6 +101,14 @@ void arch_prog_run(struct prog *prog);
|
||||||
* code it needs to that as well. */
|
* code it needs to that as well. */
|
||||||
void platform_prog_run(struct prog *prog);
|
void platform_prog_run(struct prog *prog);
|
||||||
|
|
||||||
|
struct prog_loader_ops {
|
||||||
|
const char *name;
|
||||||
|
/* Returns < 0 on error or 0 on success. This function needs to do
|
||||||
|
* different things depending on the prog type. See definition
|
||||||
|
* of struct prog above. */
|
||||||
|
int (*prepare)(struct prog *prog);
|
||||||
|
};
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
* ROMSTAGE LOADING *
|
* ROMSTAGE LOADING *
|
||||||
************************/
|
************************/
|
||||||
|
@ -111,6 +120,9 @@ void run_romstage(void);
|
||||||
* RAMSTAGE LOADING *
|
* RAMSTAGE LOADING *
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
|
/* Run ramstage from romstage. */
|
||||||
|
void run_ramstage(void);
|
||||||
|
|
||||||
struct romstage_handoff;
|
struct romstage_handoff;
|
||||||
#if IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)
|
#if IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)
|
||||||
/* Cache the loaded ramstage described by prog. */
|
/* Cache the loaded ramstage described by prog. */
|
||||||
|
@ -124,25 +136,10 @@ static inline void load_cached_ramstage(struct romstage_handoff *h,
|
||||||
struct prog *p) {}
|
struct prog *p) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Run ramstage from romstage. */
|
|
||||||
void run_ramstage(void);
|
|
||||||
|
|
||||||
struct ramstage_loader_ops {
|
|
||||||
const char *name;
|
|
||||||
/* Returns 0 on succes. < 0 on error. */
|
|
||||||
int (*load)(struct prog *ramstage);
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************
|
/***********************
|
||||||
* PAYLOAD LOADING *
|
* PAYLOAD LOADING *
|
||||||
***********************/
|
***********************/
|
||||||
|
|
||||||
struct payload {
|
|
||||||
struct prog prog;
|
|
||||||
/* Used when payload wants memory coreboot ramstage is running at. */
|
|
||||||
struct buffer_area bounce;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Load payload into memory in preparation to run. */
|
/* Load payload into memory in preparation to run. */
|
||||||
void payload_load(void);
|
void payload_load(void);
|
||||||
|
|
||||||
|
@ -150,23 +147,9 @@ void payload_load(void);
|
||||||
void payload_run(void);
|
void payload_run(void);
|
||||||
|
|
||||||
/* Mirror the payload to be loaded. */
|
/* Mirror the payload to be loaded. */
|
||||||
void mirror_payload(struct payload *payload);
|
void mirror_payload(struct prog *payload);
|
||||||
|
|
||||||
/* architecture specific function to run payload. */
|
|
||||||
void arch_payload_run(struct payload *payload);
|
|
||||||
|
|
||||||
/* Payload loading operations. */
|
|
||||||
struct payload_loader_ops {
|
|
||||||
const char *name;
|
|
||||||
/*
|
|
||||||
* Fill in payload_backing_store structure. Return 0 on success, < 0
|
|
||||||
* on failure.
|
|
||||||
*/
|
|
||||||
int (*locate)(struct payload *payload);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Defined in src/lib/selfboot.c */
|
/* Defined in src/lib/selfboot.c */
|
||||||
void *selfload(struct payload *payload);
|
void *selfload(struct prog *payload);
|
||||||
|
|
||||||
|
|
||||||
#endif /* PROGRAM_LOADING_H */
|
#endif /* PROGRAM_LOADING_H */
|
||||||
|
|
|
@ -20,24 +20,24 @@
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <program_loading.h>
|
#include <program_loading.h>
|
||||||
|
|
||||||
static int cbfs_locate_payload(struct payload *payload)
|
static int cbfs_locate_payload(struct prog *payload)
|
||||||
{
|
{
|
||||||
void *buffer;
|
void *buffer;
|
||||||
size_t size;
|
size_t size;
|
||||||
const int type = CBFS_TYPE_PAYLOAD;
|
const int type = CBFS_TYPE_PAYLOAD;
|
||||||
|
|
||||||
buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->prog.name,
|
buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->name,
|
||||||
type, &size);
|
type, &size);
|
||||||
|
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
prog_set_area(&payload->prog, buffer, size);
|
prog_set_area(payload, buffer, size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct payload_loader_ops cbfs_payload_loader = {
|
const struct prog_loader_ops cbfs_payload_loader = {
|
||||||
.name = "CBFS",
|
.name = "CBFS",
|
||||||
.locate = cbfs_locate_payload,
|
.prepare = cbfs_locate_payload,
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,7 +54,7 @@ static int cbfs_load_ramstage(struct prog *ramstage)
|
||||||
|
|
||||||
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
|
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||||
|
|
||||||
const struct ramstage_loader_ops cbfs_ramstage_loader = {
|
const struct prog_loader_ops cbfs_ramstage_loader = {
|
||||||
.name = "CBFS",
|
.name = "CBFS",
|
||||||
.load = cbfs_load_ramstage,
|
.prepare = cbfs_load_ramstage,
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,24 +26,22 @@
|
||||||
#include <program_loading.h>
|
#include <program_loading.h>
|
||||||
#include <timestamp.h>
|
#include <timestamp.h>
|
||||||
|
|
||||||
extern const struct payload_loader_ops vboot_payload_loader;
|
extern const struct prog_loader_ops vboot_payload_loader;
|
||||||
extern const struct payload_loader_ops cbfs_payload_loader;
|
extern const struct prog_loader_ops cbfs_payload_loader;
|
||||||
|
|
||||||
static const struct payload_loader_ops *payload_ops[] = {
|
static const struct prog_loader_ops *payload_ops[] = {
|
||||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||||
&vboot_payload_loader,
|
&vboot_payload_loader,
|
||||||
#endif
|
#endif
|
||||||
&cbfs_payload_loader,
|
&cbfs_payload_loader,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct payload global_payload = {
|
static struct prog global_payload = {
|
||||||
.prog = {
|
|
||||||
.name = CONFIG_CBFS_PREFIX "/payload",
|
.name = CONFIG_CBFS_PREFIX "/payload",
|
||||||
.type = PROG_PAYLOAD,
|
.type = PROG_PAYLOAD,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void __attribute__((weak)) mirror_payload(struct payload *payload)
|
void __attribute__((weak)) mirror_payload(struct prog *payload)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -51,19 +49,18 @@ void __attribute__((weak)) mirror_payload(struct payload *payload)
|
||||||
void payload_load(void)
|
void payload_load(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const struct payload_loader_ops *ops;
|
const struct prog_loader_ops *ops;
|
||||||
struct payload *payload = &global_payload;
|
struct prog *payload = &global_payload;
|
||||||
struct prog * prog = &payload->prog;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(payload_ops); i++) {
|
for (i = 0; i < ARRAY_SIZE(payload_ops); i++) {
|
||||||
ops = payload_ops[i];
|
ops = payload_ops[i];
|
||||||
if (ops->locate(payload) < 0) {
|
if (ops->prepare(payload) < 0) {
|
||||||
printk(BIOS_DEBUG, "%s: could not locate payload.\n",
|
printk(BIOS_DEBUG, "%s: could not locate payload.\n",
|
||||||
ops->name);
|
ops->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n",
|
printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n",
|
||||||
ops->name, prog_start(prog), prog_size(prog));
|
ops->name, prog_start(payload), prog_size(payload));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,23 +70,23 @@ void payload_load(void)
|
||||||
mirror_payload(payload);
|
mirror_payload(payload);
|
||||||
|
|
||||||
/* Pass cbtables to payload if architecture desires it. */
|
/* Pass cbtables to payload if architecture desires it. */
|
||||||
prog_set_entry(&payload->prog, selfload(payload),
|
prog_set_entry(payload, selfload(payload),
|
||||||
cbmem_find(CBMEM_ID_CBTABLE));
|
cbmem_find(CBMEM_ID_CBTABLE));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (prog_entry(&payload->prog) == NULL)
|
if (prog_entry(payload) == NULL)
|
||||||
die("Payload not loaded.\n");
|
die("Payload not loaded.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void payload_run(void)
|
void payload_run(void)
|
||||||
{
|
{
|
||||||
struct payload *payload = &global_payload;
|
struct prog *payload = &global_payload;
|
||||||
|
|
||||||
/* Reset to booting from this image as late as possible */
|
/* Reset to booting from this image as late as possible */
|
||||||
boot_successful();
|
boot_successful();
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n",
|
printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n",
|
||||||
prog_entry(&payload->prog), prog_entry_arg(&payload->prog));
|
prog_entry(payload), prog_entry_arg(payload));
|
||||||
post_code(POST_ENTER_ELF_BOOT);
|
post_code(POST_ENTER_ELF_BOOT);
|
||||||
|
|
||||||
timestamp_add_now(TS_SELFBOOT_JUMP);
|
timestamp_add_now(TS_SELFBOOT_JUMP);
|
||||||
|
@ -99,5 +96,5 @@ void payload_run(void)
|
||||||
*/
|
*/
|
||||||
checkstack(_estack, 0);
|
checkstack(_estack, 0);
|
||||||
|
|
||||||
arch_payload_run(payload);
|
prog_run(payload);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
#include <romstage_handoff.h>
|
#include <romstage_handoff.h>
|
||||||
#include <timestamp.h>
|
#include <timestamp.h>
|
||||||
|
|
||||||
extern const struct ramstage_loader_ops cbfs_ramstage_loader;
|
extern const struct prog_loader_ops cbfs_ramstage_loader;
|
||||||
extern const struct ramstage_loader_ops vboot_ramstage_loader;
|
extern const struct prog_loader_ops vboot_ramstage_loader;
|
||||||
|
|
||||||
static const struct ramstage_loader_ops *loaders[] = {
|
static const struct prog_loader_ops *loaders[] = {
|
||||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||||
&vboot_ramstage_loader,
|
&vboot_ramstage_loader,
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,12 +36,12 @@ static const struct ramstage_loader_ops *loaders[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_ramstage(const struct ramstage_loader_ops *ops,
|
load_ramstage(const struct prog_loader_ops *ops,
|
||||||
struct romstage_handoff *handoff, struct prog *ramstage)
|
struct romstage_handoff *handoff, struct prog *ramstage)
|
||||||
{
|
{
|
||||||
timestamp_add_now(TS_START_COPYRAM);
|
timestamp_add_now(TS_START_COPYRAM);
|
||||||
|
|
||||||
if (ops->load(ramstage))
|
if (ops->prepare(ramstage))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cache_loaded_ramstage(handoff, ramstage);
|
cache_loaded_ramstage(handoff, ramstage);
|
||||||
|
@ -68,7 +68,7 @@ static void run_ramstage_from_resume(struct romstage_handoff *handoff,
|
||||||
void run_ramstage(void)
|
void run_ramstage(void)
|
||||||
{
|
{
|
||||||
struct romstage_handoff *handoff;
|
struct romstage_handoff *handoff;
|
||||||
const struct ramstage_loader_ops *ops;
|
const struct prog_loader_ops *ops;
|
||||||
int i;
|
int i;
|
||||||
struct prog ramstage = {
|
struct prog ramstage = {
|
||||||
.name = CONFIG_CBFS_PREFIX "/ramstage",
|
.name = CONFIG_CBFS_PREFIX "/ramstage",
|
||||||
|
|
|
@ -214,13 +214,13 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
|
||||||
|
|
||||||
static int build_self_segment_list(
|
static int build_self_segment_list(
|
||||||
struct segment *head,
|
struct segment *head,
|
||||||
struct payload *payload, uintptr_t *entry)
|
struct prog *payload, uintptr_t *entry)
|
||||||
{
|
{
|
||||||
struct segment *new;
|
struct segment *new;
|
||||||
struct segment *ptr;
|
struct segment *ptr;
|
||||||
struct cbfs_payload_segment *segment, *first_segment;
|
struct cbfs_payload_segment *segment, *first_segment;
|
||||||
struct cbfs_payload *cbfs_payload;
|
struct cbfs_payload *cbfs_payload;
|
||||||
cbfs_payload = prog_start(&payload->prog);
|
cbfs_payload = prog_start(payload);
|
||||||
memset(head, 0, sizeof(*head));
|
memset(head, 0, sizeof(*head));
|
||||||
head->next = head->prev = head;
|
head->next = head->prev = head;
|
||||||
first_segment = segment = &cbfs_payload->segments;
|
first_segment = segment = &cbfs_payload->segments;
|
||||||
|
@ -311,7 +311,7 @@ static int build_self_segment_list(
|
||||||
|
|
||||||
static int load_self_segments(
|
static int load_self_segments(
|
||||||
struct segment *head,
|
struct segment *head,
|
||||||
struct payload *payload)
|
struct prog *payload)
|
||||||
{
|
{
|
||||||
struct segment *ptr;
|
struct segment *ptr;
|
||||||
struct segment *last_non_empty;
|
struct segment *last_non_empty;
|
||||||
|
@ -365,10 +365,6 @@ static int load_self_segments(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the payload's bounce buffer data used when loading. */
|
|
||||||
payload->bounce.data = (void *)(uintptr_t)bounce_buffer;
|
|
||||||
payload->bounce.size = bounce_size;
|
|
||||||
|
|
||||||
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
||||||
unsigned char *dest, *src;
|
unsigned char *dest, *src;
|
||||||
printk(BIOS_DEBUG, "Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
|
printk(BIOS_DEBUG, "Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
|
||||||
|
@ -454,10 +450,13 @@ static int load_self_segments(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the payload's area with the bounce buffer information. */
|
||||||
|
prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *selfload(struct payload *payload)
|
void *selfload(struct prog *payload)
|
||||||
{
|
{
|
||||||
uintptr_t entry = 0;
|
uintptr_t entry = 0;
|
||||||
struct segment head;
|
struct segment head;
|
||||||
|
|
Loading…
Reference in New Issue