[coreboot-gerrit] Patch set updated for coreboot: d39857f vboot2: load decompressed stage directly to load address
Aaron Durbin (adurbin@google.com)
gerrit at coreboot.org
Mon Mar 23 23:22:39 CET 2015
Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8883
-gerrit
commit d39857fe67f1a6997c99525e007a9a6033cbf0a8
Author: Daisuke Nojiri <dnojiri at chromium.org>
Date: Fri Sep 19 09:56:15 2014 -0700
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 at chromium.org>
Original-Change-Id: I76530276ff9a87b44f98a33f2c34bd5b2de6888f
Original-Reviewed-on: https://chromium-review.googlesource.com/219028
Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
Original-Commit-Queue: Daisuke Nojiri <dnojiri at chromium.org>
Original-Tested-by: Daisuke Nojiri <dnojiri at chromium.org>
(cherry picked from commit 0ad6f7fee9df31e1b35d4df9a8c373516416a235)
Change-Id: I7abdbdda0cc549894dfb9d599a576bba0a4fadfc
Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
src/include/cbfs.h | 1 +
src/lib/cbfs.c | 75 +++++++++++++++++++------------
src/vendorcode/google/chromeos/chromeos.c | 31 +++++--------
3 files changed, 57 insertions(+), 50 deletions(-)
diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index 5297230..9aa2c96 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -55,6 +55,7 @@
void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
uint16_t device, void * 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);
/* Simple buffer for streaming media. */
struct cbfs_simple_buffer {
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 9e9f4a7..a137aa8 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -73,41 +73,58 @@ 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");
+
+ return (void *)(uintptr_t)stage.entry;
+}
+
+void *cbfs_load_stage(struct cbfs_media *media, const char *name)
+{
+ struct cbfs_media default_media;
+ struct cbfs_file file;
+ ssize_t offset;
- DEBUG("stage loaded.\n");
+ init_media(&media, &default_media);
- 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 */
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index bd72e77..5696aec 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -222,9 +222,10 @@ void *vboot_load_stage(int stage_index,
struct vboot_region *fw_main,
struct vboot_components *fw_info)
{
- struct cbfs_stage *stage;
+ struct cbfs_media default_media, *media = &default_media;
uintptr_t fc_addr;
uint32_t fc_size;
+ void *entry;
if (stage_index >= fw_info->num_components) {
printk(BIOS_INFO, "invalid stage index\n");
@@ -239,27 +240,15 @@ void *vboot_load_stage(int stage_index,
return NULL;
}
- /* Loading to cbfs cache. This stage data must be retained until it's
- * decompressed. */
- stage = vboot_get_region(fc_addr, fc_size, NULL);
+ init_default_cbfs_media(media);
- if (stage == NULL) {
- printk(BIOS_INFO, "failed to load a stage\n");
- return NULL;
- }
-
- /* Stages rely the below clearing so that the bss is initialized. */
- memset((void *) (uintptr_t)stage->load, 0, stage->memlen);
-
- if (cbfs_decompress(stage->compression,
- (unsigned char *)stage + sizeof(*stage),
- (void *) (uintptr_t) stage->load,
- stage->len)) {
- printk(BIOS_INFO, "failed to decompress a stage\n");
- return NULL;
- }
-
- return (void *)(uintptr_t)stage->entry;
+ /* we're making cbfs access offset outside of the region managed by
+ * cbfs. this works because cbfs_load_stage_by_offset does not check
+ * the offset. */
+ entry = cbfs_load_stage_by_offset(media, fc_addr);
+ if (entry == (void *)-1)
+ entry = NULL;
+ return entry;
}
struct vb2_working_data * const vboot_get_working_data(void)
More information about the coreboot-gerrit
mailing list