diff options
-rw-r--r-- | payloads/libpayload/include/coreboot_tables.h | 13 | ||||
-rw-r--r-- | payloads/libpayload/include/sysinfo.h | 5 | ||||
-rw-r--r-- | payloads/libpayload/libc/coreboot.c | 7 | ||||
-rw-r--r-- | src/arch/x86/mmap_boot.c | 10 | ||||
-rw-r--r-- | src/commonlib/include/commonlib/coreboot_tables.h | 14 | ||||
-rw-r--r-- | src/drivers/spi/spi_flash.c | 8 | ||||
-rw-r--r-- | src/include/spi_flash.h | 8 | ||||
-rw-r--r-- | src/soc/intel/apollolake/mmap_boot.c | 12 | ||||
-rw-r--r-- | src/soc/intel/common/block/fast_spi/mmap_boot.c | 24 |
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; +} |