Marc Jones (marc.jones@se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8591
-gerrit
commit ac85ad19ab31c2ee90983cbf213576d28dea3a12 Author: Aaron Durbin adurbin@chromium.org Date: Fri Jul 11 15:56:31 2014 -0500
t132: handle carve-outs for addressable memory
The carve-out regions need to be taken into account when calculating addressable memory because those regions aren't accessible from the main cpu. The additional exposed functions are to accommodate adding resources during ramstage resource reading. The TZ (trust zone) region is empty for now until more documentation is provided on determining its location.
BUG=None TEST=Built and booted through attempting payload loading. MTS carve-out is taken into account programmatically.
Original-Change-Id: I3301b2a12680ad79047198ada41f32eb1b7fa68b Original-Signed-off-by: Aaron Durbin adurbin@chromium.org Original-Reviewed-on: https://chromium-review.googlesource.com/207585 Original-Reviewed-by: Furquan Shaikh furquan@chromium.org (cherry picked from commit 15b9c74dd1ef5bfb1fd7c6dab50624f815658e14) Signed-off-by: Marc Jones marc.jones@se-eng.com
Change-Id: I46d54dbbb8e102fc70ab34bc4bbd2361ef1ea504 --- src/soc/nvidia/tegra132/addressmap.c | 98 +++++++++++++++++++++++- src/soc/nvidia/tegra132/cbmem.c | 13 ++-- src/soc/nvidia/tegra132/include/soc/addressmap.h | 27 ++++++- 3 files changed, 129 insertions(+), 9 deletions(-)
diff --git a/src/soc/nvidia/tegra132/addressmap.c b/src/soc/nvidia/tegra132/addressmap.c index 92a7d76..7620b1f 100644 --- a/src/soc/nvidia/tegra132/addressmap.c +++ b/src/soc/nvidia/tegra132/addressmap.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <console/console.h> #include <soc/addressmap.h> +#include <soc/display.h> #include "mc.h" #include "sdram.h"
@@ -46,7 +47,100 @@ int sdram_size_mb(void) return total_size; }
-uintptr_t sdram_max_addressable_mb(void) +static void carveout_from_regs(uintptr_t *base_mib, size_t *size_mib, + uint32_t bom, uint32_t bom_hi, uint32_t size) { - return MIN((CONFIG_SYS_SDRAM_BASE/MiB) + sdram_size_mb(), 4096); + + /* All size regs of carveouts are in MiB. */ + if (size == 0) + return; + + *size_mib = size; + bom >>= 20; + bom |= bom_hi >> (32 - 20); + + *base_mib = bom; +} + +void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib) +{ + *base_mib = 0; + *size_mib = 0; + struct tegra_mc_regs * const mc = (struct tegra_mc_regs *)TEGRA_MC_BASE; + + switch (id) { + case CARVEOUT_TZ: + break; + case CARVEOUT_SEC: + carveout_from_regs(base_mib, size_mib, + read32(&mc->sec_carveout_bom), + read32(&mc->sec_carveout_adr_hi), + read32(&mc->sec_carveout_size_mb)); + break; + case CARVEOUT_MTS: + carveout_from_regs(base_mib, size_mib, + read32(&mc->mts_carveout_bom), + read32(&mc->mts_carveout_adr_hi), + read32(&mc->mts_carveout_size_mb)); + break; + case CARVEOUT_VPR: + carveout_from_regs(base_mib, size_mib, + read32(&mc->video_protect_bom), + read32(&mc->video_protect_bom_adr_hi), + read32(&mc->video_protect_size_mb)); + break; + default: + break; + } +} + +void memory_range_by_bits(int bits, uintptr_t *base_mib, uintptr_t *end_mib) +{ + uintptr_t base; + uintptr_t end; + int i; + + base = CONFIG_SYS_SDRAM_BASE / MiB; + end = base + sdram_size_mb(); + + if (bits == ADDRESS_SPACE_32_BIT) + end = MIN(end, 4096); + + for (i = 0; i < CARVEOUT_NUM; i++) { + uintptr_t carveout_base; + size_t carveout_size; + + carveout_range(i, &carveout_base, &carveout_size); + + if (carveout_size == 0) + continue; + + /* Bypass carveouts out of requested range. */ + if (carveout_base >= end) + continue; + + /* + * This is crude, but the assumption is that carveouts live + * at the upper range of physical memory. Therefore, update + * the end address to be equal to the base of the carveout. + */ + end = carveout_base; + } + + *base_mib = base; + *end_mib = end; +} + +uintptr_t framebuffer_attributes(size_t *size_mib) +{ + uintptr_t begin; + uintptr_t end; + + /* Place the framebuffer just below the 32-bit addressable limit. */ + memory_range_by_bits(ADDRESS_SPACE_32_BIT, &begin, &end); + + *size_mib = FB_SIZE_MB; + end -= *size_mib; + + return end; } diff --git a/src/soc/nvidia/tegra132/cbmem.c b/src/soc/nvidia/tegra132/cbmem.c index 136d3ea..ee95ba9 100644 --- a/src/soc/nvidia/tegra132/cbmem.c +++ b/src/soc/nvidia/tegra132/cbmem.c @@ -18,15 +18,16 @@ */
#include <cbmem.h> -#include <soc/display.h> #include <soc/addressmap.h>
-#define MTS_SIZE_MB 128 - void *cbmem_top(void) { - /* FIXME(adurbin): use carveout registers properly. */ - const uintptr_t reserve = FB_SIZE_MB + MTS_SIZE_MB; + static uintptr_t addr; + size_t fb_size; + + /* CBMEM starts downwards from the framebuffer. */ + if (addr == 0) + addr = framebuffer_attributes(&fb_size);
- return (void *)((sdram_max_addressable_mb() - reserve) << 20UL); + return (void *)(addr << 20UL); } diff --git a/src/soc/nvidia/tegra132/include/soc/addressmap.h b/src/soc/nvidia/tegra132/include/soc/addressmap.h index 021a523..2c6dc5e 100644 --- a/src/soc/nvidia/tegra132/include/soc/addressmap.h +++ b/src/soc/nvidia/tegra132/include/soc/addressmap.h @@ -81,7 +81,32 @@ enum { TEGRA_I2C_BASE_COUNT = 6, };
+/* Return total size of DRAM memory configured on the platform. */ int sdram_size_mb(void); -uintptr_t sdram_max_addressable_mb(void); + +enum { + ADDRESS_SPACE_32_BIT = 32, + ADDRESS_SPACE_64_BIT = 64, +}; + +/* + * Return the address range of memory for provided address width. The base + * and end parameters in 1MiB units with end being exclusive to the range. + */ +void memory_range_by_bits(int bits, uintptr_t *base_mib, uintptr_t *end_mib); + +enum { + CARVEOUT_TZ, + CARVEOUT_SEC, + CARVEOUT_MTS, + CARVEOUT_VPR, + CARVEOUT_NUM, +}; + +/* Provided the careout id, obtain the base and size in 1MiB units. */ +void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib); + +/* Return pointer and size in 1MiB units. */ +uintptr_t framebuffer_attributes(size_t *size_mib);
#endif /* __SOC_NVIDIA_TEGRA132_INCLUDE_SOC_ADDRESS_MAP_H__ */