1b2bca61dSSoby Mathew /* 2aa61368eSAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3b2bca61dSSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5b2bca61dSSoby Mathew */ 6b2bca61dSSoby Mathew 7b2bca61dSSoby Mathew #include <arch.h> 8b2bca61dSSoby Mathew #include <arch_helpers.h> 9b2bca61dSSoby Mathew #include <assert.h> 10b2bca61dSSoby Mathew #include <platform_def.h> 11b2bca61dSSoby Mathew #include <utils.h> 128933c34bSSandrine Bailleux #include <xlat_tables_arch.h> 13b2bca61dSSoby Mathew #include <xlat_tables.h> 14b2bca61dSSoby Mathew #include "../xlat_tables_private.h" 15b2bca61dSSoby Mathew 16*51b992ecSEtienne Carriere #if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING) 17*51b992ecSEtienne Carriere #error ARMv7 target does not support LPAE MMU descriptors 18*51b992ecSEtienne Carriere #endif 19*51b992ecSEtienne Carriere 208933c34bSSandrine Bailleux #define XLAT_TABLE_LEVEL_BASE \ 218933c34bSSandrine Bailleux GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE) 22b2bca61dSSoby Mathew 230029624fSAntonio Nino Diaz #define NUM_BASE_LEVEL_ENTRIES \ 248933c34bSSandrine Bailleux GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE) 25e8719552SAntonio Nino Diaz 26e8719552SAntonio Nino Diaz static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES] 27e8719552SAntonio Nino Diaz __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); 28b2bca61dSSoby Mathew 29aa61368eSAntonio Nino Diaz #if ENABLE_ASSERTIONS 300029624fSAntonio Nino Diaz static unsigned long long get_max_supported_pa(void) 310029624fSAntonio Nino Diaz { 320029624fSAntonio Nino Diaz /* Physical address space size for long descriptor format. */ 330029624fSAntonio Nino Diaz return (1ULL << 40) - 1ULL; 340029624fSAntonio Nino Diaz } 35aa61368eSAntonio Nino Diaz #endif /* ENABLE_ASSERTIONS */ 360029624fSAntonio Nino Diaz 37a5640252SAntonio Nino Diaz int xlat_arch_current_el(void) 38a5640252SAntonio Nino Diaz { 39a5640252SAntonio Nino Diaz /* 40a5640252SAntonio Nino Diaz * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System, 41a5640252SAntonio Nino Diaz * SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. 42a5640252SAntonio Nino Diaz */ 43a5640252SAntonio Nino Diaz return 3; 44a5640252SAntonio Nino Diaz } 45a5640252SAntonio Nino Diaz 46a5640252SAntonio Nino Diaz uint64_t xlat_arch_get_xn_desc(int el __unused) 47a5640252SAntonio Nino Diaz { 48a5640252SAntonio Nino Diaz return UPPER_ATTRS(XN); 49a5640252SAntonio Nino Diaz } 50a5640252SAntonio Nino Diaz 51b2bca61dSSoby Mathew void init_xlat_tables(void) 52b2bca61dSSoby Mathew { 53b2bca61dSSoby Mathew unsigned long long max_pa; 54b2bca61dSSoby Mathew uintptr_t max_va; 55b2bca61dSSoby Mathew print_mmap(); 56e8719552SAntonio Nino Diaz init_xlation_table(0, base_xlation_table, XLAT_TABLE_LEVEL_BASE, 57e8719552SAntonio Nino Diaz &max_va, &max_pa); 580029624fSAntonio Nino Diaz 590029624fSAntonio Nino Diaz assert(max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1); 600029624fSAntonio Nino Diaz assert(max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1); 610029624fSAntonio Nino Diaz assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= get_max_supported_pa()); 62b2bca61dSSoby Mathew } 63b2bca61dSSoby Mathew 64b2bca61dSSoby Mathew /******************************************************************************* 65b2bca61dSSoby Mathew * Function for enabling the MMU in Secure PL1, assuming that the 66b2bca61dSSoby Mathew * page-tables have already been created. 67b2bca61dSSoby Mathew ******************************************************************************/ 68b2bca61dSSoby Mathew void enable_mmu_secure(unsigned int flags) 69b2bca61dSSoby Mathew { 70b2bca61dSSoby Mathew unsigned int mair0, ttbcr, sctlr; 71b2bca61dSSoby Mathew uint64_t ttbr0; 72b2bca61dSSoby Mathew 73b2bca61dSSoby Mathew assert(IS_IN_SECURE()); 74b2bca61dSSoby Mathew assert((read_sctlr() & SCTLR_M_BIT) == 0); 75b2bca61dSSoby Mathew 76b2bca61dSSoby Mathew /* Set attributes in the right indices of the MAIR */ 77b2bca61dSSoby Mathew mair0 = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); 78b2bca61dSSoby Mathew mair0 |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, 79b2bca61dSSoby Mathew ATTR_IWBWA_OWBWA_NTR_INDEX); 80b2bca61dSSoby Mathew mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE, 81b2bca61dSSoby Mathew ATTR_NON_CACHEABLE_INDEX); 82b2bca61dSSoby Mathew write_mair0(mair0); 83b2bca61dSSoby Mathew 84b2bca61dSSoby Mathew /* Invalidate TLBs at the current exception level */ 85b2bca61dSSoby Mathew tlbiall(); 86b2bca61dSSoby Mathew 87b2bca61dSSoby Mathew /* 885d21b037SSummer Qin * Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1. 89b2bca61dSSoby Mathew */ 905d21b037SSummer Qin if (flags & XLAT_TABLE_NC) { 915d21b037SSummer Qin /* Inner & outer non-cacheable non-shareable. */ 925d21b037SSummer Qin ttbcr = TTBCR_EAE_BIT | 935d21b037SSummer Qin TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC | 945d21b037SSummer Qin TTBCR_RGN0_INNER_NC | 950044231dSSandrine Bailleux (32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE)); 965d21b037SSummer Qin } else { 975d21b037SSummer Qin /* Inner & outer WBWA & shareable. */ 98b2bca61dSSoby Mathew ttbcr = TTBCR_EAE_BIT | 99b2bca61dSSoby Mathew TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA | 100b2bca61dSSoby Mathew TTBCR_RGN0_INNER_WBA | 1010044231dSSandrine Bailleux (32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE)); 1025d21b037SSummer Qin } 103b2bca61dSSoby Mathew ttbcr |= TTBCR_EPD1_BIT; 104b2bca61dSSoby Mathew write_ttbcr(ttbcr); 105b2bca61dSSoby Mathew 106b2bca61dSSoby Mathew /* Set TTBR0 bits as well */ 107e8719552SAntonio Nino Diaz ttbr0 = (uintptr_t) base_xlation_table; 108b2bca61dSSoby Mathew write64_ttbr0(ttbr0); 109b2bca61dSSoby Mathew write64_ttbr1(0); 110b2bca61dSSoby Mathew 111b2bca61dSSoby Mathew /* 112b2bca61dSSoby Mathew * Ensure all translation table writes have drained 113b2bca61dSSoby Mathew * into memory, the TLB invalidation is complete, 114b2bca61dSSoby Mathew * and translation register writes are committed 115b2bca61dSSoby Mathew * before enabling the MMU 116b2bca61dSSoby Mathew */ 1176f512a3dSDimitris Papastamos dsbish(); 118b2bca61dSSoby Mathew isb(); 119b2bca61dSSoby Mathew 120b2bca61dSSoby Mathew sctlr = read_sctlr(); 121b2bca61dSSoby Mathew sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT; 122b2bca61dSSoby Mathew 123b2bca61dSSoby Mathew if (flags & DISABLE_DCACHE) 124b2bca61dSSoby Mathew sctlr &= ~SCTLR_C_BIT; 125b2bca61dSSoby Mathew else 126b2bca61dSSoby Mathew sctlr |= SCTLR_C_BIT; 127b2bca61dSSoby Mathew 128b2bca61dSSoby Mathew write_sctlr(sctlr); 129b2bca61dSSoby Mathew 130b2bca61dSSoby Mathew /* Ensure the MMU enable takes effect immediately */ 131b2bca61dSSoby Mathew isb(); 132b2bca61dSSoby Mathew } 133