drivers/vpd: Search VPD info at 0x0 first
We used to put SMBIOS header and other data before VPD. That is not the case anymore. New device will write the VPD starting at 0 instead of 0x600. Search VPD at 0x0 to support this. TEST=build and boot google/geralt. VPD is found both at 0 and at 0x600. Change-Id: I7072f7c646b6b55d11bc06dba5674828246fa1d0 Signed-off-by: Jian-Jia Su <jjsu@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/88466 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
a56a97d167
commit
cf2978f4b6
1 changed files with 23 additions and 26 deletions
|
|
@ -43,6 +43,8 @@ static struct region_device ro_vpd, rw_vpd;
|
|||
/*
|
||||
* Initializes a region_device to represent the requested VPD 2.0 formatted
|
||||
* region on flash. On errors rdev->size will be set to 0.
|
||||
* Check google_vpd_info at offset 0 first. If not found, fall back to
|
||||
* GOOGLE_VPD_2_0_OFFSET.
|
||||
*/
|
||||
static void init_vpd_rdev(const char *fmap_name, struct region_device *rdev)
|
||||
{
|
||||
|
|
@ -57,36 +59,31 @@ static void init_vpd_rdev(const char *fmap_name, struct region_device *rdev)
|
|||
|
||||
size = region_device_sz(rdev);
|
||||
|
||||
if ((size < GOOGLE_VPD_2_0_OFFSET + sizeof(info)) ||
|
||||
rdev_chain(rdev, rdev, GOOGLE_VPD_2_0_OFFSET,
|
||||
size - GOOGLE_VPD_2_0_OFFSET)) {
|
||||
printk(BIOS_ERR, "%s: Too small (%d) for Google VPD 2.0.\n",
|
||||
__func__, size);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Try if we can find a google_vpd_info, otherwise read whole VPD. */
|
||||
if (rdev_readat(rdev, &info, 0, sizeof(info)) != sizeof(info)) {
|
||||
printk(BIOS_ERR, "Failed to read %s header.\n",
|
||||
fmap_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (memcmp(info.header.magic, VPD_INFO_MAGIC, sizeof(info.header.magic))
|
||||
== 0) {
|
||||
if (rdev_chain(rdev, rdev, sizeof(info), info.size)) {
|
||||
printk(BIOS_ERR, "%s info size too large.\n",
|
||||
size_t possible_offsets[] = {0x0, GOOGLE_VPD_2_0_OFFSET};
|
||||
for (int i = 0; i < ARRAY_SIZE(possible_offsets); i++) {
|
||||
size_t offset = possible_offsets[i];
|
||||
if (size < offset + sizeof(info)) {
|
||||
printk(BIOS_ERR,
|
||||
"%s: Too small (%d) for Google VPD 2.0.\n",
|
||||
__func__, size);
|
||||
goto fail;
|
||||
}
|
||||
if (rdev_readat(rdev, &info, offset, sizeof(info)) != sizeof(info)) {
|
||||
printk(BIOS_ERR, "Failed to read %s header.\n",
|
||||
fmap_name);
|
||||
goto fail;
|
||||
}
|
||||
} else if (info.header.tlv.type == VPD_TYPE_TERMINATOR ||
|
||||
info.header.tlv.type == VPD_TYPE_IMPLICIT_TERMINATOR) {
|
||||
printk(BIOS_WARNING, "%s is uninitialized or empty.\n",
|
||||
fmap_name);
|
||||
goto fail;
|
||||
if (memcmp(info.header.magic, VPD_INFO_MAGIC, sizeof(info.header.magic)) == 0) {
|
||||
if (rdev_chain(rdev, rdev, offset + sizeof(info), info.size) == 0) {
|
||||
return;
|
||||
} else {
|
||||
printk(BIOS_ERR, "%s info size too large.\n",
|
||||
fmap_name);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
printk(BIOS_WARNING, "%s is uninitialized.\n", fmap_name);
|
||||
|
||||
fail:
|
||||
memset(rdev, 0, sizeof(*rdev));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue