<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>