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.
20 #include <console/console.h>
21 #include <device/device.h>
22 #include <device/pci.h>
24 #include <soc/pci_devs.h>
25 #include <soc/romstage.h>
27 #include <soc/systemagent.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. */
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 * +-------------------------+
73 * +-------------------------+ TSEG
75 int smm_subregion(int sub
, void **start
, size_t *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();
86 case SMM_SUBREGION_HANDLER
:
87 /* Handler starts at the base of TSEG. */
89 sub_size
-= cache_size
;
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
;
96 case SMM_SUBREGION_CHIPSET
:
97 /* IED is at the top. */
98 sub_base
+= sub_size
- ied_size
;
105 *start
= (void *)sub_base
;
114 * +--------------------------+ TOUUD
116 * +--------------------------+ 4GiB
117 * | PCI Address Space |
118 * +--------------------------+ TOLUD (also maps into MC address space)
120 * +--------------------------+ BDSM
122 * +--------------------------+ BGSM
124 * +--------------------------+ TSEGMB
125 * | DMA Protected Region |
126 * +--------------------------+ DPR
127 * | PRM (C6DRAM/SGX) |
128 * +--------------------------+ PRMRR
130 * +--------------------------+ top_of_ram
131 * | Reserved - FSP/CBMEM |
132 * +--------------------------+ TOLUM
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)
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)
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
;
176 void *cbmem_top(void)
179 * +-------------------------+ Top of RAM (aligned)
180 * | System Management Mode |
181 * | code and data | Length: CONFIG_TSEG_SIZE
183 * +-------------------------+ SMM base (aligned)
185 * | Chipset Reserved Memory |
187 * +-------------------------+ top_of_ram (aligned)
191 * +-------------------------+
193 * | FSP Reserved Memory |
195 * +-------------------------+
197 * | Various CBMEM Entries |
199 * +-------------------------+ top_of_stack (8 byte aligned)
201 * | stack (CBMEM Entry) |
203 * +-------------------------+
205 return (void *)top_of_32bit_ram();