2 * This file is part of the coreboot project.
4 * Copyright 2014 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <console/console.h>
19 #include <soc/addressmap.h>
22 #include <soc/sdram.h>
26 static uintptr_t tz_base_mib
;
27 static const size_t tz_size_mib
= CONFIG_TRUSTZONE_CARVEOUT_SIZE_MB
;
29 /* returns total amount of DRAM (in MB) from memory controller registers */
30 int sdram_size_mb(void)
32 struct tegra_mc_regs
*mc
= (struct tegra_mc_regs
*)TEGRA_MC_BASE
;
33 static int total_size
= 0;
39 * This obtains memory size from the External Memory Aperture
40 * Configuration register. Nvidia confirmed that it is safe to assume
41 * this value represents the total physical DRAM size.
43 total_size
= (read32(&mc
->emem_cfg
) >> MC_EMEM_CFG_SIZE_MB_SHIFT
) &
44 MC_EMEM_CFG_SIZE_MB_MASK
;
49 static void carveout_from_regs(uintptr_t *base_mib
, size_t *size_mib
,
50 uint32_t bom
, uint32_t bom_hi
, uint32_t size
)
53 /* All size regs of carveouts are in MiB. */
59 bom
|= bom_hi
<< (32 - 20);
64 void carveout_range(int id
, uintptr_t *base_mib
, size_t *size_mib
)
68 struct tegra_mc_regs
* const mc
= (struct tegra_mc_regs
*)TEGRA_MC_BASE
;
72 *base_mib
= tz_base_mib
;
73 *size_mib
= tz_size_mib
;
76 carveout_from_regs(base_mib
, size_mib
,
77 read32(&mc
->sec_carveout_bom
),
78 read32(&mc
->sec_carveout_adr_hi
),
79 read32(&mc
->sec_carveout_size_mb
));
82 carveout_from_regs(base_mib
, size_mib
,
83 read32(&mc
->mts_carveout_bom
),
84 read32(&mc
->mts_carveout_adr_hi
),
85 read32(&mc
->mts_carveout_size_mb
));
88 carveout_from_regs(base_mib
, size_mib
,
89 read32(&mc
->video_protect_bom
),
90 read32(&mc
->video_protect_bom_adr_hi
),
91 read32(&mc
->video_protect_size_mb
));
98 static void memory_in_range(uintptr_t *base_mib
, uintptr_t *end_mib
,
105 base
= (uintptr_t)_dram
/ MiB
;
106 end
= base
+ sdram_size_mb();
108 /* Requested limits out of range. */
109 if (*end_mib
<= base
|| *base_mib
>= end
) {
110 *end_mib
= *base_mib
= 0;
114 /* Clip region to passed in limits. */
117 if (*base_mib
> base
)
120 for (i
= 0; i
< CARVEOUT_NUM
; i
++) {
121 uintptr_t carveout_base
;
122 uintptr_t carveout_end
;
123 size_t carveout_size
;
125 if (i
== CARVEOUT_TZ
&& ignore_tz
)
128 carveout_range(i
, &carveout_base
, &carveout_size
);
130 if (carveout_size
== 0)
133 carveout_end
= carveout_base
+ carveout_size
;
135 /* Bypass carveouts out of requested range. */
136 if (carveout_base
>= end
|| carveout_end
<= base
)
140 * This is crude, but the assumption is that carveouts live
141 * at the upper range of physical memory. Therefore, update
142 * the end address to be equal to the base of the carveout.
151 void memory_in_range_below_4gb(uintptr_t *base_mib
, uintptr_t *end_mib
)
155 memory_in_range(base_mib
, end_mib
, 0);
158 void memory_in_range_above_4gb(uintptr_t *base_mib
, uintptr_t *end_mib
)
162 memory_in_range(base_mib
, end_mib
, 0);
165 void trustzone_region_init(void)
167 struct tegra_mc_regs
* const mc
= (void *)(uintptr_t)TEGRA_MC_BASE
;
168 uintptr_t end
= 4096;
170 /* Already has been initialized. */
171 if (tz_size_mib
!= 0 && tz_base_mib
!= 0)
175 * Get memory layout below 4GiB ignoring the TZ carveout because
176 * that's the one to initialize.
178 memory_in_range(&tz_base_mib
, &end
, 1);
179 tz_base_mib
= end
- tz_size_mib
;
181 /* AVP cannot set the TZ registers proper as it is always non-secure. */
185 /* Set the carveout region. */
186 write32(&mc
->security_cfg0
, tz_base_mib
<< 20);
187 write32(&mc
->security_cfg1
, tz_size_mib
);
189 /* Enable SMMU translations */
190 write32(&mc
->smmu_config
, MC_SMMU_CONFIG_ENABLE
);