tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / soc / intel / skylake / memmap.c
bloba0211c74dbc7970d8b4b8f978cfe82b8d0a75697
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Google Inc.
5 * Copyright (C) 2015 Intel Corporation.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <arch/io.h>
18 #include <cbmem.h>
19 #include <chip.h>
20 #include <console/console.h>
21 #include <device/device.h>
22 #include <device/pci.h>
23 #include <soc/msr.h>
24 #include <soc/pci_devs.h>
25 #include <soc/romstage.h>
26 #include <soc/smm.h>
27 #include <soc/systemagent.h>
28 #include <stdlib.h>
30 size_t mmap_region_granluarity(void)
32 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER))
33 /* Align to TSEG size when SMM is in use */
34 if (CONFIG_SMM_TSEG_SIZE != 0)
35 return CONFIG_SMM_TSEG_SIZE;
37 /* Make it 8MiB by default. */
38 return 8*MiB;
41 /* Returns base of requested region encoded in the system agent. */
42 static inline uintptr_t system_agent_region_base(size_t reg)
44 /* All regions concerned for have 1 MiB alignment. */
45 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB);
48 static inline uintptr_t smm_region_start(void)
50 return system_agent_region_base(TSEG);
53 static inline size_t smm_region_size(void)
55 return system_agent_region_base(BGSM) - smm_region_start();
58 void smm_region(void **start, size_t *size)
60 *start = (void *)smm_region_start();
61 *size = smm_region_size();
65 * Subregions within SMM
66 * +-------------------------+ BGSM
67 * | IED | IED_REGION_SIZE
68 * +-------------------------+
69 * | External Stage Cache | SMM_RESERVED_SIZE
70 * +-------------------------+
71 * | code and data |
72 * | (TSEG) |
73 * +-------------------------+ TSEG
75 int smm_subregion(int sub, void **start, size_t *size)
77 uintptr_t sub_base;
78 size_t sub_size;
79 const size_t ied_size = CONFIG_IED_REGION_SIZE;
80 const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
82 sub_base = smm_region_start();
83 sub_size = smm_region_size();
85 switch (sub) {
86 case SMM_SUBREGION_HANDLER:
87 /* Handler starts at the base of TSEG. */
88 sub_size -= ied_size;
89 sub_size -= cache_size;
90 break;
91 case SMM_SUBREGION_CACHE:
92 /* External cache is in the middle of TSEG. */
93 sub_base += sub_size - (ied_size + cache_size);
94 sub_size = cache_size;
95 break;
96 case SMM_SUBREGION_CHIPSET:
97 /* IED is at the top. */
98 sub_base += sub_size - ied_size;
99 sub_size = ied_size;
100 break;
101 default:
102 return -1;
105 *start = (void *)sub_base;
106 *size = sub_size;
108 return 0;
112 * Host Memory Map:
114 * +--------------------------+ TOUUD
115 * | |
116 * +--------------------------+ 4GiB
117 * | PCI Address Space |
118 * +--------------------------+ TOLUD (also maps into MC address space)
119 * | iGD |
120 * +--------------------------+ BDSM
121 * | GTT |
122 * +--------------------------+ BGSM
123 * | TSEG |
124 * +--------------------------+ TSEGMB
125 * | DMA Protected Region |
126 * +--------------------------+ DPR
127 * | PRM (C6DRAM/SGX) |
128 * +--------------------------+ PRMRR
129 * | Trace Memory |
130 * +--------------------------+ top_of_ram
131 * | Reserved - FSP/CBMEM |
132 * +--------------------------+ TOLUM
133 * | Usage DRAM |
134 * +--------------------------+ 0
136 * Some of the base registers above can be equal making the size of those
137 * regions 0. The reason is because the memory controller internally subtracts
138 * the base registers from each other to determine sizes of the regions. In
139 * other words, the memory map is in a fixed order no matter what.
142 u32 top_of_32bit_ram(void)
144 msr_t prmrr_base;
145 u32 top_of_ram;
146 const struct device *dev;
147 const struct soc_intel_skylake_config *config;
150 * Check if Tseg has been initialized, we will use this as a flag
151 * to check if the MRC is done, and only then continue to read the
152 * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before
153 * PRMRR_MASK MSR lock bit is set.
155 if (smm_region_start() == 0)
156 return 0;
158 dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
159 config = dev->chip_info;
162 * On Skylake, cbmem_top is offset down from PRMRR_BASE by reserved
163 * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB)
164 * for PTT if enabled. PTT is in fact not used on Skylake platforms.
165 * Refer to Fsp Integration Guide for the memory mapping layout.
167 prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
168 top_of_ram = prmrr_base.lo;
170 if (config->ProbelessTrace)
171 top_of_ram -= TRACE_MEMORY_SIZE;
173 return top_of_ram;
176 void *cbmem_top(void)
179 * +-------------------------+ Top of RAM (aligned)
180 * | System Management Mode |
181 * | code and data | Length: CONFIG_TSEG_SIZE
182 * | (TSEG) |
183 * +-------------------------+ SMM base (aligned)
184 * | |
185 * | Chipset Reserved Memory |
186 * | |
187 * +-------------------------+ top_of_ram (aligned)
188 * | |
189 * | CBMEM Root |
190 * | |
191 * +-------------------------+
192 * | |
193 * | FSP Reserved Memory |
194 * | |
195 * +-------------------------+
196 * | |
197 * | Various CBMEM Entries |
198 * | |
199 * +-------------------------+ top_of_stack (8 byte aligned)
200 * | |
201 * | stack (CBMEM Entry) |
202 * | |
203 * +-------------------------+
205 return (void *)top_of_32bit_ram();