xref: /aosp_15_r20/external/coreboot/src/drivers/vpd/vpd_device_feature.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <b64_decode.h>
4 #include <console/console.h>
5 #include <drivers/vpd/vpd.h>
6 #include <stdlib.h>
7 
8 #define VPD_KEY_FEATURE_DEVICE_INFO	"feature_device_info"
9 
10 /*
11  * Extracts the "feature_level" from the "feature_device_info" VPD key.
12  * This key holds a base64-encoded protobuf where "feature_level" is the first entry.
13  */
vpd_get_feature_level(void)14 uint8_t vpd_get_feature_level(void)
15 {
16 	const uint8_t *device_info;
17 	int device_info_size, feature_level = 0;
18 	uint8_t *decoded_device_info;
19 	size_t decoded_size;
20 
21 	device_info = vpd_find(VPD_KEY_FEATURE_DEVICE_INFO, &device_info_size, VPD_RW);
22 	if (!device_info)
23 		return feature_level;
24 
25 	decoded_size = B64_DECODED_SIZE(device_info_size);
26 	decoded_device_info = malloc(decoded_size);
27 	if (!decoded_device_info) {
28 		printk(BIOS_ERR, "%s: failed allocating %zd bytes\n", __func__, decoded_size);
29 		return feature_level;
30 	}
31 
32 	/* The index 1 of the decoded data is the "feature level" value */
33 	if (b64_decode(device_info, device_info_size, decoded_device_info))
34 		feature_level = decoded_device_info[1];
35 
36 	free(decoded_device_info);
37 	return feature_level;
38 }
39