Jonathan Zhang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_OR_RO ......................................................................
drivers/vpd: add VPD region VPD_RW_OR_RO
This change is based on the concept that system user's (overwrite) settings are held in VPD_RW region, while system owner's (default) settings are held in VPD_RO region.
Add VPD_RW_OR_RO, so that VPD_RW region is searched first to get overwrite setting, otherwise VPD_RO region is searched to get default setting.
Signed-off-by: Jonathan Zhang jonzhang@fb.com Change-Id: Icd7cbd9c3fb2a6b02fc417ad45d7d22ca6795457 --- M src/drivers/vpd/vpd.c M src/drivers/vpd/vpd.h 2 files changed, 30 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/41732/1
diff --git a/src/drivers/vpd/vpd.c b/src/drivers/vpd/vpd.c index f1dcf8c..9264140 100644 --- a/src/drivers/vpd/vpd.c +++ b/src/drivers/vpd/vpd.c @@ -193,17 +193,33 @@ } }
- assert(region == VPD_RO_OR_RW); /* - * As the region is set to VPD_RO_OR_RW, use the search result from VPD_RO + * If the region is set to VPD_RO_OR_RW, use the search result from VPD_RO * as the preference, otherwise use the search result from VPD_RW. */ - if (arg_ro.matched) { - *size = arg_ro.value_len; - return arg_ro.value; - } else if (arg_rw.matched) { + if (region == VPD_RO_OR_RW) { + if (arg_ro.matched) { + *size = arg_ro.value_len; + return arg_ro.value; + } else if (arg_rw.matched) { + *size = arg_rw.value_len; + return arg_rw.value; + } else { + return NULL; + } + } + + /* + * As the region is set to VPD_RW_OR_RO, use the search result from VPD_RW + * as the preference, otherwise use the search result from VPD_RO. + */ + assert(region == VPD_RW_OR_RO); + if (arg_rw.matched) { *size = arg_rw.value_len; return arg_rw.value; + } else if (arg_ro.matched) { + *size = arg_ro.value_len; + return arg_ro.value; } else { return NULL; } diff --git a/src/drivers/vpd/vpd.h b/src/drivers/vpd/vpd.h index 5fa3b4e..549b7a4 100644 --- a/src/drivers/vpd/vpd.h +++ b/src/drivers/vpd/vpd.h @@ -13,11 +13,16 @@
/* * VPD_RO_OR_RW indicates VPD_RO search result is preferred over VPD_RW search result. + * + * VPD_RW_OR_RO indicates VPD_RW search result is preferred over VPD_RO search result. + * This is based on the concept that system user's (overwrite) settings are held in + * VPD_RW region, while system owner's (default) settings are held in VPD_RO region. */ enum vpd_region { - VPD_RO_OR_RW = 0, - VPD_RO = 1, - VPD_RW = 2 + VPD_RO = 0, + VPD_RW = 1, + VPD_RO_OR_RW = 2, + VPD_RW_OR_RO = 3 };
/* VPD 2.0 data blob structure */
Hung-Te Lin has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_OR_RO ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/c/coreboot/+/41732/1/src/drivers/vpd/vpd.c File src/drivers/vpd/vpd.c:
https://review.coreboot.org/c/coreboot/+/41732/1/src/drivers/vpd/vpd.c@150 PS1, Line 150: struct vpd_blob blob = {0}; : : vpd_get_buffers(&blob); : if (blob.ro_size == 0 && blob.rw_size == 0) : return NULL; : : struct vpd_gets_arg arg_ro = {0}; : arg_ro.key = (const uint8_t *)key; : arg_ro.key_len = strlen(key); : uint32_t consumed = 0; : : /* Search VPD_RO for the key, if the region is not set to VPD_RW */ : if (blob.ro_size != 0 && region != VPD_RW) { : while (vpd_decode_string(blob.ro_size, blob.ro_base, : &consumed, vpd_gets_callback, &arg_ro) == VPD_DECODE_OK) { : /* Iterate until found or no more entries. */ : } : /* If the region is set to VPD_RO, the search result is returned */ : if (region == VPD_RO) { : if (!arg_ro.matched) : return NULL; : *size = arg_ro.value_len; : return arg_ro.value; : } : } : : struct vpd_gets_arg arg_rw = {0}; : arg_rw.key = (const uint8_t *)key; : arg_rw.key_len = strlen(key); : consumed = 0; : : /* Search VPD_RW for the key */ : if (blob.rw_size != 0) { : while (vpd_decode_string(blob.rw_size, blob.rw_base, : &consumed, vpd_gets_callback, &arg_rw) == VPD_DECODE_OK) { : /* Iterate until found or no more entries. */ : } : /* If the region is set to VPD_RW, the search result is returned */ : if (region == VPD_RW) { : if (!arg_rw.matched) : return NULL; : *size = arg_rw.value_len; : return arg_rw.value; : } : } : : /* : * If the region is set to VPD_RO_OR_RW, use the search result from VPD_RO : * as the preference, otherwise use the search result from VPD_RW. : */ : if (region == VPD_RO_OR_RW) { : if (arg_ro.matched) { : *size = arg_ro.value_len; : return arg_ro.value; : } else if (arg_rw.matched) { : *size = arg_rw.value_len; : return arg_rw.value; : } else { : return NULL; : } : } : : /* : * As the region is set to VPD_RW_OR_RO, use the search result from VPD_RW : * as the preference, otherwise use the search result from VPD_RO. : */ : assert(region == VPD_RW_OR_RO); : if (arg_rw.matched) { : *size = arg_rw.value_len; : return arg_rw.value; : } else if (arg_ro.matched) { : *size = arg_ro.value_len; : return arg_ro.value; : } else { : return NULL; : } This works, but it'll also waste time searching RO if there's already data in RW, and duplicated the logic.
I think we can have a more straightforward implementation:
static const void *vpd_find_in_buffer(const char *key, int *size, void *blob, size_t blob_size) { uint_32 consumed = 0; struct vpd_gets_arg arg = {0};
if (!blob_size) return NULL;
arg.key = (const uint8_t *)key; arg.key_len = strlen(key); while (vpd_decode_string(blob_size, blob, &consumed, vpd_gets_callback, &arg) == VPD_DECODE_OK) { /* Iterate until found or no more entries. */ }
if (!arg.matched) return NULL; *size = arg.value_len; return arg.value; }
void *vpd_find(const char *key, int *size, enum vpd_region region) { struct vpd_blob blob = {0}; void *ret = NULL;
vpd_get_buffers(&blob);
if (region == VPD_RO || region == VPD_RO_OR_RW) ret = vpd_find_in_buffer(key, size, &blob.ro_base, blob.ro_size); if (!ret && region != VPD_RO) ret = vpd_find_in_buffer(key, size, &blob.rw_base, blob.rw_size); if (!ret && region == VPD_RW_RO) ret = vpd_find_in_buffer(key, size, &blob.ro_base, blob.ro_size);
return ret; }
Hello Hung-Te Lin, build bot (Jenkins), Johnny Lin, David Hendricks,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/41732
to look at the new patch set (#2).
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
drivers/vpd: add VPD region VPD_RW_THEN_RO
This change is based on the concept that system user's (overwrite) settings are held in VPD_RW region, while system owner's (default) settings are held in VPD_RO region.
Add VPD_RW_THEN_RO region type, so that VPD_RW region is searched first to get overwrite setting, otherwise VPD_RO region is searched to get default setting.
Signed-off-by: Jonathan Zhang jonzhang@fb.com Change-Id: Icd7cbd9c3fb2a6b02fc417ad45d7d22ca6795457 --- M src/drivers/vpd/vpd.c M src/drivers/vpd/vpd.h 2 files changed, 9 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/41732/2
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
Patch Set 2: Code-Review+2
(1 comment)
https://review.coreboot.org/c/coreboot/+/41732/2/src/drivers/vpd/vpd.h File src/drivers/vpd/vpd.h:
https://review.coreboot.org/c/coreboot/+/41732/2/src/drivers/vpd/vpd.h@11 PS2, Line 11: VPD_RO = 0, Generally, enums should only use an explict = 0, = 1, etc. when there is some external reason why they need to be exactly this number. Since that's not the case here, I think you should remove that while you're here.
Hello Hung-Te Lin, build bot (Jenkins), Johnny Lin, David Hendricks, Julius Werner,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/41732
to look at the new patch set (#3).
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
drivers/vpd: add VPD region VPD_RW_THEN_RO
This change is based on the concept that system user's (overwrite) settings are held in VPD_RW region, while system owner's (default) settings are held in VPD_RO region.
Add VPD_RW_THEN_RO region type, so that VPD_RW region is searched first to get overwrite setting, otherwise VPD_RO region is searched to get default setting.
Signed-off-by: Jonathan Zhang jonzhang@fb.com Change-Id: Icd7cbd9c3fb2a6b02fc417ad45d7d22ca6795457 --- M src/drivers/vpd/vpd.c M src/drivers/vpd/vpd.h 2 files changed, 9 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/41732/3
Hung-Te Lin has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
Patch Set 3:
(1 comment)
https://review.coreboot.org/c/coreboot/+/41732/3/src/drivers/vpd/vpd.c File src/drivers/vpd/vpd.c:
https://review.coreboot.org/c/coreboot/+/41732/3/src/drivers/vpd/vpd.c@215 PS3, Line 215: region != VPD_RW changed my mind - give we have so many cases now, let's do an explicit list here so people will be easier to figure out what how this will be executed. e,g,
(region == VPD_RO || region == VPD_RO_THEN_RW || region == VPD_RW_THEN_RO)
Jonathan Zhang has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
Patch Set 3:
(3 comments)
https://review.coreboot.org/c/coreboot/+/41732/2/src/drivers/vpd/vpd.h File src/drivers/vpd/vpd.h:
https://review.coreboot.org/c/coreboot/+/41732/2/src/drivers/vpd/vpd.h@11 PS2, Line 11: VPD_RO = 0,
Generally, enums should only use an explict = 0, = 1, etc. […]
Done
https://review.coreboot.org/c/coreboot/+/41732/1/src/drivers/vpd/vpd.c File src/drivers/vpd/vpd.c:
https://review.coreboot.org/c/coreboot/+/41732/1/src/drivers/vpd/vpd.c@150 PS1, Line 150: struct vpd_blob blob = {0}; : : vpd_get_buffers(&blob); : if (blob.ro_size == 0 && blob.rw_size == 0) : return NULL; : : struct vpd_gets_arg arg_ro = {0}; : arg_ro.key = (const uint8_t *)key; : arg_ro.key_len = strlen(key); : uint32_t consumed = 0; : : /* Search VPD_RO for the key, if the region is not set to VPD_RW */ : if (blob.ro_size != 0 && region != VPD_RW) { : while (vpd_decode_string(blob.ro_size, blob.ro_base, : &consumed, vpd_gets_callback, &arg_ro) == VPD_DECODE_OK) { : /* Iterate until found or no more entries. */ : } : /* If the region is set to VPD_RO, the search result is returned */ : if (region == VPD_RO) { : if (!arg_ro.matched) : return NULL; : *size = arg_ro.value_len; : return arg_ro.value; : } : } : : struct vpd_gets_arg arg_rw = {0}; : arg_rw.key = (const uint8_t *)key; : arg_rw.key_len = strlen(key); : consumed = 0; : : /* Search VPD_RW for the key */ : if (blob.rw_size != 0) { : while (vpd_decode_string(blob.rw_size, blob.rw_base, : &consumed, vpd_gets_callback, &arg_rw) == VPD_DECODE_OK) { : /* Iterate until found or no more entries. */ : } : /* If the region is set to VPD_RW, the search result is returned */ : if (region == VPD_RW) { : if (!arg_rw.matched) : return NULL; : *size = arg_rw.value_len; : return arg_rw.value; : } : } : : /* : * If the region is set to VPD_RO_OR_RW, use the search result from VPD_RO : * as the preference, otherwise use the search result from VPD_RW. : */ : if (region == VPD_RO_OR_RW) { : if (arg_ro.matched) { : *size = arg_ro.value_len; : return arg_ro.value; : } else if (arg_rw.matched) { : *size = arg_rw.value_len; : return arg_rw.value; : } else { : return NULL; : } : } : : /* : * As the region is set to VPD_RW_OR_RO, use the search result from VPD_RW : * as the preference, otherwise use the search result from VPD_RO. : */ : assert(region == VPD_RW_OR_RO); : if (arg_rw.matched) { : *size = arg_rw.value_len; : return arg_rw.value; : } else if (arg_ro.matched) { : *size = arg_ro.value_len; : return arg_ro.value; : } else { : return NULL; : }
This works, but it'll also waste time searching RO if there's already data in RW, and duplicated the […]
Done
https://review.coreboot.org/c/coreboot/+/41732/3/src/drivers/vpd/vpd.c File src/drivers/vpd/vpd.c:
https://review.coreboot.org/c/coreboot/+/41732/3/src/drivers/vpd/vpd.c@215 PS3, Line 215: region != VPD_RW
changed my mind - give we have so many cases now, let's do an explicit list here so people will be e […]
Done
Hello Hung-Te Lin, build bot (Jenkins), Johnny Lin, David Hendricks, Julius Werner,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/41732
to look at the new patch set (#4).
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
drivers/vpd: add VPD region VPD_RW_THEN_RO
This change is based on the concept that system user's (overwrite) settings are held in VPD_RW region, while system owner's (default) settings are held in VPD_RO region.
Add VPD_RW_THEN_RO region type, so that VPD_RW region is searched first to get overwrite setting, otherwise VPD_RO region is searched to get default setting.
Signed-off-by: Jonathan Zhang jonzhang@fb.com Change-Id: Icd7cbd9c3fb2a6b02fc417ad45d7d22ca6795457 --- M src/drivers/vpd/vpd.c M src/drivers/vpd/vpd.h 2 files changed, 10 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/41732/4
Hung-Te Lin has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
Patch Set 4: Code-Review+2
Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
drivers/vpd: add VPD region VPD_RW_THEN_RO
This change is based on the concept that system user's (overwrite) settings are held in VPD_RW region, while system owner's (default) settings are held in VPD_RO region.
Add VPD_RW_THEN_RO region type, so that VPD_RW region is searched first to get overwrite setting, otherwise VPD_RO region is searched to get default setting.
Signed-off-by: Jonathan Zhang jonzhang@fb.com Change-Id: Icd7cbd9c3fb2a6b02fc417ad45d7d22ca6795457 Reviewed-on: https://review.coreboot.org/c/coreboot/+/41732 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Hung-Te Lin hungte@chromium.org --- M src/drivers/vpd/vpd.c M src/drivers/vpd/vpd.h 2 files changed, 10 insertions(+), 5 deletions(-)
Approvals: build bot (Jenkins): Verified Hung-Te Lin: Looks good to me, approved
diff --git a/src/drivers/vpd/vpd.c b/src/drivers/vpd/vpd.c index f5ac81e..c332a6e 100644 --- a/src/drivers/vpd/vpd.c +++ b/src/drivers/vpd/vpd.c @@ -209,10 +209,14 @@
init_vpd_rdevs();
- if (region != VPD_RW) + if (region == VPD_RW_THEN_RO) + vpd_find_in(&rw_vpd, &arg); + + if (!arg.matched && (region == VPD_RO || region == VPD_RO_THEN_RW || + region == VPD_RW_THEN_RO)) vpd_find_in(&ro_vpd, &arg);
- if (!arg.matched && region != VPD_RO) + if (!arg.matched && (region == VPD_RW || region == VPD_RO_THEN_RW)) vpd_find_in(&rw_vpd, &arg);
if (!arg.matched) diff --git a/src/drivers/vpd/vpd.h b/src/drivers/vpd/vpd.h index df7711a..25e0aed 100644 --- a/src/drivers/vpd/vpd.h +++ b/src/drivers/vpd/vpd.h @@ -8,9 +8,10 @@ #define GOOGLE_VPD_2_0_OFFSET 0x600
enum vpd_region { - VPD_RO_THEN_RW = 0, - VPD_RO = 1, - VPD_RW = 2 + VPD_RO, + VPD_RW, + VPD_RO_THEN_RW, + VPD_RW_THEN_RO };
/*
9elements QA has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41732 )
Change subject: drivers/vpd: add VPD region VPD_RW_THEN_RO ......................................................................
Patch Set 5:
Automatic boot test returned (PASS/FAIL/TOTAL): 4/0/4 Emulation targets: "QEMU x86 q35/ich9" using payload TianoCore : SUCCESS : https://lava.9esec.io/r/4572 "QEMU x86 q35/ich9" using payload SeaBIOS : SUCCESS : https://lava.9esec.io/r/4571 "QEMU x86 i440fx/piix4" using payload SeaBIOS : SUCCESS : https://lava.9esec.io/r/4570 "QEMU AArch64" using payload LinuxBoot_u-root_kexec : SUCCESS : https://lava.9esec.io/r/4569
Please note: This test is under development and might not be accurate at all!