aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/vpd/Kconfig28
-rw-r--r--src/drivers/vpd/Makefile.inc2
-rw-r--r--src/drivers/vpd/lib_vpd.c113
-rw-r--r--src/drivers/vpd/lib_vpd.h (renamed from src/vendorcode/google/chromeos/lib_vpd.h)32
-rw-r--r--src/drivers/vpd/vpd.c (renamed from src/vendorcode/google/chromeos/cros_vpd.c)23
-rw-r--r--src/drivers/vpd/vpd.h (renamed from src/vendorcode/google/chromeos/cros_vpd.h)18
-rw-r--r--src/drivers/vpd/vpd_tables.h (renamed from src/vendorcode/google/chromeos/vpd_tables.h)0
-rw-r--r--src/mainboard/google/reef/variants/snappy/mainboard.c4
-rw-r--r--src/vendorcode/google/chromeos/Kconfig1
-rw-r--r--src/vendorcode/google/chromeos/Makefile.inc3
-rw-r--r--src/vendorcode/google/chromeos/sar.c9
-rw-r--r--src/vendorcode/google/chromeos/vpd_calibration.c4
-rw-r--r--src/vendorcode/google/chromeos/vpd_decode.c89
-rw-r--r--src/vendorcode/google/chromeos/vpd_mac.c6
-rw-r--r--src/vendorcode/google/chromeos/vpd_serialno.c6
-rw-r--r--src/vendorcode/google/chromeos/wrdd.c8
16 files changed, 206 insertions, 140 deletions
diff --git a/src/drivers/vpd/Kconfig b/src/drivers/vpd/Kconfig
new file mode 100644
index 0000000000..335b9079de
--- /dev/null
+++ b/src/drivers/vpd/Kconfig
@@ -0,0 +1,28 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+
+config VPD
+ bool "Support for Vital Product Data tables"
+ default n
+ help
+ Enable support for flash based vital product data.
+
+if VPD
+
+config VPD_DEBUG
+ bool "Enable VPD debug output"
+ default n
+
+endif
diff --git a/src/drivers/vpd/Makefile.inc b/src/drivers/vpd/Makefile.inc
new file mode 100644
index 0000000000..91c069d6c8
--- /dev/null
+++ b/src/drivers/vpd/Makefile.inc
@@ -0,0 +1,2 @@
+romstage-$(CONFIG_VPD) += lib_vpd.c
+ramstage-$(CONFIG_VPD) += vpd.c lib_vpd.c
diff --git a/src/drivers/vpd/lib_vpd.c b/src/drivers/vpd/lib_vpd.c
new file mode 100644
index 0000000000..0744a712ab
--- /dev/null
+++ b/src/drivers/vpd/lib_vpd.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ */
+#include <assert.h>
+#include "lib_vpd.h"
+
+/* Given an encoded string, this functions decodes the length field which varies
+ * from 1 byte to many bytes.
+ *
+ * The in points the actual byte going to be decoded. The *length returns
+ * the decoded length field. The number of consumed bytes will be stroed in
+ * decoded_len.
+ *
+ * Returns VPD_FAIL if more bit is 1, but actually reaches the end of string.
+ */
+int decodeLen(const int32_t max_len,
+ const uint8_t *in,
+ int32_t *length,
+ int32_t *decoded_len)
+{
+ uint8_t more;
+ int i = 0;
+
+ assert(length);
+ assert(decoded_len);
+
+ *length = 0;
+ do {
+ if (i >= max_len)
+ return VPD_FAIL;
+
+ more = in[i] & 0x80;
+ *length <<= 7;
+ *length |= in[i] & 0x7f;
+ ++i;
+ } while (more);
+
+ *decoded_len = i;
+
+ return VPD_OK;
+}
+
+/* Given the encoded string, this function invokes callback with extracted
+ * (key, value). The *consumed will be plused the number of bytes consumed in
+ * this function.
+ *
+ * The input_buf points to the first byte of the input buffer.
+ *
+ * The *consumed starts from 0, which is actually the next byte to be decoded.
+ * It can be non-zero to be used in multiple calls.
+ *
+ * If one entry is successfully decoded, sends it to callback and returns the
+ * result.
+ */
+int decodeVpdString(const int32_t max_len,
+ const uint8_t *input_buf,
+ int32_t *consumed,
+ VpdDecodeCallback callback,
+ void *callback_arg)
+{
+ int type;
+ int32_t key_len, value_len;
+ int32_t decoded_len;
+ const uint8_t *key, *value;
+
+ /* type */
+ if (*consumed >= max_len)
+ return VPD_FAIL;
+
+ type = input_buf[*consumed];
+ switch (type) {
+ case VPD_TYPE_INFO:
+ case VPD_TYPE_STRING:
+ (*consumed)++;
+ /* key */
+ if (VPD_OK != decodeLen(max_len - *consumed,
+ &input_buf[*consumed], &key_len,
+ &decoded_len) ||
+ *consumed + decoded_len >= max_len) {
+ return VPD_FAIL;
+ }
+
+ *consumed += decoded_len;
+ key = &input_buf[*consumed];
+ *consumed += key_len;
+
+ /* value */
+ if (VPD_OK != decodeLen(max_len - *consumed,
+ &input_buf[*consumed],
+ &value_len, &decoded_len) ||
+ *consumed + decoded_len > max_len) {
+ return VPD_FAIL;
+ }
+ *consumed += decoded_len;
+ value = &input_buf[*consumed];
+ *consumed += value_len;
+
+ if (type == VPD_TYPE_STRING)
+ return callback(key, key_len, value, value_len,
+ callback_arg);
+
+ return VPD_OK;
+
+ default:
+ return VPD_FAIL;
+ break;
+ }
+
+ return VPD_OK;
+}
diff --git a/src/vendorcode/google/chromeos/lib_vpd.h b/src/drivers/vpd/lib_vpd.h
index e08cb3a654..7a7566b234 100644
--- a/src/vendorcode/google/chromeos/lib_vpd.h
+++ b/src/drivers/vpd/lib_vpd.h
@@ -11,25 +11,25 @@
#include <inttypes.h>
enum {
- VPD_OK = 0,
- VPD_FAIL,
+ VPD_OK = 0,
+ VPD_FAIL,
};
enum {
- VPD_TYPE_TERMINATOR = 0,
- VPD_TYPE_STRING,
- VPD_TYPE_INFO = 0xfe,
- VPD_TYPE_IMPLICIT_TERMINATOR = 0xff,
+ VPD_TYPE_TERMINATOR = 0,
+ VPD_TYPE_STRING,
+ VPD_TYPE_INFO = 0xfe,
+ VPD_TYPE_IMPLICIT_TERMINATOR = 0xff,
};
enum {
- VPD_AS_LONG_AS = -1,
+ VPD_AS_LONG_AS = -1,
};
enum { /* export_type */
- VPD_EXPORT_KEY_VALUE = 1,
- VPD_EXPORT_VALUE,
- VPD_EXPORT_AS_PARAMETER,
+ VPD_EXPORT_KEY_VALUE = 1,
+ VPD_EXPORT_VALUE,
+ VPD_EXPORT_AS_PARAMETER,
};
/* Callback for decodeVpdString to invoke. */
@@ -39,15 +39,15 @@ typedef int VpdDecodeCallback(const uint8_t *key, int32_t key_len,
/* Container data types */
struct StringPair {
- uint8_t *key;
- uint8_t *value;
- int pad_len;
- int filter_out; /* TRUE means not exported. */
- struct StringPair *next;
+ uint8_t *key;
+ uint8_t *value;
+ int pad_len;
+ int filter_out; /* TRUE means not exported. */
+ struct StringPair *next;
};
struct PairContainer {
- struct StringPair *first;
+ struct StringPair *first;
};
diff --git a/src/vendorcode/google/chromeos/cros_vpd.c b/src/drivers/vpd/vpd.c
index d0e2cc1ef9..e620b58b31 100644
--- a/src/vendorcode/google/chromeos/cros_vpd.c
+++ b/src/drivers/vpd/vpd.c
@@ -5,14 +5,13 @@
*/
#include <console/console.h>
-
#include <cbmem.h>
#include <fmap.h>
#include <stdlib.h>
#include <string.h>
#include <timestamp.h>
-#include "cros_vpd.h"
+#include "vpd.h"
#include "lib_vpd.h"
#include "vpd_tables.h"
@@ -178,7 +177,7 @@ static int vpd_gets_callback(const uint8_t *key, int32_t key_len,
return VPD_FAIL;
}
-const void *cros_vpd_find(const char *key, int *size)
+const void *vpd_find(const char *key, int *size, enum vpd_region region)
{
struct vpd_gets_arg arg = {0};
int consumed = 0;
@@ -191,10 +190,18 @@ const void *cros_vpd_find(const char *key, int *size)
arg.key = (const uint8_t *)key;
arg.key_len = strlen(key);
- while (VPD_OK == decodeVpdString(vpd->ro_size, vpd->blob, &consumed,
- vpd_gets_callback, &arg)) {
+ if (region == VPD_ANY || region == VPD_RO)
+ while (VPD_OK == decodeVpdString(vpd->ro_size, vpd->blob,
+ &consumed, vpd_gets_callback, &arg)) {
/* Iterate until found or no more entries. */
- }
+ }
+
+ if (!arg.matched && region != VPD_RO)
+ while (VPD_OK == decodeVpdString(vpd->rw_size,
+ vpd->blob + vpd->ro_size, &consumed,
+ vpd_gets_callback, &arg)) {
+ /* Iterate until found or no more entries. */
+ }
if (!arg.matched)
return NULL;
@@ -203,12 +210,12 @@ const void *cros_vpd_find(const char *key, int *size)
return arg.value;
}
-char *cros_vpd_gets(const char *key, char *buffer, int size)
+char *vpd_gets(const char *key, char *buffer, int size, enum vpd_region region)
{
const void *string_address;
int string_size;
- string_address = cros_vpd_find(key, &string_size);
+ string_address = vpd_find(key, &string_size, region);
if (!string_address)
return NULL;
diff --git a/src/vendorcode/google/chromeos/cros_vpd.h b/src/drivers/vpd/vpd.h
index 1fa56a4725..6009b8bc0d 100644
--- a/src/vendorcode/google/chromeos/cros_vpd.h
+++ b/src/drivers/vpd/vpd.h
@@ -4,12 +4,14 @@
* found in the LICENSE file.
*/
-#ifndef __CROS_VPD_H__
-#define __CROS_VPD_H__
-
-#define CROS_VPD_REGION_NAME "region"
-#define CROS_VPD_WIFI_SAR_NAME "wifi_sar"
+#ifndef __VPD_H__
+#define __VPD_H__
+enum vpd_region {
+ VPD_ANY = 0,
+ VPD_RO = 1,
+ VPD_RW = 2
+};
/*
* Reads VPD string value by key.
*
@@ -19,7 +21,7 @@
*
* Returns NULL if key is not found, otherwise buffer.
*/
-char *cros_vpd_gets(const char *key, char *buffer, int size);
+char *vpd_gets(const char *key, char *buffer, int size, enum vpd_region region);
/*
* Find VPD value by key.
@@ -35,6 +37,6 @@ char *cros_vpd_gets(const char *key, char *buffer, int size);
* Returns NULL if key is not found.
*/
-const void *cros_vpd_find(const char *key, int *size);
+const void *vpd_find(const char *key, int *size, enum vpd_region region);
-#endif /* __CROS_VPD_H__ */
+#endif /* __VPD_H__ */
diff --git a/src/vendorcode/google/chromeos/vpd_tables.h b/src/drivers/vpd/vpd_tables.h
index 822ed08b0f..822ed08b0f 100644
--- a/src/vendorcode/google/chromeos/vpd_tables.h
+++ b/src/drivers/vpd/vpd_tables.h
diff --git a/src/mainboard/google/reef/variants/snappy/mainboard.c b/src/mainboard/google/reef/variants/snappy/mainboard.c
index a625c60b6b..73de67e525 100644
--- a/src/mainboard/google/reef/variants/snappy/mainboard.c
+++ b/src/mainboard/google/reef/variants/snappy/mainboard.c
@@ -16,7 +16,7 @@
#include <string.h>
#include <baseboard/variants.h>
#include <ec/google/chromeec/ec.h>
-#include <vendorcode/google/chromeos/cros_vpd.h>
+#include <drivers/vpd/vpd.h>
#include <soc/cpu.h>
#include <soc/intel/apollolake/chip.h>
@@ -59,7 +59,7 @@ uint8_t variant_board_sku(void)
if (!IS_ENABLED(CONFIG_CHROMEOS))
return board_sku_num;
- if (!cros_vpd_gets(vpd_skuid, vpd_buffer, ARRAY_SIZE(vpd_buffer)))
+ if (!vpd_gets(vpd_skuid, vpd_buffer, ARRAY_SIZE(vpd_buffer), VPD_ANY))
return board_sku_num;
vpd_len = strlen(vpd_buffer);
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 4f1fad9a73..1dd726f551 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -24,6 +24,7 @@ config CHROMEOS
select ELOG if BOOT_DEVICE_SUPPORTS_WRITES
select COLLECT_TIMESTAMPS
select VBOOT
+ select VPD
help
Enable ChromeOS specific features like the GPIO sub table in
the coreboot table. NOTE: Enabling this option on an unsupported
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index e833e0dd74..ecd82b7a83 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -17,8 +17,7 @@ ramstage-$(CONFIG_ELOG) += elog.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += gnvs.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
ramstage-$(CONFIG_CHROMEOS_RAMOOPS) += ramoops.c
-romstage-y += vpd_decode.c
-ramstage-y += vpd_decode.c cros_vpd.c vpd_mac.c vpd_serialno.c vpd_calibration.c
+ramstage-y += vpd_mac.c vpd_serialno.c vpd_calibration.c
ramstage-$(CONFIG_CHROMEOS_DISABLE_PLATFORM_HIERARCHY_ON_RESUME) += tpm2.c
ramstage-$(CONFIG_HAVE_REGULATORY_DOMAIN) += wrdd.c
ramstage-$(CONFIG_USE_SAR) += sar.c
diff --git a/src/vendorcode/google/chromeos/sar.c b/src/vendorcode/google/chromeos/sar.c
index fc72dc1348..6799f12a24 100644
--- a/src/vendorcode/google/chromeos/sar.c
+++ b/src/vendorcode/google/chromeos/sar.c
@@ -19,9 +19,10 @@
#include <types.h>
#include <string.h>
#include <sar.h>
-#include "cros_vpd.h"
+#include <drivers/vpd/vpd.h>
#define WIFI_SAR_CBFS_FILENAME "wifi_sar_defaults.hex"
+#define CROS_VPD_WIFI_SAR_NAME "wifi_sar"
static int load_sar_file_from_cbfs(void *buf, size_t buffer_size)
{
@@ -55,7 +56,7 @@ For [WGDS_VERSION] 0x00,
int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
{
const char *wifi_sar_limit_key = CROS_VPD_WIFI_SAR_NAME;
- /* cros_vpd_gets() reads in one less than size characters from the VPD
+ /* vpd_gets() reads in one less than size characters from the VPD
* with a terminating null byte ('\0') stored as the last character into
* the buffer, thus the increasing by 1 for buffer_size. */
const size_t buffer_size = (sizeof(struct wifi_sar_limits) /
@@ -79,8 +80,8 @@ int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
}
/* Try to read the SAR limit entry from VPD */
- if (!cros_vpd_gets(wifi_sar_limit_key, wifi_sar_limit_str,
- buffer_size)) {
+ if (!vpd_gets(wifi_sar_limit_key, wifi_sar_limit_str,
+ buffer_size, VPD_ANY)) {
printk(BIOS_ERR, "Error: Could not locate '%s' in VPD.\n",
wifi_sar_limit_key);
diff --git a/src/vendorcode/google/chromeos/vpd_calibration.c b/src/vendorcode/google/chromeos/vpd_calibration.c
index 697ff953dd..7f9910b3f9 100644
--- a/src/vendorcode/google/chromeos/vpd_calibration.c
+++ b/src/vendorcode/google/chromeos/vpd_calibration.c
@@ -19,7 +19,7 @@
#include <string.h>
#include <vendorcode/google/chromeos/chromeos.h>
-#include <vendorcode/google/chromeos/cros_vpd.h>
+#include <drivers/vpd/vpd.h>
/*
* This file provides functions looking in the VPD for WiFi calibration data,
@@ -112,7 +112,7 @@ static size_t fill_up_entries_cache(struct vpd_blob_cache_t *cache,
strcpy(cache->key_name, templates[i]);
cache->key_name[index_location] = j + '0';
- payload = cros_vpd_find(cache->key_name, &payload_size);
+ payload = vpd_find(cache->key_name, &payload_size, VPD_ANY);
if (!payload)
continue;
diff --git a/src/vendorcode/google/chromeos/vpd_decode.c b/src/vendorcode/google/chromeos/vpd_decode.c
deleted file mode 100644
index 545fd8106f..0000000000
--- a/src/vendorcode/google/chromeos/vpd_decode.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- */
-#include <assert.h>
-#include "lib_vpd.h"
-
-int decodeLen(
- const int32_t max_len,
- const uint8_t *in,
- int32_t *length,
- int32_t *decoded_len) {
- uint8_t more;
- int i = 0;
-
- assert(length);
- assert(decoded_len);
-
- *length = 0;
- do {
- if (i >= max_len) return VPD_FAIL;
- more = in[i] & 0x80;
- *length <<= 7;
- *length |= in[i] & 0x7f;
- ++i;
- } while (more);
-
- *decoded_len = i;
-
- return VPD_OK;
-}
-
-/* Sequentially decodes type, key, and value.
- */
-int decodeVpdString(
- const int32_t max_len,
- const uint8_t *input_buf,
- int32_t *consumed,
- VpdDecodeCallback callback,
- void *callback_arg) {
- int type;
- int32_t key_len, value_len;
- int32_t decoded_len;
- const uint8_t *key, *value;
-
- /* type */
- if (*consumed >= max_len)
- return VPD_FAIL;
-
- type = input_buf[*consumed];
- switch (type) {
- case VPD_TYPE_INFO:
- case VPD_TYPE_STRING:
- (*consumed)++;
-
- /* key */
- if (VPD_OK != decodeLen(max_len - *consumed, &input_buf[*consumed],
- &key_len, &decoded_len) ||
- *consumed + decoded_len >= max_len) {
- return VPD_FAIL;
- }
-
- *consumed += decoded_len;
- key = &input_buf[*consumed];
- *consumed += key_len;
-
- /* value */
- if (VPD_OK != decodeLen(max_len - *consumed, &input_buf[*consumed],
- &value_len, &decoded_len) ||
- *consumed + decoded_len > max_len) {
- return VPD_FAIL;
- }
- *consumed += decoded_len;
- value = &input_buf[*consumed];
- *consumed += value_len;
-
- if (type == VPD_TYPE_STRING)
- return callback(key, key_len, value, value_len, callback_arg);
-
- return VPD_OK;
-
- default:
- return VPD_FAIL;
- break;
- }
- return VPD_OK;
-}
diff --git a/src/vendorcode/google/chromeos/vpd_mac.c b/src/vendorcode/google/chromeos/vpd_mac.c
index 061997453a..e3ef04b669 100644
--- a/src/vendorcode/google/chromeos/vpd_mac.c
+++ b/src/vendorcode/google/chromeos/vpd_mac.c
@@ -17,7 +17,7 @@
#include <console/console.h>
#include <string.h>
-#include <vendorcode/google/chromeos/cros_vpd.h>
+#include <drivers/vpd/vpd.h>
/*
* Decode string representation of the MAC address (a string of 12 hex
@@ -84,8 +84,8 @@ void lb_table_add_macs_from_vpd(struct lb_header *header)
* If there are no more MAC addresses of this template
* in the VPD - move on.
*/
- if (!cros_vpd_gets(mac_addr_key, mac_addr_str,
- sizeof(mac_addr_str)))
+ if (!vpd_gets(mac_addr_key, mac_addr_str,
+ sizeof(mac_addr_str), VPD_ANY))
break;
if (!macs) {
diff --git a/src/vendorcode/google/chromeos/vpd_serialno.c b/src/vendorcode/google/chromeos/vpd_serialno.c
index e9a771ebaa..8cae5d6d20 100644
--- a/src/vendorcode/google/chromeos/vpd_serialno.c
+++ b/src/vendorcode/google/chromeos/vpd_serialno.c
@@ -18,7 +18,7 @@
#include <assert.h>
#include <string.h>
-#include <vendorcode/google/chromeos/cros_vpd.h>
+#include <drivers/vpd/vpd.h>
void lb_table_add_serialno_from_vpd(struct lb_header *header)
{
@@ -27,8 +27,8 @@ void lb_table_add_serialno_from_vpd(struct lb_header *header)
char serialno[32];
size_t len;
- if (!cros_vpd_gets(serialno_key, serialno,
- sizeof(serialno))) {
+ if (!vpd_gets(serialno_key, serialno,
+ sizeof(serialno), VPD_ANY)) {
printk(BIOS_ERR, "no serial number in vpd\n");
return;
}
diff --git a/src/vendorcode/google/chromeos/wrdd.c b/src/vendorcode/google/chromeos/wrdd.c
index ad8099247b..093e6cdb74 100644
--- a/src/vendorcode/google/chromeos/wrdd.c
+++ b/src/vendorcode/google/chromeos/wrdd.c
@@ -18,7 +18,9 @@
#include <types.h>
#include <string.h>
#include <wrdd.h>
-#include "cros_vpd.h"
+#include <drivers/vpd/vpd.h>
+
+#define CROS_VPD_REGION_NAME "region"
/*
* wrdd_domain_value is ISO 3166-2
@@ -59,8 +61,8 @@ uint16_t wifi_regulatory_domain(void)
char *separator;
/* If not found for any reason fall backto the default value */
- if (!cros_vpd_gets(wrdd_domain_key, wrdd_domain_code,
- ARRAY_SIZE(wrdd_domain_code))) {
+ if (!vpd_gets(wrdd_domain_key, wrdd_domain_code,
+ ARRAY_SIZE(wrdd_domain_code), VPD_ANY)) {
printk(BIOS_DEBUG,
"Error: Could not locate '%s' in VPD\n", wrdd_domain_key);
return WRDD_DEFAULT_REGULATORY_DOMAIN;