Add arch_vm_mm_reset()

When running tests on Android dev boards, it is necessary to be able
to break out of the reboot-test loop, boot into the Android Bootloader,
and flash a new system image. The bootloader expects the MMU to be
disabled, so record the initial values of the corresponding system
registers and provide a function to reset them before branching to the
bootloader.

Change-Id: Ic191223e4dc849118e24f2cd7e2ecc113f05b310
diff --git a/src/arch/aarch64/hftest/mm.c b/src/arch/aarch64/hftest/mm.c
index 86f27d8..60ca2f0 100644
--- a/src/arch/aarch64/hftest/mm.c
+++ b/src/arch/aarch64/hftest/mm.c
@@ -30,6 +30,11 @@
 static uintreg_t mm_tcr_el1;
 static uintreg_t mm_sctlr_el1;
 
+static uintreg_t mm_reset_ttbr0_el1;
+static uintreg_t mm_reset_mair_el1;
+static uintreg_t mm_reset_tcr_el1;
+static uintreg_t mm_reset_sctlr_el1;
+
 /**
  * Initialize MMU for a test running in EL1.
  */
@@ -53,6 +58,15 @@
 	}
 
 	/*
+	 * Preserve initial values of the system registers in case we want to
+	 * reset them.
+	 */
+	mm_reset_ttbr0_el1 = read_msr(ttbr0_el1);
+	mm_reset_mair_el1 = read_msr(mair_el1);
+	mm_reset_tcr_el1 = read_msr(tcr_el1);
+	mm_reset_sctlr_el1 = read_msr(sctlr_el1);
+
+	/*
 	 * 0    -> Device-nGnRnE memory
 	 * 0xff -> Normal memory, Inner/Outer Write-Back Non-transient,
 	 *         Write-Alloc, Read-Alloc.
@@ -99,3 +113,16 @@
 	write_msr(sctlr_el1, mm_sctlr_el1);
 	isb();
 }
+
+void arch_vm_mm_reset(void)
+{
+	/* Set system registers to their reset values. */
+	write_msr(ttbr0_el1, mm_reset_ttbr0_el1);
+	write_msr(mair_el1, mm_reset_mair_el1);
+	write_msr(tcr_el1, mm_reset_tcr_el1);
+
+	dsb(sy);
+	isb();
+	write_msr(sctlr_el1, mm_reset_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 d212fa5..993f801 100644
--- a/src/arch/aarch64/inc/hf/arch/vm/mm.h
+++ b/src/arch/aarch64/inc/hf/arch/vm/mm.h
@@ -20,3 +20,8 @@
 
 bool arch_vm_mm_init(void);
 void arch_vm_mm_enable(paddr_t table);
+
+/**
+ * Reset MMU-related system registers. Must be called after arch_vm_mm_init().
+ */
+void arch_vm_mm_reset(void);