[coreboot-gerrit] Patch set updated for coreboot: b03e159 vpd: retrieve mac addresses and pass them to bootloader

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu Apr 2 14:45:31 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9207

-gerrit

commit b03e15944a22326e363402548d3092415c300fc0
Author: Vadim Bendebury <vbendeb at chromium.org>
Date:   Mon Sep 22 18:48:41 2014 -0700

    vpd: retrieve mac addresses and pass them to bootloader
    
    Chrome OS devices firmware usually includes an area called VPD (Vital
    Product Data). VPD is a blob of a certain structure, in particular
    containing freely defined variable size fields. A field is a tuple of
    the field name and field contents.
    
    MAC addresses of the interfaces are stored in VPD as well. Field names
    are in the form of 'ethernet_macN', where N is the zero based
    interface number.
    
    This patch retrieves the MAC address(es) from the VPD and populates
    them in the coreboot table so that they become available to the
    bootloader.
    
    BUG=chrome-os-partner:32152, chromium:417117
    TEST=with this and other patches in place the storm device tree shows
         up with MAC addresses properly initialized.
    
    Change-Id: I955207b3a644cde100cc4b48e51a2ab9a3cb1ba0
    Signed-off-by: Stefan Reinauer <reinauer at chromium.org>
    Original-Commit-Id: 1972b9e97b57cc8503c5e4dc496706970ed2ffbe
    Original-Change-Id: I12c0d15ca84f60e4824e1056c9be2e81a7ad8e73
    Original-Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/219443
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/include/boot/coreboot_tables.h | 13 +++++++
 src/lib/coreboot_table.c           | 74 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h
index 46c1df5..0efb8fd 100644
--- a/src/include/boot/coreboot_tables.h
+++ b/src/include/boot/coreboot_tables.h
@@ -263,6 +263,19 @@ struct lb_board_id {
 	uint32_t board_id;
 };
 
+#define LB_TAG_MAC_ADDRS	0x0026
+struct mac_address {
+	uint8_t mac_addr[6];
+	uint8_t pad[2];		/* Pad it to 8 bytes to keep it simple. */
+};
+
+struct lb_macs {
+	uint32_t tag;
+	uint32_t size;
+	uint32_t count;
+	struct mac_address mac_addrs[0];
+};
+
 /* The following structures are for the cmos definitions table */
 #define LB_TAG_CMOS_OPTION_TABLE 200
 /* cmos header record */
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index d6d84cd..a8b5edf 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -38,6 +38,7 @@
 #endif
 #include <vendorcode/google/chromeos/chromeos.h>
 #include <vendorcode/google/chromeos/gnvs.h>
+#include <vendorcode/google/chromeos/cros_vpd.h>
 #endif
 #if CONFIG_ARCH_X86
 #include <cpu/x86/mtrr.h>
@@ -157,9 +158,79 @@ void fill_lb_gpio(struct lb_gpio *gpio, int num,
 }
 
 #if CONFIG_CHROMEOS
+static void lb_macs(struct lb_header *header)
+{
+	/*
+	 * In case there is one or more MAC addresses stored in the VPD, the
+	 * key is "ethernet_mac{0..9}", up to 10 values.
+	 */
+	static const char mac_addr_key_base[] = "ethernet_mac0";
+	char mac_addr_key[sizeof(mac_addr_key_base)];
+	char mac_addr_str[13]; /* 12 symbols and the trailing zero. */
+	int count;
+	struct lb_macs *macs = NULL;
+	const int index_of_index = sizeof(mac_addr_key) - 2;
+
+	/*
+	 * MAC addresses are stored in the VPD as strings of hex numbers,
+	 * which need to be converted into binary for storing in the coreboot
+	 * table.
+	 */
+	strcpy(mac_addr_key, mac_addr_key_base);
+	count = 0;
+	do {
+		int i;
+
+		if (!cros_vpd_gets(mac_addr_key, mac_addr_str,
+				   sizeof(mac_addr_str)))
+			break; /* No more MAC addresses in VPD */
+
+		if (!macs) {
+			macs = (struct lb_macs *)lb_new_record(header);
+			macs->tag = LB_TAG_MAC_ADDRS;
+		}
+
+		/* MAC address in symbolic form is in mac_addr_str. */
+		for (i = 0; i < sizeof(macs->mac_addrs[0].mac_addr); i++) {
+			int j;
+			uint8_t n = 0;
+
+			for (j = 0; j < 2; j++) {
+				char c = mac_addr_str[i * 2 + j];
+
+				if (isxdigit(c)) {
+					if (isdigit(c))
+						c -= '0';
+					else
+						c = tolower(c) - 'a' + 10;
+				} else {
+					printk(BIOS_ERR,
+					       "%s: non hexadecimal symbol "
+					       "%#2.2x in the VPD field %s\n",
+					       __func__, (uint8_t)c,
+					       mac_addr_key);
+					c = 0;
+				}
+				n <<= 4;
+				n |= c;
+			}
+			macs->mac_addrs[count].mac_addr[i] = n;
+		}
+		count++;
+		mac_addr_key[index_of_index] = '0' + count;
+	} while (count < 10);
+
+	if (!count)
+		return; /* No MAC addresses in the VPD. */
+
+	macs->count = count;
+	macs->size = sizeof(*macs) + count * sizeof(struct mac_address);
+}
+
 static void lb_gpios(struct lb_header *header)
 {
 	struct lb_gpios *gpios;
+
 	gpios = (struct lb_gpios *)lb_new_record(header);
 	gpios->tag = LB_TAG_GPIO;
 	gpios->size = sizeof(*gpios);
@@ -446,6 +517,9 @@ unsigned long write_coreboot_table(
 
 	/* pass along the vboot_handoff address. */
 	lb_vboot_handoff(head);
+
+	/* Retrieve mac addresses from VPD, if any. */
+	lb_macs(head);
 #endif
 
 	/* Add board ID if available */



More information about the coreboot-gerrit mailing list