intel/apollolake: Calculate BIOS mmap at runtime
Instead of hard-coding the BIOS region start and end addresses, read BIOS_BFPREG to determine the base and limit for the mapped BIOS region. BUG=chrome-os-partner:54563 Change-Id: Iddd3d4cc945f09e8f147e293bb9144471a6a220d Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://review.coreboot.org/15269 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins)
This commit is contained in:
parent
bdcda710a7
commit
0be3da53c6
@ -56,11 +56,13 @@ ramstage-y += tsc_freq.c
|
|||||||
ramstage-y += pmutil.c
|
ramstage-y += pmutil.c
|
||||||
ramstage-y += pmc.c
|
ramstage-y += pmc.c
|
||||||
ramstage-y += smi.c
|
ramstage-y += smi.c
|
||||||
|
ramstage-y += spi.c
|
||||||
ramstage-y += reset.c
|
ramstage-y += reset.c
|
||||||
|
|
||||||
postcar-y += exit_car.S
|
postcar-y += exit_car.S
|
||||||
postcar-y += memmap.c
|
postcar-y += memmap.c
|
||||||
postcar-y += mmap_boot.c
|
postcar-y += mmap_boot.c
|
||||||
|
postcar-y += spi.c
|
||||||
postcar-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
|
postcar-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
|
||||||
postcar-y += tsc_freq.c
|
postcar-y += tsc_freq.c
|
||||||
|
|
||||||
@ -71,6 +73,7 @@ verstage-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
|
|||||||
verstage-y += tsc_freq.c
|
verstage-y += tsc_freq.c
|
||||||
verstage-y += pmutil.c
|
verstage-y += pmutil.c
|
||||||
verstage-y += reset.c
|
verstage-y += reset.c
|
||||||
|
verstage-y += spi.c
|
||||||
|
|
||||||
CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include
|
CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include
|
||||||
|
|
||||||
|
@ -28,12 +28,19 @@
|
|||||||
#define SPIBAR_BIOS_CONTROL_EISS (1 << 5)
|
#define SPIBAR_BIOS_CONTROL_EISS (1 << 5)
|
||||||
|
|
||||||
/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */
|
/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */
|
||||||
|
#define SPIBAR_BIOS_BFPREG 0x00
|
||||||
#define SPIBAR_HSFSTS_CTL 0x04
|
#define SPIBAR_HSFSTS_CTL 0x04
|
||||||
#define SPIBAR_FADDR 0x08
|
#define SPIBAR_FADDR 0x08
|
||||||
#define SPIBAR_FDATA(n) (0x10 + ((n) & 0xf) * 4)
|
#define SPIBAR_FDATA(n) (0x10 + ((n) & 0xf) * 4)
|
||||||
#define SPIBAR_PTINX 0xcc
|
#define SPIBAR_PTINX 0xcc
|
||||||
#define SPIBAR_PTDATA 0xd0
|
#define SPIBAR_PTDATA 0xd0
|
||||||
|
|
||||||
|
/* Bit definitions and masks for BIOS_BFPREG register. */
|
||||||
|
#define SPIBAR_BFPREG_PRB_MASK (0x7fff)
|
||||||
|
#define SPIBAR_BFPREG_PRL_SHIFT (16)
|
||||||
|
#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT)
|
||||||
|
#define SPIBAR_BFPREG_SBRS (1 << 31)
|
||||||
|
|
||||||
/* Bit definitions for HSFSTS_CTL register */
|
/* Bit definitions for HSFSTS_CTL register */
|
||||||
#define SPIBAR_HSFSTS_FBDC_MASK (0x3f << 24)
|
#define SPIBAR_HSFSTS_FBDC_MASK (0x3f << 24)
|
||||||
#define SPIBAR_HSFSTS_FBDC(n) (((n) << 24) & SPIBAR_HSFSTS_FBDC_MASK)
|
#define SPIBAR_HSFSTS_FBDC(n) (((n) << 24) & SPIBAR_HSFSTS_FBDC_MASK)
|
||||||
|
@ -16,42 +16,115 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <arch/early_variables.h>
|
||||||
#include <boot_device.h>
|
#include <boot_device.h>
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <commonlib/region.h>
|
#include <commonlib/region.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <fmap.h>
|
#include <fmap.h>
|
||||||
#include <soc/intel/common/nvm.h>
|
#include <soc/intel/common/nvm.h>
|
||||||
|
#include <soc/spi.h>
|
||||||
/* The 256 KiB right below 4G are decoded by readonly SRAM, not boot media */
|
|
||||||
#define IFD_BIOS_MAX_MAPPED (CONFIG_IFD_BIOS_END - 256 * KiB)
|
|
||||||
#define IFD_MAPPED_SIZE (IFD_BIOS_MAX_MAPPED - CONFIG_IFD_BIOS_START)
|
|
||||||
#define IFD_BIOS_SIZE (CONFIG_IFD_BIOS_END - CONFIG_IFD_BIOS_START)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If Apollo Lake is configured to boot from SPI flash "BIOS" region
|
* BIOS region on the flash is mapped right below 4GiB in the address
|
||||||
* (as defined in descriptor) is mapped below 4GiB. Form a pointer for
|
* space. However, 256KiB right below 4GiB is decoded by read-only SRAM and not
|
||||||
* the base.
|
* boot media.
|
||||||
|
*
|
||||||
|
* +----------------+ 0
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* +------------+ | |
|
||||||
|
* | IFD | | |
|
||||||
|
* bios_start +---> +------------+--------------------------> +----------------+ 4GiB - bios_size
|
||||||
|
* ^ | | ^ | |
|
||||||
|
* | | | | | |
|
||||||
|
* | | | bios_mapped_size | BIOS |
|
||||||
|
* | | BIOS | | | |
|
||||||
|
* bios_size | | | | |
|
||||||
|
* | | | v | |
|
||||||
|
* | | +--------------------------> +----------------+ 4GiB - 256KiB
|
||||||
|
* v | | | Read only SRAM |
|
||||||
|
* bios_end +---> +------------+ +----------------+ 4GiB
|
||||||
|
* | Device ext |
|
||||||
|
* +------------+
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#define VIRTUAL_ROM_BASE ((uintptr_t)(0x100000000ULL - IFD_BIOS_SIZE))
|
|
||||||
|
|
||||||
static const struct mem_region_device shadow_dev = MEM_REGION_DEV_INIT(
|
static size_t bios_start CAR_GLOBAL;
|
||||||
VIRTUAL_ROM_BASE, IFD_BIOS_MAX_MAPPED
|
static size_t bios_size CAR_GLOBAL;
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
static struct mem_region_device shadow_dev CAR_GLOBAL;
|
||||||
* This is how we translate physical SPI flash address space into CPU memory-mapped space. In
|
static struct xlate_region_device real_dev CAR_GLOBAL;
|
||||||
* essence this means "BIOS" region (usually starts at flash physical 0x1000 is mapped to
|
|
||||||
* 4G - IFD_BIOS_SIZE.
|
static void bios_mmap_init(void)
|
||||||
*/
|
{
|
||||||
static const struct xlate_region_device real_dev = XLATE_REGION_DEV_INIT(
|
size_t size;
|
||||||
&shadow_dev.rdev, CONFIG_IFD_BIOS_START,
|
|
||||||
IFD_MAPPED_SIZE, CONFIG_ROM_SIZE
|
size = car_get_var(bios_size);
|
||||||
);
|
|
||||||
|
/* If bios_size is initialized, then bail out. */
|
||||||
|
if (size != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t start, bios_end, bios_mapped_size;
|
||||||
|
uintptr_t base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BIOS_BFPREG provides info about BIOS Flash Primary Region
|
||||||
|
* Base and Limit.
|
||||||
|
* Base and Limit fields are in units of 4KiB.
|
||||||
|
*/
|
||||||
|
uint32_t val = spi_ctrlr_reg_read(SPIBAR_BIOS_BFPREG);
|
||||||
|
|
||||||
|
start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
|
||||||
|
bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
|
||||||
|
SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
|
||||||
|
size = bios_end - start;
|
||||||
|
|
||||||
|
printk(BIOS_INFO, "IFD BIOS region info loaded from FLREG%d\n",
|
||||||
|
(val & SPIBAR_BFPREG_SBRS) ? 6 : 1);
|
||||||
|
printk(BIOS_INFO, "IFD BIOS Start: 0x%zx\n", start);
|
||||||
|
printk(BIOS_INFO, "IFD BIOS End : 0x%zx\n", bios_end);
|
||||||
|
|
||||||
|
/* BIOS region is mapped right below 4G. */
|
||||||
|
base = 4ULL * GiB - size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 256 KiB right below 4G are decoded by readonly SRAM,
|
||||||
|
* not boot media.
|
||||||
|
*/
|
||||||
|
bios_mapped_size = size - 256 * KiB;
|
||||||
|
|
||||||
|
struct mem_region_device *shadow_dev_ptr;
|
||||||
|
struct xlate_region_device *real_dev_ptr;
|
||||||
|
shadow_dev_ptr = car_get_var_ptr(&shadow_dev);
|
||||||
|
real_dev_ptr = car_get_var_ptr(&real_dev);
|
||||||
|
|
||||||
|
mem_region_device_init(shadow_dev_ptr, (void *)base,
|
||||||
|
bios_mapped_size);
|
||||||
|
|
||||||
|
xlate_region_device_init(real_dev_ptr, &shadow_dev_ptr->rdev,
|
||||||
|
start, bios_mapped_size,
|
||||||
|
CONFIG_ROM_SIZE);
|
||||||
|
|
||||||
|
car_set_var(bios_start, start);
|
||||||
|
car_set_var(bios_size, size);
|
||||||
|
}
|
||||||
|
|
||||||
const struct region_device *boot_device_ro(void)
|
const struct region_device *boot_device_ro(void)
|
||||||
{
|
{
|
||||||
return &real_dev.rdev;
|
bios_mmap_init();
|
||||||
|
|
||||||
|
struct xlate_region_device *real_dev_ptr;
|
||||||
|
real_dev_ptr = car_get_var_ptr(&real_dev);
|
||||||
|
|
||||||
|
return &real_dev_ptr->rdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iafw_boot_region_properties(struct cbfs_props *props)
|
static int iafw_boot_region_properties(struct cbfs_props *props)
|
||||||
@ -81,7 +154,16 @@ const struct cbfs_locator cbfs_master_header_locator = {
|
|||||||
|
|
||||||
uint32_t nvm_mmio_to_flash_offset(void *p)
|
uint32_t nvm_mmio_to_flash_offset(void *p)
|
||||||
{
|
{
|
||||||
uintptr_t xlate_base;
|
bios_mmap_init();
|
||||||
xlate_base = VIRTUAL_ROM_BASE;
|
|
||||||
return (uintptr_t)p - xlate_base + CONFIG_IFD_BIOS_START;
|
size_t start, size;
|
||||||
|
start = car_get_var(bios_start);
|
||||||
|
size = car_get_var(bios_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns :
|
||||||
|
* addr - base of mmaped region in addr space + offset of mmaped region
|
||||||
|
* start on flash
|
||||||
|
*/
|
||||||
|
return (uintptr_t)p - (4ULL * GiB - size) + start;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user