<p>Marc Jones has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23132">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">amdfwtool: Add SPI mode and SPI speed support<br><br>Add SPI mode and SPI speed setting to the ROMSIG.<br>This is used by AGESA and the PSP for optimal SPI ROM reads.<br><br>BUG=b:70844938<br>TEST=build with mode and speed options.<br>     Check ROMSIG offset 0x40 is set as expected.<br><br>Change-Id: I025ab969893553982bb2191111912f7334143440<br>Signed-off-by: Marc Jones <marcj303@gmail.com><br>---<br>M util/amdfwtool/amdfwtool.c<br>1 file changed, 175 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/23132/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c</span><br><span>index 61c2a05..5a06e2a 100644</span><br><span>--- a/util/amdfwtool/amdfwtool.c</span><br><span>+++ b/util/amdfwtool/amdfwtool.c</span><br><span>@@ -21,6 +21,12 @@</span><br><span>  *  +------------+---------------+----------------+------------+</span><br><span>  *  | PSPDIR ADDR|PSPDIR ADDR    |<-- Field 0x14 could be either</span><br><span>  *  +------------+---------------+   2nd PSP directory or PSP COMBO directory</span><br><span style="color: hsl(120, 100%, 40%);">+ * ...</span><br><span style="color: hsl(120, 100%, 40%);">+ *  40</span><br><span style="color: hsl(120, 100%, 40%);">+ *  +------------+</span><br><span style="color: hsl(120, 100%, 40%);">+ *  | SPI Mode   | <- SPI mode(0x40) and SPI fast read speed(0x41)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  +------------+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span>  *  EC ROM should be 64K aligned.</span><br><span>  *</span><br><span>  *  PSP directory (Where "PSPDIR ADDR" points)</span><br><span>@@ -58,7 +64,6 @@</span><br><span>  *  +------------+---------------+----------------+------------+</span><br><span>  *</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #include <fcntl.h></span><br><span> #include <errno.h></span><br><span> #include <stdio.h></span><br><span>@@ -77,6 +82,7 @@</span><br><span> #define MIN_ROM_KB                256</span><br><span> </span><br><span> #define ALIGN(val, by) (((val) + (by) - 1) & ~((by) - 1))</span><br><span style="color: hsl(120, 100%, 40%);">+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))</span><br><span> </span><br><span> /*</span><br><span>   Reserved for future.</span><br><span>@@ -191,6 +197,10 @@</span><br><span>              MIN_ROM_KB);</span><br><span>         printf("                               and must a multiple of 1024\n");</span><br><span>    printf("-l | --location                Location of Directory\n");</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("-q | --spimode <MODE>          norm33, norm66\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("                               dual112, dual122\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("                               quad114, quad144, fast\n");</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("-z | --spispeed <SPEED>        16, 22, 33, 66, 100 (Mhz)\n");</span><br><span>        printf("-h | --help                    show this help\n");</span><br><span> </span><br><span> }</span><br><span>@@ -376,17 +386,129 @@</span><br><span>       return pos;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPI read modes</span><br><span style="color: hsl(120, 100%, 40%);">+ * 000b Normal read (up to 33M)</span><br><span style="color: hsl(120, 100%, 40%);">+ * 001b Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ * 010b Dual IO (1-1-2)</span><br><span style="color: hsl(120, 100%, 40%);">+ * 011b Quad IO (1-1-4)</span><br><span style="color: hsl(120, 100%, 40%);">+ * 100b Dual IO (1-2-2)</span><br><span style="color: hsl(120, 100%, 40%);">+ * 101b Quad IO (1-4-4)</span><br><span style="color: hsl(120, 100%, 40%);">+ * 110b Normal read (up to 66M)</span><br><span style="color: hsl(120, 100%, 40%);">+ * 111b Fast Read</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%);">+struct spimodes {</span><br><span style="color: hsl(120, 100%, 40%);">+      char *mode;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t val;</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 const struct spimodes modesettings[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+   {</span><br><span style="color: hsl(120, 100%, 40%);">+             .mode = "norm33",</span><br><span style="color: hsl(120, 100%, 40%);">+           .val =  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%);">+             .mode = "norm66",</span><br><span style="color: hsl(120, 100%, 40%);">+           .val =  6,</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%);">+             .mode = "dual112",</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 2,</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%);">+             .mode = "dual122",</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 4,</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%);">+             .mode = "quad114",</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 3,</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%);">+             .mode = "quad144",</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 5</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%);">+             .mode = "fast",</span><br><span style="color: hsl(120, 100%, 40%);">+             .val = 7,</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%);">+ * SPI read speed</span><br><span style="color: hsl(120, 100%, 40%);">+ * 0000b 66.66 MHz    0100b 100 MHz</span><br><span style="color: hsl(120, 100%, 40%);">+ * 0001b 33.33 MHz    0101b 800 KHz</span><br><span style="color: hsl(120, 100%, 40%);">+ * 0010b 22.22 MHz    1111b-0110b Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ * 0011b 16.66 MHz</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%);">+struct spispeeds {</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t speed;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t val;</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 const struct spispeeds speedsettings[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+             .speed = 66,</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 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%);">+             .speed = 33,</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 1,</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%);">+             .speed = 22,</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 2,</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%);">+             .speed = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+          .val = 3,</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%);">+             .speed = 100,</span><br><span style="color: hsl(120, 100%, 40%);">+         .val = 4,</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%);">+ * Set the mode in ROM_SIG offset 0x40 and the speed in offset 0x41.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void spi_mode_speed(uint32_t *romsig, char *spimode, uint8_t spispeed)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t modeval;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t speedval;</span><br><span style="color: hsl(120, 100%, 40%);">+     int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i  = 0; i < ARRAY_SIZE(modesettings); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (strcmp(spimode, modesettings[i].mode) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     modeval = modesettings[i].val;</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%);">+   for (i  = 0; i < ARRAY_SIZE(speedsettings); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (spispeed == speedsettings[i].speed) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     speedval = speedsettings[i].val;</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%);">+   romsig[16] = modeval | speedval << 8 | 0xDEAD << 16;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #if PSP2</span><br><span> static const char *optstring  =</span><br><span style="color: hsl(0, 100%, 40%);">-    "x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:P:B:S:L:R:K:C:N:D:T:U:W:E:M:o:f:l:h";</span><br><span style="color: hsl(120, 100%, 40%);">+        "x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:P:B:S:L:R:K:C:N:D:T:U:W:E:M:o:f:l:q:z:h";</span><br><span> #else</span><br><span style="color: hsl(0, 100%, 40%);">-static const char *optstring  = "x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:o:f:l:h";</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *optstring  = "x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:o:f:l:q:z:h";</span><br><span> #endif</span><br><span> </span><br><span> static struct option long_options[] = {</span><br><span>       {"xhci",             required_argument, 0, 'x' },</span><br><span>  {"imc",              required_argument, 0, 'i' },</span><br><span>  {"gec",              required_argument, 0, 'g' },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        /* PSP */</span><br><span>    {"pubkey",           required_argument, 0, 'p' },</span><br><span>  {"bootloader",       required_argument, 0, 'b' },</span><br><span>@@ -422,6 +544,8 @@</span><br><span>    {"output",           required_argument, 0, 'o' },</span><br><span>  {"flashsize",        required_argument, 0, 'f' },</span><br><span>  {"location",         required_argument, 0, 'l' },</span><br><span style="color: hsl(120, 100%, 40%);">+   {"spimode",          required_argument, 0, 'q' },</span><br><span style="color: hsl(120, 100%, 40%);">+   {"spispeed",         required_argument, 0, 'z' },</span><br><span>  {"help",             no_argument,       0, 'h' },</span><br><span> </span><br><span>      {NULL,               0,                 0,  0  }</span><br><span>@@ -484,6 +608,9 @@</span><br><span>       uint32_t dir_location = 0;</span><br><span>   uint32_t romsig_offset;</span><br><span>      uint32_t rom_base_address;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t spispeed = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *spimode = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span> </span><br><span>   while (1) {</span><br><span>          int optindex = 0;</span><br><span>@@ -636,6 +763,17 @@</span><br><span>                             retval = 1;</span><br><span>                  }</span><br><span>                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'q':</span><br><span style="color: hsl(120, 100%, 40%);">+                     spimode = optarg;</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'z':</span><br><span style="color: hsl(120, 100%, 40%);">+                     spispeed = (uint8_t)strtoul(optarg, &tmp, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (*tmp != '\0') {</span><br><span style="color: hsl(120, 100%, 40%);">+                           printf("Error: spispeed  specified"</span><br><span style="color: hsl(120, 100%, 40%);">+                                 " incorrectly (%s)\n\n", optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                           retval = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                   }</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span> </span><br><span>           case 'h':</span><br><span>                    usage();</span><br><span>@@ -667,6 +805,36 @@</span><br><span>              retval = 1;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (spimode) {</span><br><span style="color: hsl(120, 100%, 40%);">+                for (i  = 0; i < ARRAY_SIZE(modesettings); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (strcmp(spimode, modesettings[i].mode) == 0)</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%);">+           if (i == ARRAY_SIZE(modesettings)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("Error: spimode %s is not supported.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             spimode);</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("   Valid values are: norm33, norm66\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("                     dual112, dual122\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("                     quad114, quad144\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("                     fast\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    retval = 1;</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%);">+   if (spispeed) {</span><br><span style="color: hsl(120, 100%, 40%);">+               for (i  = 0; i < ARRAY_SIZE(speedsettings); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (spispeed == speedsettings[i].speed)</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%);">+           if (i == ARRAY_SIZE(speedsettings)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("Error: spispeed %d is not supported.\n", spispeed);</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("   Valid speeds are 16, 33, 66, and 100 (Mhz).\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                       retval = 1;</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>  if (retval) {</span><br><span>                usage();</span><br><span>             return retval;</span><br><span>@@ -714,7 +882,9 @@</span><br><span>         amd_romsig[2] = 0;</span><br><span>   amd_romsig[3] = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  current += 0x20;            /* size of ROMSIG */</span><br><span style="color: hsl(120, 100%, 40%);">+      spi_mode_speed(amd_romsig, spimode, spispeed);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      current += 0x50;                /* size of ROMSIG */</span><br><span>         current = ALIGN(current, 0x1000U);</span><br><span>   current = integrate_firmwares(rom, current, amd_romsig,</span><br><span>                      amd_fw_table, rom_size);</span><br><span>@@ -769,6 +939,7 @@</span><br><span>       }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);</span><br><span>   if (targetfd >= 0) {</span><br><span>              write(targetfd, amd_romsig, current - romsig_offset);</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23132">change 23132</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/23132"/><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: I025ab969893553982bb2191111912f7334143440 </div>
<div style="display:none"> Gerrit-Change-Number: 23132 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Marc Jones <marc@marcjonesconsulting.com> </div>