blob: a0211c74dbc7970d8b4b8f978cfe82b8d0a75697 [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 Leahy1d14b3e2015-05-12 18:23:27 -07005 * Copyright (C) 2015 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>
20#include <console/console.h>
21#include <device/device.h>
Lee Leahyb0005132015-05-12 18:19:47 -070022#include <device/pci.h>
Rizwan Qureshi188e3702015-07-23 17:40:32 +053023#include <soc/msr.h>
Lee Leahyb0005132015-05-12 18:19:47 -070024#include <soc/pci_devs.h>
Lee Leahy1d14b3e2015-05-12 18:23:27 -070025#include <soc/romstage.h>
26#include <soc/smm.h>
Lee Leahyb0005132015-05-12 18:19:47 -070027#include <soc/systemagent.h>
Aaron Durbina0429b62015-08-05 14:33:37 -050028#include <stdlib.h>
Lee Leahyb0005132015-05-12 18:19:47 -070029
Lee Leahy1d14b3e2015-05-12 18:23:27 -070030size_t mmap_region_granluarity(void)
31{
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;
36
37 /* Make it 8MiB by default. */
Aaron Durbina0429b62015-08-05 14:33:37 -050038 return 8*MiB;
Lee Leahy1d14b3e2015-05-12 18:23:27 -070039}
40
Aaron Durbina0429b62015-08-05 14:33:37 -050041/* Returns base of requested region encoded in the system agent. */
42static inline uintptr_t system_agent_region_base(size_t reg)
Lee Leahyb0005132015-05-12 18:19:47 -070043{
Aaron Durbina0429b62015-08-05 14:33:37 -050044 /* All regions concerned for have 1 MiB alignment. */
45 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB);
46}
47
48static inline uintptr_t smm_region_start(void)
49{
50 return system_agent_region_base(TSEG);
51}
52
53static inline size_t smm_region_size(void)
54{
55 return system_agent_region_base(BGSM) - smm_region_start();
Lee Leahy1d14b3e2015-05-12 18:23:27 -070056}
Lee Leahyb0005132015-05-12 18:19:47 -070057
Lee Leahy1d14b3e2015-05-12 18:23:27 -070058void smm_region(void **start, size_t *size)
59{
Aaron Durbina0429b62015-08-05 14:33:37 -050060 *start = (void *)smm_region_start();
61 *size = smm_region_size();
Lee Leahyb0005132015-05-12 18:19:47 -070062}
63
Aaron Durbinc43d4172015-08-05 14:51:48 -050064/*
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
74 */
75int smm_subregion(int sub, void **start, size_t *size)
76{
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;
81
82 sub_base = smm_region_start();
83 sub_size = smm_region_size();
84
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;
103 }
104
105 *start = (void *)sub_base;
106 *size = sub_size;
107
108 return 0;
109}
110
Rizwan Qureshi188e3702015-07-23 17:40:32 +0530111/*
112 * Host Memory Map:
113 *
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
135 *
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.
140 */
141
142u32 top_of_32bit_ram(void)
143{
144 msr_t prmrr_base;
145 u32 top_of_ram;
146 const struct device *dev;
147 const struct soc_intel_skylake_config *config;
148
149 /*
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.
154 */
155 if (smm_region_start() == 0)
156 return 0;
157
158 dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
159 config = dev->chip_info;
160
161 /*
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.
166 */
167 prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
168 top_of_ram = prmrr_base.lo;
169
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}
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700207