coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
addressmap.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <device/mmio.h>
5 #include <commonlib/helpers.h>
6 #include <console/console.h>
7 #include <soc/addressmap.h>
8 #include <soc/id.h>
9 #include <soc/mc.h>
10 #include <soc/sdram.h>
11 #include <symbols.h>
12 #include <soc/nvidia/tegra/types.h>
13 #include <types.h>
14 
16 static const size_t tz_size_mib = CONFIG_TRUSTZONE_CARVEOUT_SIZE_MB;
17 
18 /* returns total amount of DRAM (in MB) from memory controller registers */
19 int sdram_size_mb(void)
20 {
21  struct tegra_mc_regs *mc = (struct tegra_mc_regs *)TEGRA_MC_BASE;
22  static int total_size = 0;
23 
24  if (total_size)
25  return total_size;
26 
27  /*
28  * This obtains memory size from the External Memory Aperture
29  * Configuration register. Nvidia confirmed that it is safe to assume
30  * this value represents the total physical DRAM size.
31  */
32  total_size = (read32(&mc->emem_cfg) >>
34 
35  return total_size;
36 }
37 
38 static void carveout_from_regs(uintptr_t *base_mib, size_t *size_mib,
39  uint32_t bom, uint32_t bom_hi, uint32_t size)
40 {
41 
42  /* All size regs of carveouts are in MiB. */
43  if (size == 0)
44  return;
45 
46  *size_mib = size;
47  bom >>= 20;
48  bom |= bom_hi << (32 - 20);
49 
50  *base_mib = bom;
51 }
52 
53 void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib)
54 {
55  *base_mib = 0;
56  *size_mib = 0;
57  struct tegra_mc_regs * const mc = (struct tegra_mc_regs *)TEGRA_MC_BASE;
58  size_t region_size_mb;
59 
60  switch (id) {
61  case CARVEOUT_TZ:
62  *base_mib = tz_base_mib;
63  *size_mib = tz_size_mib;
64  break;
65  case CARVEOUT_SEC:
66  carveout_from_regs(base_mib, size_mib,
70  break;
71  case CARVEOUT_MTS:
72  carveout_from_regs(base_mib, size_mib,
76  break;
77  case CARVEOUT_VPR:
78  /*
79  * A 128MB VPR carveout is felt to be sufficient as per syseng.
80  * Set it up in vpr_region_init, below.
81  */
82  carveout_from_regs(base_mib, size_mib,
86  break;
87  case CARVEOUT_GPU:
88  /* These carveout regs use 128KB granularity - convert to MB */
89  region_size_mb = DIV_ROUND_UP(read32(&mc->security_carveout2_size_128kb), 8);
90 
91  /* BOM address set in gpu_region_init, below */
92  carveout_from_regs(base_mib, size_mib,
95  region_size_mb);
96  break;
97  case CARVEOUT_NVDEC:
98  /* These carveout regs use 128KB granularity - convert to MB */
99  region_size_mb = DIV_ROUND_UP(read32(&mc->security_carveout1_size_128kb), 8);
100 
101  /* BOM address set in nvdec_region_init, below */
102  carveout_from_regs(base_mib, size_mib,
105  region_size_mb);
106  break;
107  case CARVEOUT_TSEC:
108  /* These carveout regs use 128KB granularity - convert to MB */
109  region_size_mb = DIV_ROUND_UP(read32(&mc->security_carveout4_size_128kb), 8);
110 
111  /* BOM address set in tsec_region_init, below.
112  * Since the TSEC region consumes 2 carveouts, and is
113  * expected to be split evenly between the two, size_mib
114  * is doubled here.
115  */
116  region_size_mb *= 2;
117  carveout_from_regs(base_mib, size_mib,
120  region_size_mb);
121  break;
122  default:
123  break;
124  }
125 }
126 
127 void print_carveouts(void)
128 {
129  int i;
130  printk(BIOS_INFO, "Carveout ranges:\n");
131  for (i = 0; i < CARVEOUT_NUM; i++) {
132  uintptr_t base, end;
133  size_t size;
134  carveout_range(i, &base, &size);
135  end = base + size;
136  if (end && base)
137  printk(BIOS_INFO, "ID:%d [%lx - %lx)\n", i,
138  (unsigned long)base * MiB,
139  (unsigned long)end * MiB);
140  }
141 }
142 
143 /*
144  * Memory Map is as follows
145  *
146  * ------------------------------ <-- Start of DRAM
147  * | |
148  * | Available DRAM |
149  * |____________________________|
150  * | |
151  * | CBMEM |
152  * |____________________________|
153  * | |
154  * | Other carveouts |
155  * | (with dynamic allocation) |
156  * |____________________________|
157  * | |
158  * | TZ carveout of size |
159  * | TRUSTZONE_CARVEOUT_SIZE_MB |
160  * |____________________________| <-- 0x100000000
161  * | |
162  * | Available DRAM |
163  * | |
164  * ------------------------------ <-- End of DRAM
165  *
166  */
167 static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib,
168  int ignore_carveout_id)
169 {
170  uintptr_t base;
171  uintptr_t end;
172  int i;
173 
174  base = (uintptr_t)_dram / MiB;
175  end = base + sdram_size_mb();
176 
177  /* Requested limits out of range. */
178  if (*end_mib <= base || *base_mib >= end) {
179  *end_mib = *base_mib = 0;
180  return;
181  }
182 
183  /* Clip region to passed in limits. */
184  if (*end_mib < end)
185  end = *end_mib;
186  if (*base_mib > base)
187  base = *base_mib;
188 
189  for (i = 0; i < CARVEOUT_NUM; i++) {
190  uintptr_t carveout_base;
191  uintptr_t carveout_end;
192  size_t carveout_size;
193 
194  if (i == ignore_carveout_id)
195  continue;
196 
197  carveout_range(i, &carveout_base, &carveout_size);
198  if (carveout_size == 0)
199  continue;
200 
201  carveout_end = carveout_base + carveout_size;
202 
203  /* Bypass carveouts out of requested range. */
204  if (carveout_base >= end || carveout_end <= base)
205  continue;
206 
207  /*
208  * This is crude, but the assumption is that carveouts live
209  * at the upper range of physical memory. Therefore, update
210  * the end address to be equal to the base of the carveout.
211  */
212  end = carveout_base;
213  }
214 
215  *base_mib = base;
216  *end_mib = end;
217 }
218 
220 {
221  *base_mib = 0;
222  *end_mib = 4096;
223  memory_in_range(base_mib, end_mib, CARVEOUT_NUM);
224 }
225 
227 {
228  *base_mib = 4096;
229  *end_mib = ~0UL;
230  memory_in_range(base_mib, end_mib, CARVEOUT_NUM);
231 }
232 
234 {
235  struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
236  uintptr_t end = 4096;
237 
238  /* Already has been initialized. */
239  if (tz_size_mib != 0 && tz_base_mib != 0)
240  return;
241 
242  /*
243  * Get memory layout below 4GiB ignoring the TZ carveout because
244  * that's the one to initialize.
245  */
246  tz_base_mib = end - tz_size_mib;
248 
249  /*
250  * IMPORTANT!!!!!
251  * We need to ensure that trustzone region is located at the end of
252  * 32-bit address space. If any carveout is allocated space before
253  * trustzone_region_init is called, then this assert will ensure that
254  * the boot flow fails. If you are here because of this assert, please
255  * move your call to initialize carveout after trustzone_region_init in
256  * romstage and ramstage.
257  */
258  assert(end == 4096);
259 
260  /* AVP cannot set the TZ registers proper as it is always non-secure. */
261  if (context_avp())
262  return;
263 
264  /* Set the carveout region. */
265  write32(&mc->security_cfg0, tz_base_mib << 20);
267 
268  /* Enable SMMU translations */
270 }
271 
272 void gpu_region_init(void)
273 {
274  struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
275  uintptr_t gpu_base_mib = 0, end = 4096;
276  size_t gpu_size_mib = GPU_CARVEOUT_SIZE_MB;
277 
278  /* Get memory layout below 4GiB */
279  memory_in_range(&gpu_base_mib, &end, CARVEOUT_GPU);
280  gpu_base_mib = end - gpu_size_mib;
281 
282  /* Set the carveout2 base address. Everything else has been set in the BCT cfg/inc */
283  write32(&mc->security_carveout2_bom, gpu_base_mib << 20);
285 
286  /* Set the locked bit. This will lock out any other writes! */
288 
289  /* Set the carveout3 base to 0, unused */
292 
293  /* Set the locked bit. This will lock out any other writes! */
295 }
296 
298 {
299  struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
300  uintptr_t nvdec_base_mib = 0, end = 4096;
301  size_t nvdec_size_mib = NVDEC_CARVEOUT_SIZE_MB;
302 
303  /* Get memory layout below 4GiB */
304  memory_in_range(&nvdec_base_mib, &end, CARVEOUT_NVDEC);
305  nvdec_base_mib = end - nvdec_size_mib;
306 
307  /* Set the carveout1 base address. Everything else has been set in the BCT cfg/inc */
308  write32(&mc->security_carveout1_bom, nvdec_base_mib << 20);
310 
311  /* Set the locked bit. This will lock out any other writes! */
313 }
314 
316 {
317  struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
318  uintptr_t tsec_base_mib = 0, end = 4096;
319  size_t tsec_size_mib = TSEC_CARVEOUT_SIZE_MB;
320 
321  /* Get memory layout below 4GiB */
322  memory_in_range(&tsec_base_mib, &end, CARVEOUT_TSEC);
323  tsec_base_mib = end - tsec_size_mib;
324 
325  /*
326  * Set the carveout4/5 base address. Everything else has been set in the BCT cfg/inc
327  * Note that the TSEC range is split evenly between the 2 carveouts (i.e. 1MB each)
328  */
329  write32(&mc->security_carveout4_bom, tsec_base_mib << 20);
331  write32(&mc->security_carveout5_bom, (tsec_base_mib + (TSEC_CARVEOUT_SIZE_MB / 2)) << 20);
333 
334  /* Set the locked bit. This will lock out any other writes! */
337 }
338 
339 void vpr_region_init(void)
340 {
341  struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
342  uintptr_t vpr_base_mib = 0, end = 4096;
343  size_t vpr_size_mib = VPR_CARVEOUT_SIZE_MB;
344 
345  /* Get memory layout below 4GiB */
346  memory_in_range(&vpr_base_mib, &end, CARVEOUT_VPR);
347  vpr_base_mib = end - vpr_size_mib;
348 
349  /* Set the carveout base address and size */
350  write32(&mc->video_protect_bom, vpr_base_mib << 20);
352  write32(&mc->video_protect_size_mb, vpr_size_mib);
353 
354  /* Set the locked bit. This will lock out any other writes! */
356 }
void print_carveouts(void)
Definition: addressmap.c:127
static const size_t tz_size_mib
Definition: addressmap.c:16
void gpu_region_init(void)
Definition: addressmap.c:272
static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib, int ignore_carveout_id)
Definition: addressmap.c:167
static void carveout_from_regs(uintptr_t *base_mib, size_t *size_mib, uint32_t bom, uint32_t bom_hi, uint32_t size)
Definition: addressmap.c:38
static uintptr_t tz_base_mib
Definition: addressmap.c:15
void memory_in_range_above_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
Definition: addressmap.c:226
void vpr_region_init(void)
Definition: addressmap.c:339
void nvdec_region_init(void)
Definition: addressmap.c:297
void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib)
Definition: addressmap.c:53
int sdram_size_mb(void)
Definition: addressmap.c:19
void memory_in_range_below_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
Definition: addressmap.c:219
void tsec_region_init(void)
Definition: addressmap.c:315
void trustzone_region_init(void)
Definition: addressmap.c:233
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define assert(statement)
Definition: assert.h:74
#define MiB
Definition: helpers.h:76
#define DIV_ROUND_UP(x, y)
Definition: helpers.h:60
#define printk(level,...)
Definition: stdlib.h:16
static int context_avp(void)
Definition: id.h:9
#define setbits32(addr, set)
Definition: mmio.h:21
u8 _dram[]
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
uintptr_t base
Definition: uart.c:17
@ TEGRA_MC_BASE
Definition: addressmap.h:53
#define NVDEC_CARVEOUT_SIZE_MB
Definition: addressmap.h:90
#define VPR_CARVEOUT_SIZE_MB
Definition: addressmap.h:92
#define TSEC_CARVEOUT_SIZE_MB
Definition: addressmap.h:91
@ CARVEOUT_MTS
Definition: addressmap.h:104
@ CARVEOUT_GPU
Definition: addressmap.h:106
@ CARVEOUT_VPR
Definition: addressmap.h:105
@ CARVEOUT_TZ
Definition: addressmap.h:102
@ CARVEOUT_SEC
Definition: addressmap.h:103
@ CARVEOUT_NUM
Definition: addressmap.h:109
@ CARVEOUT_TSEC
Definition: addressmap.h:108
@ CARVEOUT_NVDEC
Definition: addressmap.h:107
#define GPU_CARVEOUT_SIZE_MB
Definition: addressmap.h:89
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
uint32_t security_carveout2_size_128kb
Definition: mc.h:135
uint32_t security_carveout1_cfg0
Definition: mc.h:116
uint32_t video_protect_size_mb
Definition: mc.h:73
uint32_t security_carveout2_bom
Definition: mc.h:133
uint32_t sec_carveout_size_mb
Definition: mc.h:79
uint32_t mts_carveout_adr_hi
Definition: mc.h:91
uint32_t smmu_config
Definition: mc.h:13
uint32_t video_protect_bom_adr_hi
Definition: mc.h:84
uint32_t security_carveout3_bom
Definition: mc.h:149
uint32_t security_carveout1_bom_hi
Definition: mc.h:118
uint32_t security_carveout3_cfg0
Definition: mc.h:148
uint32_t emem_cfg
Definition: mc.h:22
uint32_t security_carveout2_bom_hi
Definition: mc.h:134
uint32_t security_carveout1_bom
Definition: mc.h:117
uint32_t security_carveout4_cfg0
Definition: mc.h:164
uint32_t video_protect_bom
Definition: mc.h:72
uint32_t security_carveout4_bom
Definition: mc.h:165
uint32_t security_carveout4_size_128kb
Definition: mc.h:167
uint32_t security_cfg0
Definition: mc.h:30
uint32_t security_cfg1
Definition: mc.h:31
uint32_t security_carveout5_cfg0
Definition: mc.h:180
uint32_t security_carveout3_bom_hi
Definition: mc.h:150
uint32_t security_carveout5_bom
Definition: mc.h:181
uint32_t mts_carveout_bom
Definition: mc.h:89
uint32_t sec_carveout_bom
Definition: mc.h:78
uint32_t sec_carveout_adr_hi
Definition: mc.h:99
uint32_t security_carveout1_size_128kb
Definition: mc.h:119
uint32_t security_carveout5_bom_hi
Definition: mc.h:182
uint32_t security_carveout4_bom_hi
Definition: mc.h:166
uint32_t video_protect_reg_ctrl
Definition: mc.h:74
uint32_t mts_carveout_size_mb
Definition: mc.h:90
uint32_t security_carveout2_cfg0
Definition: mc.h:132
@ MC_EMEM_CFG_SIZE_MB_SHIFT
Definition: mc.h:103
@ MC_EMEM_CFG_SIZE_MB_MASK
Definition: mc.h:104
@ MC_SMMU_CONFIG_ENABLE
Definition: mc.h:197
#define MC_VPR_WR_ACCESS_DISABLE
Definition: mc.h:211
#define MC_SECURITY_CARVEOUT_LOCKED
Definition: mc.h:210