diff options
Diffstat (limited to 'arch/arm/cpu/mmu_64.h')
-rw-r--r-- | arch/arm/cpu/mmu_64.h | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/arch/arm/cpu/mmu_64.h b/arch/arm/cpu/mmu_64.h index e2e125686d..e3959e4407 100644 --- a/arch/arm/cpu/mmu_64.h +++ b/arch/arm/cpu/mmu_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "mmu-common.h" @@ -8,6 +9,23 @@ PTE_BLOCK_OUTER_SHARE | \ PTE_BLOCK_AF) +static inline unsigned long attrs_uncached_mem(void) +{ + unsigned long attrs = UNCACHED_MEM; + + switch (current_el()) { + case 3: + case 2: + attrs |= PTE_BLOCK_UXN; + break; + default: + attrs |= PTE_BLOCK_UXN | PTE_BLOCK_PXN; + break; + } + + return attrs; +} + /* * Do it the simple way for now and invalidate the entire tlb */ @@ -75,7 +93,9 @@ static inline uint64_t level2mask(int level) { uint64_t mask = -EINVAL; - if (level == 1) + if (level == 0) + mask = L0_ADDR_MASK; + else if (level == 1) mask = L1_ADDR_MASK; else if (level == 2) mask = L2_ADDR_MASK; @@ -85,13 +105,27 @@ static inline uint64_t level2mask(int level) return mask; } -static inline uint64_t calc_tcr(int el) +/** + * @brief Returns the TCR (Translation Control Register) value + * + * @param el - Exception Level + * @param va_bits - Virtual Address bits + * @return uint64_t TCR + */ +static inline uint64_t calc_tcr(int el, int va_bits) { - u64 ips, va_bits; - u64 tcr; + u64 ips; // Intermediate Physical Address Size + u64 tcr; // Translation Control Register +#if (BITS_PER_PA == 40) ips = 2; - va_bits = BITS_PER_VA; +#elif (BITS_PER_PA == 36) + ips = 1; +#elif (BITS_PER_PA == 32) + ips = 0; +#else +#error "Unsupported" +#endif if (el == 1) tcr = (ips << 32) | TCR_EPD1_DISABLE; |