<p>Edward Hill would like Keith Short to <strong>review</strong> this change.</p><p><a href="https://review.coreboot.org/c/coreboot/+/30295">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cr50: Add probe command to poll Cr50 until DID VID is valid<br><br>Added new routine cr50_i2c_probe() which ensures that communication<br>with the Cr50 over I2C is good prior to attempting other initialization<br>of the Cr50 and TPM state.  This avoids a race condition when the Cr50<br>is first booting that it may reset it's I2C slave interface during the<br>first few I2C transactions initiated from coreboot.<br><br>BUG=b:120009037<br>BRANCH=none<br>TEST=Run the Cr50 factory update against Careena board.  Confirm that<br>I2C reads are retried until the DID VID is valid.  Tested against debug<br>Cr50 firmware that forced failure of cr50_i2c_probe() and verfied that<br>coreboot shows recovery screen.<br><br>Change-Id: I47c59a32378ad00336277e111e81ba8d2d63e69a<br>Signed-off-by: Keith Short <keithshort@chromium.org><br>---<br>M src/drivers/i2c/tpm/cr50.c<br>1 file changed, 38 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/95/30295/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/drivers/i2c/tpm/cr50.c b/src/drivers/i2c/tpm/cr50.c</span><br><span>index b0d3b29..c0d8afd 100644</span><br><span>--- a/src/drivers/i2c/tpm/cr50.c</span><br><span>+++ b/src/drivers/i2c/tpm/cr50.c</span><br><span>@@ -456,6 +456,41 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int cr50_i2c_probe(struct tpm_chip *chip)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int retries;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t vendor = 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%);">+     * 150 ms should be enough to synchronize with the TPM even under the</span><br><span style="color: hsl(120, 100%, 40%);">+  * worst nested reset request conditions. In vast majority of cases</span><br><span style="color: hsl(120, 100%, 40%);">+    * there would be no wait at all.</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   printk(BIOS_INFO, "Probing TPM I2C: ");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   for (retries = 15; retries > 0; retries--) {</span><br><span style="color: hsl(120, 100%, 40%);">+               int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = cr50_i2c_read(chip, TPM_DID_VID(0), (uint8_t *)&vendor, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Exit once DID and VID verified */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!rc && (vendor == CR50_DID_VID)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        printk(BIOS_INFO, " done! DID_VID %08x\n", vendor);</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%);">+           /* TPM might be resetting, let's retry in a bit. */</span><br><span style="color: hsl(120, 100%, 40%);">+               mdelay(10);</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_INFO, ".");</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%);">+     * I2C reads were successful, but the DID and VID didn't match</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   printk(BIOS_ERR, "Vendor ID 0x%08x not recognized\n", vendor);</span><br><span style="color: hsl(120, 100%, 40%);">+      return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)</span><br><span> {</span><br><span>      struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev);</span><br><span>@@ -471,6 +506,9 @@</span><br><span> </span><br><span>     cr50_vendor_init(chip);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   if (cr50_i2c_probe(chip))</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         if (ENV_VERSTAGE || ENV_BOOTBLOCK)</span><br><span>           if (process_reset(chip))</span><br><span>                     return -1;</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/c/coreboot/+/30295">change 30295</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/c/coreboot/+/30295"/><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-Change-Id: I47c59a32378ad00336277e111e81ba8d2d63e69a </div>
<div style="display:none"> Gerrit-Change-Number: 30295 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Edward Hill <ecgh@chromium.org> </div>
<div style="display:none"> Gerrit-Reviewer: Keith Short <keithshort@chromium.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>