[coreboot-gerrit] New patch to review for coreboot: 843f7e9 lib/cbfs: Copy stage header to stack before decompressing stage
Alexandru Gagniuc (mr.nuke.me@gmail.com)
gerrit at coreboot.org
Fri Dec 27 22:34:37 CET 2013
Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4579
-gerrit
commit 843f7e9e2d7246638b6f4f577fede101e9f89faf
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date: Fri Dec 27 16:13:04 2013 -0500
lib/cbfs: Copy stage header to stack before decompressing stage
On SoCs with limited amount of SRAM, we have to cache the romstage in
the same memory block in which it will be used. The header of the
stage is within this cached region, and risks being overwritten by
cbfs_decompress() when called from cbfs_load_stage(). In order to
ensure that the header does not get overwritten, copy it to the stack
and use the information in the stack.
This is especially useful in the bootblock on lower-end ARM SoCs,
which do not have enough SRAM to hold the bootblock, stack, romstage
and the CBFS cache.
Change-Id: Ibb7f769645b02377745d568fe539919f83da8d68
Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
src/lib/cbfs.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 1f44695..bfed6a4 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -256,36 +256,44 @@ void * cbfs_load_stage(struct cbfs_media *media, const char *name)
void * cbfs_load_stage(struct cbfs_media *media, const char *name)
{
- struct cbfs_stage *stage = (struct cbfs_stage *)
+ struct cbfs_stage stage;
+ struct cbfs_stage *mm_stage = (struct cbfs_stage *)
cbfs_get_file_content(media, name, CBFS_TYPE_STAGE);
/* this is a mess. There is no ntohll. */
/* for now, assume compatible byte order until we solve this. */
uint32_t entry;
uint32_t final_size;
- if (stage == NULL)
+ if (mm_stage == NULL)
return (void *) -1;
+ /* Copy the stage header to the stack. On ARM SoCs, the memory region
+ * returned by cbfs_get_file_content() may be in the CBFS cache, and if
+ * the stage is to be copied to the same region, the header can be
+ * overwritten by cbfs_decompress().
+ */
+ memcpy(&stage, mm_stage, sizeof(stage));
+
LOG("loading stage %s @ 0x%x (%d bytes), entry @ 0x%llx\n",
name,
- (uint32_t) stage->load, stage->memlen,
- stage->entry);
+ (uint32_t) stage.load, stage.memlen,
+ stage.entry);
- final_size = cbfs_decompress(stage->compression,
- ((unsigned char *) stage) +
+ final_size = cbfs_decompress(stage.compression,
+ ((unsigned char *) mm_stage) +
sizeof(struct cbfs_stage),
- (void *) (uint32_t) stage->load,
- stage->len);
+ (void *) (uint32_t) stage.load,
+ stage.len);
if (!final_size)
return (void *) -1;
/* 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 + final_size), 0,
+ stage.memlen - final_size);
DEBUG("stage loaded.\n");
- entry = stage->entry;
+ entry = stage.entry;
// entry = ntohll(stage->entry);
return (void *) entry;
More information about the coreboot-gerrit
mailing list