Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16202
-gerrit
commit fbe9fa581126b355b23dab8f0157e12e8c0c9c06
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 23:55:39 2016 -0500
soc/intel/skylake: use SPI flash boot_device_rw() for ealy stages
If the boot device is SPI flash use the common one in the
early stages. While tweaking the config don't auto select
SPI_FLASH as that is handled automatically by the rest of the
build system.
BUG=chrome-os-partner:56151
Change-Id: Ifd51a80fd008c336233d6e460c354190fcc0ef22
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/soc/intel/skylake/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index 909dcec..f13c84e 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -13,6 +13,7 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_ROMSTAGE_X86_32
select ARCH_VERSTAGE_X86_32
select ACPI_NHLT
+ select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH
select BOOT_DEVICE_SUPPORTS_WRITES
select CACHE_MRC_SETTINGS
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
@@ -46,7 +47,6 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON_RESET
select SMM_TSEG
select SMP
- select SPI_FLASH
select SSE2
select SUPPORT_CPU_UCODE_IN_CBFS
select TSC_CONSTANT_RATE
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16203
-gerrit
commit 847d2b050d71c8f2d0cd52cc4dfa94b65397d7ba
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Aug 12 12:42:04 2016 -0500
lib/fmap: provide RW region device support
Explicitly provide a RW view of an FMAP region. This is required
for platforms which have separate implementations of a RO boot
device and a RW boot device.
BUG=chrome-os-partner:56151
Change-Id: Ibafa3dc534f53a3d90487f3190c0f8a2e82858c2
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/fmap.h | 4 ++++
src/lib/fmap.c | 10 ++++++++++
2 files changed, 14 insertions(+)
diff --git a/src/include/fmap.h b/src/include/fmap.h
index 684a05c..5834831 100644
--- a/src/include/fmap.h
+++ b/src/include/fmap.h
@@ -27,6 +27,10 @@ int find_fmap_directory(struct region_device *fmrd);
* 0 on success, < 0 on error. */
int fmap_locate_area_as_rdev(const char *name, struct region_device *area);
+/* Just like fmap_locate_area_as_rdev(), however the region device is
+ * created from the RW boot device. */
+int fmap_locate_area_as_rdev_rw(const char *name, struct region_device *area);
+
/* Locate the named area in the fmap and fill in a region with the
* offset and size of that area within the boot media. Return 0 on success,
* < 0 on error. */
diff --git a/src/lib/fmap.c b/src/lib/fmap.c
index bf99037..9602134 100644
--- a/src/lib/fmap.c
+++ b/src/lib/fmap.c
@@ -80,6 +80,16 @@ int fmap_locate_area_as_rdev(const char *name, struct region_device *area)
return boot_device_ro_subregion(&ar, area);
}
+int fmap_locate_area_as_rdev_rw(const char *name, struct region_device *area)
+{
+ struct region ar;
+
+ if (fmap_locate_area(name, &ar))
+ return -1;
+
+ return boot_device_rw_subregion(&ar, area);
+}
+
int fmap_locate_area(const char *name, struct region *ar)
{
struct region_device fmrd;
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16200
-gerrit
commit 7c00026a40b210b6ee198abe3c8689fa3072028a
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 18:24:54 2016 -0500
drivers/spi: provide optional implementation of boot_device_rw()
On many x86 platforms the boot device is SPI which is memory
mapped. However, in order to write to the boot device one needs
to use the SPI api. Therefore, provide a common implementation
of boot_device_rw() which has no mmap() functionality. It only
reads, writes, and erases. This will be used in the existing
infrastructure but in a SPI agnostic way.
Two options are added:
1. BOOT_DEVICE_SPI_FLASH_RW_NOMMAP
2. BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY
The former is auto-selected when COMMON_CBFS_SPI_WRAPPER is not
selected. The latter can be used to include the implementation
in the early stages such as bootblock, verstage, and romstage.
BUG=chrome-os-partner:56151
Change-Id: I2aa75f88409309e3f9b9bd79b52d27c0061139c8
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/drivers/spi/Kconfig | 17 +++++++
src/drivers/spi/Makefile.inc | 5 ++
src/drivers/spi/boot_device_rw_nommap.c | 90 +++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+)
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig
index 5eb9b56..4c2fd1f 100644
--- a/src/drivers/spi/Kconfig
+++ b/src/drivers/spi/Kconfig
@@ -39,6 +39,23 @@ config BOOT_DEVICE_SPI_FLASH_BUS
help
Which SPI bus the boot device is connected to.
+config BOOT_DEVICE_SPI_FLASH_RW_NOMMAP
+ bool
+ default y if !COMMON_CBFS_SPI_WRAPPER
+ default n
+ depends on BOOT_DEVICE_SPI_FLASH
+ help
+ Provide common implementation of the RW boot device that
+ doesn't provide mmap() operations.
+
+config BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY
+ bool
+ default n
+ depends on BOOT_DEVICE_SPI_FLASH_RW_NOMMAP
+ help
+ Include the common implementation in all stages, including the
+ early ones.
+
config SPI_FLASH_INCLUDE_ALL_DRIVERS
bool
default n if COMMON_CBFS_SPI_WRAPPER
diff --git a/src/drivers/spi/Makefile.inc b/src/drivers/spi/Makefile.inc
index 8fd5984..92baf62 100644
--- a/src/drivers/spi/Makefile.inc
+++ b/src/drivers/spi/Makefile.inc
@@ -9,6 +9,7 @@ endif
bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
bootblock-$(CONFIG_SPI_FLASH) += spi_flash.c
+bootblock-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY) += boot_device_rw_nommap.c
bootblock-$(CONFIG_SPI_FLASH_ADESTO) += adesto.c
bootblock-$(CONFIG_SPI_FLASH_AMIC) += amic.c
bootblock-$(CONFIG_SPI_FLASH_ATMEL) += atmel.c
@@ -23,6 +24,7 @@ bootblock-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
romstage-$(CONFIG_SPI_FLASH) += spi_flash.c
+romstage-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY) += boot_device_rw_nommap.c
romstage-$(CONFIG_SPI_FLASH_ADESTO) += adesto.c
romstage-$(CONFIG_SPI_FLASH_AMIC) += amic.c
romstage-$(CONFIG_SPI_FLASH_ATMEL) += atmel.c
@@ -37,6 +39,7 @@ romstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
verstage-$(CONFIG_SPI_FLASH) += spi_flash.c
+verstage-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY) += boot_device_rw_nommap.c
verstage-$(CONFIG_SPI_FLASH_ADESTO) += adesto.c
verstage-$(CONFIG_SPI_FLASH_AMIC) += amic.c
verstage-$(CONFIG_SPI_FLASH_ATMEL) += atmel.c
@@ -51,6 +54,7 @@ verstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
ramstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
ramstage-$(CONFIG_SPI_FLASH) += spi_flash.c
+ramstage-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP) += boot_device_rw_nommap.c
ramstage-$(CONFIG_SPI_FLASH_ADESTO) += adesto.c
ramstage-$(CONFIG_SPI_FLASH_AMIC) += amic.c
ramstage-$(CONFIG_SPI_FLASH_ATMEL) += atmel.c
@@ -66,6 +70,7 @@ ramstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
ifeq ($(CONFIG_SPI_FLASH_SMM),y)
# SPI flash driver interface
smm-$(CONFIG_SPI_FLASH) += spi_flash.c
+smm-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP) += boot_device_rw_nommap.c
# drivers
smm-$(CONFIG_SPI_FLASH_ADESTO) += adesto.c
diff --git a/src/drivers/spi/boot_device_rw_nommap.c b/src/drivers/spi/boot_device_rw_nommap.c
new file mode 100644
index 0000000..2a9f19f
--- /dev/null
+++ b/src/drivers/spi/boot_device_rw_nommap.c
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/early_variables.h>
+#include <boot_device.h>
+#include <spi_flash.h>
+
+static struct spi_flash *sfg CAR_GLOBAL;
+
+static ssize_t spi_readat(const struct region_device *rd, void *b,
+ size_t offset, size_t size)
+{
+ struct spi_flash *sf = car_get_var(sfg);
+
+ if (sf == NULL)
+ return -1;
+
+ if (sf->read(sf, offset, size, b))
+ return -1;
+
+ return size;
+}
+
+static ssize_t spi_writeat(const struct region_device *rd, const void *b,
+ size_t offset, size_t size)
+{
+ struct spi_flash *sf = car_get_var(sfg);
+
+ if (sf == NULL)
+ return -1;
+
+ if (sf->write(sf, offset, size, b))
+ return -1;
+
+ return size;
+}
+
+static ssize_t spi_eraseat(const struct region_device *rd,
+ size_t offset, size_t size)
+{
+ struct spi_flash *sf = car_get_var(sfg);
+
+ if (sf == NULL)
+ return -1;
+
+ if (sf->erase(sf, offset, size))
+ return -1;
+
+ return size;
+}
+
+static const struct region_device_ops spi_ops = {
+ .readat = spi_readat,
+ .writeat = spi_writeat,
+ .eraseat = spi_eraseat,
+};
+
+static const struct region_device spi_rw =
+ REGION_DEV_INIT(&spi_ops, 0, CONFIG_ROM_SIZE);
+
+void boot_device_init(void)
+{
+ const int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS;
+ const int cs = 0;
+
+ if (car_get_var(sfg) != NULL)
+ return;
+
+ car_set_var(sfg, spi_flash_probe(bus, cs));
+}
+
+const struct region_device *boot_device_rw(void)
+{
+ if (car_get_var(sfg) == NULL)
+ return NULL;
+
+ return &spi_rw;
+}
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16201
-gerrit
commit fb630ee52405ade13dc308f8597c6e5075a9025f
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 23:51:42 2016 -0500
soc/intel/apollolake: use SPI flash boot_device_rw() for ealy stages
If the boot device is SPI flash use the common one in the
early stages. While tweaking the config don't auto select
SPI_FLASH as that is handled automatically by the rest of the
build system.
BUG=chrome-os-partner:56151
Change-Id: If5e3d06008d5529dd6d7c05d374a81ba172d58fd
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/soc/intel/apollolake/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index 0c7f27a..db4559c 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -12,6 +12,7 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_RAMSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_VERSTAGE_X86_32
+ select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH
select BOOT_DEVICE_SUPPORTS_WRITES
# CPU specific options
select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
@@ -49,7 +50,6 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
select SOC_INTEL_COMMON_LPSS_I2C
select SOC_INTEL_COMMON_SMI
- select SPI_FLASH
select UDELAY_TSC
select TSC_CONSTANT_RATE
select TSC_MONOTONIC_TIMER
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16228
-gerrit
commit c51857e34b13b099a103ff5956b8180b664d488d
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 14:04:10 2016 -0500
Kconfig: separate memory mapped boot device from SPI
Make the indication of the boot device being memory mapped
separate from SPI. However, retain the same defaults that
previously existed.
BUG=chrome-os-partner:56151
Change-Id: I06f138078c47a1e4b4b3edbdbf662f171e11c9d4
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/Kconfig | 7 +++++++
src/drivers/elog/elog.c | 4 ++--
src/drivers/spi/Kconfig | 7 -------
src/lib/cbfs.c | 2 +-
src/soc/intel/apollolake/romstage.c | 3 ++-
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index 04b8d24..f7a924f 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -483,6 +483,13 @@ config BOOT_DEVICE_SPI_FLASH
default y if !BOOT_DEVICE_NOT_SPI_FLASH
default n
+config BOOT_DEVICE_MEMORY_MAPPED
+ bool
+ default y if ARCH_X86 && BOOT_DEVICE_SPI_FLASH
+ default n
+ help
+ Inform system if SPI is memory-mapped or not.
+
config RTC
bool
default n
diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c
index 0b7dee3..3d8c85c8 100644
--- a/src/drivers/elog/elog.c
+++ b/src/drivers/elog/elog.c
@@ -586,8 +586,8 @@ static int elog_shrink(void)
*/
static inline u8 *elog_flash_offset_to_address(void)
{
- /* Only support memory-mapped SPI devices. */
- if (!IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED))
+ /* Only support memory-mapped devices. */
+ if (!IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED))
return NULL;
if (!elog_spi)
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig
index ee48d67..b0187fd 100644
--- a/src/drivers/spi/Kconfig
+++ b/src/drivers/spi/Kconfig
@@ -45,13 +45,6 @@ config SPI_ATOMIC_SEQUENCING
in the SPI controller. Hardware manages the transaction instead of
software. This is common on x86 platforms.
-config SPI_FLASH_MEMORY_MAPPED
- bool
- default y if ARCH_X86
- default n if !ARCH_X86
- help
- Inform system if SPI is memory-mapped or not.
-
config SPI_FLASH_SMM
bool "SPI flash driver support in SMM"
default n
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 7a0f187..7318c87 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -193,7 +193,7 @@ int cbfs_prog_stage_load(struct prog *pstage)
/* Hacky way to not load programs over read only media. The stages
* that would hit this path initialize themselves. */
if (ENV_VERSTAGE && !IS_ENABLED(CONFIG_NO_XIP_EARLY_STAGES) &&
- IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED)) {
void *mapping = rdev_mmap(fh, foffset, fsize);
rdev_munmap(fh, mapping);
if (mapping == load)
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index 8f17fdd..067d654 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -160,7 +160,8 @@ void platform_fsp_memory_init_params_cb(struct FSPM_UPD *mupd)
* state machine transition to next boot state, so that it can function
* as designed.
*/
- mupd->FspmConfig.SkipCseRbp = IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED);
+ mupd->FspmConfig.SkipCseRbp =
+ IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED);
}
__attribute__ ((weak))
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16199
-gerrit
commit 9c8fcdf264bc058627ec302b9d29dab5bc8f9cbf
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 11:10:42 2016 -0500
lib/cbfs_spi: provide boot_device_rw() support
Provide the RW boot device operations for the common cbfs
SPI wrapper. The RW region_device is the same as the read-only
one. As noted in the boot_device_rw() introduction patch the
mmap() support should not be used in conjuction with writing
as that results in incoherent operations. That's fine as the
current mmap() support is only used in the cbfs layer which
does not support writing, i.e. no cbfs regions would be
written to with any previous or outstanding mmap() calls.
BUG=chrome-os-partner:56151
Change-Id: I7cc7309a68ad23b30208ac961b1999a79626b307
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/drivers/spi/cbfs_spi.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/drivers/spi/cbfs_spi.c b/src/drivers/spi/cbfs_spi.c
index bbe9125..1895b9d 100644
--- a/src/drivers/spi/cbfs_spi.c
+++ b/src/drivers/spi/cbfs_spi.c
@@ -34,10 +34,29 @@ static ssize_t spi_readat(const struct region_device *rd, void *b,
return size;
}
+static ssize_t spi_writeat(const struct region_device *rd, const void *b,
+ size_t offset, size_t size)
+{
+ if (spi_flash_info->write(spi_flash_info, offset, size, b))
+ return -1;
+ return size;
+}
+
+static ssize_t spi_eraseat(const struct region_device *rd,
+ size_t offset, size_t size)
+{
+ if (spi_flash_info->erase(spi_flash_info, offset, size))
+ return -1;
+ return size;
+}
+
+/* Provide all operations on the same device. */
static const struct region_device_ops spi_ops = {
.mmap = mmap_helper_rdev_mmap,
.munmap = mmap_helper_rdev_munmap,
.readat = spi_readat,
+ .writeat = spi_writeat,
+ .eraseat = spi_eraseat,
};
static struct mmap_helper_region_device mdev =
@@ -78,3 +97,9 @@ const struct region_device *boot_device_ro(void)
return &mdev.rdev;
}
+
+/* The read-only and read-write implementations are symmetric. */
+const struct region_device *boot_device_rw(void)
+{
+ return boot_device_ro();
+}
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16196
-gerrit
commit 0bab5b7f9c72289dbf5bd11a0a47e72798d8fc40
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 17:13:40 2016 -0500
soc/intel/skylake: make SPI support early stages
Using malloc() in SPI code is unnecessary as there's only
one SPI device that the SoC support code handles: boot
device. Therefore, use CAR to for the storage to work around
the current limiations of the SPI API which expects one to
return pointers to objects that are writable. Additionally,
include the SPI support code as well as its dependencies in
all the stages.
BUG=chrome-os-partner:56151
Change-Id: I0192ab59f3555deaf6a6878cc31c059c5c2b7d3f
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/soc/intel/skylake/Makefile.inc | 3 +++
src/soc/intel/skylake/flash_controller.c | 22 +++++++++++-----------
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index 7b27c57..fa7a693 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -14,6 +14,7 @@ bootblock-y += bootblock/cache_as_ram.S
bootblock-y += bootblock/cpu.c
bootblock-y += bootblock/pch.c
bootblock-y += bootblock/systemagent.c
+bootblock-y += flash_controller.c
bootblock-$(CONFIG_UART_DEBUG) += bootblock/uart.c
bootblock-y += gpio.c
bootblock-y += monotonic_timer.c
@@ -23,6 +24,8 @@ bootblock-y += pmutil.c
bootblock-y += tsc_freq.c
bootblock-$(CONFIG_UART_DEBUG) += uart_debug.c
+verstage-y += flash_controller.c
+verstage-y += pch.c
verstage-$(CONFIG_UART_DEBUG) += uart_debug.c
romstage-y += flash_controller.c
diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c
index 9c2378b..6601e6c 100644
--- a/src/soc/intel/skylake/flash_controller.c
+++ b/src/soc/intel/skylake/flash_controller.c
@@ -13,6 +13,7 @@
*/
/* This file is derived from the flashrom project. */
+#include <arch/early_variables.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -341,15 +342,17 @@ int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg)
return 0;
}
+static struct spi_slave boot_spi CAR_GLOBAL;
+static struct spi_flash boot_flash CAR_GLOBAL;
+
static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi)
{
struct spi_flash *flash;
- flash = malloc(sizeof(*flash));
- if (!flash) {
- printk(BIOS_WARNING, "SF: Failed to allocate memory\n");
- return NULL;
- }
+ flash = car_get_var_ptr(&boot_flash);
+
+ /* Ensure writes can take place to the flash. */
+ spi_init();
flash->spi = spi;
flash->name = "Opaque HW-sequencing";
@@ -369,14 +372,11 @@ static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi)
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
{
- struct spi_slave *slave = malloc(sizeof(*slave));
-
- if (!slave) {
- printk(BIOS_DEBUG, "PCH SPI: Bad allocation\n");
+ /* This is special hardware. We expect bus 0 and CS line 0 here. */
+ if ((bus != 0) || (cs != 0))
return NULL;
- }
- memset(slave, 0, sizeof(*slave));
+ struct spi_slave *slave = car_get_var_ptr(&boot_spi);
slave->bus = bus;
slave->cs = cs;
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16212
-gerrit
commit 210cbf2e3396a33c4f3d77b0b2fb4b9411ba9654
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Aug 12 15:50:16 2016 -0500
drivers/spi: move cbfs_spi.c location
The common boot device spi implementation is very much
specific to SPI flash. As such it should be moved into
that subdirectory. It's still a high-level option but
it correctly depends on BOOT_DEVICE_SPI_FLASH. Additionally
that allows the auto-selection of SPI_FLASH by a platform
selecting COMMON_CBFS_SPI_WRAPPER which allows for culling
of SPI_FLASH selections everywhere.
BUG=chrome-os-partner:56151
Change-Id: Ia2ccfdc9e1a4348cd91b381f9712d8853b7d2a79
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/Kconfig | 8 -----
src/drivers/spi/Kconfig | 8 +++++
src/drivers/spi/Makefile.inc | 4 +++
src/drivers/spi/cbfs_spi.c | 80 ++++++++++++++++++++++++++++++++++++++++++++
src/lib/Makefile.inc | 5 ---
src/lib/cbfs_spi.c | 80 --------------------------------------------
6 files changed, 92 insertions(+), 93 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index f7a924f..fd98cc8 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -35,14 +35,6 @@ config CBFS_PREFIX
Select the prefix to all files put into the image. It's "fallback"
by default, "normal" is a common alternative.
-config COMMON_CBFS_SPI_WRAPPER
- bool
- default n
- depends on SPI_FLASH
- depends on !ARCH_X86
- help
- Use common wrapper to interface CBFS to SPI bootrom.
-
choice
prompt "Compiler to use"
default COMPILER_GCC
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig
index b0187fd..030fa6c 100644
--- a/src/drivers/spi/Kconfig
+++ b/src/drivers/spi/Kconfig
@@ -13,6 +13,14 @@
## GNU General Public License for more details.
##
+config COMMON_CBFS_SPI_WRAPPER
+ bool
+ default n
+ depends on !ARCH_X86
+ depends on BOOT_DEVICE_SPI_FLASH
+ help
+ Use common wrapper to interface CBFS to SPI bootrom.
+
config SPI_FLASH
bool
default y if BOOT_DEVICE_SPI_FLASH
diff --git a/src/drivers/spi/Makefile.inc b/src/drivers/spi/Makefile.inc
index 6b4182e..e976059 100644
--- a/src/drivers/spi/Makefile.inc
+++ b/src/drivers/spi/Makefile.inc
@@ -8,6 +8,7 @@ smm-$(CONFIG_DEBUG_SMI) += spiconsole.c
endif
ifeq ($(CONFIG_COMMON_CBFS_SPI_WRAPPER),y)
+bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
bootblock-y += spi_flash.c
bootblock-$(CONFIG_SPI_FLASH_EON) += eon.c
bootblock-$(CONFIG_SPI_FLASH_GIGADEVICE) += gigadevice.c
@@ -18,6 +19,7 @@ bootblock-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c
bootblock-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c
bootblock-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
+romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
romstage-$(CONFIG_SPI_FLASH) += spi_flash.c
romstage-$(CONFIG_SPI_FLASH_EON) += eon.c
romstage-$(CONFIG_SPI_FLASH_GIGADEVICE) += gigadevice.c
@@ -28,6 +30,7 @@ romstage-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c
romstage-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c
romstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
+verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
verstage-$(CONFIG_SPI_FLASH) += spi_flash.c
verstage-$(CONFIG_SPI_FLASH_EON) += eon.c
verstage-$(CONFIG_SPI_FLASH_GIGADEVICE) += gigadevice.c
@@ -40,6 +43,7 @@ verstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c
endif
+ramstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
ramstage-$(CONFIG_SPI_FLASH) += spi_flash.c
# drivers
diff --git a/src/drivers/spi/cbfs_spi.c b/src/drivers/spi/cbfs_spi.c
new file mode 100644
index 0000000..bbe9125
--- /dev/null
+++ b/src/drivers/spi/cbfs_spi.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This file provides a common CBFS wrapper for SPI storage. SPI driver
+ * context is expanded with the buffer descriptor used to store data read from
+ * SPI.
+ */
+
+#include <boot_device.h>
+#include <spi_flash.h>
+#include <symbols.h>
+#include <cbmem.h>
+
+static struct spi_flash *spi_flash_info;
+
+static ssize_t spi_readat(const struct region_device *rd, void *b,
+ size_t offset, size_t size)
+{
+ if (spi_flash_info->read(spi_flash_info, offset, size, b))
+ return -1;
+ return size;
+}
+
+static const struct region_device_ops spi_ops = {
+ .mmap = mmap_helper_rdev_mmap,
+ .munmap = mmap_helper_rdev_munmap,
+ .readat = spi_readat,
+};
+
+static struct mmap_helper_region_device mdev =
+ MMAP_HELPER_REGION_INIT(&spi_ops, 0, CONFIG_ROM_SIZE);
+
+static void switch_to_postram_cache(int unused)
+{
+ /*
+ * Call boot_device_init() to ensure spi_flash is initialized before
+ * backing mdev with postram cache. This prevents the mdev backing from
+ * being overwritten if spi_flash was not accessed before dram was up.
+ */
+ boot_device_init();
+ if (_preram_cbfs_cache != _postram_cbfs_cache)
+ mmap_helper_device_init(&mdev, _postram_cbfs_cache,
+ _postram_cbfs_cache_size);
+}
+ROMSTAGE_CBMEM_INIT_HOOK(switch_to_postram_cache);
+
+void boot_device_init(void)
+{
+ int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS;
+ int cs = 0;
+
+ if (spi_flash_info != NULL)
+ return;
+
+ spi_flash_info = spi_flash_probe(bus, cs);
+
+ mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size);
+}
+
+/* Return the CBFS boot device. */
+const struct region_device *boot_device_ro(void)
+{
+ if (spi_flash_info == NULL)
+ return NULL;
+
+ return &mdev.rdev;
+}
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 5f708a6..e2cf9ef 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -22,7 +22,6 @@ endif
bootblock-y += prog_loaders.c
bootblock-y += prog_ops.c
bootblock-y += cbfs.c
-bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
bootblock-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
bootblock-y += libgcc.c
bootblock-$(CONFIG_GENERIC_UDELAY) += timer.c
@@ -49,7 +48,6 @@ verstage-y += memcmp.c
verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
verstage-y += boot_device.c
verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
-verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
ifeq ($(MOCK_TPM),1)
libverstage-y += mocked_tlcl.c
@@ -73,7 +71,6 @@ $(foreach arch,$(ARCH_SUPPORTED),\
romstage-y += fmap.c
romstage-y += delay.c
romstage-y += cbfs.c
-romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
romstage-$(CONFIG_COMPRESS_RAMSTAGE) += lzma.c lzmadecode.c
romstage-y += libgcc.c
romstage-y += memrange.c
@@ -117,7 +114,6 @@ ramstage-y += delay.c
ramstage-y += fallback_boot.c
ramstage-y += compute_ip_checksum.c
ramstage-y += cbfs.c
-ramstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
ramstage-y += lzma.c lzmadecode.c
ramstage-y += stack.c
ramstage-y += hexstrtobin.c
@@ -214,7 +210,6 @@ smm-y += halt.c
postcar-y += bootmode.c
postcar-y += boot_device.c
postcar-y += cbfs.c
-postcar-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
postcar-y += delay.c
postcar-y += fmap.c
postcar-y += gcc.c
diff --git a/src/lib/cbfs_spi.c b/src/lib/cbfs_spi.c
deleted file mode 100644
index bbe9125..0000000
--- a/src/lib/cbfs_spi.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/*
- * This file provides a common CBFS wrapper for SPI storage. SPI driver
- * context is expanded with the buffer descriptor used to store data read from
- * SPI.
- */
-
-#include <boot_device.h>
-#include <spi_flash.h>
-#include <symbols.h>
-#include <cbmem.h>
-
-static struct spi_flash *spi_flash_info;
-
-static ssize_t spi_readat(const struct region_device *rd, void *b,
- size_t offset, size_t size)
-{
- if (spi_flash_info->read(spi_flash_info, offset, size, b))
- return -1;
- return size;
-}
-
-static const struct region_device_ops spi_ops = {
- .mmap = mmap_helper_rdev_mmap,
- .munmap = mmap_helper_rdev_munmap,
- .readat = spi_readat,
-};
-
-static struct mmap_helper_region_device mdev =
- MMAP_HELPER_REGION_INIT(&spi_ops, 0, CONFIG_ROM_SIZE);
-
-static void switch_to_postram_cache(int unused)
-{
- /*
- * Call boot_device_init() to ensure spi_flash is initialized before
- * backing mdev with postram cache. This prevents the mdev backing from
- * being overwritten if spi_flash was not accessed before dram was up.
- */
- boot_device_init();
- if (_preram_cbfs_cache != _postram_cbfs_cache)
- mmap_helper_device_init(&mdev, _postram_cbfs_cache,
- _postram_cbfs_cache_size);
-}
-ROMSTAGE_CBMEM_INIT_HOOK(switch_to_postram_cache);
-
-void boot_device_init(void)
-{
- int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS;
- int cs = 0;
-
- if (spi_flash_info != NULL)
- return;
-
- spi_flash_info = spi_flash_probe(bus, cs);
-
- mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size);
-}
-
-/* Return the CBFS boot device. */
-const struct region_device *boot_device_ro(void)
-{
- if (spi_flash_info == NULL)
- return NULL;
-
- return &mdev.rdev;
-}
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16197
-gerrit
commit 56a53519181d12e98e71c4a6d9eecc0c703d7215
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Aug 11 14:51:38 2016 -0500
drivers/spi: ensure SPI flash is boot device for coreboot tables
The spi_flash_probe() routine was setting a global varible
unconditonally regardless if the probe was for the boot device
or even if the boot devcie was flash. Moreover, there's no need
to report the SPI information if the boot device isn't even SPI.
Lastly, it's possible that the boot device is a SPI flash, but
the platform may never probe (selecting SPI_FLASH) for the
actual device connected. In that situation don't fill anything
in as no correct information is known.
BUG=chrome-os-partner:56151
Change-Id: Ib0eba601df4d77bede313c358c92b0536355bbd0
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/drivers/spi/spi_flash.c | 18 +++++++++++-------
src/lib/coreboot_table.c | 13 ++++++++++---
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index 690b277..6006420 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -11,6 +11,7 @@
#include <cbfs.h>
#include <cpu/x86/smm.h>
#include <delay.h>
+#include <rules.h>
#include <stdlib.h>
#include <string.h>
#include <spi-generic.h>
@@ -372,7 +373,13 @@ flash_detected:
printk(BIOS_INFO, "SF: Detected %s with sector size 0x%x, total 0x%x\n",
flash->name, flash->sector_size, flash->size);
- spi_flash_dev = flash;
+ /*
+ * Only set the global spi_flash_dev if this is the boot
+ * device's bus and it's previously unset while in ramstage.
+ */
+ if (ENV_RAMSTAGE && IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH) &&
+ CONFIG_BOOT_DEVICE_SPI_FLASH_BUS == bus && !spi_flash_dev)
+ spi_flash_dev = flash;
return flash;
@@ -381,14 +388,13 @@ err_read_id:
return NULL;
}
-/* Only the RAM stage will build in the lb_new_record symbol
- * so only define this function if we are after that stage */
-#ifdef __RAMSTAGE__
-
void lb_spi_flash(struct lb_header *header)
{
struct lb_spi_flash *flash;
+ if (!IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH))
+ return;
+
flash = (struct lb_spi_flash *)lb_new_record(header);
flash->tag = LB_TAG_SPI_FLASH;
@@ -410,5 +416,3 @@ void lb_spi_flash(struct lb_header *header)
flash->erase_cmd = CMD_BLOCK_ERASE;
}
}
-
-#endif
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index 44ae733..34f8016 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -419,6 +419,14 @@ static void lb_record_version_timestamp(struct lb_header *header)
void __attribute__((weak)) lb_board(struct lb_header *header) { /* NOOP */ }
+/*
+ * It's possible that the system is using a SPI flash as the boot device,
+ * however it is not probing for devices to fill in specifics. In that
+ * case don't provide any information as the correct infromation is
+ * not known.
+ */
+void __attribute__((weak)) lb_spi_flash(struct lb_header *header) { /* NOOP */ }
+
static struct lb_forward *lb_forward(struct lb_header *header, struct lb_header *next_header)
{
struct lb_record *rec;
@@ -532,10 +540,9 @@ static uintptr_t write_coreboot_table(uintptr_t rom_table_end)
/* Add RAM config if available */
lb_ram_code(head);
-#if IS_ENABLED(CONFIG_SPI_FLASH)
/* Add SPI flash description if available */
- lb_spi_flash(head);
-#endif
+ if (IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH))
+ lb_spi_flash(head);
add_cbmem_pointers(head);