aboutsummaryrefslogtreecommitdiff
path: root/src/lib/cbfs.c
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2015-03-20 13:00:20 -0500
committerAaron Durbin <adurbin@google.com>2015-04-03 14:51:51 +0200
commit3948e5392bbfd685e6e2f9abfb16c46a2eae18b9 (patch)
tree480a94bff1f7c2587dfc5943d45dfc8c66ec971b /src/lib/cbfs.c
parent3b631615f6c382965e239704b1f417c6a67b6730 (diff)
program loading: introduce struct prog
The struct prog serves as way to consolidate program loading. This abstraction can be used to perform more complicated execution paths such as running a program on a separate CPU after it has been loaded. Currently t124 and t132 need to do that in the boot path. Follow on patches will allow the platform to decide how to execute a particular program. Note: the vboot path is largely untouched because it's already broken in the coreboot.org tree. After getting all the necessary patches pushed then vboot will be fixed. Change-Id: Ic6e6fe28c5660fb41edee5fd8661eaf58222f883 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/8839 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Reviewed-by: Marc Jones <marc.jones@se-eng.com>
Diffstat (limited to 'src/lib/cbfs.c')
-rw-r--r--src/lib/cbfs.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index ebcc134044..fc6e88721e 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -74,17 +74,18 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
return dest;
}
-void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset)
+static int cbfs_load_prog_stage_by_offset(struct cbfs_media *media,
+ struct prog *prog, ssize_t offset)
{
struct cbfs_stage stage;
struct cbfs_media backing_store;
if (init_backing_media(&media, &backing_store))
- return (void *)-1;
+ return -1;
if (cbfs_read(media, &stage, offset, sizeof(stage)) != sizeof(stage)) {
ERROR("ERROR: failed to read stage header\n");
- return (void *)-1;
+ return -1;
}
LOG("loading stage @ 0x%llx (%d bytes), entry @ 0x%llx\n",
@@ -97,41 +98,71 @@ void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset)
if (cbfs_read(media, (void *)(uintptr_t)stage.load,
offset + sizeof(stage), stage.len) != stage.len) {
ERROR("ERROR: Reading stage failed.\n");
- return (void *)-1;
+ return -1;
}
} else {
void *data = media->map(media, offset + sizeof(stage),
stage.len);
if (data == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
ERROR("ERROR: Mapping stage failed.\n");
- return (void *)-1;
+ return -1;
}
if (!cbfs_decompress(stage.compression, data,
(void *)(uintptr_t)stage.load, stage.len))
- return (void *)-1;
+ return -1;
media->unmap(media, data);
}
arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL);
DEBUG("stage loaded\n");
- return (void *)(uintptr_t)stage.entry;
+ prog_set_area(prog, (void *)(uintptr_t)stage.load, stage.memlen);
+ prog_set_entry(prog, (void *)(uintptr_t)stage.entry, NULL);
+
+ return 0;
}
-void *cbfs_load_stage(struct cbfs_media *media, const char *name)
+int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog)
{
struct cbfs_file file;
ssize_t offset;
struct cbfs_media backing_store;
if (init_backing_media(&media, &backing_store))
- return (void *)-1;
+ return -1;
- offset = cbfs_locate_file(media, &file, name);
+ offset = cbfs_locate_file(media, &file, prog->name);
if (offset < 0 || file.type != CBFS_TYPE_STAGE)
+ return -1;
+
+ if (cbfs_load_prog_stage_by_offset(media, prog, offset) < 0)
+ return -1;
+
+ return 0;
+}
+
+void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset)
+{
+ struct prog prog = {
+ .name = NULL,
+ };
+
+ if (cbfs_load_prog_stage_by_offset(media, &prog, offset) < 0)
+ return (void *)-1;
+
+ return prog_entry(&prog);
+}
+
+void *cbfs_load_stage(struct cbfs_media *media, const char *name)
+{
+ struct prog prog = {
+ .name = name,
+ };
+
+ if (cbfs_load_prog_stage(media, &prog) < 0)
return (void *)-1;
- return cbfs_load_stage_by_offset(media, offset);
+ return prog_entry(&prog);
}
/* Simple buffer */