[coreboot] New patch to review for coreboot: 857f723 SMM: Add option for SPI driver to be available in SMM

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Jul 24 00:31:19 CEST 2012


Stefan Reinauer (stefan.reinauer at 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 at 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 at 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);




More information about the coreboot mailing list