summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShelley Chen <shchen@google.com>2020-09-15 00:41:14 -0700
committerShelley Chen <shchen@google.com>2020-09-16 16:02:54 +0000
commit2d90ddd2d226fbc593c7741eae2160d02ff98431 (patch)
tree9255591b621fe8d3b76dfc5b8c71712ba1ad30d8
parenta79e01bf7167ae6bfc8435341bab87e590789ae9 (diff)
downloadcoreboot-2d90ddd2d226fbc593c7741eae2160d02ff98431.tar.xz
region_file_update_data_arr: Modify region_file with array of buffers
Add region_file_update_data_arr, which has the same functionality as region_file_update_data, but accepts 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> Reviewed-on: https://review.coreboot.org/c/coreboot/+/45407 Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/include/region_file.h17
-rw-r--r--src/lib/region_file.c37
2 files changed, 43 insertions, 11 deletions
diff --git a/src/include/region_file.h b/src/include/region_file.h
index 063e0e0235..a3cb79d044 100644
--- a/src/include/region_file.h
+++ b/src/include/region_file.h
@@ -31,9 +31,22 @@ int region_file_init(struct region_file *f, const struct region_device *p);
*/
int region_file_data(const struct region_file *f, struct region_device *rdev);
+/*
+ * Create region file entry struct to insert multiple data buffers
+ * into the same region_file.
+ */
+struct update_region_file_entry {
+ /* size of this entry */
+ size_t 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_arr(struct region_file *f,
+ const struct update_region_file_entry *entries,
+ size_t num_entries);
+int region_file_update_data(struct region_file *f, const void *buf, size_t size);
/* Declared here for easy object allocation. */
struct region_file {
diff --git a/src/lib/region_file.c b/src/lib/region_file.c
index ce2ed30f7a..4fe91b62bf 100644
--- a/src/lib/region_file.c
+++ b/src/lib/region_file.c
@@ -365,12 +365,16 @@ static int commit_data_allocation(struct region_file *f, size_t data_blks)
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,
+ const 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 @@ static int handle_need_to_empty(struct region_file *f)
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,
+ const 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 @@ static int handle_update(struct region_file *f, size_t blocks, const void *buf,
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 @@ static int handle_update(struct region_file *f, size_t blocks, const void *buf,
return 0;
}
-int region_file_update_data(struct region_file *f, const void *buf, size_t size)
+int region_file_update_data_arr(struct region_file *f,
+ const 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 @@ int region_file_update_data(struct region_file *f, const void *buf, size_t size)
ret = -1;
break;
default:
- ret = handle_update(f, blocks, buf, size);
+ ret = handle_update(f, blocks, entries, num_entries);
break;
}
@@ -459,3 +469,12 @@ int region_file_update_data(struct region_file *f, const void *buf, size_t size)
return ret;
}
+
+int region_file_update_data(struct region_file *f, const void *buf, size_t size)
+{
+ struct update_region_file_entry entry = {
+ .size = size,
+ .data = buf,
+ };
+ return region_file_update_data_arr(f, &entry, 1);
+}