blob: 17dbc320c6c97e568cb8c0c0af16327cb36ce555 [file] [log] [blame]
Lee Leahyb0005132015-05-12 18:19:47 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
Lee Leahye0918bb2016-01-29 14:28:43 -08005 * Copyright (C) 2015-2016 Intel Corporation.
Lee Leahyb0005132015-05-12 18:19:47 -07006 *
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.
10 *
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.
Lee Leahyb0005132015-05-12 18:19:47 -070015 */
16
17#include <arch/io.h>
18#include <cbmem.h>
Rizwan Qureshi188e3702015-07-23 17:40:32 +053019#include <chip.h>
Rizwan Qureshi188e3702015-07-23 17:40:32 +053020#include <device/device.h>
Lee Leahyb0005132015-05-12 18:19:47 -070021#include <device/pci.h>
Rizwan Qureshi188e3702015-07-23 17:40:32 +053022#include <soc/msr.h>
Lee Leahyb0005132015-05-12 18:19:47 -070023#include <soc/pci_devs.h>
Lee Leahy1d14b3e2015-05-12 18:23:27 -070024#include <soc/smm.h>
Lee Leahyb0005132015-05-12 18:19:47 -070025#include <soc/systemagent.h>
Aaron Durbina0429b62015-08-05 14:33:37 -050026#include <stdlib.h>
Lee Leahyb0005132015-05-12 18:19:47 -070027
Lee Leahye0918bb2016-01-29 14:28:43 -080028size_t mmap_region_granularity(void)
Lee Leahy1d14b3e2015-05-12 18:23:27 -070029{
30 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER))
31 /* Align to TSEG size when SMM is in use */
32 if (CONFIG_SMM_TSEG_SIZE != 0)
33 return CONFIG_SMM_TSEG_SIZE;
34
35 /* Make it 8MiB by default. */
Aaron Durbina0429b62015-08-05 14:33:37 -050036 return 8*MiB;
Lee Leahy1d14b3e2015-05-12 18:23:27 -070037}
38
Aaron Durbina0429b62015-08-05 14:33:37 -050039/* Returns base of requested region encoded in the system agent. */
40static inline uintptr_t system_agent_region_base(size_t reg)
Lee Leahyb0005132015-05-12 18:19:47 -070041{
Aaron Durbina0429b62015-08-05 14:33:37 -050042 /* All regions concerned for have 1 MiB alignment. */
43 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB);
44}
45
46static inline uintptr_t smm_region_start(void)
47{
48 return system_agent_region_base(TSEG);
49}
50
51static inline size_t smm_region_size(void)
52{
53 return system_agent_region_base(BGSM) - smm_region_start();
Lee Leahy1d14b3e2015-05-12 18:23:27 -070054}
Lee Leahyb0005132015-05-12 18:19:47 -070055
Lee Leahy1d14b3e2015-05-12 18:23:27 -070056void smm_region(void **start, size_t *size)
57{
Aaron Durbina0429b62015-08-05 14:33:37 -050058 *start = (void *)smm_region_start();
59 *size = smm_region_size();
Lee Leahyb0005132015-05-12 18:19:47 -070060}
61
Aaron Durbinc43d4172015-08-05 14:51:48 -050062/*
63 * Subregions within SMM
64 * +-------------------------+ BGSM
65 * | IED | IED_REGION_SIZE
66 * +-------------------------+
67 * | External Stage Cache | SMM_RESERVED_SIZE
68 * +-------------------------+
69 * | code and data |
70 * | (TSEG) |
71 * +-------------------------+ TSEG
72 */
73int smm_subregion(int sub, void **start, size_t *size)
74{
75 uintptr_t sub_base;
76 size_t sub_size;
77 const size_t ied_size = CONFIG_IED_REGION_SIZE;
78 const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
79
80 sub_base = smm_region_start();
81 sub_size = smm_region_size();
82
83 switch (sub) {
84 case SMM_SUBREGION_HANDLER:
85 /* Handler starts at the base of TSEG. */
86 sub_size -= ied_size;
87 sub_size -= cache_size;
88 break;
89 case SMM_SUBREGION_CACHE:
90 /* External cache is in the middle of TSEG. */
91 sub_base += sub_size - (ied_size + cache_size);
92 sub_size = cache_size;
93 break;
94 case SMM_SUBREGION_CHIPSET:
95 /* IED is at the top. */
96 sub_base += sub_size - ied_size;
97 sub_size = ied_size;
98 break;
99 default:
100 return -1;
101 }
102
103 *start = (void *)sub_base;
104 *size = sub_size;
105
106 return 0;
107}
108
Rizwan Qureshi188e3702015-07-23 17:40:32 +0530109/*
110 * Host Memory Map:
111 *
112 * +--------------------------+ TOUUD
113 * | |
114 * +--------------------------+ 4GiB
115 * | PCI Address Space |
116 * +--------------------------+ TOLUD (also maps into MC address space)
117 * | iGD |
118 * +--------------------------+ BDSM
119 * | GTT |
120 * +--------------------------+ BGSM
121 * | TSEG |
122 * +--------------------------+ TSEGMB
123 * | DMA Protected Region |
124 * +--------------------------+ DPR
125 * | PRM (C6DRAM/SGX) |
126 * +--------------------------+ PRMRR
127 * | Trace Memory |
128 * +--------------------------+ top_of_ram
129 * | Reserved - FSP/CBMEM |
130 * +--------------------------+ TOLUM
131 * | Usage DRAM |
132 * +--------------------------+ 0
133 *
134 * Some of the base registers above can be equal making the size of those
135 * regions 0. The reason is because the memory controller internally subtracts
136 * the base registers from each other to determine sizes of the regions. In
137 * other words, the memory map is in a fixed order no matter what.
138 */
139
140u32 top_of_32bit_ram(void)
141{
142 msr_t prmrr_base;
143 u32 top_of_ram;
144 const struct device *dev;
145 const struct soc_intel_skylake_config *config;
146
147 /*
148 * Check if Tseg has been initialized, we will use this as a flag
149 * to check if the MRC is done, and only then continue to read the
150 * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before
151 * PRMRR_MASK MSR lock bit is set.
152 */
Naresh G Solanki721d1b32016-11-16 21:32:04 +0530153 top_of_ram = smm_region_start();
154 if (top_of_ram == 0)
Rizwan Qureshi188e3702015-07-23 17:40:32 +0530155 return 0;
156
157 dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
158 config = dev->chip_info;
159
160 /*
161 * On Skylake, cbmem_top is offset down from PRMRR_BASE by reserved
162 * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB)
163 * for PTT if enabled. PTT is in fact not used on Skylake platforms.
164 * Refer to Fsp Integration Guide for the memory mapping layout.
165 */
166 prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
Naresh G Solanki721d1b32016-11-16 21:32:04 +0530167 if (prmrr_base.lo)
168 top_of_ram = prmrr_base.lo;
Rizwan Qureshi188e3702015-07-23 17:40:32 +0530169
170 if (config->ProbelessTrace)
171 top_of_ram -= TRACE_MEMORY_SIZE;
172
173 return top_of_ram;
174}
175
Lee Leahyb0005132015-05-12 18:19:47 -0700176void *cbmem_top(void)
177{
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700178 /*
179 * +-------------------------+ Top of RAM (aligned)
180 * | System Management Mode |
181 * | code and data | Length: CONFIG_TSEG_SIZE
182 * | (TSEG) |
183 * +-------------------------+ SMM base (aligned)
184 * | |
Rizwan Qureshi188e3702015-07-23 17:40:32 +0530185 * | Chipset Reserved Memory |
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700186 * | |
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 * +-------------------------+
204 */
Rizwan Qureshi188e3702015-07-23 17:40:32 +0530205 return (void *)top_of_32bit_ram();
Lee Leahyb0005132015-05-12 18:19:47 -0700206}