1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <platform_def.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <arch.h> 12*91f16700Schasinglulu #include <arch_helpers.h> 13*91f16700Schasinglulu #include <lib/utils.h> 14*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_arch.h> 15*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables.h> 16*91f16700Schasinglulu 17*91f16700Schasinglulu #include "../xlat_tables_private.h" 18*91f16700Schasinglulu 19*91f16700Schasinglulu #if (ARM_ARCH_MAJOR == 7) && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING) 20*91f16700Schasinglulu #error ARMv7 target does not support LPAE MMU descriptors 21*91f16700Schasinglulu #endif 22*91f16700Schasinglulu 23*91f16700Schasinglulu #define XLAT_TABLE_LEVEL_BASE \ 24*91f16700Schasinglulu GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE) 25*91f16700Schasinglulu 26*91f16700Schasinglulu #define NUM_BASE_LEVEL_ENTRIES \ 27*91f16700Schasinglulu GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE) 28*91f16700Schasinglulu 29*91f16700Schasinglulu static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES] 30*91f16700Schasinglulu __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); 31*91f16700Schasinglulu 32*91f16700Schasinglulu #if ENABLE_ASSERTIONS 33*91f16700Schasinglulu static unsigned long long get_max_supported_pa(void) 34*91f16700Schasinglulu { 35*91f16700Schasinglulu /* Physical address space size for long descriptor format. */ 36*91f16700Schasinglulu return (1ULL << 40) - 1ULL; 37*91f16700Schasinglulu } 38*91f16700Schasinglulu #endif /* ENABLE_ASSERTIONS */ 39*91f16700Schasinglulu 40*91f16700Schasinglulu unsigned int xlat_arch_current_el(void) 41*91f16700Schasinglulu { 42*91f16700Schasinglulu /* 43*91f16700Schasinglulu * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System, 44*91f16700Schasinglulu * SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. 45*91f16700Schasinglulu */ 46*91f16700Schasinglulu return 3U; 47*91f16700Schasinglulu } 48*91f16700Schasinglulu 49*91f16700Schasinglulu uint64_t xlat_arch_get_xn_desc(unsigned int el __unused) 50*91f16700Schasinglulu { 51*91f16700Schasinglulu return UPPER_ATTRS(XN); 52*91f16700Schasinglulu } 53*91f16700Schasinglulu 54*91f16700Schasinglulu void init_xlat_tables(void) 55*91f16700Schasinglulu { 56*91f16700Schasinglulu unsigned long long max_pa; 57*91f16700Schasinglulu uintptr_t max_va; 58*91f16700Schasinglulu 59*91f16700Schasinglulu assert(PLAT_VIRT_ADDR_SPACE_SIZE >= MIN_VIRT_ADDR_SPACE_SIZE); 60*91f16700Schasinglulu assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE); 61*91f16700Schasinglulu assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE)); 62*91f16700Schasinglulu 63*91f16700Schasinglulu print_mmap(); 64*91f16700Schasinglulu init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE, 65*91f16700Schasinglulu &max_va, &max_pa); 66*91f16700Schasinglulu 67*91f16700Schasinglulu assert(max_va <= (PLAT_VIRT_ADDR_SPACE_SIZE - 1U)); 68*91f16700Schasinglulu assert(max_pa <= (PLAT_PHY_ADDR_SPACE_SIZE - 1U)); 69*91f16700Schasinglulu assert((PLAT_PHY_ADDR_SPACE_SIZE - 1U) <= get_max_supported_pa()); 70*91f16700Schasinglulu } 71*91f16700Schasinglulu 72*91f16700Schasinglulu void enable_mmu_svc_mon(unsigned int flags) 73*91f16700Schasinglulu { 74*91f16700Schasinglulu unsigned int mair0, ttbcr, sctlr; 75*91f16700Schasinglulu uint64_t ttbr0; 76*91f16700Schasinglulu 77*91f16700Schasinglulu assert(IS_IN_SECURE()); 78*91f16700Schasinglulu assert((read_sctlr() & SCTLR_M_BIT) == 0U); 79*91f16700Schasinglulu 80*91f16700Schasinglulu /* Set attributes in the right indices of the MAIR */ 81*91f16700Schasinglulu mair0 = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); 82*91f16700Schasinglulu mair0 |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, 83*91f16700Schasinglulu ATTR_IWBWA_OWBWA_NTR_INDEX); 84*91f16700Schasinglulu mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE, 85*91f16700Schasinglulu ATTR_NON_CACHEABLE_INDEX); 86*91f16700Schasinglulu write_mair0(mair0); 87*91f16700Schasinglulu 88*91f16700Schasinglulu /* Invalidate TLBs at the current exception level */ 89*91f16700Schasinglulu tlbiall(); 90*91f16700Schasinglulu 91*91f16700Schasinglulu /* 92*91f16700Schasinglulu * Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1. 93*91f16700Schasinglulu */ 94*91f16700Schasinglulu int t0sz = 32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE); 95*91f16700Schasinglulu 96*91f16700Schasinglulu if ((flags & XLAT_TABLE_NC) != 0U) { 97*91f16700Schasinglulu /* Inner & outer non-cacheable non-shareable. */ 98*91f16700Schasinglulu ttbcr = TTBCR_EAE_BIT | 99*91f16700Schasinglulu TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC | 100*91f16700Schasinglulu TTBCR_RGN0_INNER_NC | (uint32_t) t0sz; 101*91f16700Schasinglulu } else { 102*91f16700Schasinglulu /* Inner & outer WBWA & shareable. */ 103*91f16700Schasinglulu ttbcr = TTBCR_EAE_BIT | 104*91f16700Schasinglulu TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA | 105*91f16700Schasinglulu TTBCR_RGN0_INNER_WBA | (uint32_t) t0sz; 106*91f16700Schasinglulu } 107*91f16700Schasinglulu ttbcr |= TTBCR_EPD1_BIT; 108*91f16700Schasinglulu write_ttbcr(ttbcr); 109*91f16700Schasinglulu 110*91f16700Schasinglulu /* Set TTBR0 bits as well */ 111*91f16700Schasinglulu ttbr0 = (uintptr_t) base_xlation_table; 112*91f16700Schasinglulu write64_ttbr0(ttbr0); 113*91f16700Schasinglulu write64_ttbr1(0U); 114*91f16700Schasinglulu 115*91f16700Schasinglulu /* 116*91f16700Schasinglulu * Ensure all translation table writes have drained 117*91f16700Schasinglulu * into memory, the TLB invalidation is complete, 118*91f16700Schasinglulu * and translation register writes are committed 119*91f16700Schasinglulu * before enabling the MMU 120*91f16700Schasinglulu */ 121*91f16700Schasinglulu dsbish(); 122*91f16700Schasinglulu isb(); 123*91f16700Schasinglulu 124*91f16700Schasinglulu sctlr = read_sctlr(); 125*91f16700Schasinglulu sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT; 126*91f16700Schasinglulu 127*91f16700Schasinglulu if ((flags & DISABLE_DCACHE) != 0U) 128*91f16700Schasinglulu sctlr &= ~SCTLR_C_BIT; 129*91f16700Schasinglulu else 130*91f16700Schasinglulu sctlr |= SCTLR_C_BIT; 131*91f16700Schasinglulu 132*91f16700Schasinglulu write_sctlr(sctlr); 133*91f16700Schasinglulu 134*91f16700Schasinglulu /* Ensure the MMU enable takes effect immediately */ 135*91f16700Schasinglulu isb(); 136*91f16700Schasinglulu } 137*91f16700Schasinglulu 138*91f16700Schasinglulu void enable_mmu_direct_svc_mon(unsigned int flags) 139*91f16700Schasinglulu { 140*91f16700Schasinglulu enable_mmu_svc_mon(flags); 141*91f16700Schasinglulu } 142