<p>John E. Kabat Jr. would like frank vibrans to <strong>review</strong> this change.</p><p><a href="https://review.coreboot.org/22065">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">(WIP) soc/amd/common: Add FV access to SPI<br><br>Add firmware volume related access to SPI code. Translates<br>fmap access requests to SPI flash requests.<br>TODO: Update this code to work for S3 save and restore.<br><br>Change-Id: I32208a214a6896308833ff34d459d5513b60ba7a<br>Signed-off-by: Frank Vibrans <frank.vibrans@scarletltd.com><br>---<br>M src/soc/amd/common/block/include/amdblocks/spi.h<br>M src/soc/amd/common/block/spi/spi.c<br>2 files changed, 186 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/65/22065/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/amd/common/block/include/amdblocks/spi.h b/src/soc/amd/common/block/include/amdblocks/spi.h<br>index c06d097..b303450 100644<br>--- a/src/soc/amd/common/block/include/amdblocks/spi.h<br>+++ b/src/soc/amd/common/block/include/amdblocks/spi.h<br>@@ -58,4 +58,87 @@<br> /* SPI related functions called from AMD vendorcode */<br> void spi_SaveS3info(uint32_t pos, size_t size, uint8_t *buf, u32 len);<br> <br>+/*<br>++ * EFI_FVB_ATTRIBUTES_2<br>++ * From UEFI PI spec rev. 1.6<br>++ *<br>++ * The SPI attributes are currently defined as:<br>++ *<br>++ * EFI_FVB2_READ_ENABLED_CAP | EFI_FVB2_READ_STATUS |<br>++ * EFI_FVB2_WRITE_ENABLED_CAP | EFI_FVB2_WRITE_STATUS |<br>++ * EFI_FVB2_STICKY_WRITE | EFI_FVB2_MEMORY_MAPPED | EFI_FVB2_ERASE_POLARITY |<br>++ * EFI_FVB2_ALIGNMENT_8M | EFI_FVB2_WEAK_ALIGNMENT<br>++ *<br>++ * All other bits are 0.<br>++ */<br>+#define SPI_FV_ATTRIBUTES                0x80170e36<br>+<br>+/* Attributes bit definitions */<br>+#define EFI_FVB2_READ_DISABLED_CAP   0x00000001<br>+#define EFI_FVB2_READ_ENABLED_CAP  0x00000002<br>+#define EFI_FVB2_READ_STATUS               0x00000004<br>+<br>+#define EFI_FVB2_WRITE_DISABLED_CAP     0x00000008<br>+#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010<br>+#define EFI_FVB2_WRITE_STATUS              0x00000020<br>+<br>+#define EFI_FVB2_LOCK_CAP               0x00000040<br>+#define EFI_FVB2_LOCK_STATUS               0x00000080<br>+<br>+#define EFI_FVB2_STICKY_WRITE           0x00000200<br>+#define EFI_FVB2_MEMORY_MAPPED             0x00000400<br>+#define EFI_FVB2_ERASE_POLARITY            0x00000800<br>+<br>+#define EFI_FVB2_READ_LOCK_CAP          0x00001000<br>+#define EFI_FVB2_READ_LOCK_STATUS  0x00002000<br>+<br>+#define EFI_FVB2_WRITE_LOCK_CAP         0x00004000<br>+#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000<br>+#define EFI_FVB2_ALIGNMENT         0x00170000<br>+#define EFI_FVB2_WEAK_ALIGNMENT            0x80000000<br>+<br>+#define EFI_FVB2_ALIGNMENT_1            0x00000000<br>+#define EFI_FVB2_ALIGNMENT_2               0x00010000<br>+#define EFI_FVB2_ALIGNMENT_4               0x00020000<br>+#define EFI_FVB2_ALIGNMENT_8               0x00030000<br>+#define EFI_FVB2_ALIGNMENT_16              0x00040000<br>+#define EFI_FVB2_ALIGNMENT_32              0x00050000<br>+#define EFI_FVB2_ALIGNMENT_64              0x00060000<br>+#define EFI_FVB2_ALIGNMENT_128             0x00070000<br>+#define EFI_FVB2_ALIGNMENT_256             0x00080000<br>+#define EFI_FVB2_ALIGNMENT_512             0x00090000<br>+#define EFI_FVB2_ALIGNMENT_1K              0x000a0000<br>+#define EFI_FVB2_ALIGNMENT_2K              0x000b0000<br>+#define EFI_FVB2_ALIGNMENT_4K              0x000c0000<br>+#define EFI_FVB2_ALIGNMENT_8K              0x000d0000<br>+#define EFI_FVB2_ALIGNMENT_16K             0x000e0000<br>+#define EFI_FVB2_ALIGNMENT_32K             0x000f0000<br>+#define EFI_FVB2_ALIGNMENT_64K             0x00100000<br>+#define EFI_FVB2_ALIGNMENT_128K            0x00110000<br>+#define EFI_FVB2_ALIGNMENT_256K            0x00120000<br>+#define EFI_FVB2_ALIGNMENT_512K            0x00130000<br>+#define EFI_FVB2_ALIGNMENT_1M              0x00140000<br>+#define EFI_FVB2_ALIGNMENT_2M              0x00150000<br>+#define EFI_FVB2_ALIGNMENT_4M              0x00160000<br>+#define EFI_FVB2_ALIGNMENT_8M              0x00170000<br>+#define EFI_FVB2_ALIGNMENT_16M             0x00180000<br>+#define EFI_FVB2_ALIGNMENT_32M             0x00190000<br>+#define EFI_FVB2_ALIGNMENT_64M             0x001a0000<br>+#define EFI_FVB2_ALIGNMENT_128M            0x001b0000<br>+#define EFI_FVB2_ALIGNMENT_256M            0x001c0000<br>+#define EFI_FVB2_ALIGNMENT_512M            0x001d0000<br>+#define EFI_FVB2_ALIGNMENT_1G              0x001e0000<br>+#define EFI_FVB2_ALIGNMENT_2G              0x001f0000<br>+<br>+/* SPI firmware volume and fmap related functions -<br>+ * This set of functions is based on the EFI firmware volume block2 protocol.<br>+ */<br>+uint32_t spi_get_fv_attribute(void);<br>+size_t spi_get_fv_blocksize(void);<br>+<br>+/* These functions translate fmap related requests to SPI related requests. */<br>+int spi_read_fmap_region(const char *name, uint32_t offset, size_t size, void *buffer);<br>+int spi_write_fmap_region(const char *name, uint32_t offset, size_t size, void *buffer);<br>+int spi_erase_fmap_region(const char *name, uint32_t offset, size_t size);<br>+<br> #endif /* __AMD_SPI_H__ */<br>diff --git a/src/soc/amd/common/block/spi/spi.c b/src/soc/amd/common/block/spi/spi.c<br>index 9bff570..34c973f 100644<br>--- a/src/soc/amd/common/block/spi/spi.c<br>+++ b/src/soc/amd/common/block/spi/spi.c<br>@@ -21,6 +21,7 @@<br> #include <device/device.h><br> #include <device/pci.h><br> #include <device/pci_ops.h><br>+#include <fmap.h><br> #include <spi_flash.h><br> #include <spi-generic.h><br> #include <amdblocks/spi.h><br>@@ -44,6 +45,107 @@<br> <br>   spi_flash_volatile_group_end(flash);<br> }<br>+<br>+/* SPI firmware volume related routines */<br>+<br>+/* Return the firmware volume attributes. These are currently fixed. */<br>+uint32_t spi_get_fv_attribute(void)<br>+{<br>+      return SPI_FV_ATTRIBUTES;<br>+}<br>+<br>+/* Return the erasable block size */<br>+size_t spi_get_fv_blocksize(void)<br>+{<br>+      struct spi_flash *flash = NULL;<br>+      int retval = spi_flash_probe(0, 0, flash);<br>+   if (retval) {<br>+                printk(BIOS_DEBUG, "Could not find SPI device\n");<br>+         return 0;<br>+    }<br>+<br>+ return flash->sector_size;<br>+}<br>+<br>+/* Memory mapped SPI access routines -<br>+ * These routines access the SPI through its memory mapped interface.<br>+ */<br>+<br>+int spi_read_fmap_region(const char *name, uint32_t offset, size_t size, void *buffer)<br>+{<br>+  struct spi_flash *flash = NULL;<br>+      struct region *area = NULL;<br>+  uint32_t spi_offset;<br>+<br>+      int retval = spi_flash_probe(0, 0, flash);<br>+   if (retval) {<br>+                printk(BIOS_DEBUG, "Could not find SPI device\n");<br>+         return -3;<br>+   }<br>+<br>+ if (fmap_locate_area(name, area)) {<br>+          printk(BIOS_DEBUG, "SPI FV region not found %s\n",name);<br>+           return -1;<br>+   };<br>+<br>+        if (offset + size > area->size) {<br>+              printk(BIOS_DEBUG, "SPI FV read upper bound violation\n");<br>+         return -2;<br>+   }<br>+<br>+ spi_offset = area->offset + offset + CONFIG_ROM_SIZE;<br>+     return spi_flash_read(flash, spi_offset, size, buffer);<br>+}<br>+<br>+int spi_write_fmap_region(const char *name, uint32_t offset, size_t size, void *buffer)<br>+{<br>+ struct spi_flash *flash = NULL;<br>+      struct region *area = NULL;<br>+  uint32_t spi_offset;<br>+<br>+      int retval = spi_flash_probe(0, 0, flash);<br>+   if (retval) {<br>+                printk(BIOS_DEBUG, "Could not find SPI device\n");<br>+         return -3;<br>+   }<br>+<br>+ if (fmap_locate_area(name, area)) {<br>+          printk(BIOS_DEBUG, "SPI FV region not found %s\n",name);<br>+           return -1;<br>+   };<br>+<br>+        if (offset + size > area->size) {<br>+              printk(BIOS_DEBUG, "SPI FV write upper bound violation\n");<br>+                return -2;<br>+   }<br>+<br>+ spi_offset = area->offset + offset + CONFIG_ROM_SIZE;<br>+     return spi_flash_write(flash, spi_offset, size, buffer);<br>+}<br>+<br>+int spi_erase_fmap_region(const char *name, uint32_t offset, size_t size)<br>+{<br>+      struct spi_flash *flash = NULL;<br>+      struct region *area = NULL;<br>+  uint32_t spi_offset;<br>+<br>+      int retval = spi_flash_probe(0, 0, flash);<br>+   if (retval) {<br>+                printk(BIOS_DEBUG, "Could not find SPI device\n");<br>+         return -3;<br>+   }<br>+<br>+ if (fmap_locate_area(name, area)) {<br>+          printk(BIOS_DEBUG, "SPI FV region not found %s\n",name);<br>+           return -1;<br>+   };<br>+   spi_offset = area->offset + offset + CONFIG_ROM_SIZE;<br>+     return spi_flash_erase(flash, spi_offset, size);<br>+}<br>+<br>+/* SPI alternate access mechanism -<br>+ * These routines access the SPI through its PCI register based interface.<br>+ */<br> <br> static uintptr_t spibar;<br> <br>@@ -136,6 +238,7 @@<br>        return 0;<br> }<br> <br>+/* TODO: Update these two routines to work with S3 */<br> int chipset_volatile_group_begin(const struct spi_flash *flash)<br> {<br>        if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))<br></pre><p>To view, visit <a href="https://review.coreboot.org/22065">change 22065</a>. To unsubscribe, 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/22065"/><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: I32208a214a6896308833ff34d459d5513b60ba7a </div>
<div style="display:none"> Gerrit-Change-Number: 22065 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: John E. Kabat Jr. <john.kabat@scarletltd.com> </div>
<div style="display:none"> Gerrit-Reviewer: frank vibrans <frank.vibrans@scarletltd.com> </div>