Separate mm initialization from enablement for VMs.
Change-Id: I891911bcd9087f584aed086f37b1aadf40673ce5
diff --git a/src/arch/aarch64/hftest/mm.c b/src/arch/aarch64/hftest/mm.c
index 6673d90..86f27d8 100644
--- a/src/arch/aarch64/hftest/mm.c
+++ b/src/arch/aarch64/hftest/mm.c
@@ -17,6 +17,7 @@
#include "hf/mm.h"
#include "hf/arch/barriers.h"
+#include "hf/arch/vm/mm.h"
#include "hf/dlog.h"
@@ -25,14 +26,17 @@
#define STAGE1_DEVICEINDX UINT64_C(0)
#define STAGE1_NORMALINDX UINT64_C(1)
+static uintreg_t mm_mair_el1;
+static uintreg_t mm_tcr_el1;
+static uintreg_t mm_sctlr_el1;
+
/**
* Initialize MMU for a test running in EL1.
*/
-bool arch_vm_mm_init(paddr_t table)
+bool arch_vm_mm_init(void)
{
static const int pa_bits_table[16] = {32, 36, 40, 42, 44, 48};
uint64_t features = read_msr(id_aa64mmfr0_el1);
- uint64_t v;
int pa_bits = pa_bits_table[features & 0xf];
/* Check that 4KB granules are supported. */
@@ -53,39 +57,45 @@
* 0xff -> Normal memory, Inner/Outer Write-Back Non-transient,
* Write-Alloc, Read-Alloc.
*/
- v = (0 << (8 * STAGE1_DEVICEINDX)) | (0xff << (8 * STAGE1_NORMALINDX));
- write_msr(mair_el1, v);
+ mm_mair_el1 = (0 << (8 * STAGE1_DEVICEINDX)) |
+ (0xff << (8 * STAGE1_NORMALINDX));
- write_msr(ttbr0_el1, pa_addr(table));
+ mm_tcr_el1 = (1 << 20) | /* TBI, top byte ignored. */
+ ((features & 0xf) << 16) | /* PS. */
+ (0 << 14) | /* TG0, granule size, 4KB. */
+ (3 << 12) | /* SH0, inner shareable. */
+ (1 << 10) | /* ORGN0, normal mem, WB RA WA Cacheable. */
+ (1 << 8) | /* IRGN0, normal mem, WB RA WA Cacheable. */
+ (25 << 0) | /* T0SZ, input address is 2^39 bytes. */
+ 0;
- v = (1 << 20) | /* TBI, top byte ignored. */
- ((features & 0xf) << 16) | /* PS. */
- (0 << 14) | /* TG0, granule size, 4KB. */
- (3 << 12) | /* SH0, inner shareable. */
- (1 << 10) | /* ORGN0, normal mem, WB RA WA Cacheable. */
- (1 << 8) | /* IRGN0, normal mem, WB RA WA Cacheable. */
- (25 << 0) | /* T0SZ, input address is 2^39 bytes. */
- 0;
- write_msr(tcr_el1, v);
-
- v = (1 << 0) | /* M, enable stage 1 EL2 MMU. */
- (1 << 1) | /* A, enable alignment check faults. */
- (1 << 2) | /* C, data cache enable. */
- (1 << 3) | /* SA, enable stack alignment check. */
- (3 << 4) | /* RES1 bits. */
- (1 << 11) | /* RES1 bit. */
- (1 << 12) | /* I, instruction cache enable. */
- (1 << 16) | /* RES1 bit. */
- (1 << 18) | /* RES1 bit. */
- (0 << 19) | /* WXN bit, writable execute never. */
- (3 << 22) | /* RES1 bits. */
- (3 << 28) | /* RES1 bits. */
- 0;
-
- dsb(sy);
- isb();
- write_msr(sctlr_el1, v);
- isb();
+ mm_sctlr_el1 = (1 << 0) | /* M, enable stage 1 EL2 MMU. */
+ (1 << 1) | /* A, enable alignment check faults. */
+ (1 << 2) | /* C, data cache enable. */
+ (1 << 3) | /* SA, enable stack alignment check. */
+ (3 << 4) | /* RES1 bits. */
+ (1 << 11) | /* RES1 bit. */
+ (1 << 12) | /* I, instruction cache enable. */
+ (1 << 16) | /* RES1 bit. */
+ (1 << 18) | /* RES1 bit. */
+ (0 << 19) | /* WXN bit, writable execute never. */
+ (3 << 22) | /* RES1 bits. */
+ (3 << 28) | /* RES1 bits. */
+ 0;
return true;
}
+
+void arch_vm_mm_enable(paddr_t table)
+{
+ /* Configure translation management registers. */
+ write_msr(ttbr0_el1, pa_addr(table));
+ write_msr(mair_el1, mm_mair_el1);
+ write_msr(tcr_el1, mm_tcr_el1);
+
+ /* Configure sctlr_el1 to enable MMU and cache. */
+ dsb(sy);
+ isb();
+ write_msr(sctlr_el1, mm_sctlr_el1);
+ isb();
+}
diff --git a/src/arch/aarch64/inc/hf/arch/vm/mm.h b/src/arch/aarch64/inc/hf/arch/vm/mm.h
index 8bbb70e..d212fa5 100644
--- a/src/arch/aarch64/inc/hf/arch/vm/mm.h
+++ b/src/arch/aarch64/inc/hf/arch/vm/mm.h
@@ -18,4 +18,5 @@
#include "hf/mm.h"
-bool arch_vm_mm_init(paddr_t table);
+bool arch_vm_mm_init(void);
+void arch_vm_mm_enable(paddr_t table);
diff --git a/test/hftest/hftest_mm.c b/test/hftest/hftest_mm.c
index 36b977b..c4f908d 100644
--- a/test/hftest/hftest_mm.c
+++ b/test/hftest/hftest_mm.c
@@ -51,7 +51,13 @@
pa_init(mm_ptable_addr_space_end(MM_FLAG_STAGE1)),
MM_MODE_R | MM_MODE_W | MM_MODE_X, &ppool);
- return arch_vm_mm_init(ptable.root);
+ if (!arch_vm_mm_init()) {
+ return false;
+ }
+
+ arch_vm_mm_enable(ptable.root);
+
+ return true;
}
void hftest_mm_identity_map(const void *base, size_t size, int mode)
@@ -78,7 +84,7 @@
struct cpu_start_state local = *s;
sl_unlock(&s->lock);
- ASSERT_TRUE(arch_vm_mm_init(ptable.root));
+ arch_vm_mm_enable(ptable.root);
local.entry(local.arg);
}