cbfs: don't load x86 programs over the top of read-only media

On x86 the early stages are currently execute-in-place which
means they live in the memory-mapped spi flash. However, when
loading romstage from verstage the romstage is
execute-in-place so it's unnecessary to write over a read-only
media -- not to mention writing to read-only memory is wrong
to begin with.

BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built and booted glados. Noted reduction of 20ms when
     loading romstage.

Change-Id: I7cd399302a3925a05fbce82600b4c50ea66a0fcb
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11823
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2015-10-07 17:22:42 -05:00 committed by Aaron Durbin
parent fb9e378f2d
commit ed253c8fd8
1 changed files with 12 additions and 0 deletions

View File

@ -220,6 +220,16 @@ int cbfs_prog_stage_load(struct prog *pstage)
load = (void *)(uintptr_t)stage.load; load = (void *)(uintptr_t)stage.load;
entry = (void *)(uintptr_t)stage.entry; entry = (void *)(uintptr_t)stage.entry;
/* Hacky way to not load programs over read only media. The stages
* that would hit this path initialize themselves. */
if (ENV_VERSTAGE && IS_ENABLED(CONFIG_ARCH_X86) &&
IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
void *mapping = rdev_mmap(fh, foffset, fsize);
rdev_munmap(fh, mapping);
if (mapping == load)
goto out;
}
if (stage.compression == CBFS_COMPRESS_NONE) { if (stage.compression == CBFS_COMPRESS_NONE) {
if (rdev_readat(fh, load, foffset, fsize) != fsize) if (rdev_readat(fh, load, foffset, fsize) != fsize)
return -1; return -1;
@ -242,6 +252,8 @@ int cbfs_prog_stage_load(struct prog *pstage)
memset(&load[fsize], 0, stage.memlen - fsize); memset(&load[fsize], 0, stage.memlen - fsize);
arch_segment_loaded((uintptr_t)load, stage.memlen, SEG_FINAL); arch_segment_loaded((uintptr_t)load, stage.memlen, SEG_FINAL);
out:
prog_set_area(pstage, load, stage.memlen); prog_set_area(pstage, load, stage.memlen);
prog_set_entry(pstage, entry, NULL); prog_set_entry(pstage, entry, NULL);