<p>Daisuke Nojiri has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23548">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Fizz: Get OEM ID and SKU ID from EC<br><br>This patch makes coreboot fetch OEM ID and SKU ID from EC. If it fails,<br>it falls back to GPIO pins.<br><br>Devices with an invalid or uninitialized EEPROM will keep reading from<br>GPIOs because EC_CMD_GET_CROS_BOARD_INFO returns error.<br><br>BUG=b:70294260<br>BRANCH=none<br>TEST=Verify AP log shows expected OEM ID and SKU ID on Fizz.<br><br>Change-Id: I06d3a205275b46660b3974bc3673d4be8e13f6d1<br>Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org><br>---<br>M 3rdparty/blobs<br>M src/ec/google/chromeec/ec.c<br>M src/ec/google/chromeec/ec.h<br>M src/ec/google/chromeec/ec_commands.h<br>M src/mainboard/google/fizz/mainboard.c<br>5 files changed, 146 insertions(+), 15 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/48/23548/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/3rdparty/blobs b/3rdparty/blobs</span><br><span>index a5efee5..d2e558a 160000</span><br><span>--- a/3rdparty/blobs</span><br><span>+++ b/3rdparty/blobs</span><br><span>@@ -1 +1 @@</span><br><span style="color: hsl(0, 100%, 40%);">-Subproject commit a5efee5fdea55f398decc9cabebce3744bbd8147</span><br><span style="color: hsl(120, 100%, 40%);">+Subproject commit d2e558a81f95f7b9149bea6b8362bb43ade82584</span><br><span>diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c</span><br><span>index 89241da..3f81716 100644</span><br><span>--- a/src/ec/google/chromeec/ec.c</span><br><span>+++ b/src/ec/google/chromeec/ec.c</span><br><span>@@ -558,6 +558,40 @@</span><br><span>   return google_chromeec_command(&cec_cmd);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int cbi_get_uint32(uint32_t *id, uint32_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct chromeec_command cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct ec_params_get_cbi p;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t r;</span><br><span style="color: hsl(120, 100%, 40%);">+   int rv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     p.type = type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      cmd.cmd_code = EC_CMD_GET_CROS_BOARD_INFO;</span><br><span style="color: hsl(120, 100%, 40%);">+    cmd.cmd_version = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  cmd.cmd_data_in = &p;</span><br><span style="color: hsl(120, 100%, 40%);">+     cmd.cmd_data_out = &r;</span><br><span style="color: hsl(120, 100%, 40%);">+    cmd.cmd_size_in = sizeof(p);</span><br><span style="color: hsl(120, 100%, 40%);">+  cmd.cmd_size_out = sizeof(r);</span><br><span style="color: hsl(120, 100%, 40%);">+ cmd.cmd_dev_index = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      rv = google_chromeec_command(&cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (rv < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return rv;</span><br><span style="color: hsl(120, 100%, 40%);">+    *id = r;</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int google_chromeec_get_sku_id2(uint32_t *id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return cbi_get_uint32(id, CBI_DATA_SKU_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int google_chromeec_get_oem_id(uint32_t *id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return cbi_get_uint32(id, CBI_DATA_OEM_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifndef __SMM__</span><br><span> u16 google_chromeec_get_board_version(void)</span><br><span> {</span><br><span>diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h</span><br><span>index 90bb6fa..7192315 100644</span><br><span>--- a/src/ec/google/chromeec/ec.h</span><br><span>+++ b/src/ec/google/chromeec/ec.h</span><br><span>@@ -64,6 +64,15 @@</span><br><span>    success, < 0 otherwise. */</span><br><span> int google_chromeec_reboot(int dev_idx, enum ec_reboot_cmd type, uint8_t flags);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Get OEM (or SKU) ID from EC</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param id [OUT] oem/sku id</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return 0 on success or negative integer for errors.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int google_chromeec_get_oem_id(uint32_t *id);</span><br><span style="color: hsl(120, 100%, 40%);">+int google_chromeec_get_sku_id2(uint32_t *id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* MEC uses 0x800/0x804 as register/index pair, thus an 8-byte resource. */</span><br><span> #define MEC_EMI_BASE         0x800</span><br><span> #define MEC_EMI_SIZE           8</span><br><span>diff --git a/src/ec/google/chromeec/ec_commands.h b/src/ec/google/chromeec/ec_commands.h</span><br><span>index 92fb2a8..a8d6b30 100644</span><br><span>--- a/src/ec/google/chromeec/ec_commands.h</span><br><span>+++ b/src/ec/google/chromeec/ec_commands.h</span><br><span>@@ -4363,6 +4363,66 @@</span><br><span>      uint32_t action;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Run verification on a slot */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMD_EFS_VERIFY 0x011E</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct __ec_align1 ec_params_efs_verify {</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t region;         /* enum ec_flash_region */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Retrieve info from Cros Board Info store. Response is based on the data</span><br><span style="color: hsl(120, 100%, 40%);">+ * type. Integers return a uint32. Strings return a string, using the response</span><br><span style="color: hsl(120, 100%, 40%);">+ * size to determine how big it is.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMD_GET_CROS_BOARD_INFO  0x011F</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Write info into Cros Board Info on EEPROM. Write fails if the board has</span><br><span style="color: hsl(120, 100%, 40%);">+ * hardware write-protect enabled.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMD_SET_CROS_BOARD_INFO     0x0120</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum cbi_data_type {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* integer types */</span><br><span style="color: hsl(120, 100%, 40%);">+   CBI_DATA_BOARD_VERSION = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+   CBI_DATA_OEM_ID = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+  CBI_DATA_SKU_ID = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+  /* string types */</span><br><span style="color: hsl(120, 100%, 40%);">+    CBI_FIRST_STRING_PARAM = 0x1000,</span><br><span style="color: hsl(120, 100%, 40%);">+      CBI_DATA_COUNT,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Flags to control read operation</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * RELOAD:  Invalidate cache and read data from EEPROM. Useful to verify</span><br><span style="color: hsl(120, 100%, 40%);">+ *          write was successful without reboot.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define CBI_GET_RELOAD              (1 << 0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct __ec_align4 ec_params_get_cbi {</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t type;          /* enum cbi_data_type */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t flag;          /* CBI_GET_* */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Flags to control write behavior.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * NO_SYNC: Makes EC update data in RAM but skip writing to EEPROM. It's</span><br><span style="color: hsl(120, 100%, 40%);">+ *          useful when writing multiple fields in a row.</span><br><span style="color: hsl(120, 100%, 40%);">+ * INIT:    Need to be set when creating a new CBI from scratch. All fields</span><br><span style="color: hsl(120, 100%, 40%);">+ *          will be initialized to zero first.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define CBI_SET_NO_SYNC          (1 << 0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define CBI_SET_INIT            (1 << 1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct __ec_align1 ec_params_set_cbi {</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t type;          /* enum cbi_data_type */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t flag;          /* CBI_SET_* */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t data;          /* For numeric value */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t raw[];          /* For string and raw data */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*****************************************************************************/</span><br><span> /* The command range 0x200-0x2FF is reserved for Rotor. */</span><br><span> </span><br><span>diff --git a/src/mainboard/google/fizz/mainboard.c b/src/mainboard/google/fizz/mainboard.c</span><br><span>index 3a8aa54..343785c 100644</span><br><span>--- a/src/mainboard/google/fizz/mainboard.c</span><br><span>+++ b/src/mainboard/google/fizz/mainboard.c</span><br><span>@@ -86,21 +86,32 @@</span><br><span>                      BJ_90W_19V, BJ_90W_19V, BJ_65W_19V },</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const char *oem_id = "GOOGLE";</span><br><span style="color: hsl(0, 100%, 40%);">-static const char *oem_table_id = "FIZZ";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t board_sku_id(void)</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t read_sku_id_from_gpio(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     static int id = -1;</span><br><span>  const gpio_t sku_id_gpios[] = {</span><br><span>              GPIO_SKU_ID0,</span><br><span>                GPIO_SKU_ID1,</span><br><span>                GPIO_SKU_ID2,</span><br><span>                GPIO_SKU_ID3,</span><br><span>        };</span><br><span style="color: hsl(0, 100%, 40%);">-      if (id < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          id = gpio_base2_value(sku_id_gpios, ARRAY_SIZE(sku_id_gpios));</span><br><span style="color: hsl(0, 100%, 40%);">-  return id;</span><br><span style="color: hsl(120, 100%, 40%);">+    return gpio_base2_value(sku_id_gpios, ARRAY_SIZE(sku_id_gpios));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t board_sku_id(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   static int sku_id = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (sku_id < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          uint32_t id;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (google_chromeec_get_sku_id2(&id))</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* TODO: Once transition completes, raise error instead</span><br><span style="color: hsl(120, 100%, 40%);">+                        * of returning gpio value which could be unintended. */</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* No caching if it's read from GPIO. */</span><br><span style="color: hsl(120, 100%, 40%);">+                  return read_sku_id_from_gpio();</span><br><span style="color: hsl(120, 100%, 40%);">+               sku_id = id;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return sku_id;</span><br><span> }</span><br><span> </span><br><span> /*</span><br><span>@@ -162,17 +173,31 @@</span><br><span>        *psyspl2_val = SET_PSYSPL2(psyspl2);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t board_oem_id(void)</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t read_oem_id_from_gpio(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- static int id = -1;</span><br><span>  const gpio_t oem_id_gpios[] = {</span><br><span>              GPIO_OEM_ID1,</span><br><span>                GPIO_OEM_ID2,</span><br><span>                GPIO_OEM_ID3,</span><br><span>        };</span><br><span style="color: hsl(0, 100%, 40%);">-      if (id < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          id = gpio_base2_value(oem_id_gpios, ARRAY_SIZE(oem_id_gpios));</span><br><span style="color: hsl(0, 100%, 40%);">-  return id;</span><br><span style="color: hsl(120, 100%, 40%);">+    return gpio_base2_value(oem_id_gpios, ARRAY_SIZE(oem_id_gpios));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t board_oem_id(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   static int oem_id = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (oem_id < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          uint32_t id;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (google_chromeec_get_oem_id(&id))</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* TODO: Once transition completes, raise error instead</span><br><span style="color: hsl(120, 100%, 40%);">+                        * of returning gpio value which could be unintended. */</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* No caching if it's read from GPIO. */</span><br><span style="color: hsl(120, 100%, 40%);">+                  return read_oem_id_from_gpio();</span><br><span style="color: hsl(120, 100%, 40%);">+               oem_id = id;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return oem_id;</span><br><span> }</span><br><span> </span><br><span> const char *smbios_mainboard_sku(void)</span><br><span>@@ -192,6 +217,8 @@</span><br><span> static unsigned long mainboard_write_acpi_tables(</span><br><span>         device_t device, unsigned long current, acpi_rsdp_t *rsdp)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *oem_id = "GOOGLE";</span><br><span style="color: hsl(120, 100%, 40%);">+      const char *oem_table_id = "FIZZ";</span><br><span>         uintptr_t start_addr;</span><br><span>        uintptr_t end_addr;</span><br><span>  struct nhlt *nhlt;</span><br><span>@@ -227,8 +254,9 @@</span><br><span>     uint8_t sku = board_sku_id();</span><br><span>        enum bj_adapter bj;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       printk(BIOS_INFO, "OEM:%u(0x%x) SKU:%u(0x%x)\n", oem, oem, sku, sku);</span><br><span>      if (oem >= OEM_ID_COUNT || sku >= SKU_ID_COUNT) {</span><br><span style="color: hsl(0, 100%, 40%);">-         printk(BIOS_ERR, "Unrecognized OEM or SKU: %d/%d\n", oem, sku);</span><br><span style="color: hsl(120, 100%, 40%);">+             printk(BIOS_ERR, "Unrecognized OEM or SKU\n");</span><br><span>             return;</span><br><span>      }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23548">change 23548</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/23548"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I06d3a205275b46660b3974bc3673d4be8e13f6d1 </div>
<div style="display:none"> Gerrit-Change-Number: 23548 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Daisuke Nojiri <dnojiri@chromium.org> </div>