aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/lib/xlat_tables/xlat_mmu_helpers.h18
-rw-r--r--include/lib/xlat_tables/xlat_tables_defs.h2
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2.h7
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2_helpers.h35
-rw-r--r--lib/xlat_tables/xlat_tables_common.c11
-rw-r--r--lib/xlat_tables_v2/aarch32/enable_mmu.S12
-rw-r--r--lib/xlat_tables_v2/aarch32/xlat_tables_arch.c53
-rw-r--r--lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h22
-rw-r--r--lib/xlat_tables_v2/aarch64/enable_mmu.S8
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch.c74
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h28
-rw-r--r--lib/xlat_tables_v2/xlat_tables.mk2
-rw-r--r--lib/xlat_tables_v2/xlat_tables_context.c33
-rw-r--r--lib/xlat_tables_v2/xlat_tables_core.c22
-rw-r--r--lib/xlat_tables_v2/xlat_tables_private.h20
-rw-r--r--lib/xlat_tables_v2/xlat_tables_utils.c3
-rw-r--r--services/std_svc/spm/sp_setup.c49
17 files changed, 159 insertions, 240 deletions
diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h
index b6c53e267..a290a92d8 100644
--- a/include/lib/xlat_tables/xlat_mmu_helpers.h
+++ b/include/lib/xlat_tables/xlat_mmu_helpers.h
@@ -41,10 +41,28 @@
*/
#define XLAT_TABLE_NC (U(1) << 1)
+/*
+ * Offsets into a mmu_cfg_params array generated by setup_mmu_cfg(). All
+ * parameters are 64 bits wide.
+ */
+#define MMU_CFG_MAIR 0
+#define MMU_CFG_TCR 1
+#define MMU_CFG_TTBR0 2
+#define MMU_CFG_PARAM_MAX 3
+
#ifndef __ASSEMBLY__
#include <sys/types.h>
+/*
+ * Return the values that the MMU configuration registers must contain for the
+ * specified translation context. `params` must be a pointer to array of size
+ * MMU_CFG_PARAM_MAX.
+ */
+void setup_mmu_cfg(uint64_t *params, unsigned int flags,
+ const uint64_t *base_table, unsigned long long max_pa,
+ uintptr_t max_va, int xlat_regime);
+
#ifdef AARCH32
/* AArch32 specific translation table API */
void enable_mmu_secure(unsigned int flags);
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 5eb1d309d..c9d54177d 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -62,7 +62,7 @@
/*
* The ARMv8-A architecture allows translation granule sizes of 4KB, 16KB or
- * 64KB. However, TF only supports the 4KB case at the moment.
+ * 64KB. However, only 4KB are supported at the moment.
*/
#define PAGE_SIZE_SHIFT FOUR_KB_SHIFT
#define PAGE_SIZE (U(1) << PAGE_SIZE_SHIFT)
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 20a9ea1de..2e5aba527 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -121,10 +121,12 @@ typedef struct mmap_region {
} mmap_region_t;
/*
- * Translation regimes supported by this library.
+ * Translation regimes supported by this library. EL_REGIME_INVALID tells the
+ * library to detect it at runtime.
*/
#define EL1_EL0_REGIME 1
#define EL3_REGIME 3
+#define EL_REGIME_INVALID -1
/*
* Declare the translation context type.
@@ -165,8 +167,7 @@ typedef struct xlat_ctx xlat_ctx_t;
(_xlat_tables_count), \
(_virt_addr_space_size), \
(_phy_addr_space_size), \
- IMAGE_XLAT_DEFAULT_REGIME, \
- "xlat_table")
+ EL_REGIME_INVALID, "xlat_table")
/*
* Same as REGISTER_XLAT_CONTEXT plus the additional parameters:
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index 56b9a93f4..82d96e7d7 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -16,13 +16,6 @@
#error "Do not include this header file directly. Include xlat_tables_v2.h instead."
#endif
-/* Offsets into mmu_cfg_params array. All parameters are 32 bits wide. */
-#define MMU_CFG_MAIR0 0
-#define MMU_CFG_TCR 1
-#define MMU_CFG_TTBR0_LO 2
-#define MMU_CFG_TTBR0_HI 3
-#define MMU_CFG_PARAM_MAX 4
-
#ifndef __ASSEMBLY__
#include <cassert.h>
@@ -31,9 +24,6 @@
#include <xlat_tables_arch.h>
#include <xlat_tables_defs.h>
-/* Parameters of register values required when enabling MMU */
-extern uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
/* Forward declaration */
struct mmap_region;
@@ -172,29 +162,4 @@ struct xlat_ctx {
#endif /*__ASSEMBLY__*/
-#if AARCH64
-
-/*
- * This IMAGE_EL macro must not to be used outside the library, and it is only
- * used in AArch64.
- */
-#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
-# define IMAGE_EL 3
-# define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME
-#else
-# define IMAGE_EL 1
-# define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
-#endif
-
-#else /* if AARCH32 */
-
-/*
- * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime in
- * AArch64 except for the XN bits, but we set and unset them at the same time,
- * so there's no difference in practice.
- */
-#define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
-
-#endif /* AARCH64 */
-
#endif /* __XLAT_TABLES_V2_HELPERS_H__ */
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index b42cd6814..ce6e341a2 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -195,6 +195,10 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
desc |= (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC : BLOCK_DESC;
desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0;
desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
+ /*
+ * Always set the access flag, as this library assumes access flag
+ * faults aren't managed.
+ */
desc |= LOWER_ATTRS(ACCESS_FLAG);
desc |= ap1_mask;
@@ -222,9 +226,10 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
} else { /* Normal memory */
/*
* Always map read-write normal memory as execute-never.
- * (Trusted Firmware doesn't self-modify its code, therefore
- * R/W memory is reserved for data storage, which must not be
- * executable.)
+ * This library assumes that it is used by software that does
+ * not self-modify its code, therefore R/W memory is reserved
+ * for data storage, which must not be executable.
+ *
* Note that setting the XN bit here is for consistency only.
* The function that enables the MMU sets the SCTLR_ELx.WXN bit,
* which makes any writable memory region to be treated as
diff --git a/lib/xlat_tables_v2/aarch32/enable_mmu.S b/lib/xlat_tables_v2/aarch32/enable_mmu.S
index 97cdde751..99cf0881e 100644
--- a/lib/xlat_tables_v2/aarch32/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch32/enable_mmu.S
@@ -24,17 +24,17 @@ func enable_mmu_direct
mov r3, r0
ldr r0, =mmu_cfg_params
- /* MAIR0 */
- ldr r1, [r0, #(MMU_CFG_MAIR0 << 2)]
+ /* MAIR0. Only the lower 32 bits are used. */
+ ldr r1, [r0, #(MMU_CFG_MAIR << 3)]
stcopr r1, MAIR0
- /* TTBCR */
- ldr r2, [r0, #(MMU_CFG_TCR << 2)]
+ /* TTBCR. Only the lower 32 bits are used. */
+ ldr r2, [r0, #(MMU_CFG_TCR << 3)]
stcopr r2, TTBCR
/* TTBR0 */
- ldr r1, [r0, #(MMU_CFG_TTBR0_LO << 2)]
- ldr r2, [r0, #(MMU_CFG_TTBR0_HI << 2)]
+ ldr r1, [r0, #(MMU_CFG_TTBR0 << 3)]
+ ldr r2, [r0, #((MMU_CFG_TTBR0 << 3) + 4)]
stcopr16 r1, r2, TTBR0_64
/* TTBR1 is unused right now; set it to 0. */
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 6e9719258..5e3220c60 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -18,16 +18,14 @@
#error ARMv7 target does not support LPAE MMU descriptors
#endif
-uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
/*
* Returns 1 if the provided granule size is supported, 0 otherwise.
*/
int xlat_arch_is_granule_size_supported(size_t size)
{
/*
- * The Trusted Firmware uses long descriptor translation table format,
- * which supports 4 KiB pages only.
+ * The library uses the long descriptor translation table format, which
+ * supports 4 KiB pages only.
*/
return (size == (4U * 1024U));
}
@@ -50,18 +48,12 @@ int is_mmu_enabled_ctx(const xlat_ctx_t *ctx __unused)
return (read_sctlr() & SCTLR_M_BIT) != 0;
}
-void xlat_arch_tlbi_va(uintptr_t va)
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime __unused)
{
- /*
- * Ensure the translation table write has drained into memory before
- * invalidating the TLB entry.
- */
- dsbishst();
-
- tlbimvaais(TLBI_ADDR(va));
+ return UPPER_ATTRS(XN);
}
-void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime __unused)
+void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime __unused)
{
/*
* Ensure the translation table write has drained into memory before
@@ -103,29 +95,32 @@ int xlat_arch_current_el(void)
/*
* If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System,
* SVC, Abort, UND, IRQ and FIQ modes) execute at EL3.
+ *
+ * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime
+ * in AArch64 except for the XN bits, but we set and unset them at the
+ * same time, so there's no difference in practice.
*/
- return 3;
+ return 1;
}
/*******************************************************************************
* Function for enabling the MMU in Secure PL1, assuming that the page tables
* have already been created.
******************************************************************************/
-void setup_mmu_cfg(unsigned int flags,
- const uint64_t *base_table,
- unsigned long long max_pa,
- uintptr_t max_va)
+void setup_mmu_cfg(uint64_t *params, unsigned int flags,
+ const uint64_t *base_table, unsigned long long max_pa,
+ uintptr_t max_va, __unused int xlat_regime)
{
- u_register_t mair0, ttbcr;
- uint64_t ttbr0;
+ uint64_t mair, ttbr0;
+ uint32_t ttbcr;
assert(IS_IN_SECURE());
/* Set attributes in the right indices of the MAIR */
- mair0 = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
- mair0 |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
+ mair = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+ mair |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
ATTR_IWBWA_OWBWA_NTR_INDEX);
- mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
+ mair |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
ATTR_NON_CACHEABLE_INDEX);
/*
@@ -173,17 +168,17 @@ void setup_mmu_cfg(unsigned int flags,
/* Set TTBR0 bits as well */
ttbr0 = (uint64_t)(uintptr_t) base_table;
+
#if ARM_ARCH_AT_LEAST(8, 2)
/*
- * Enable CnP bit so as to share page tables with all PEs.
- * Mandatory for ARMv8.2 implementations.
+ * Enable CnP bit so as to share page tables with all PEs. This
+ * is mandatory for ARMv8.2 implementations.
*/
ttbr0 |= TTBR_CNP_BIT;
#endif
/* Now populate MMU configuration */
- mmu_cfg_params[MMU_CFG_MAIR0] = mair0;
- mmu_cfg_params[MMU_CFG_TCR] = ttbcr;
- mmu_cfg_params[MMU_CFG_TTBR0_LO] = (uint32_t) ttbr0;
- mmu_cfg_params[MMU_CFG_TTBR0_HI] = ttbr0 >> 32;
+ params[MMU_CFG_MAIR] = mair;
+ params[MMU_CFG_TCR] = (uint64_t) ttbcr;
+ params[MMU_CFG_TTBR0] = ttbr0;
}
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h b/lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h
deleted file mode 100644
index 9b41f4df2..000000000
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __XLAT_TABLES_ARCH_PRIVATE_H__
-#define __XLAT_TABLES_ARCH_PRIVATE_H__
-
-#include <xlat_tables_defs.h>
-#include <xlat_tables_v2.h>
-
-/*
- * Return the execute-never mask that will prevent instruction fetch at the
- * given translation regime.
- */
-static inline uint64_t xlat_arch_regime_get_xn_desc(int regime __unused)
-{
- return UPPER_ATTRS(XN);
-}
-
-#endif /* __XLAT_TABLES_ARCH_PRIVATE_H__ */
diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S
index a72c7fae5..5c5a2a927 100644
--- a/lib/xlat_tables_v2/aarch64/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S
@@ -43,17 +43,15 @@
ldr x0, =mmu_cfg_params
/* MAIR */
- ldr w1, [x0, #(MMU_CFG_MAIR0 << 2)]
+ ldr x1, [x0, #(MMU_CFG_MAIR << 3)]
_msr mair, \el, x1
/* TCR */
- ldr w2, [x0, #(MMU_CFG_TCR << 2)]
+ ldr x2, [x0, #(MMU_CFG_TCR << 3)]
_msr tcr, \el, x2
/* TTBR */
- ldr w3, [x0, #(MMU_CFG_TTBR0_LO << 2)]
- ldr w4, [x0, #(MMU_CFG_TTBR0_HI << 2)]
- orr x3, x3, x4, lsl #32
+ ldr x3, [x0, #(MMU_CFG_TTBR0 << 3)]
_msr ttbr0, \el, x3
/*
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 4bbbe5443..0f289e28e 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -13,8 +13,6 @@
#include <xlat_tables_v2.h>
#include "../xlat_tables_private.h"
-uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
/*
* Returns 1 if the provided granule size is supported, 0 otherwise.
*/
@@ -113,19 +111,17 @@ int is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
}
}
-
-void xlat_arch_tlbi_va(uintptr_t va)
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime)
{
-#if IMAGE_EL == 1
- assert(IS_IN_EL(1));
- xlat_arch_tlbi_va_regime(va, EL1_EL0_REGIME);
-#elif IMAGE_EL == 3
- assert(IS_IN_EL(3));
- xlat_arch_tlbi_va_regime(va, EL3_REGIME);
-#endif
+ if (xlat_regime == EL1_EL0_REGIME) {
+ return UPPER_ATTRS(UXN) | UPPER_ATTRS(PXN);
+ } else {
+ assert(xlat_regime == EL3_REGIME);
+ return UPPER_ATTRS(XN);
+ }
}
-void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime)
+void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime)
{
/*
* Ensure the translation table write has drained into memory before
@@ -182,12 +178,11 @@ int xlat_arch_current_el(void)
return el;
}
-void setup_mmu_cfg(unsigned int flags,
- const uint64_t *base_table,
- unsigned long long max_pa,
- uintptr_t max_va)
+void setup_mmu_cfg(uint64_t *params, unsigned int flags,
+ const uint64_t *base_table, unsigned long long max_pa,
+ uintptr_t max_va, int xlat_regime)
{
- uint64_t mair, ttbr, tcr;
+ uint64_t mair, ttbr0, tcr;
uintptr_t virtual_addr_space_size;
/* Set attributes in the right indices of the MAIR. */
@@ -195,8 +190,6 @@ void setup_mmu_cfg(unsigned int flags,
mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX);
mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);
- ttbr = (uint64_t) base_table;
-
/*
* Limit the input address ranges and memory region sizes translated
* using TTBR0 to the given virtual address space size.
@@ -232,30 +225,29 @@ void setup_mmu_cfg(unsigned int flags,
*/
unsigned long long tcr_ps_bits = tcr_physical_addr_size_bits(max_pa);
-#if IMAGE_EL == 1
- assert(IS_IN_EL(1));
- /*
- * TCR_EL1.EPD1: Disable translation table walk for addresses that are
- * translated using TTBR1_EL1.
- */
- tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT);
-#elif IMAGE_EL == 3
- assert(IS_IN_EL(3));
- tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
-#endif
-
- mmu_cfg_params[MMU_CFG_MAIR0] = (uint32_t) mair;
- mmu_cfg_params[MMU_CFG_TCR] = (uint32_t) tcr;
-
- /* Set TTBR bits as well */
- if (ARM_ARCH_AT_LEAST(8, 2)) {
+ if (xlat_regime == EL1_EL0_REGIME) {
/*
- * Enable CnP bit so as to share page tables with all PEs. This
- * is mandatory for ARMv8.2 implementations.
+ * TCR_EL1.EPD1: Disable translation table walk for addresses
+ * that are translated using TTBR1_EL1.
*/
- ttbr |= TTBR_CNP_BIT;
+ tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT);
+ } else {
+ assert(xlat_regime == EL3_REGIME);
+ tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
}
- mmu_cfg_params[MMU_CFG_TTBR0_LO] = (uint32_t) ttbr;
- mmu_cfg_params[MMU_CFG_TTBR0_HI] = (uint32_t) (ttbr >> 32);
+ /* Set TTBR bits as well */
+ ttbr0 = (uint64_t) base_table;
+
+#if ARM_ARCH_AT_LEAST(8, 2)
+ /*
+ * Enable CnP bit so as to share page tables with all PEs. This
+ * is mandatory for ARMv8.2 implementations.
+ */
+ ttbr0 |= TTBR_CNP_BIT;
+#endif
+
+ params[MMU_CFG_MAIR] = mair;
+ params[MMU_CFG_TCR] = tcr;
+ params[MMU_CFG_TTBR0] = ttbr0;
}
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h b/lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h
deleted file mode 100644
index 39b0a653a..000000000
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __XLAT_TABLES_ARCH_PRIVATE_H__
-#define __XLAT_TABLES_ARCH_PRIVATE_H__
-
-#include <assert.h>
-#include <xlat_tables_defs.h>
-#include <xlat_tables_v2.h>
-
-/*
- * Return the execute-never mask that will prevent instruction fetch at all ELs
- * that are part of the given translation regime.
- */
-static inline uint64_t xlat_arch_regime_get_xn_desc(int regime)
-{
- if (regime == EL1_EL0_REGIME) {
- return UPPER_ATTRS(UXN) | UPPER_ATTRS(PXN);
- } else {
- assert(regime == EL3_REGIME);
- return UPPER_ATTRS(XN);
- }
-}
-
-#endif /* __XLAT_TABLES_ARCH_PRIVATE_H__ */
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index b25c805cf..9507ad715 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -10,5 +10,3 @@ XLAT_TABLES_LIB_SRCS := $(addprefix lib/xlat_tables_v2/, \
xlat_tables_context.c \
xlat_tables_core.c \
xlat_tables_utils.c)
-
-INCLUDES += -Ilib/xlat_tables_v2/${ARCH}
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index 0964b49b2..76c429d75 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <debug.h>
#include <platform_def.h>
#include <xlat_tables_defs.h>
@@ -12,6 +13,12 @@
#include "xlat_tables_private.h"
/*
+ * MMU configuration register values for the active translation context. Used
+ * from the MMU assembly helpers.
+ */
+uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+/*
* Each platform can define the size of its physical and virtual address spaces.
* If the platform hasn't defined one or both of them, default to
* ADDR_SPACE_SIZE. The latter is deprecated, though.
@@ -69,6 +76,17 @@ int mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
void init_xlat_tables(void)
{
+ assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID);
+
+ int current_el = xlat_arch_current_el();
+
+ if (current_el == 1) {
+ tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME;
+ } else {
+ assert(current_el == 3);
+ tf_xlat_ctx.xlat_regime = EL3_REGIME;
+ }
+
init_xlat_tables_ctx(&tf_xlat_ctx);
}
@@ -93,8 +111,9 @@ void init_xlat_tables(void)
void enable_mmu_secure(unsigned int flags)
{
- setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
- tf_xlat_ctx.va_max_address);
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL1_EL0_REGIME);
enable_mmu_direct(flags);
}
@@ -102,15 +121,17 @@ void enable_mmu_secure(unsigned int flags)
void enable_mmu_el1(unsigned int flags)
{
- setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
- tf_xlat_ctx.va_max_address);
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL1_EL0_REGIME);
enable_mmu_direct_el1(flags);
}
void enable_mmu_el3(unsigned int flags)
{
- setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
- tf_xlat_ctx.va_max_address);
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL3_REGIME);
enable_mmu_direct_el3(flags);
}
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index f555524a9..e3306e6df 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -12,7 +12,6 @@
#include <string.h>
#include <types.h>
#include <utils_def.h>
-#include <xlat_tables_arch_private.h>
#include <xlat_tables_defs.h>
#include <xlat_tables_v2.h>
@@ -104,12 +103,14 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
*/
desc |= (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC : BLOCK_DESC;
/*
- * Always set the access flag, as TF doesn't manage access flag faults.
+ * Always set the access flag, as this library assumes access flag
+ * faults aren't managed.
+ */
+ desc |= LOWER_ATTRS(ACCESS_FLAG);
+ /*
* Deduce other fields of the descriptor based on the MT_NS and MT_RW
* memory region attributes.
*/
- desc |= LOWER_ATTRS(ACCESS_FLAG);
-
desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0;
desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
@@ -155,9 +156,10 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
} else { /* Normal memory */
/*
* Always map read-write normal memory as execute-never.
- * (Trusted Firmware doesn't self-modify its code, therefore
- * R/W memory is reserved for data storage, which must not be
- * executable.)
+ * This library assumes that it is used by software that does
+ * not self-modify its code, therefore R/W memory is reserved
+ * for data storage, which must not be executable.
+ *
* Note that setting the XN bit here is for consistency only.
* The function that enables the MMU sets the SCTLR_ELx.WXN bit,
* which makes any writable memory region to be treated as
@@ -311,7 +313,7 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
if (action == ACTION_WRITE_BLOCK_ENTRY) {
table_base[table_idx] = INVALID_DESC;
- xlat_arch_tlbi_va_regime(table_idx_va, ctx->xlat_regime);
+ xlat_arch_tlbi_va(table_idx_va, ctx->xlat_regime);
} else if (action == ACTION_RECURSE_INTO_TABLE) {
@@ -327,8 +329,8 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
*/
if (xlat_table_is_empty(ctx, subtable)) {
table_base[table_idx] = INVALID_DESC;
- xlat_arch_tlbi_va_regime(table_idx_va,
- ctx->xlat_regime);
+ xlat_arch_tlbi_va(table_idx_va,
+ ctx->xlat_regime);
}
} else {
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 4a54ec5d0..93640ddbc 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -36,21 +36,23 @@
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
/*
+ * Return the execute-never mask that will prevent instruction fetch at the
+ * given translation regime.
+ */
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime);
+
+/*
* Invalidate all TLB entries that match the given virtual address. This
* operation applies to all PEs in the same Inner Shareable domain as the PE
* that executes this function. This functions must be called for every
- * translation table entry that is modified.
- *
- * xlat_arch_tlbi_va() applies the invalidation to the exception level of the
- * current translation regime, whereas xlat_arch_tlbi_va_regime() applies it to
- * the given translation regime.
+ * translation table entry that is modified. It only affects the specified
+ * translation regime.
*
* Note, however, that it is architecturally UNDEFINED to invalidate TLB entries
* pertaining to a higher exception level, e.g. invalidating EL3 entries from
* S-EL1.
*/
-void xlat_arch_tlbi_va(uintptr_t va);
-void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime);
+void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime);
/*
* This function has to be called at the end of any code that uses the function
@@ -86,10 +88,6 @@ int xlat_arch_current_el(void);
*/
unsigned long long xlat_arch_get_max_supported_pa(void);
-/* Enable MMU and configure it to use the specified translation tables. */
-void setup_mmu_cfg(unsigned int flags, const uint64_t *base_table,
- unsigned long long max_pa, uintptr_t max_va);
-
/*
* Return 1 if the MMU of the translation regime managed by the given xlat_ctx_t
* is enabled, 0 otherwise.
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index 5a78434ab..90a0a8626 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -11,7 +11,6 @@
#include <platform_def.h>
#include <types.h>
#include <utils_def.h>
-#include <xlat_tables_arch_private.h>
#include <xlat_tables_defs.h>
#include <xlat_tables_v2.h>
@@ -544,7 +543,7 @@ int change_mem_attributes(xlat_ctx_t *ctx,
*entry = INVALID_DESC;
/* Invalidate any cached copy of this mapping in the TLBs. */
- xlat_arch_tlbi_va_regime(base_va, ctx->xlat_regime);
+ xlat_arch_tlbi_va(base_va, ctx->xlat_regime);
/* Ensure completion of the invalidation. */
xlat_arch_tlbi_va_sync();
diff --git a/services/std_svc/spm/sp_setup.c b/services/std_svc/spm/sp_setup.c
index b9b67f722..0d61306fa 100644
--- a/services/std_svc/spm/sp_setup.c
+++ b/services/std_svc/spm/sp_setup.c
@@ -107,38 +107,22 @@ void spm_sp_setup(sp_context_t *sp_ctx)
* MMU-related registers
* ---------------------
*/
+ xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle;
- /* Set attributes in the right indices of the MAIR */
- u_register_t mair_el1 =
- MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX) |
- MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX) |
- MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);
-
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1, mair_el1);
-
- /* Setup TCR_EL1. */
- u_register_t tcr_ps_bits = tcr_physical_addr_size_bits(PLAT_PHY_ADDR_SPACE_SIZE);
-
- u_register_t tcr_el1 =
- /* Size of region addressed by TTBR0_EL1 = 2^(64-T0SZ) bytes. */
- (64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE)) |
- /* Inner and outer WBWA, shareable. */
- TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA |
- /* Set the granularity to 4KB. */
- TCR_TG0_4K |
- /* Limit Intermediate Physical Address Size. */
- tcr_ps_bits << TCR_EL1_IPS_SHIFT |
- /* Disable translations using TBBR1_EL1. */
- TCR_EPD1_BIT
- /* The remaining fields related to TBBR1_EL1 are left as zero. */
- ;
+ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
- tcr_el1 &= ~(
- /* Enable translations using TBBR0_EL1 */
- TCR_EPD0_BIT
- );
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table,
+ xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
+ EL1_EL0_REGIME);
+
+ write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1,
+ mmu_cfg_params[MMU_CFG_MAIR]);
+
+ write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
+ mmu_cfg_params[MMU_CFG_TCR]);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1, tcr_el1);
+ write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+ mmu_cfg_params[MMU_CFG_TTBR0]);
/* Setup SCTLR_EL1 */
u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
@@ -174,13 +158,6 @@ void spm_sp_setup(sp_context_t *sp_ctx)
write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
- uint64_t *xlat_base =
- ((xlat_ctx_t *)sp_ctx->xlat_ctx_handle)->base_table;
-
- /* Point TTBR0_EL1 at the tables of the context created for the SP. */
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
- (u_register_t)xlat_base);
-
/*
* Setup other system registers
* ----------------------------