Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1313
-gerrit
commit 857f723d69b14fa52a3ab3c1c515d2303e75c8cb Author: Duncan Laurie dlaurie@chromium.org Date: Sat Jun 23 16:53:57 2012 -0700
SMM: Add option for SPI driver to be available in SMM
- add Kconfig option for CONFIG_SPI_FLASH_SMM - compile subsystem and chip drivers for smm if enabled - change mdelay(1) to udelay(500) since mdelay is not defined in SMM and a 1ms delay is worth avoiding - make flash chip structure non-const so the probe function pointers can be relocated for use in TSEG - Make SMM PCI access possible in southbridge SPI code
Change-Id: Icfcbbe8e4e56658769d46af0b5bf6c79a6432641 Signed-off-by: Duncan Laurie dlaurie@chromium.org --- src/drivers/spi/Kconfig | 7 ++++ src/drivers/spi/Makefile.inc | 13 ++++++++ src/drivers/spi/spi_flash.c | 11 ++++++- src/southbridge/intel/bd82x6x/Makefile.inc | 1 + src/southbridge/intel/bd82x6x/spi.c | 43 +++++++++++++++++++++++---- 5 files changed, 66 insertions(+), 9 deletions(-)
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig index ee7584c..e022290 100644 --- a/src/drivers/spi/Kconfig +++ b/src/drivers/spi/Kconfig @@ -24,6 +24,13 @@ config SPI_FLASH Select this option if your chipset driver needs to store certain data in the SPI flash.
+config SPI_FLASH_SMM + bool "SPI flash driver support in SMM" + default n + depends on SPI_FLASH && HAVE_SMI_HANDLER + help + Select this option if you want SPI flash support in SMM. + config SPI_FLASH_EON bool default y diff --git a/src/drivers/spi/Makefile.inc b/src/drivers/spi/Makefile.inc index 1814e80..7f94abd 100644 --- a/src/drivers/spi/Makefile.inc +++ b/src/drivers/spi/Makefile.inc @@ -10,3 +10,16 @@ ramstage-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c ramstage-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c ramstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
+ifeq ($(CONFIG_SPI_FLASH_SMM),y) +# SPI flash driver interface +smm-$(CONFIG_SPI_FLASH) += spi_flash.c + +# drivers +smm-$(CONFIG_SPI_FLASH_EON) += eon.c +smm-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.c +smm-$(CONFIG_SPI_FLASH_SPANSION) += spansion.c +smm-$(CONFIG_SPI_FLASH_SST) += sst.c +smm-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c +smm-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c +smm-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c +endif \ No newline at end of file diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index 6cec611..78c209d 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -12,6 +12,9 @@ #include <spi.h> #include <spi_flash.h> #include <delay.h> +#ifdef __SMM__ +#include <cpu/x86/smm.h> +#endif #include "spi_flash_internal.h"
static void spi_flash_addr(u32 addr, u8 *cmd) @@ -115,7 +118,7 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, if ((status & poll_bit) == 0) break;
- mdelay(1); + udelay(500); } while (timebase--);
if ((status & poll_bit) == 0) @@ -206,7 +209,7 @@ out: */ #define IDCODE_CONT_LEN 0 #define IDCODE_PART_LEN 5 -static const struct { +static struct { const u8 shift; const u8 idcode; struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); @@ -275,6 +278,10 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, /* search the table for matches in shift and id */ for (i = 0; i < ARRAY_SIZE(flashes); ++i) if (flashes[i].shift == shift && flashes[i].idcode == *idp) { +#ifdef __SMM__ + /* Need to relocate this function */ + tseg_relocate((void **)&flashes[i].probe); +#endif /* we have a match, call probe */ flash = flashes[i].probe(spi, idp); if (flash) diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc index 11a6b08..3de2bd0 100644 --- a/src/southbridge/intel/bd82x6x/Makefile.inc +++ b/src/southbridge/intel/bd82x6x/Makefile.inc @@ -33,6 +33,7 @@ ramstage-y += reset.c ramstage-y += watchdog.c
ramstage-y += spi.c +smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c me_8.x.c finalize.c diff --git a/src/southbridge/intel/bd82x6x/spi.c b/src/southbridge/intel/bd82x6x/spi.c index 4cd9af0..6b39571 100644 --- a/src/southbridge/intel/bd82x6x/spi.c +++ b/src/southbridge/intel/bd82x6x/spi.c @@ -27,20 +27,45 @@ #include <delay.h> #include <arch/io.h> #include <console/console.h> -#include <device/pci.h> #include <device/pci_ids.h>
#include <spi.h>
#define min(a, b) ((a)<(b)?(a):(b))
+#ifdef __SMM__ +#include <arch/romcc_io.h> +#include <northbridge/intel/sandybridge/pcie_config.c> +typedef device_t pci_dev_t; +#define pci_read_config_byte(dev, reg, targ)\ + *(targ) = pcie_read_config8(dev, reg) +#define pci_read_config_word(dev, reg, targ)\ + *(targ) = pcie_read_config16(dev, reg) +#define pci_read_config_dword(dev, reg, targ)\ + *(targ) = pcie_read_config32(dev, reg) +#define pci_write_config_byte(dev, reg, val)\ + pcie_write_config8(dev, reg, val) +#define pci_write_config_word(dev, reg, val)\ + pcie_write_config16(dev, reg, val) +#define pci_write_config_dword(dev, reg, val)\ + pcie_write_config32(dev, reg, val) +#else /* !__SMM__ */ +#include <device/device.h> +#include <device/pci.h> typedef device_t pci_dev_t; -#define pci_read_config_byte(dev, reg, targ) *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ) *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ) *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val) pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val) pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val) pci_write_config32(dev, reg, val) +#define pci_read_config_byte(dev, reg, targ)\ + *(targ) = pci_read_config8(dev, reg) +#define pci_read_config_word(dev, reg, targ)\ + *(targ) = pci_read_config16(dev, reg) +#define pci_read_config_dword(dev, reg, targ)\ + *(targ) = pci_read_config32(dev, reg) +#define pci_write_config_byte(dev, reg, val)\ + pci_write_config8(dev, reg, val) +#define pci_write_config_word(dev, reg, val)\ + pci_write_config16(dev, reg, val) +#define pci_write_config_dword(dev, reg, val)\ + pci_write_config32(dev, reg, val) +#endif /* !__SMM__ */
typedef struct spi_slave ich_spi_slave;
@@ -310,7 +335,11 @@ void spi_init(void) uint32_t ids; uint16_t vendor_id, device_id;
+#ifdef __SMM__ + dev = PCI_DEV(0, 31, 0); +#else dev = dev_find_slot(0, PCI_DEVFN(31, 0)); +#endif pci_read_config_dword(dev, 0, &ids); vendor_id = ids; device_id = (ids >> 16);