From 609490854e60aa17fec246642fdf9a6205b33eb4 Mon Sep 17 00:00:00 2001 From: Srinidhi N Kaushik Date: Wed, 25 Nov 2020 01:58:34 -0800 Subject: soc/intel/common/fast_spi: Add extended decode window support This change enables support for configuration of extended BIOS region decode window. This configuration needs to be performed as early as possible in the boot flow. This is required to ensure that any access to the SPI flash region below 16MiB in coreboot is decoded correctly. The configuration for the extended BIOS window if required is done as part of fast_spi_early_init(). Changes include: 1. Make a call to fast_spi_enable_ext_bios() before the bus master and memory space is enabled for the fast SPI controller. 2. Added a helper function fast_spi_enable_ext_bios() which calls fast_spi_get_ext_bios_window() to get details about the extended BIOS window from the boot media map. 3. Depending upon the SPI flash device used by the mainboard and the size of the BIOS region in the flashmap, this function will have to perform this additional configuration only if the BIOS region is greater than 16MiB 4. Adddditionally, set up the general purpose memory range registers in DMI. BUG=b:171534504 Signed-off-by: Srinidhi N Kaushik Signed-off-by: Furquan Shaikh Change-Id: Idafd8be0261892122d0b5a95d9ce9d5604a10cf2 Reviewed-on: https://review.coreboot.org/c/coreboot/+/47990 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/fast_spi/fast_spi.c | 64 ++++++++++++++++++++++ src/soc/intel/common/block/fast_spi/fast_spi_def.h | 5 ++ .../common/block/include/intelblocks/fast_spi.h | 5 +- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/fast_spi/fast_spi.c b/src/soc/intel/common/block/fast_spi/fast_spi.c index 4190253dd1..24c667b845 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -246,6 +247,63 @@ void fast_spi_cache_bios_region(void) } } +/* + * Enable extended BIOS support + * Checks BIOS region in the flashmap, if its more than 16Mib, enables extended BIOS + * region support. + */ +static void fast_spi_enable_ext_bios(void) +{ +#if defined(__SIMPLE_DEVICE__) + pci_devfn_t dev = PCH_DEV_SPI; +#else + struct device *dev = PCH_DEV_SPI; +#endif + if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)) + return; + +#if CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW) + /* + * Ensure that the base for the extended window in host space is a multiple of 32 MiB + * and size is fixed at 32 MiB. Controller assumes that the extended window has a fixed + * size of 32 MiB even if the actual BIOS region is smaller. The mapping of the BIOS + * region happens at the top of the extended window in this case. + */ + _Static_assert(ALIGN_UP(CONFIG_EXT_BIOS_WIN_BASE, 32 * MiB) == CONFIG_EXT_BIOS_WIN_BASE, + "Extended BIOS window base must be a multiple of 32 * MiB!"); + _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE == (32 * MiB), + "Only 32MiB windows are supported for extended BIOS!"); +#endif + + /* Confgiure DMI Source decode for Extended BIOS Region */ + if (dmi_enable_gpmr(CONFIG_EXT_BIOS_WIN_BASE, CONFIG_EXT_BIOS_WIN_SIZE, + soc_get_spi_dmi_destination_id()) == CB_ERR) + return; + + /* Program EXT_BIOS_BAR1 with obtained ext_bios_base */ + pci_write_config32(dev, SPI_CFG_BAR1, + CONFIG_EXT_BIOS_WIN_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY); + + /* + * Since the top 16MiB of the BIOS region is always decoded by the standard window + * below the 4G boundary, we need to map the rest of the BIOS region that lies + * below the top 16MiB in the extended window. Thus, EXT_BIOS_LIMIT will be set to + * 16MiB. This determines the maximum address in the SPI flash space that is mapped + * to the top of the extended window in the host address space. EXT_BIOS_LIMIT is + * basically the offset from the end of the BIOS region that will be mapped to the top + * of the extended window. + * This enables the decoding as follows: + -Standard decode window: (bios_region_top - 16MiB) to bios_region_top + -Extended decode window: + (bios_region_top - 16MiB - MIN(extended_window_size, bios_size - 16MiB)) + to (bios_region_top - 16MiB). + */ + pci_or_config32(dev, SPIBAR_BIOS_CONTROL, SPIBAR_BIOS_CONTROL_EXT_BIOS_LIMIT(16 * MiB)); + + /* Program EXT_BIOS EN */ + pci_or_config32(dev, SPIBAR_BIOS_CONTROL, SPIBAR_BIOS_CONTROL_EXT_BIOS_ENABLE); +} + /* * Program temporary BAR for SPI in case any of the stages before ramstage need * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI @@ -270,6 +328,12 @@ void fast_spi_early_init(uintptr_t spi_base_address) pci_write_config32(dev, PCI_BASE_ADDRESS_0, spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY); + /* + * Enable extended bios support. Since it configures memory BAR, this is done before + * enabling MMIO space. + */ + fast_spi_enable_ext_bios(); + /* Enable Bus Master and MMIO Space */ pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_def.h b/src/soc/intel/common/block/fast_spi/fast_spi_def.h index bafe131877..883c3ce3eb 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_def.h +++ b/src/soc/intel/common/block/fast_spi/fast_spi_def.h @@ -8,6 +8,9 @@ #define SPIDVID_OFFSET 0x0 #define SPIBAR_BIOS_CONTROL 0xdc +/* Extended Bios Support Registers */ +#define SPI_CFG_BAR1 0xe0 /* SPI BAR1 MMIO */ + /* Bit definitions for BIOS_CONTROL */ #define SPIBAR_BIOS_CONTROL_WPD (1 << 0) #define SPIBAR_BIOS_CONTROL_LOCK_ENABLE (1 << 1) @@ -15,6 +18,8 @@ #define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE (1 << 3) #define SPIBAR_BIOS_CONTROL_EISS (1 << 5) #define SPIBAR_BIOS_CONTROL_BILD (1 << 7) +#define SPIBAR_BIOS_CONTROL_EXT_BIOS_ENABLE (1 << 27) +#define SPIBAR_BIOS_CONTROL_EXT_BIOS_LIMIT(x) ((x) & ~(0xfff)) /* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ diff --git a/src/soc/intel/common/block/include/intelblocks/fast_spi.h b/src/soc/intel/common/block/include/intelblocks/fast_spi.h index 0a7e64dad4..81437b6e6a 100644 --- a/src/soc/intel/common/block/include/intelblocks/fast_spi.h +++ b/src/soc/intel/common/block/include/intelblocks/fast_spi.h @@ -73,12 +73,15 @@ bool fast_spi_wpd_status(void); * Enable SPI Write protect. */ void fast_spi_enable_wp(void); - /* * Get base and size of extended BIOS decode window used at runtime in host address space. If * the BIOS region is not greater than 16MiB, then this function returns 0 for both base and * size. */ void fast_spi_get_ext_bios_window(uintptr_t *base, size_t *size); +/* + * SOC function to get SPI-DMI Destination Id + */ +uint32_t soc_get_spi_dmi_destination_id(void); #endif /* SOC_INTEL_COMMON_BLOCK_FAST_SPI_H */ -- cgit v1.2.3