Edward O'Callaghan submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Sam McNally: Looks good to me, approved
sb600spi.c: Add support for 0x790b rev 0x61 (AMD Zen)

Adds support for rev 0x59 || 0x61 of did 0x790b.

This is quite confusing however it turns out FCH chipsets
called 'Promontory' contain the so-called SPI100 ip
core that uses memory mapping and not a ring buffer for
transactions. Typically this is found on both Stoney Ridge
and Zen platforms. In light of this, separate out the
promontory path into its own callback struct state tracker
so that it's implementation does not interfere with previous
generations that predate the SPI100 controller.

Since there is some life-time state required to track the mapping
during between the first attempted read and the final tear-down of
the spi master we take the opportunity to avoid static locals and
instead implement the functionality in a re-entrant way for follow
up clean ups.

BUG=none
BRANCH=none
TEST= Zork => 'Promontory (rev 0x61) detected.' &&
Grunt => 'Promontory (rev 0x4b) detected.'

Change-Id: I5ce63b5de863aed0442cb4ffeff981e9b2fa445b
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/44073
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Sam McNally <sammc@google.com>
---
M sb600spi.c
1 file changed, 64 insertions(+), 3 deletions(-)

diff --git a/sb600spi.c b/sb600spi.c
index 40434f0..2e27cee 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -55,6 +55,10 @@
#define FIFO_SIZE_OLD 8
#define FIFO_SIZE_YANGTZE 71

+struct sb600spi_data {
+ struct flashctx *flash;
+};
+
static int find_smbus_dev_rev(uint16_t vendor, uint16_t device)
{
struct pci_dev *smbus_dev = pci_dev_find(vendor, device);
@@ -116,8 +120,17 @@
if (rev == 0x4a) {
msg_pdbg("Yangtze detected.\n");
return CHIPSET_YANGTZE;
- } else if (rev == 0x4b) {
- msg_pdbg("Promontory detected.\n");
+ /**
+ * FCH chipsets called 'Promontory' are one's with the
+ * so-called SPI100 ip core that uses memory mapping and
+ * not a ring buffer for transactions. Typically this is
+ * found on both Stoney Ridge and Zen platforms.
+ *
+ * The revisions I have found by searching various lspci
+ * outputs are as follows: 0x4b, 0x59 & 0x61.
+ */
+ } else if (rev == 0x4b || rev == 0x59 || rev == 0x61) {
+ msg_pdbg("Promontory (rev 0x%02x) detected.\n", rev);
return CHIPSET_PROMONTORY;
} else {
msg_pwarn("FCH device found but SMBus revision 0x%02x does not match known values.\n"
@@ -541,6 +554,18 @@
return amd_imc_shutdown(dev);
}

+static int promontory_read_memmapped(struct flashctx *flash, uint8_t *buf,
+ unsigned int start, unsigned int len)
+{
+ struct sb600spi_data * data = (struct sb600spi_data *)flash->mst->spi.data;
+ if (!data->flash) {
+ map_flash(flash);
+ data->flash = flash; /* keep a copy of flashctx for unmap() on tear-down. */
+ }
+ mmio_readn((void *)(flash->virtual_memory + start), buf, len);
+ return 0;
+}
+
static struct spi_master spi_master_sb600 = {
.max_data_read = FIFO_SIZE_OLD,
.max_data_write = FIFO_SIZE_OLD - 3,
@@ -561,6 +586,25 @@
.write_aai = default_spi_write_aai,
};

+static struct spi_master spi_master_promontory = {
+ .max_data_read = MAX_DATA_READ_UNLIMITED,
+ .max_data_write = FIFO_SIZE_YANGTZE - 3,
+ .command = spi100_spi_send_command,
+ .multicommand = default_spi_send_multicommand,
+ .read = promontory_read_memmapped,
+ .write_256 = default_spi_write_256,
+ .write_aai = default_spi_write_aai,
+};
+
+static int sb600spi_shutdown(void *data)
+{
+ struct flashctx *flash = ((struct sb600spi_data *)data)->flash;
+ if (flash)
+ finalize_flash_access(flash);
+ free(data);
+ return 0;
+}
+
int sb600_probe_spi(struct pci_dev *dev)
{
struct pci_dev *smbus_dev;
@@ -726,11 +770,28 @@
if (handle_imc(dev, amd_gen) != 0)
return ERROR_FATAL;

+ struct sb600spi_data *data = calloc(1, sizeof(struct sb600spi_data));
+ if (!data) {
+ msg_perr("Unable to allocate space for extra SPI master data.\n");
+ return SPI_GENERIC_ERROR;
+ }
+
+ data->flash = NULL;
+
+ register_shutdown(sb600spi_shutdown, data);
+ spi_master_sb600.data = data;
+ spi_master_yangtze.data = data;
+ spi_master_promontory.data = data;
+
+
/* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */
if (amd_gen < CHIPSET_YANGTZE)
register_spi_master(&spi_master_sb600);
- else
+ else if (amd_gen == CHIPSET_YANGTZE)
register_spi_master(&spi_master_yangtze);
+ else
+ register_spi_master(&spi_master_promontory);
+
return 0;
}


To view, visit change 44073. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I5ce63b5de863aed0442cb4ffeff981e9b2fa445b
Gerrit-Change-Number: 44073
Gerrit-PatchSet: 11
Gerrit-Owner: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-Reviewer: Angel Pons <th3fanbus@gmail.com>
Gerrit-Reviewer: Chris McDonald <cjmcdonald@chromium.org>
Gerrit-Reviewer: Daniel Kurtz <djkurtz@chromium.org>
Gerrit-Reviewer: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-Reviewer: Kangheui Won <khwon@chromium.org>
Gerrit-Reviewer: Kangheui Won <khwon@google.com>
Gerrit-Reviewer: Martin Roth <martinroth@google.com>
Gerrit-Reviewer: Nico Huber <nico.h@gmx.de>
Gerrit-Reviewer: Sam McNally <sammc@google.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter@users.sourceforge.net>
Gerrit-MessageType: merged