memory: Make the RAM base dynamic

For now we compute this as phys_base aligned down to a 4GiB boundary.
Hopefully that works for future SoCs too.

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-11-01 13:39:40 +09:00
parent 38fc7a0780
commit 7ff48f6201
3 changed files with 18 additions and 16 deletions

View file

@ -440,8 +440,8 @@ class GUARD(IntFlag):
SILENT = 0x100 SILENT = 0x100
REGION_RWX_EL0 = 0x8000000000 REGION_RWX_EL0 = 0x8000000000
REGION_RW_EL0 = 0x9000000000 REGION_RW_EL0 = 0xa000000000
REGION_RX_EL1 = 0xa000000000 REGION_RX_EL1 = 0xc000000000
# Uses UartInterface.proxyreq() to send requests to M1N1 and process # Uses UartInterface.proxyreq() to send requests to M1N1 and process
# reponses sent back. # reponses sent back.

View file

@ -37,6 +37,8 @@ extern u8 _stack_top[];
extern u8 gl1_stack[GL_STACK_SIZE]; extern u8 gl1_stack[GL_STACK_SIZE];
extern u8 gl2_stack[MAX_CPUS][GL_STACK_SIZE]; extern u8 gl2_stack[MAX_CPUS][GL_STACK_SIZE];
uint64_t ram_base = 0;
static inline u64 read_sctlr(void) static inline u64 read_sctlr(void)
{ {
sysop("isb"); sysop("isb");
@ -339,8 +341,8 @@ static void mmu_unmap_carveouts(void)
uint64_t start = ((uint64_t)read32(mcc_tz_base + TZ_START(i))) << 12; uint64_t start = ((uint64_t)read32(mcc_tz_base + TZ_START(i))) << 12;
uint64_t end = ((uint64_t)(1 + read32(mcc_tz_base + TZ_END(i)))) << 12; uint64_t end = ((uint64_t)(1 + read32(mcc_tz_base + TZ_END(i)))) << 12;
if (start) { if (start) {
start |= 0x0800000000; start |= ram_base;
end |= 0x0800000000; end |= ram_base;
printf("MMU: Unmapping TZ%d region at 0x%lx..0x%lx\n", i, start, end); printf("MMU: Unmapping TZ%d region at 0x%lx..0x%lx\n", i, start, end);
mmu_rm_mapping(start, end - start); mmu_rm_mapping(start, end - start);
} }
@ -360,18 +362,19 @@ static void mmu_add_default_mappings(void)
mmu_add_mapping(0x0680000000, 0x0680000000, 0x0020000000, MAIR_IDX_DEVICE_nGnRnE, PERM_RW_EL0); mmu_add_mapping(0x0680000000, 0x0680000000, 0x0020000000, MAIR_IDX_DEVICE_nGnRnE, PERM_RW_EL0);
mmu_add_mapping(0x06a0000000, 0x06a0000000, 0x0060000000, MAIR_IDX_DEVICE_nGnRE, PERM_RW_EL0); mmu_add_mapping(0x06a0000000, 0x06a0000000, 0x0060000000, MAIR_IDX_DEVICE_nGnRE, PERM_RW_EL0);
uint64_t ram_size = cur_boot_args.mem_size + cur_boot_args.phys_base - 0x0800000000; ram_base = ALIGN_DOWN(cur_boot_args.phys_base, BIT(32));
uint64_t ram_size = cur_boot_args.mem_size + cur_boot_args.phys_base - ram_base;
ram_size = ALIGN_DOWN(ram_size, 0x4000); ram_size = ALIGN_DOWN(ram_size, 0x4000);
printf("MMU: Top of normal RAM: 0x%lx\n", 0x0800000000 + ram_size); printf("MMU: RAM base: 0x%lx\n", ram_base);
printf("MMU: Top of normal RAM: 0x%lx\n", ram_base + ram_size);
/* /*
* Create identity mapping for RAM from 0x08_0000_0000 * Create identity mapping for RAM from 0x08_0000_0000
* With SPRR enabled, this becomes RW. * With SPRR enabled, this becomes RW.
* This range includes all real RAM, including carveouts * This range includes all real RAM, including carveouts
*/ */
mmu_add_mapping(0x0800000000, 0x0800000000, cur_boot_args.mem_size_actual, MAIR_IDX_NORMAL, mmu_add_mapping(ram_base, ram_base, cur_boot_args.mem_size_actual, MAIR_IDX_NORMAL, PERM_RWX);
PERM_RWX);
/* Unmap carveout regions */ /* Unmap carveout regions */
mmu_unmap_carveouts(); mmu_unmap_carveouts();
@ -398,22 +401,19 @@ static void mmu_add_default_mappings(void)
* read/writable/exec by EL0 (but not executable by EL1) * read/writable/exec by EL0 (but not executable by EL1)
* With SPRR enabled, this becomes RX_EL0. * With SPRR enabled, this becomes RX_EL0.
*/ */
mmu_add_mapping(0x0800000000 | REGION_RWX_EL0, 0x0800000000, ram_size, MAIR_IDX_NORMAL, mmu_add_mapping(ram_base | REGION_RWX_EL0, ram_base, ram_size, MAIR_IDX_NORMAL, PERM_RWX_EL0);
PERM_RWX_EL0);
/* /*
* Create mapping for RAM from 0x98_0000_0000, * Create mapping for RAM from 0x98_0000_0000,
* read/writable by EL0 (but not executable by EL1) * read/writable by EL0 (but not executable by EL1)
* With SPRR enabled, this becomes RW_EL0. * With SPRR enabled, this becomes RW_EL0.
*/ */
mmu_add_mapping(0x0800000000 | REGION_RW_EL0, 0x0800000000, ram_size, MAIR_IDX_NORMAL, mmu_add_mapping(ram_base | REGION_RW_EL0, ram_base, ram_size, MAIR_IDX_NORMAL, PERM_RW_EL0);
PERM_RW_EL0);
/* /*
* Create mapping for RAM from 0xa8_0000_0000, * Create mapping for RAM from 0xa8_0000_0000,
* read/executable by EL1 * read/executable by EL1
* This allows executing from dynamic regions in EL1 * This allows executing from dynamic regions in EL1
*/ */
mmu_add_mapping(0x0800000000 | REGION_RX_EL1, 0x0800000000, ram_size, MAIR_IDX_NORMAL, mmu_add_mapping(ram_base | REGION_RX_EL1, ram_base, ram_size, MAIR_IDX_NORMAL, PERM_RX_EL0);
PERM_RX_EL0);
/* /*
* Create two seperate nGnRnE and nGnRE full mappings of MMIO space * Create two seperate nGnRnE and nGnRE full mappings of MMIO space

View file

@ -7,8 +7,8 @@
#include "types.h" #include "types.h"
#define REGION_RWX_EL0 0x8000000000 #define REGION_RWX_EL0 0x8000000000
#define REGION_RW_EL0 0x9000000000 #define REGION_RW_EL0 0xa000000000
#define REGION_RX_EL1 0xa000000000 #define REGION_RX_EL1 0xc000000000
/* /*
* https://armv8-ref.codingbelief.com/en/chapter_d4/d43_2_armv8_translation_table_level_3_descriptor_formats.html * https://armv8-ref.codingbelief.com/en/chapter_d4/d43_2_armv8_translation_table_level_3_descriptor_formats.html
@ -48,6 +48,8 @@
#include "utils.h" #include "utils.h"
extern uint64_t ram_base;
void ic_ivau_range(void *addr, size_t length); void ic_ivau_range(void *addr, size_t length);
void dc_ivac_range(void *addr, size_t length); void dc_ivac_range(void *addr, size_t length);
void dc_zva_range(void *addr, size_t length); void dc_zva_range(void *addr, size_t length);