Shelley Chen has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/45407 )
Change subject: region_file_update_data: Change API to accept array of structs ......................................................................
region_file_update_data: Change API to accept array of structs
Updating region_file_update_data to accept mutliple data buffers. This is useful for when we have the mrc_metadata and data in non-contiguous addresses, which is the case when we bypass the storing of mrc_cache data into the cbmem.
BUG=b:150502246 BRANCH=None TEST=reboot from ec console. Make sure memory training happens. reboot from ec console. Make sure that we don't do training again.
Change-Id: Ia530f7d428b9b07ce3a73e348016038d9daf4c15 Signed-off-by: Shelley Chen shchen@google.com --- M src/drivers/mrc_cache/mrc_cache.c M src/include/region_file.h M src/lib/region_file.c 3 files changed, 47 insertions(+), 15 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/07/45407/1
diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c index 0e42120..4cfd921 100644 --- a/src/drivers/mrc_cache/mrc_cache.c +++ b/src/drivers/mrc_cache/mrc_cache.c @@ -419,9 +419,13 @@
printk(BIOS_DEBUG, "MRC: cache data '%s' needs update.\n", cr->name);
- if (region_file_update_data(&cache_file, - cbmem_entry_start(to_be_updated), - cbmem_entry_size(to_be_updated)) < 0) { + struct update_region_file_entry entries[1]; + struct update_region_file_entry cbmem_entry = { + .size = cbmem_entry_size(to_be_updated), + .data = cbmem_entry_start(to_be_updated), + }; + entries[0] = cbmem_entry; + if (region_file_update_data(&cache_file, entries, 1) < 0) { printk(BIOS_DEBUG, "MRC: failed to update '%s'.\n", cr->name); log_event_cache_update(cr->elog_slot, UPDATE_FAILURE); } else { @@ -544,7 +548,13 @@
/* Push an update that consists of 4 bytes that is smaller than the * MRC metadata as well as an invalid signature. */ - if (region_file_update_data(&cache_file, &invalid, sizeof(invalid)) < 0) + struct update_region_file_entry entries[1]; + struct update_region_file_entry invalid_entry = { + .size = sizeof(invalid), + .data = &invalid, + }; + entries[0] = invalid_entry; + if (region_file_update_data(&cache_file, entries, 1) < 0) printk(BIOS_ERR, "MRC: invalidation failed for '%s'.\n", name); }
diff --git a/src/include/region_file.h b/src/include/region_file.h index 063e0e0..b5767d8 100644 --- a/src/include/region_file.h +++ b/src/include/region_file.h @@ -31,9 +31,21 @@ */ int region_file_data(const struct region_file *f, struct region_device *rdev);
+/** + * Creating region file entry struct to insert multiple data buffers + * into the same region_file. + */ +struct update_region_file_entry { + /* size of this entry */ + int size; + /* data pointer */ + const void *data; +}; + /* Update region file with latest data. Returns < 0 on error, 0 on success. */ -int region_file_update_data(struct region_file *f, const void *buf, - size_t size); +int region_file_update_data(struct region_file *f, + struct update_region_file_entry *entries, + size_t num_entries);
/* Declared here for easy object allocation. */ struct region_file { diff --git a/src/lib/region_file.c b/src/lib/region_file.c index ce2ed30..8fce3f9 100644 --- a/src/lib/region_file.c +++ b/src/lib/region_file.c @@ -365,12 +365,16 @@ return 0; }
-static int commit_data(const struct region_file *f, const void *buf, - size_t size) +static int commit_data(const struct region_file *f, + struct update_region_file_entry *entries, + size_t num_entries) { size_t offset = block_to_bytes(region_file_data_begin(f)); - if (rdev_writeat(&f->rdev, buf, offset, size) < 0) - return -1; + for (int i = 0; i < num_entries; i++) { + if (rdev_writeat(&f->rdev, entries[i].data, offset, entries[i].size) < 0) + return -1; + offset += entries[i].size; + } return 0; }
@@ -399,8 +403,9 @@ return 0; }
-static int handle_update(struct region_file *f, size_t blocks, const void *buf, - size_t size) +static int handle_update(struct region_file *f, size_t blocks, + struct update_region_file_entry *entries, + size_t num_entries) { if (!update_can_fit(f, blocks)) { printk(BIOS_INFO, "REGF update can't fit. Will empty.\n"); @@ -413,7 +418,7 @@ return -1; }
- if (commit_data(f, buf, size)) { + if (commit_data(f, entries, num_entries)) { printk(BIOS_ERR, "REGF failed to commit data.\n"); return -1; } @@ -421,11 +426,16 @@ return 0; }
-int region_file_update_data(struct region_file *f, const void *buf, size_t size) +int region_file_update_data(struct region_file *f, + struct update_region_file_entry *entries, + size_t num_entries) { int ret; size_t blocks; + size_t size = 0;
+ for (int i = 0; i < num_entries; i++) + size += entries[i].size; blocks = bytes_to_block(ALIGN_UP(size, REGF_BLOCK_GRANULARITY));
while (1) { @@ -442,7 +452,7 @@ ret = -1; break; default: - ret = handle_update(f, blocks, buf, size); + ret = handle_update(f, blocks, entries, num_entries); break; }