+/*
+ * Macro to prepare and set a EL2 MPU memory region.
+ * We will also create an according MPU memory region entry, which
+ * is a structure of pr_t, in table \prmap.
+ *
+ * sel: region selector
+ * base: reg storing base address
+ * limit: reg storing limit address
+ * prbar: store computed PRBAR_EL2 value
+ * prlar: store computed PRLAR_EL2 value
+ * maxcount: maximum number of EL2 regions supported
+ * attr_prbar: PRBAR_EL2-related memory attributes. If not
specified it will be
+ * REGION_DATA_PRBAR
+ * attr_prlar: PRLAR_EL2-related memory attributes. If not
specified it will be
+ * REGION_NORMAL_PRLAR
+ *
+ * Preserves \maxcount
+ * Clobbers \sel, \base, \limit, \prbar, \prlar
+ *
+ * Note that all parameters using registers should be distinct.
+ */
+.macro prepare_xen_region, sel, base, limit, prbar, prlar, maxcount,
attr_prbar=REGION_DATA_PRBAR, attr_prlar=REGION_NORMAL_PRLAR
+ /* Check if the region is empty */
+ cmp \base, \limit
+ beq 1f
+
+ /* Check if the number of regions exceeded the count specified
in MPUIR_EL2 */
+ cmp \sel, \maxcount
+ bge fail_insufficient_regions
+
+ /* Prepare value for PRBAR_EL2 reg and preserve it in \prbar.*/
+ and \base, \base, #MPU_REGION_MASK
+ mov \prbar, #\attr_prbar
+ orr \prbar, \prbar, \base
+
+ /* Limit address should be inclusive */
+ sub \limit, \limit, #1
+ and \limit, \limit, #MPU_REGION_MASK
+ mov \prlar, #\attr_prlar
+ orr \prlar, \prlar, \limit
+
+ msr PRSELR_EL2, \sel
+ isb
+ msr PRBAR_EL2, \prbar
+ msr PRLAR_EL2, \prlar
+ dsb sy
+ isb
+
+ add \sel, \sel, #1
+
+1:
+.endm
+
+/*
+ * Failure caused due to insufficient MPU regions.
+ */
+FUNC_LOCAL(fail_insufficient_regions)
+ PRINT("- Selected MPU region is above the implemented number in
MPUIR_EL2 -\r\n")
+1: wfe
+ b 1b
+END(fail_insufficient_regions)
+
+/*
+ * Maps the various sections of Xen (described in xen.lds.S) as
different MPU
+ * regions.
+ *
+ * Clobbers x0 - x5
+ *
+ */
+FUNC(enable_boot_cpu_mm)
+ /* Get the number of regions specified in MPUIR_EL2 */
+ mrs x5, MPUIR_EL2
+ and x5, x5, #NUM_MPU_REGIONS_MASK
+
+ /* x0: region sel */
+ mov x0, xzr
+ /* Xen text section. */
+ ldr x1, =_stext
+ ldr x2, =_etext
+ prepare_xen_region x0, x1, x2, x3, x4, x5,
attr_prbar=REGION_TEXT_PRBAR
+
+ /* Xen read-only data section. */
+ ldr x1, =_srodata
+ ldr x2, =_erodata
+ prepare_xen_region x0, x1, x2, x3, x4, x5,
attr_prbar=REGION_RO_PRBAR