From: Caleb Connolly Date: Thu, 8 Aug 2024 23:59:31 +0000 (+0200) Subject: armv8: mmu: add a way to map additional regions X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=9f2d4561465b42f8cdc478ea5df44b93e12a90d9;p=u-boot.git armv8: mmu: add a way to map additional regions In some cases we might want to map some memory region after enabling caches. Introduce a new helper for this. Reviewed-by: Neil Armstrong Signed-off-by: Caleb Connolly --- diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index c3f8dac648..631d9efa5e 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -339,6 +339,31 @@ static void map_range(u64 virt, u64 phys, u64 size, int level, } } +void mmu_map_region(phys_addr_t addr, u64 size, bool emergency) +{ + u64 va_bits; + int level = 0; + u64 attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE; + + attrs |= PTE_TYPE_BLOCK | PTE_BLOCK_AF; + + get_tcr(NULL, &va_bits); + if (va_bits < 39) + level = 1; + + if (emergency) + map_range(addr, addr, size, level, + (u64 *)gd->arch.tlb_emerg, attrs); + + /* Switch pagetables while we update the primary one */ + __asm_switch_ttbr(gd->arch.tlb_emerg); + + map_range(addr, addr, size, level, + (u64 *)gd->arch.tlb_addr, attrs); + + __asm_switch_ttbr(gd->arch.tlb_addr); +} + static void add_map(struct mm_region *map) { u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF; diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 7e30cac32a..2237d7d006 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -277,6 +277,16 @@ void protect_secure_region(void); void smp_kick_all_cpus(void); void flush_l3_cache(void); + +/** + * mmu_map_region() - map a region of previously unmapped memory. + * Will be mapped MT_NORMAL & PTE_BLOCK_INNER_SHARE. + * + * @start: Start address of the region + * @size: Size of the region + * @emerg: Also map the region in the emergency table + */ +void mmu_map_region(phys_addr_t start, u64 size, bool emerg); void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs); /*