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>
This commit is contained in:
parent
a79e01bf71
commit
2d90ddd2d2
|
@ -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);
|
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. */
|
/* 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,
|
int region_file_update_data_arr(struct region_file *f,
|
||||||
size_t size);
|
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. */
|
/* Declared here for easy object allocation. */
|
||||||
struct region_file {
|
struct region_file {
|
||||||
|
|
|
@ -365,12 +365,16 @@ static int commit_data_allocation(struct region_file *f, size_t data_blks)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int commit_data(const struct region_file *f, const void *buf,
|
static int commit_data(const struct region_file *f,
|
||||||
size_t size)
|
const struct update_region_file_entry *entries,
|
||||||
|
size_t num_entries)
|
||||||
{
|
{
|
||||||
size_t offset = block_to_bytes(region_file_data_begin(f));
|
size_t offset = block_to_bytes(region_file_data_begin(f));
|
||||||
if (rdev_writeat(&f->rdev, buf, offset, size) < 0)
|
for (int i = 0; i < num_entries; i++) {
|
||||||
return -1;
|
if (rdev_writeat(&f->rdev, entries[i].data, offset, entries[i].size) < 0)
|
||||||
|
return -1;
|
||||||
|
offset += entries[i].size;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +403,9 @@ static int handle_need_to_empty(struct region_file *f)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_update(struct region_file *f, size_t blocks, const void *buf,
|
static int handle_update(struct region_file *f, size_t blocks,
|
||||||
size_t size)
|
const struct update_region_file_entry *entries,
|
||||||
|
size_t num_entries)
|
||||||
{
|
{
|
||||||
if (!update_can_fit(f, blocks)) {
|
if (!update_can_fit(f, blocks)) {
|
||||||
printk(BIOS_INFO, "REGF update can't fit. Will empty.\n");
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit_data(f, buf, size)) {
|
if (commit_data(f, entries, num_entries)) {
|
||||||
printk(BIOS_ERR, "REGF failed to commit data.\n");
|
printk(BIOS_ERR, "REGF failed to commit data.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -421,11 +426,16 @@ static int handle_update(struct region_file *f, size_t blocks, const void *buf,
|
||||||
return 0;
|
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;
|
int ret;
|
||||||
size_t blocks;
|
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));
|
blocks = bytes_to_block(ALIGN_UP(size, REGF_BLOCK_GRANULARITY));
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -442,7 +452,7 @@ int region_file_update_data(struct region_file *f, const void *buf, size_t size)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = handle_update(f, blocks, buf, size);
|
ret = handle_update(f, blocks, entries, num_entries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,3 +469,12 @@ int region_file_update_data(struct region_file *f, const void *buf, size_t size)
|
||||||
|
|
||||||
return ret;
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue