mrc_cache: add version field
In order to allow for updateable memory init code on intel x86 platforms one needs to ensure the saved mrc data matches the code consuming the data. To that end add a version field to the saved data structure. BUG=chrome-os-partner:46050 BRANCH=None TEST=Built and booted on glados. Suspended and resumed. Also verified version mismatch path. Change-Id: Ie86db1750af5d9bff6446999b0d04b60612f8d29 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/12700 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
a606598150
commit
bc6e7c0905
|
@ -93,9 +93,6 @@ static int mrc_cache_valid(const struct mrc_data_region *region,
|
||||||
if (cache->size > region->size)
|
if (cache->size > region->size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (cache->reserved != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
checksum = compute_ip_checksum((void *)&cache->data[0], cache->size);
|
checksum = compute_ip_checksum((void *)&cache->data[0], cache->size);
|
||||||
|
|
||||||
if (cache->checksum != checksum)
|
if (cache->checksum != checksum)
|
||||||
|
@ -116,7 +113,8 @@ next_cache_block(const struct mrc_saved_data *cache)
|
||||||
|
|
||||||
/* Locate the most recently saved MRC data. */
|
/* Locate the most recently saved MRC data. */
|
||||||
static int __mrc_cache_get_current(const struct mrc_data_region *region,
|
static int __mrc_cache_get_current(const struct mrc_data_region *region,
|
||||||
const struct mrc_saved_data **cache)
|
const struct mrc_saved_data **cache,
|
||||||
|
uint32_t version)
|
||||||
{
|
{
|
||||||
const struct mrc_saved_data *msd;
|
const struct mrc_saved_data *msd;
|
||||||
const struct mrc_saved_data *verified_cache;
|
const struct mrc_saved_data *verified_cache;
|
||||||
|
@ -136,35 +134,47 @@ static int __mrc_cache_get_current(const struct mrc_data_region *region,
|
||||||
if (verified_cache == NULL)
|
if (verified_cache == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (verified_cache->version != version) {
|
||||||
|
printk(BIOS_DEBUG, "MRC cache version mismatch: %x vs %x\n",
|
||||||
|
verified_cache->version, version);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
*cache = verified_cache;
|
*cache = verified_cache;
|
||||||
printk(BIOS_DEBUG, "MRC cache slot %d @ %p\n", slot-1, verified_cache);
|
printk(BIOS_DEBUG, "MRC cache slot %d @ %p\n", slot-1, verified_cache);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mrc_cache_get_current(const struct mrc_saved_data **cache)
|
int mrc_cache_get_current_with_version(const struct mrc_saved_data **cache,
|
||||||
|
uint32_t version)
|
||||||
{
|
{
|
||||||
struct mrc_data_region region;
|
struct mrc_data_region region;
|
||||||
|
|
||||||
if (mrc_cache_get_region(®ion) < 0)
|
if (mrc_cache_get_region(®ion) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return __mrc_cache_get_current(®ion, cache);
|
return __mrc_cache_get_current(®ion, cache, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mrc_cache_get_current(const struct mrc_saved_data **cache)
|
||||||
|
{
|
||||||
|
return mrc_cache_get_current_with_version(cache, 0);
|
||||||
|
}
|
||||||
/* Fill in mrc_saved_data structure with payload. */
|
/* Fill in mrc_saved_data structure with payload. */
|
||||||
static void mrc_cache_fill(struct mrc_saved_data *cache, void *data,
|
static void mrc_cache_fill(struct mrc_saved_data *cache, void *data,
|
||||||
size_t size)
|
size_t size, uint32_t version)
|
||||||
{
|
{
|
||||||
cache->signature = MRC_DATA_SIGNATURE;
|
cache->signature = MRC_DATA_SIGNATURE;
|
||||||
cache->size = size;
|
cache->size = size;
|
||||||
cache->reserved = 0;
|
cache->version = version;
|
||||||
memcpy(&cache->data[0], data, size);
|
memcpy(&cache->data[0], data, size);
|
||||||
cache->checksum = compute_ip_checksum((void *)&cache->data[0],
|
cache->checksum = compute_ip_checksum((void *)&cache->data[0],
|
||||||
cache->size);
|
cache->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mrc_cache_stash_data(void *data, size_t size)
|
int mrc_cache_stash_data_with_version(void *data, size_t size,
|
||||||
|
uint32_t version)
|
||||||
{
|
{
|
||||||
int cbmem_size;
|
int cbmem_size;
|
||||||
struct mrc_saved_data *cache;
|
struct mrc_saved_data *cache;
|
||||||
|
@ -184,11 +194,16 @@ int mrc_cache_stash_data(void *data, size_t size)
|
||||||
printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n",
|
printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n",
|
||||||
data, cache, size);
|
data, cache, size);
|
||||||
|
|
||||||
mrc_cache_fill(cache, data, size);
|
mrc_cache_fill(cache, data, size, version);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mrc_cache_stash_data(void *data, size_t size)
|
||||||
|
{
|
||||||
|
return mrc_cache_stash_data_with_version(data, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int mrc_slot_valid(const struct mrc_data_region *region,
|
static int mrc_slot_valid(const struct mrc_data_region *region,
|
||||||
const struct mrc_saved_data *slot,
|
const struct mrc_saved_data *slot,
|
||||||
const struct mrc_saved_data *to_save)
|
const struct mrc_saved_data *to_save)
|
||||||
|
@ -281,7 +296,8 @@ static void update_mrc_cache(void *unused)
|
||||||
|
|
||||||
current_saved = NULL;
|
current_saved = NULL;
|
||||||
|
|
||||||
if (!__mrc_cache_get_current(®ion, ¤t_saved)) {
|
if (!__mrc_cache_get_current(®ion, ¤t_saved,
|
||||||
|
current_boot->version)) {
|
||||||
if (current_saved->size == current_boot->size &&
|
if (current_saved->size == current_boot->size &&
|
||||||
!memcmp(¤t_saved->data[0], ¤t_boot->data[0],
|
!memcmp(¤t_saved->data[0], ¤t_boot->data[0],
|
||||||
current_saved->size)) {
|
current_saved->size)) {
|
||||||
|
|
|
@ -24,14 +24,18 @@ struct mrc_saved_data {
|
||||||
uint32_t signature;
|
uint32_t signature;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
uint32_t reserved;
|
uint32_t version;
|
||||||
uint8_t data[0];
|
uint8_t data[0];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/* Locate the most recently saved MRC data. */
|
/* Locate the most recently saved MRC data. */
|
||||||
int mrc_cache_get_current(const struct mrc_saved_data **cache);
|
int mrc_cache_get_current(const struct mrc_saved_data **cache);
|
||||||
|
int mrc_cache_get_current_with_version(const struct mrc_saved_data **cache,
|
||||||
|
uint32_t version);
|
||||||
|
|
||||||
/* Stash the resulting MRC data to be saved in non-volatile storage later. */
|
/* Stash the resulting MRC data to be saved in non-volatile storage later. */
|
||||||
int mrc_cache_stash_data(void *data, size_t size);
|
int mrc_cache_stash_data(void *data, size_t size);
|
||||||
|
int mrc_cache_stash_data_with_version(void *data, size_t size,
|
||||||
|
uint32_t version);
|
||||||
|
|
||||||
#endif /* _COMMON_MRC_CACHE_H_ */
|
#endif /* _COMMON_MRC_CACHE_H_ */
|
||||||
|
|
Loading…
Reference in New Issue