[coreboot-gerrit] New patch to review for coreboot: intel/apollolake: Calculate BIOS mmap at runtime

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Mon Jun 20 19:35:14 CEST 2016


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15269

-gerrit

commit 1dd8798134aebf45b7ade5727792ea7d9ae4367c
Author: Furquan Shaikh <furquan at google.com>
Date:   Sun Jun 19 23:20:43 2016 -0700

    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 at google.com>
---
 src/soc/intel/apollolake/Makefile.inc      |   3 +
 src/soc/intel/apollolake/include/soc/spi.h |   7 ++
 src/soc/intel/apollolake/mmap_boot.c       | 115 ++++++++++++++++++++++-------
 3 files changed, 99 insertions(+), 26 deletions(-)

diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index a7596e4..7d49b06 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -56,11 +56,13 @@ ramstage-y += tsc_freq.c
 ramstage-y += pmutil.c
 ramstage-y += pmc.c
 ramstage-y += smi.c
+ramstage-y += spi.c
 ramstage-y += reset.c
 
 postcar-y += exit_car.S
 postcar-y += memmap.c
 postcar-y += mmap_boot.c
+postcar-y += spi.c
 postcar-$(CONFIG_SOC_UART_DEBUG) += uart_early.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 += pmutil.c
 verstage-y += reset.c
+verstage-y += spi.c
 
 CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include
 
diff --git a/src/soc/intel/apollolake/include/soc/spi.h b/src/soc/intel/apollolake/include/soc/spi.h
index 0b3f645..fad3923 100644
--- a/src/soc/intel/apollolake/include/soc/spi.h
+++ b/src/soc/intel/apollolake/include/soc/spi.h
@@ -28,12 +28,19 @@
 #define  SPIBAR_BIOS_CONTROL_EISS	(1 << 5)
 
 /* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */
+#define SPIBAR_BIOS_BFPREG		0x00
 #define SPIBAR_HSFSTS_CTL		0x04
 #define SPIBAR_FADDR			0x08
 #define SPIBAR_FDATA(n)			(0x10 + ((n) & 0xf) * 4)
 #define SPIBAR_PTINX			0xcc
 #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 */
 #define  SPIBAR_HSFSTS_FBDC_MASK	(0x3f << 24)
 #define  SPIBAR_HSFSTS_FBDC(n)		(((n) << 24) & SPIBAR_HSFSTS_FBDC_MASK)
diff --git a/src/soc/intel/apollolake/mmap_boot.c b/src/soc/intel/apollolake/mmap_boot.c
index 8009ab9..67eb865 100644
--- a/src/soc/intel/apollolake/mmap_boot.c
+++ b/src/soc/intel/apollolake/mmap_boot.c
@@ -16,42 +16,106 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/early_variables.h>
 #include <boot_device.h>
 #include <cbfs.h>
 #include <commonlib/region.h>
 #include <console/console.h>
 #include <fmap.h>
 #include <soc/intel/common/nvm.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)
+#include <soc/spi.h>
 
 /*
- *  If Apollo Lake is configured to boot from SPI flash "BIOS" region
- *  (as defined in descriptor) is mapped below 4GiB.  Form a pointer for
- *  the base.
+ * BIOS region on the flash is mapped right below 4GiB in the address
+ * space. However, 256KiB right below 4GiB is decoded by read-only SRAM and not
+ * boot media.
+ *
+ *                                                            +----------------+ 0
+ *                                                            |                |
+ *                                                            |                |
+ *                                                            |                |
+ *                                                            |                |
+ *                                                            |                |
+ *                                                            |                |
+ *                                                            |                |
+ *                                                            |                |
+ *                  +------------+----+ virtual_rom_base +--> |                |
+ *                  |    IFD     |                            |                |
+ * bios_start +---> +------------+--------------------------> +----------------+ 4GiB - bios_size
+ *     ^            |            |              ^             |                |
+ *     |            |            |              |             |                |
+ *     |            |            |       bios_mapped_size     |      BIOS      |
+ *     |            |    BIOS    |              |             |                |
+ * bios_size        |            |              |             |                |
+ *     |            |            |              v             |                |
+ *     |            |            +----+ bios_mapped_end +---> +----------------+ 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(
-	VIRTUAL_ROM_BASE, IFD_BIOS_MAX_MAPPED
-);
 
-/*
- * This is how we translate physical SPI flash address space into CPU memory-mapped space. In
- * essence this means "BIOS" region (usually starts at flash physical 0x1000 is mapped to
- * 4G - IFD_BIOS_SIZE.
- */
-static const struct xlate_region_device real_dev = XLATE_REGION_INIT(
-		&shadow_dev.rdev, CONFIG_IFD_BIOS_START,
-		IFD_MAPPED_SIZE, CONFIG_ROM_SIZE
-);
+static uintptr_t bios_start CAR_GLOBAL;
+static uintptr_t bios_end CAR_GLOBAL;
+static uintptr_t virtual_rom_base CAR_GLOBAL;
+static struct mem_region_device shadow_dev CAR_GLOBAL;
+static struct xlate_region_device real_dev CAR_GLOBAL;
 
 const struct region_device *boot_device_ro(void)
 {
-	return &real_dev.rdev;
+	uintptr_t start, end;
+	struct mem_region_device *shadow_dev_ptr;
+	struct xlate_region_device *real_dev_ptr;
+
+	start = car_get_var(bios_start);
+	end = car_get_var(bios_end);
+	shadow_dev_ptr = car_get_var_ptr(&shadow_dev);
+	real_dev_ptr = car_get_var_ptr(&real_dev);
+
+	/* Initialize boot device info if not already done. */
+	if ((start == 0) && (end == 0)) {
+		uintptr_t bios_size, bios_mapped_end, bios_mapped_size, 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_reg_read(SPIBAR_BIOS_BFPREG);
+
+		start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
+		end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
+			SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
+		bios_size = end - start;
+
+		printk(BIOS_INFO, "BIOS region info loaded from FLREG%d\n",
+		       (val & SPIBAR_BFPREG_SBRS) ? 6 : 1);
+		printk(BIOS_INFO, "BIOS Start: %p\n", (void *)start);
+		printk(BIOS_INFO, "BIOS End  : %p\n", (void *)end);
+
+		/* BIOS region is mapped right below 4G. */
+		base = 4ULL * GiB - bios_size;
+
+		/*
+		 * The 256 KiB right below 4G are decoded by readonly SRAM,
+		 * not boot media.
+		 */
+		bios_mapped_end = end - 256 * KiB;
+		bios_mapped_size = bios_mapped_end - start;
+
+		mem_region_device_init(shadow_dev_ptr, (void *)base,
+				       bios_mapped_end);
+
+		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_end, end);
+		car_set_var(virtual_rom_base, base);
+	}
+	return &real_dev_ptr->rdev;
 }
 
 static int iafw_boot_region_properties(struct cbfs_props *props)
@@ -81,7 +145,6 @@ const struct cbfs_locator cbfs_master_header_locator = {
 
 uint32_t nvm_mmio_to_flash_offset(void *p)
 {
-	uintptr_t xlate_base;
-	xlate_base = VIRTUAL_ROM_BASE;
-	return (uintptr_t)p - xlate_base + CONFIG_IFD_BIOS_START;
+	return (uintptr_t)p - car_get_var(virtual_rom_base) +
+		car_get_var(bios_start);
 }



More information about the coreboot-gerrit mailing list