diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2014-09-19 09:56:15 -0700 |
---|---|---|
committer | Aaron Durbin <adurbin@google.com> | 2015-03-24 15:19:21 +0100 |
commit | 35890170b56941a155635d57b9ee693e5f690311 (patch) | |
tree | a4726d08c3aafcb85527a10779536df5abd09956 /src/lib | |
parent | 1bbac3fd248ad7c91511d12c74b61c239ba3aa9f (diff) | |
download | coreboot-35890170b56941a155635d57b9ee693e5f690311.tar.xz |
vboot2: load decompressed stage directly to load address
this change allows vboot_load_stage to load a decompressed stage directly to the
load address without using the cbfs cache.
BUG=None
TEST=Booted Nyan Blaze.
BRANCH=None
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Original-Change-Id: I76530276ff9a87b44f98a33f2c34bd5b2de6888f
Original-Reviewed-on: https://chromium-review.googlesource.com/219028
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Original-Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org>
Original-Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
(cherry picked from commit 0ad6f7fee9df31e1b35d4df9a8c373516416a235)
Change-Id: I7abdbdda0cc549894dfb9d599a576bba0a4fadfc
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/8883
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/cbfs.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 9e9f4a7bf8..54d159fc86 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -73,41 +73,55 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor, return dest; } -void * cbfs_load_stage(struct cbfs_media *media, const char *name) +void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset) { - struct cbfs_stage *stage = (struct cbfs_stage *) - cbfs_get_file_content(media, name, CBFS_TYPE_STAGE, NULL); - /* this is a mess. There is no ntohll. */ - /* for now, assume compatible byte order until we solve this. */ - uintptr_t entry; - uint32_t final_size; - - if (stage == NULL) - return (void *) -1; - - LOG("loading stage %s @ 0x%llx (%d bytes), entry @ 0x%llx\n", - name, - stage->load, stage->memlen, - stage->entry); - - final_size = cbfs_decompress(stage->compression, - ((unsigned char *) stage) + - sizeof(struct cbfs_stage), - (void *) (uintptr_t) stage->load, - stage->len); - if (!final_size) - return (void *) -1; + struct cbfs_stage stage; + + if (cbfs_read(media, &stage, offset, sizeof(stage)) != sizeof(stage)) { + ERROR("ERROR: failed to read stage header\n"); + return (void *)-1; + } + + LOG("loading stage @ 0x%llx (%d bytes), entry @ 0x%llx\n", + stage.load, stage.memlen, stage.entry); /* Stages rely the below clearing so that the bss is initialized. */ - memset((void *)((uintptr_t)stage->load + final_size), 0, - stage->memlen - final_size); + memset((void *)(uintptr_t)stage.load, 0, stage.memlen); + + if (stage.compression == CBFS_COMPRESS_NONE) { + 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; + } + } 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; + } + if (!cbfs_decompress(stage.compression, data, + (void *)(uintptr_t)stage.load, stage.len)) + return (void *)-1; + media->unmap(media, data); + } - DEBUG("stage loaded.\n"); + DEBUG("stage loaded\n"); + + return (void *)(uintptr_t)stage.entry; +} + +void *cbfs_load_stage(struct cbfs_media *media, const char *name) +{ + struct cbfs_file file; + ssize_t offset; - entry = stage->entry; - // entry = ntohll(stage->entry); + offset = cbfs_locate_file(media, &file, name); + if (offset < 0 || file.type != CBFS_TYPE_STAGE) + return (void *)-1; - return (void *) entry; + return cbfs_load_stage_by_offset(media, offset); } /* Simple buffer */ |