coreboot tables: Add SPI flash memory map windows to coreboot tables

This change adds details about the memory map windows to translate
addresses between SPI flash space and host address space to coreboot
tables. This is useful for payloads to setup the translation using the
decode windows already known to coreboot. Until now, there was a
single decode window at the top of 4G used by all x86
platforms. However, going forward, platforms might support more decode
windows and hence in order to avoid duplication in payloads this
information is filled in coreboot tables.

`lb_spi_flash()` is updated to fill in the details about these windows
by making a call to `spi_flash_get_mmap_windows()` which is
implemented by the driver providing the boot media mapping device.

BUG=b:171534504

Signed-off-by: Furquan Shaikh <furquan@google.com>
Change-Id: I00ae33d9b53fecd0a8eadd22531fdff8bde9ee94
Reviewed-on: https://review.coreboot.org/c/coreboot/+/48185
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Furquan Shaikh 2020-11-25 17:15:09 -08:00
parent b53280ab53
commit 493937e1d6
9 changed files with 101 additions and 0 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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 {

View File

@ -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,

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;
}