cbfs: look for CBFS header in a predefined place

This patch introduces a new option (CONFIG_MULTIPLE_CBFS_INSTANCES) to
allow multiple CBFS instances in the bootrom.

When the new option is enabled, the code running on the target
controls which CBFS instance is used. Since all other then header CBFS
structures use relative addressing, the only value which needs
explicit setting is the offset of the CBFS header in the bootrom.

This patch adds a facility to set the CBFS header offset. The offset
value of zero means default. i.e. the CBFS initialization code still
discovers the offset through the value saved at the top of the ROM.

BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=with the rest patches in, storm target successfully boots from RW
     section A.

Change-Id: Id8333c9373e61597f0c653c727dcee4ef6a58cd2
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: e57a3a15bba7cdcca4a5d684ed78f8ac6dbbc95e
Original-Change-Id: I4c026389ec4fbaa19bd11b2160202282d2f9283c
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237569
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/9747
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com>
This commit is contained in:
Vadim Bendebury 2014-12-25 15:07:22 -08:00 committed by Patrick Georgi
parent 7271e23ec2
commit 6bfabce33b
5 changed files with 52 additions and 6 deletions

View File

@ -55,6 +55,16 @@ config COMMON_CBFS_SPI_WRAPPER
help help
Use common wrapper to interface CBFS to SPI bootrom. Use common wrapper to interface CBFS to SPI bootrom.
config MULTIPLE_CBFS_INSTANCES
bool "Multiple CBFS instances in the bootrom"
default n
depends on !ARCH_X86
help
Account for the firmware image containing more than one CBFS
instance. Locations of instances are known at build time and are
communicated between coreboot stages to make sure the next stage is
loaded from the appropriate instance.
choice choice
prompt "Compiler to use" prompt "Compiler to use"
default COMPILER_GCC default COMPILER_GCC

View File

@ -84,5 +84,10 @@ void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
*/ */
int init_default_cbfs_media(struct cbfs_media *media); int init_default_cbfs_media(struct cbfs_media *media);
#if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES))
void cbfs_set_header_offset(size_t offset);
#else
static inline void cbfs_set_header_offset(size_t offset) {}
#endif
#endif #endif

View File

@ -102,4 +102,6 @@
. += sz; . += sz;
#endif #endif
#define CBFS_HEADER_OFFSET(addr) REGION(cbfs_header_offset, addr, 4, 4)
#endif /* __MEMLAYOUT_H */ #endif /* __MEMLAYOUT_H */

View File

@ -27,6 +27,7 @@ extern u8 _esram[];
#define _sram_size (_esram - _sram) #define _sram_size (_esram - _sram)
extern u8 _dram[]; extern u8 _dram[];
extern u32 _cbfs_header_offset[];
extern u8 _preram_cbmem_console[]; extern u8 _preram_cbmem_console[];
extern u8 _epreram_cbmem_console[]; extern u8 _epreram_cbmem_console[];

View File

@ -47,6 +47,25 @@
#include <cbfs.h> #include <cbfs.h>
#include <string.h> #include <string.h>
#include <symbols.h>
#if IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)
void cbfs_set_header_offset(size_t offset)
{
_cbfs_header_offset[0] = offset;
LOG("header set to: %#zx\n", offset);
}
static size_t get_header_offset(void)
{
return _cbfs_header_offset[0];
}
#else
static size_t get_header_offset(void)
{
return 0;
}
#endif
#include "cbfs_core.h" #include "cbfs_core.h"
@ -73,13 +92,22 @@ const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
offset = *(int32_t *)(uintptr_t)0xfffffffc; offset = *(int32_t *)(uintptr_t)0xfffffffc;
header = media->map(media, offset, sizeof(*header)); header = media->map(media, offset, sizeof(*header));
} else { } else {
int32_t rel_offset;
if (!media->read(media, &rel_offset, CONFIG_CBFS_SIZE - offset = get_header_offset();
sizeof(int32_t), sizeof(int32_t))) {
ERROR("Could not read CBFS master header offset!\n"); if (!offset) {
return CBFS_HEADER_INVALID_ADDRESS; int32_t rel_offset;
size_t cbfs_top = CONFIG_CBFS_SIZE;
DEBUG("CBFS top at offset: 0x%zx\n", cbfs_top);
if (!media->read(media, &rel_offset, cbfs_top -
sizeof(int32_t),
sizeof(int32_t))) {
ERROR("Could not read master header offset!\n");
media->close(media);
return CBFS_HEADER_INVALID_ADDRESS;
}
offset = cbfs_top + rel_offset;
} }
offset = CONFIG_CBFS_SIZE + rel_offset;
header = media->map(media, offset, sizeof(*header)); header = media->map(media, offset, sizeof(*header));
} }
DEBUG("CBFS header offset: 0x%zx/0x%x\n", offset, CONFIG_ROM_SIZE); DEBUG("CBFS header offset: 0x%zx/0x%x\n", offset, CONFIG_ROM_SIZE);