summaryrefslogtreecommitdiff
path: root/src/soc/intel/skylake/memmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/skylake/memmap.c')
-rw-r--r--src/soc/intel/skylake/memmap.c81
1 files changed, 68 insertions, 13 deletions
diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c
index 7b8df28f71..f8ef01a6df 100644
--- a/src/soc/intel/skylake/memmap.c
+++ b/src/soc/intel/skylake/memmap.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,33 +15,87 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Foundation, Inc.
*/
#include <arch/io.h>
#include <cbmem.h>
#include <device/pci.h>
#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/smm.h>
#include <soc/systemagent.h>
-static uintptr_t dpr_region_start(void)
+size_t mmap_region_granluarity(void)
+{
+ if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER))
+ /* Align to TSEG size when SMM is in use */
+ if (CONFIG_SMM_TSEG_SIZE != 0)
+ return CONFIG_SMM_TSEG_SIZE;
+
+ /* Make it 8MiB by default. */
+ return 8 << 20;
+}
+
+static void *smm_region_start(void)
{
/*
- * Base of DPR is top of usable DRAM below 4GiB. The register has
- * 1 MiB alignment and reports the TOP of the range, the base
- * must be calculated from the size in MiB in bits 11:4.
+ * SMM base address matches the top of DPR. The DPR register has
+ * 1 MiB alignment and reports the TOP of the DPR range.
*/
- uintptr_t dpr = pci_read_config32(SA_DEV_ROOT, DPR);
- uintptr_t tom = dpr & ~((1 << 20) - 1);
-
- /* Subtract DMA Protected Range size if enabled */
- if (dpr & DPR_EPM)
- tom -= (dpr & DPR_SIZE_MASK) << 16;
+ uint32_t smm_base = pci_read_config32(SA_DEV_ROOT, DPR);
+ smm_base = ALIGN_DOWN(smm_base, 1 << 20);
+ return (void *)smm_base;
+}
- return tom;
+void smm_region(void **start, size_t *size)
+{
+ *start = smm_region_start();
+ *size = mmap_region_granluarity();
}
void *cbmem_top(void)
{
- return (void *) dpr_region_start();
+ /*
+ * +-------------------------+ Top of RAM (aligned)
+ * | System Management Mode |
+ * | code and data | Length: CONFIG_TSEG_SIZE
+ * | (TSEG) |
+ * +-------------------------+ SMM base (aligned)
+ * | |
+ * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE
+ * | |
+ * +-------------------------+ top_of_ram (aligned)
+ * | |
+ * | CBMEM Root |
+ * | |
+ * +-------------------------+
+ * | |
+ * | FSP Reserved Memory |
+ * | |
+ * +-------------------------+
+ * | |
+ * | Various CBMEM Entries |
+ * | |
+ * +-------------------------+ top_of_stack (8 byte aligned)
+ * | |
+ * | stack (CBMEM Entry) |
+ * | |
+ * +-------------------------+
+ */
+
+ unsigned long top_of_ram = (unsigned long)smm_region_start();
+
+ /*
+ * Subtract DMA Protected Range size if enabled and align to a multiple
+ * of TSEG size.
+ */
+ u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR);
+ if (dpr & DPR_EPM) {
+ top_of_ram -= (dpr & DPR_SIZE_MASK) << 16;
+ top_of_ram = ALIGN_DOWN(top_of_ram, mmap_region_granluarity());
+ }
+
+ return (void *)(top_of_ram - CONFIG_CHIPSET_RESERVED_MEM_BYTES);
}
+