summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/mmu_64.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/mmu_64.h')
-rw-r--r--arch/arm/cpu/mmu_64.h44
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;