reef: Calculate BIOS mmap details at runtime
authorFurquan Shaikh <furquan@google.com>
Tue, 21 Jun 2016 12:47:54 +0000 (05:47 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Thu, 23 Jun 2016 03:01:41 +0000 (20:01 -0700)
BUG=chrome-os-partner:54563
BRANCH=None
TEST=Compiles successfully and boots to OS on reef.

Change-Id: If928c3af762adfe6752ba55e39f995309f195c79
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://chromium-review.googlesource.com/354381
Commit-Ready: Furquan Shaikh <furquan@chromium.org>
Tested-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
src/board/reef/board.c

index 8081d71..6ce0524 100644 (file)
@@ -17,7 +17,9 @@
  *
  */
 
+#include <arch/io.h>
 #include <libpayload.h>
+#include <pci/pci.h>
 #include <sysinfo.h>
 
 #include "base/init_funcs.h"
 #define EMMC_SD_CLOCK_MIN       400000
 #define EMMC_CLOCK_MAX          200000000
 
-/*
- * FIXME: this needs to be derived differently. The coreboot code actually
- * handles the situation better than assuming a specific descriptor layout
- * and re-calculating the same information. Nevertheless in order to
- * utilize the exist set of flash ops one needs to assume the following layout:
- *
- *         0 +----------------------+
- *           | descriptor           |
- *        4K +----------------------+
- *           | BIOS region          |
- *         X +----------------------+
- *           | CSE device extension |
- * rom size  +----------------------+
- *
- * The BIOS region is the only thing memory-mapped. And one needs to include
- * the size of the descriptor in order for the math to work out within the
- * memory-mapped flash implementation. In short, the 'X' above is the size
- * used for FLASH_MEM_MAP_SIZE.
- *
- */
-#define FLASH_MEM_MAP_SIZE 0xf7f000
-#define FLASH_MEM_MAP_BASE ((uintptr_t)(0x100000000ULL - FLASH_MEM_MAP_SIZE))
+#define SPIBAR_BIOS_BFPREG     (0x0)
+#define  BFPREG_BASE_MASK       (0x7fff)
+#define  BFPREG_LIMIT_SHIFT     (16)
+#define  BFPREG_LIMIT_MASK      (0x7fff << BFPREG_LIMIT_SHIFT)
+
+static void board_flash_init(void)
+{
+       uintptr_t mmio_base = pci_read_config32(PCI_DEV(0, 0xd, 2),
+                                               PCI_BASE_ADDRESS_0);
+       mmio_base &= PCI_BASE_ADDRESS_MEM_MASK;
+
+       uint32_t val = read32((void *)(mmio_base + SPIBAR_BIOS_BFPREG));
+
+       uintptr_t mmap_start;
+       size_t bios_base, bios_end, mmap_size;
+
+       bios_base = (val & BFPREG_BASE_MASK) * 4 * KiB;
+       bios_end  = (((val & BFPREG_LIMIT_MASK) >> BFPREG_LIMIT_SHIFT) + 1) *
+               4 * KiB;
+       mmap_size = bios_end - bios_base;
+
+       /* BIOS region is mapped directly below 4GiB. */
+       mmap_start = 4ULL * GiB - mmap_size;
+
+       printf("BIOS MMAP details:\n");
+       printf("IFD Base Offset  : 0x%zx\n", bios_base);
+       printf("IFD End Offset   : 0x%zx\n", bios_end);
+       printf("MMAP Size        : 0x%zx\n", mmap_size);
+       printf("MMAP Start       : 0x%lx\n", mmap_start);
+
+       /* W25Q128FV SPI Flash */
+       flash_set_ops(&new_mem_mapped_flash_with_offset(mmap_start, mmap_size,
+                                                       bios_base)->ops);
+}
 
 static int board_setup(void)
 {
@@ -65,9 +79,7 @@ static int board_setup(void)
        CrosEc *cros_ec = new_cros_ec(&cros_ec_lpc_bus->ops, 0, NULL);
        register_vboot_ec(&cros_ec->vboot, 0);
 
-       /* W25Q128FV SPI Flash */
-       flash_set_ops(&new_mem_mapped_flash(FLASH_MEM_MAP_BASE,
-                                        FLASH_MEM_MAP_SIZE)->ops);
+       board_flash_init();
 
        /* FIXME: not stuffed but need MOCK_TPM to work. */
        tpm_set_ops(&new_lpc_tpm((void *)(uintptr_t)0xfed40000)->ops);