summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/vpd/vpd.h5
-rw-r--r--src/drivers/vpd/vpd_device_feature.c37
2 files changed, 33 insertions, 9 deletions
diff --git a/src/drivers/vpd/vpd.h b/src/drivers/vpd/vpd.h
index a23005fca1..a6631aab55 100644
--- a/src/drivers/vpd/vpd.h
+++ b/src/drivers/vpd/vpd.h
@@ -60,8 +60,9 @@ bool vpd_get_bool(const char *key, enum vpd_region region,
bool vpd_get_int(const char *key, enum vpd_region region, int *val);
/*
- * Return the value after reading the VPD key named "feature_device_info".
+ * Extracts the "feature_level" from the "feature_device_info" VPD key.
+ * This key holds a base64-encoded protobuf where "feature_level" is the first entry.
*/
-const char *vpd_get_feature_device_info(void);
+uint8_t vpd_get_feature_level(void);
#endif /* __VPD_H__ */
diff --git a/src/drivers/vpd/vpd_device_feature.c b/src/drivers/vpd/vpd_device_feature.c
index 1c8682ab7e..7b92756e54 100644
--- a/src/drivers/vpd/vpd_device_feature.c
+++ b/src/drivers/vpd/vpd_device_feature.c
@@ -1,15 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <b64_decode.h>
+#include <console/console.h>
#include <drivers/vpd/vpd.h>
+#include <stdlib.h>
#define VPD_KEY_FEATURE_DEVICE_INFO "feature_device_info"
-#define VPD_FEATURE_DEVICE_INFO_LEN 64
-const char *vpd_get_feature_device_info(void)
+/*
+ * Extracts the "feature_level" from the "feature_device_info" VPD key.
+ * This key holds a base64-encoded protobuf where "feature_level" is the first entry.
+ */
+uint8_t vpd_get_feature_level(void)
{
- static char device_info[VPD_FEATURE_DEVICE_INFO_LEN];
- if (vpd_gets(VPD_KEY_FEATURE_DEVICE_INFO, device_info, VPD_FEATURE_DEVICE_INFO_LEN,
- VPD_RW))
- return device_info;
- return "";
+ const uint8_t *device_info;
+ int device_info_size, feature_level = 0;
+ uint8_t *decoded_device_info;
+ size_t decoded_size;
+
+ device_info = vpd_find(VPD_KEY_FEATURE_DEVICE_INFO, &device_info_size, VPD_RW);
+ if (!device_info)
+ return feature_level;
+
+ decoded_size = B64_DECODED_SIZE(device_info_size);
+ decoded_device_info = malloc(decoded_size);
+ if (!decoded_device_info) {
+ printk(BIOS_ERR, "%s: failed allocating %zd bytes\n", __func__, decoded_size);
+ return feature_level;
+ }
+
+ /* The index 1 of the decoded data is the "feature level" value */
+ if (b64_decode(device_info, device_info_size, decoded_device_info))
+ feature_level = decoded_device_info[1];
+
+ free(decoded_device_info);
+ return feature_level;
}