armv8: Ensure EL1&0 VMSA is enabled
authorPeter Hoyes <Peter.Hoyes@arm.com>
Thu, 19 Aug 2021 15:53:10 +0000 (16:53 +0100)
committerTom Rini <trini@konsulko.com>
Thu, 2 Sep 2021 14:17:45 +0000 (10:17 -0400)
On Armv8-R, the EL1&0 memory system architecture is configurable as a
VMSA or PMSA, and resets to an "architecturally unknown" value.

Add code to armv8_switch_to_el1_m which detects whether the MSA at
EL1&0 is configurable using the id_aa64mmfr0_el1 register MSA fields.
If it is we must ensure the VMSA is enabled so that a rich OS can boot.

The MSA and MSA_FRAC fields are described in the Armv8-R architecture
profile supplement (section G1.3.7):
https://developer.arm.com/documentation/ddi0600/latest/

Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
arch/arm/include/asm/macro.h
arch/arm/include/asm/system.h

index e1eefc2..ecd8221 100644 (file)
@@ -316,6 +316,23 @@ lr .req    x30
        csel    \tmp, \tmp2, \tmp, eq
        msr     hcr_el2, \tmp
 
+       /*
+        * Detect whether the system has a configurable memory system
+        * architecture at EL1&0
+        */
+       mrs     \tmp, id_aa64mmfr0_el1
+       lsr     \tmp, \tmp, #48
+       and     \tmp, \tmp, #((ID_AA64MMFR0_EL1_MSA_MASK | \
+                       ID_AA64MMFR0_EL1_MSA_FRAC_MASK) >> 48)
+       cmp     \tmp, #((ID_AA64MMFR0_EL1_MSA_USE_FRAC | \
+                       ID_AA64MMFR0_EL1_MSA_FRAC_VMSA) >> 48)
+       bne     2f
+
+       /* Ensure the EL1&0 VMSA is enabled */
+       mov     \tmp, #(VTCR_EL2_MSA)
+       msr     vtcr_el2, \tmp
+2:
+
        /* Return to the EL1_SP1 mode from EL2 */
        ldr     \tmp, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
                        SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
index 77aa189..e4c11e8 100644 (file)
 #define HCR_EL2_HCD_DIS                (1 << 29) /* Hypervisor Call disabled         */
 
 /*
+ * VTCR_EL2 bits definitions
+ */
+#define VTCR_EL2_MSA           (1 << 31) /* EL1&0 memory architecture        */
+
+/*
+ * ID_AA64MMFR0_EL1 bits definitions
+ */
+#define ID_AA64MMFR0_EL1_MSA_FRAC_MASK         (0xFUL << 52) /* Memory system
+                                                                architecture
+                                                                frac         */
+#define ID_AA64MMFR0_EL1_MSA_FRAC_VMSA         (0x2UL << 52) /* EL1&0 supports
+                                                                VMSA         */
+#define ID_AA64MMFR0_EL1_MSA_FRAC_PMSA         (0x1UL << 52) /* EL1&0 only
+                                                                supports PMSA*/
+#define ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA      (0x0UL << 52) /* No PMSA
+                                                                support      */
+#define ID_AA64MMFR0_EL1_MSA_MASK              (0xFUL << 48) /* Memory system
+                                                                architecture */
+#define ID_AA64MMFR0_EL1_MSA_USE_FRAC          (0xFUL << 48) /* Use MSA_FRAC */
+#define ID_AA64MMFR0_EL1_MSA_VMSA              (0x0UL << 48) /* Memory system
+                                                                architecture
+                                                                is VMSA      */
+
+/*
  * ID_AA64ISAR1_EL1 bits definitions
  */
 #define ID_AA64ISAR1_EL1_GPI   (0xF << 28) /* Implementation-defined generic