summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/include/coreboot_tables.h13
-rw-r--r--payloads/libpayload/include/sysinfo.h5
-rw-r--r--payloads/libpayload/libc/coreboot.c7
-rw-r--r--src/arch/x86/mmap_boot.c10
-rw-r--r--src/commonlib/include/commonlib/coreboot_tables.h14
-rw-r--r--src/drivers/spi/spi_flash.c8
-rw-r--r--src/include/spi_flash.h8
-rw-r--r--src/soc/intel/apollolake/mmap_boot.c12
-rw-r--r--src/soc/intel/common/block/fast_spi/mmap_boot.c24
9 files changed, 101 insertions, 0 deletions
diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h
index 64db83bbd4..e042a900b9 100644
--- a/payloads/libpayload/include/coreboot_tables.h
+++ b/payloads/libpayload/include/coreboot_tables.h
@@ -261,12 +261,25 @@ struct cb_x86_rom_mtrr {
uint32_t index;
};
+/* Memory map windows to translate addresses between SPI flash space and host address space. */
+struct flash_mmap_window {
+ uint32_t flash_base;
+ uint32_t host_base;
+ uint32_t size;
+};
+
struct cb_spi_flash {
uint32_t tag;
uint32_t size;
uint32_t flash_size;
uint32_t sector_size;
uint32_t erase_cmd;
+ /*
+ * Number of mmap windows used by the platform to decode addresses between SPI flash
+ * space and host address space. This determines the number of entries in mmap_table.
+ */
+ uint32_t mmap_count;
+ struct flash_mmap_window mmap_table[0];
};
struct cb_boot_media_params {
diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h
index dd739abab4..5a24e1405f 100644
--- a/payloads/libpayload/include/sysinfo.h
+++ b/payloads/libpayload/include/sysinfo.h
@@ -40,6 +40,9 @@
/* Up to 10 MAC addresses */
#define SYSINFO_MAX_MACS 10
+/* Maximum of 2 MMAP windows for decoding SPI flash. */
+#define SYSINFO_MAX_MMAP_WINDOWS 2
+
#include <coreboot_tables.h>
/*
@@ -126,6 +129,8 @@ struct sysinfo_t {
uint32_t size;
uint32_t sector_size;
uint32_t erase_cmd;
+ uint32_t mmap_window_count;
+ struct flash_mmap_window mmap_table[SYSINFO_MAX_MMAP_WINDOWS];
} spi_flash;
uint64_t fmap_offset;
uint64_t cbfs_offset;
diff --git a/payloads/libpayload/libc/coreboot.c b/payloads/libpayload/libc/coreboot.c
index b7d2a537b5..7e23afe2e5 100644
--- a/payloads/libpayload/libc/coreboot.c
+++ b/payloads/libpayload/libc/coreboot.c
@@ -211,6 +211,13 @@ static void cb_parse_spi_flash(void *ptr, struct sysinfo_t *info)
info->spi_flash.size = flash->flash_size;
info->spi_flash.sector_size = flash->sector_size;
info->spi_flash.erase_cmd = flash->erase_cmd;
+
+ if (flash->mmap_count == 0)
+ return;
+
+ info->spi_flash.mmap_window_count = MIN(flash->mmap_count, SYSINFO_MAX_MMAP_WINDOWS);
+ memcpy(info->spi_flash.mmap_table, flash->mmap_table,
+ info->spi_flash.mmap_window_count * sizeof(struct flash_mmap_window));
}
static void cb_parse_boot_media_params(unsigned char *ptr,
diff --git a/src/arch/x86/mmap_boot.c b/src/arch/x86/mmap_boot.c
index 66ba0e145b..f0ccc86fbe 100644
--- a/src/arch/x86/mmap_boot.c
+++ b/src/arch/x86/mmap_boot.c
@@ -2,6 +2,7 @@
#include <boot_device.h>
#include <endian.h>
+#include <spi_flash.h>
/* The ROM is memory mapped just below 4GiB. Form a pointer for the base. */
#define rom_base ((void *)(uintptr_t)(0x100000000ULL-CONFIG_ROM_SIZE))
@@ -13,3 +14,12 @@ const struct region_device *boot_device_ro(void)
{
return &boot_dev.rdev;
}
+
+uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
+{
+ table->flash_base = 0;
+ table->host_base = (uint32_t)(uintptr_t)rom_base;
+ table->size = CONFIG_ROM_SIZE;
+
+ return 1;
+}
diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h
index 3e74e6b59c..c740975bc7 100644
--- a/src/commonlib/include/commonlib/coreboot_tables.h
+++ b/src/commonlib/include/commonlib/coreboot_tables.h
@@ -349,12 +349,26 @@ struct lb_x86_rom_mtrr {
uint32_t index;
};
+/* Memory map windows to translate addresses between SPI flash space and host address space. */
+struct flash_mmap_window {
+ uint32_t flash_base;
+ uint32_t host_base;
+ uint32_t size;
+};
+
struct lb_spi_flash {
uint32_t tag;
uint32_t size;
uint32_t flash_size;
uint32_t sector_size;
uint32_t erase_cmd;
+ /*
+ * Number of mmap windows used by the platform to decode addresses between SPI flash
+ * space and host address space. This determines the number of entries in mmap_table.
+ */
+
+ uint32_t mmap_count;
+ struct flash_mmap_window mmap_table[0];
};
struct lb_boot_media_params {
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index f2610a181d..2406a90e52 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -663,6 +663,14 @@ void lb_spi_flash(struct lb_header *header)
flash->sector_size = 64 * KiB;
flash->erase_cmd = CMD_BLOCK_ERASE;
}
+
+ if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED)) {
+ flash->mmap_count = 0;
+ } else {
+ struct flash_mmap_window *table = (struct flash_mmap_window *)(flash + 1);
+ flash->mmap_count = spi_flash_get_mmap_windows(table);
+ flash->size += flash->mmap_count * sizeof(*table);
+ }
}
int spi_flash_ctrlr_protect_region(const struct spi_flash *flash,
diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h
index 1061e9905e..a7f707eb1c 100644
--- a/src/include/spi_flash.h
+++ b/src/include/spi_flash.h
@@ -225,4 +225,12 @@ int spi_flash_vector_helper(const struct spi_slave *slave,
int (*func)(const struct spi_slave *slave, const void *dout,
size_t bytesout, void *din, size_t bytesin));
+/*
+ * Fill in the memory mapped windows used by the SPI flash device. This is useful for payloads
+ * to identify SPI flash to host space mapping.
+ *
+ * Returns number of windows added to the table.
+ */
+uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table);
+
#endif /* _SPI_FLASH_H_ */
diff --git a/src/soc/intel/apollolake/mmap_boot.c b/src/soc/intel/apollolake/mmap_boot.c
index 79c2a0716b..23c819e3a0 100644
--- a/src/soc/intel/apollolake/mmap_boot.c
+++ b/src/soc/intel/apollolake/mmap_boot.c
@@ -5,6 +5,7 @@
#include <console/console.h>
#include <fmap.h>
#include <intelblocks/fast_spi.h>
+#include <spi_flash.h>
/*
* BIOS region on the flash is mapped right below 4GiB in the address
@@ -91,3 +92,14 @@ const struct region_device *boot_device_ro(void)
return &real_dev.rdev;
}
+
+uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
+{
+ bios_mmap_init();
+
+ table->flash_base = region_offset(&real_dev_window.sub_region);
+ table->host_base = (uintptr_t)rdev_mmap_full(&shadow_dev.rdev);
+ table->size = region_sz(&real_dev_window.sub_region);
+
+ return 1;
+}
diff --git a/src/soc/intel/common/block/fast_spi/mmap_boot.c b/src/soc/intel/common/block/fast_spi/mmap_boot.c
index 8435a855f5..fa163d7e49 100644
--- a/src/soc/intel/common/block/fast_spi/mmap_boot.c
+++ b/src/soc/intel/common/block/fast_spi/mmap_boot.c
@@ -11,6 +11,7 @@
#include <console/console.h>
#include <fmap.h>
#include <intelblocks/fast_spi.h>
+#include <spi_flash.h>
enum window_type {
/* Fixed decode window of max 16MiB size just below 4G boundary */
@@ -160,3 +161,26 @@ void fast_spi_get_ext_bios_window(uintptr_t *base, size_t *size)
*base = (uintptr_t)rdev_mmap_full(rd);
}
}
+
+uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
+{
+ int i;
+ uint32_t count = 0;
+
+ bios_mmap_init();
+
+ for (i = 0; i < TOTAL_DECODE_WINDOWS; i++) {
+
+ if (region_sz(&real_dev_windows[i].sub_region) == 0)
+ continue;
+
+ count++;
+ table->flash_base = region_offset(&real_dev_windows[i].sub_region);
+ table->host_base = (uintptr_t)rdev_mmap_full(&shadow_devs[i].rdev);
+ table->size = region_sz(&real_dev_windows[i].sub_region);
+
+ table++;
+ }
+
+ return count;
+}