1b2bca61dSSoby Mathew /* 2*4c700c15SGovindraj Raja * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved. 3b2bca61dSSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5b2bca61dSSoby Mathew */ 6b2bca61dSSoby Mathew 709d40e0eSAntonio Nino Diaz #include <assert.h> 809d40e0eSAntonio Nino Diaz 909d40e0eSAntonio Nino Diaz #include <platform_def.h> 1009d40e0eSAntonio Nino Diaz 11b2bca61dSSoby Mathew #include <arch.h> 12b2bca61dSSoby Mathew #include <arch_helpers.h> 1309d40e0eSAntonio Nino Diaz #include <lib/utils.h> 1409d40e0eSAntonio Nino Diaz #include <lib/xlat_tables/xlat_tables_arch.h> 1509d40e0eSAntonio Nino Diaz #include <lib/xlat_tables/xlat_tables.h> 1609d40e0eSAntonio Nino Diaz 17b2bca61dSSoby Mathew #include "../xlat_tables_private.h" 18b2bca61dSSoby Mathew 19e7b9886cSAntonio Nino Diaz #if (ARM_ARCH_MAJOR == 7) && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING) 2051b992ecSEtienne Carriere #error ARMv7 target does not support LPAE MMU descriptors 2151b992ecSEtienne Carriere #endif 2251b992ecSEtienne Carriere 238933c34bSSandrine Bailleux #define XLAT_TABLE_LEVEL_BASE \ 248933c34bSSandrine Bailleux GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE) 25b2bca61dSSoby Mathew 260029624fSAntonio Nino Diaz #define NUM_BASE_LEVEL_ENTRIES \ 278933c34bSSandrine Bailleux GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE) 28e8719552SAntonio Nino Diaz 29e8719552SAntonio Nino Diaz static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES] 30e8719552SAntonio Nino Diaz __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); 31b2bca61dSSoby Mathew 32aa61368eSAntonio Nino Diaz #if ENABLE_ASSERTIONS 330029624fSAntonio Nino Diaz static unsigned long long get_max_supported_pa(void) 340029624fSAntonio Nino Diaz { 350029624fSAntonio Nino Diaz /* Physical address space size for long descriptor format. */ 360029624fSAntonio Nino Diaz return (1ULL << 40) - 1ULL; 370029624fSAntonio Nino Diaz } 38aa61368eSAntonio Nino Diaz #endif /* ENABLE_ASSERTIONS */ 390029624fSAntonio Nino Diaz 40e7b9886cSAntonio Nino Diaz unsigned int xlat_arch_current_el(void) 41a5640252SAntonio Nino Diaz { 42a5640252SAntonio Nino Diaz /* 43a5640252SAntonio Nino Diaz * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System, 44a5640252SAntonio Nino Diaz * SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. 45a5640252SAntonio Nino Diaz */ 46e7b9886cSAntonio Nino Diaz return 3U; 47a5640252SAntonio Nino Diaz } 48a5640252SAntonio Nino Diaz 49e7b9886cSAntonio Nino Diaz uint64_t xlat_arch_get_xn_desc(unsigned int el __unused) 50a5640252SAntonio Nino Diaz { 51a5640252SAntonio Nino Diaz return UPPER_ATTRS(XN); 52a5640252SAntonio Nino Diaz } 53a5640252SAntonio Nino Diaz 54b2bca61dSSoby Mathew void init_xlat_tables(void) 55b2bca61dSSoby Mathew { 56b2bca61dSSoby Mathew unsigned long long max_pa; 57b2bca61dSSoby Mathew uintptr_t max_va; 58cedfa04bSSathees Balya 59cedfa04bSSathees Balya assert(PLAT_VIRT_ADDR_SPACE_SIZE >= MIN_VIRT_ADDR_SPACE_SIZE); 60cedfa04bSSathees Balya assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE); 61cedfa04bSSathees Balya assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE)); 62cedfa04bSSathees Balya 63b2bca61dSSoby Mathew print_mmap(); 64e7b9886cSAntonio Nino Diaz init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE, 65e8719552SAntonio Nino Diaz &max_va, &max_pa); 660029624fSAntonio Nino Diaz 67e7b9886cSAntonio Nino Diaz assert(max_va <= (PLAT_VIRT_ADDR_SPACE_SIZE - 1U)); 68e7b9886cSAntonio Nino Diaz assert(max_pa <= (PLAT_PHY_ADDR_SPACE_SIZE - 1U)); 69e7b9886cSAntonio Nino Diaz assert((PLAT_PHY_ADDR_SPACE_SIZE - 1U) <= get_max_supported_pa()); 70b2bca61dSSoby Mathew } 71b2bca61dSSoby Mathew 721a92a0e0SAntonio Nino Diaz void enable_mmu_svc_mon(unsigned int flags) 731a92a0e0SAntonio Nino Diaz { 74b2bca61dSSoby Mathew unsigned int mair0, ttbcr, sctlr; 75b2bca61dSSoby Mathew uint64_t ttbr0; 76b2bca61dSSoby Mathew 77b2bca61dSSoby Mathew assert(IS_IN_SECURE()); 78e7b9886cSAntonio Nino Diaz assert((read_sctlr() & SCTLR_M_BIT) == 0U); 79b2bca61dSSoby Mathew 80b2bca61dSSoby Mathew /* Set attributes in the right indices of the MAIR */ 81b2bca61dSSoby Mathew mair0 = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); 82b2bca61dSSoby Mathew mair0 |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, 83b2bca61dSSoby Mathew ATTR_IWBWA_OWBWA_NTR_INDEX); 84b2bca61dSSoby Mathew mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE, 85b2bca61dSSoby Mathew ATTR_NON_CACHEABLE_INDEX); 86b2bca61dSSoby Mathew write_mair0(mair0); 87b2bca61dSSoby Mathew 88b2bca61dSSoby Mathew /* Invalidate TLBs at the current exception level */ 89b2bca61dSSoby Mathew tlbiall(); 90b2bca61dSSoby Mathew 91b2bca61dSSoby Mathew /* 925d21b037SSummer Qin * Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1. 93b2bca61dSSoby Mathew */ 94e7b9886cSAntonio Nino Diaz int t0sz = 32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE); 95e7b9886cSAntonio Nino Diaz 96e7b9886cSAntonio Nino Diaz if ((flags & XLAT_TABLE_NC) != 0U) { 975d21b037SSummer Qin /* Inner & outer non-cacheable non-shareable. */ 985d21b037SSummer Qin ttbcr = TTBCR_EAE_BIT | 995d21b037SSummer Qin TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC | 100e7b9886cSAntonio Nino Diaz TTBCR_RGN0_INNER_NC | (uint32_t) t0sz; 1015d21b037SSummer Qin } else { 1025d21b037SSummer Qin /* Inner & outer WBWA & shareable. */ 103b2bca61dSSoby Mathew ttbcr = TTBCR_EAE_BIT | 104b2bca61dSSoby Mathew TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA | 105e7b9886cSAntonio Nino Diaz TTBCR_RGN0_INNER_WBA | (uint32_t) t0sz; 1065d21b037SSummer Qin } 107b2bca61dSSoby Mathew ttbcr |= TTBCR_EPD1_BIT; 108b2bca61dSSoby Mathew write_ttbcr(ttbcr); 109b2bca61dSSoby Mathew 110b2bca61dSSoby Mathew /* Set TTBR0 bits as well */ 111e8719552SAntonio Nino Diaz ttbr0 = (uintptr_t) base_xlation_table; 112b2bca61dSSoby Mathew write64_ttbr0(ttbr0); 113e7b9886cSAntonio Nino Diaz write64_ttbr1(0U); 114b2bca61dSSoby Mathew 115b2bca61dSSoby Mathew /* 116b2bca61dSSoby Mathew * Ensure all translation table writes have drained 117b2bca61dSSoby Mathew * into memory, the TLB invalidation is complete, 118b2bca61dSSoby Mathew * and translation register writes are committed 119b2bca61dSSoby Mathew * before enabling the MMU 120b2bca61dSSoby Mathew */ 1216f512a3dSDimitris Papastamos dsbish(); 122b2bca61dSSoby Mathew isb(); 123b2bca61dSSoby Mathew 124b2bca61dSSoby Mathew sctlr = read_sctlr(); 125b2bca61dSSoby Mathew sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT; 126b2bca61dSSoby Mathew 127e7b9886cSAntonio Nino Diaz if ((flags & DISABLE_DCACHE) != 0U) 128b2bca61dSSoby Mathew sctlr &= ~SCTLR_C_BIT; 129b2bca61dSSoby Mathew else 130b2bca61dSSoby Mathew sctlr |= SCTLR_C_BIT; 131b2bca61dSSoby Mathew 132b2bca61dSSoby Mathew write_sctlr(sctlr); 133b2bca61dSSoby Mathew 134b2bca61dSSoby Mathew /* Ensure the MMU enable takes effect immediately */ 135b2bca61dSSoby Mathew isb(); 136b2bca61dSSoby Mathew } 13792bec97fSJeenu Viswambharan 1381a92a0e0SAntonio Nino Diaz void enable_mmu_direct_svc_mon(unsigned int flags) 13992bec97fSJeenu Viswambharan { 1401a92a0e0SAntonio Nino Diaz enable_mmu_svc_mon(flags); 14192bec97fSJeenu Viswambharan } 142