<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/26888">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP]sb/intel/common/spi: Add method to probe protected regions<br><br>In preparation for VBOOT introduce a method to check if a region<br>is write-protected. For example the RO region.<br><br>Change-Id: I40812eacba552d9c24790942fc5612b4836238f3<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>M src/include/spi-generic.h<br>M src/southbridge/intel/common/spi.c<br>2 files changed, 82 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/26888/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h</span><br><span>index e3e7f82..bfbf03d 100644</span><br><span>--- a/src/include/spi-generic.h</span><br><span>+++ b/src/include/spi-generic.h</span><br><span>@@ -145,6 +145,8 @@</span><br><span>                           struct spi_flash *flash);</span><br><span>    int (*flash_protect)(const struct spi_flash *flash,</span><br><span>                          const struct region *region);</span><br><span style="color: hsl(120, 100%, 40%);">+ bool (*get_write_protection)(const struct spi_flash *flash,</span><br><span style="color: hsl(120, 100%, 40%);">+                                const struct region *region);</span><br><span> };</span><br><span> </span><br><span> /*-----------------------------------------------------------------------</span><br><span>diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c</span><br><span>index bd89025..c87a85c 100644</span><br><span>--- a/src/southbridge/intel/common/spi.c</span><br><span>+++ b/src/southbridge/intel/common/spi.c</span><br><span>@@ -28,7 +28,7 @@</span><br><span> #include <device/pci_ids.h></span><br><span> #include <device/pci.h></span><br><span> #include <spi_flash.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+#include <memrange.h></span><br><span> #include <spi-generic.h></span><br><span> </span><br><span> #define HSFC_FCYCLE_OFF          1       /* 1-2: FLASH Cycle */</span><br><span>@@ -1006,6 +1006,80 @@</span><br><span>      return ret;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static u32 spi_fpr_limit(const u32 reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 mask, limit_shift;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_I82801GX)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          mask = ICH7_SPI_FPR_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+             limit_shift = ICH7_SPI_FPR_LIMIT_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              mask = ICH9_SPI_FPR_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+             limit_shift = ICH9_SPI_FPR_LIMIT_SHIFT;</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 ((reg >> limit_shift) & mask) << SPI_FPR_SHIFT;</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 u32 spi_fpr_base(const u32 reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        u32 mask;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_I82801GX)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          mask = ICH7_SPI_FPR_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              mask = ICH9_SPI_FPR_MASK;</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 ((reg >> SPI_FPR_BASE_SHIFT) & mask) << SPI_FPR_SHIFT;</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%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Test if a region defined by [start, start+size-1] is write-protected using</span><br><span style="color: hsl(120, 100%, 40%);">+ * Flash Protected Range (FPR) register if available.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns true if the whole region is write-protected by one ore multiple</span><br><span style="color: hsl(120, 100%, 40%);">+ * protected range regions.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static bool spi_get_write_protection(const struct spi_flash *flash,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  const struct region *region)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  const ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr);</span><br><span style="color: hsl(120, 100%, 40%);">+      const u32 start = region_offset(region);</span><br><span style="color: hsl(120, 100%, 40%);">+      const u32 end = start + region_sz(region) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        int fpr;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t *fpr_base = cntlr->fpr;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct memranges prot_space;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct range_entry *entry;</span><br><span style="color: hsl(120, 100%, 40%);">+    bool ret = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   memranges_init_empty(&prot_space, NULL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Merge active protected regions */</span><br><span style="color: hsl(120, 100%, 40%);">+  for (fpr = 0; (fpr < cntlr->fpr_max) && read32(&fpr_base[fpr]); fpr++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            u32 reg = read32(&fpr_base[fpr]);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!(reg & SPI_FPR_WPE))</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           memranges_insert(&prot_space, spi_fpr_base(reg),</span><br><span style="color: hsl(120, 100%, 40%);">+                           spi_fpr_limit(reg) + 1 - spi_fpr_base(reg), 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%);">+   for (entry = prot_space.entries; entry;</span><br><span style="color: hsl(120, 100%, 40%);">+            entry = memranges_next_entry(&prot_space, entry)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (range_entry_base(entry) <= start &&</span><br><span style="color: hsl(120, 100%, 40%);">+                range_entry_end(entry) >= end)</span><br><span style="color: hsl(120, 100%, 40%);">+         {</span><br><span style="color: hsl(120, 100%, 40%);">+                     ret = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                   break;</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%);">+   memranges_teardown(&prot_space);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        printk(BIOS_INFO, "%s: Range 0x%08x-0x%08x is %swrite-protected\n",</span><br><span style="color: hsl(120, 100%, 40%);">+         __func__, start, end, ret ? " " : "not ");</span><br><span style="color: hsl(120, 100%, 40%);">+        return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*</span><br><span>  * Protect range of SPI flash defined by [start, start+size-1] using Flash</span><br><span>  * Protected Range (FPR) register if available.</span><br><span>@@ -1021,6 +1095,10 @@</span><br><span>     int fpr;</span><br><span>     uint32_t *fpr_base;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       /* Test if region is already covered by FPR */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (spi_get_write_protection(flash, region))</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  fpr_base = cntlr->fpr;</span><br><span> </span><br><span>        /* Find first empty FPR */</span><br><span>@@ -1056,6 +1134,7 @@</span><br><span>   .max_xfer_size = member_size(ich9_spi_regs, fdata),</span><br><span>  .flash_probe = spi_flash_programmer_probe,</span><br><span>   .flash_protect = spi_flash_protect,</span><br><span style="color: hsl(120, 100%, 40%);">+   .get_write_protection = spi_get_write_protection,</span><br><span> };</span><br><span> </span><br><span> const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/26888">change 26888</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/26888"/><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: I40812eacba552d9c24790942fc5612b4836238f3 </div>
<div style="display:none"> Gerrit-Change-Number: 26888 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>