@@ -1 +1,2 @@
obj-y += mm.o
+obj-y += setup.init.o
new file mode 100644
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xen/arch/arm/mpu/setup.c
+ *
+ * MPU system boot code for Armv8-R AArch64.
+ *
+ */
+
+#include <xen/bootfdt.h>
+#include <xen/init.h>
+#include <xen/libfdt/libfdt.h>
+#include <xen/mm.h>
+
+/* Needs to be kept in sync with the regions programmed in arm64/mpu/head.S */
+#define EARLY_FDT_MAP_REGION_NUMBER 6
+
+void * __init early_fdt_map(paddr_t fdt_paddr)
+{
+ /* Map at least a page containing the DTB address, exclusive range */
+ paddr_t base_paddr = round_pgdown(fdt_paddr);
+ paddr_t end_paddr = round_pgup(fdt_paddr + sizeof(struct fdt_header));
+ unsigned int flags = PAGE_HYPERVISOR_RO;
+ void *fdt_virt = (void *)fdt_paddr; /* virt == paddr for MPU */
+ pr_t fdt_region;
+
+ /*
+ * Check whether the physical FDT address is set and meets the minimum
+ * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be at
+ * least 8 bytes so that we always access the magic and size fields
+ * of the FDT header after mapping the first chunk, double check if
+ * that is indeed the case.
+ */
+ BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
+ if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN )
+ return NULL;
+
+ /* Map the device tree blob header */
+ fdt_region = pr_of_xenaddr(base_paddr, end_paddr, PAGE_AI_MASK(flags));
+ fdt_region.prbar.reg.ap = PAGE_AP_MASK(flags);
+ fdt_region.prbar.reg.xn = PAGE_XN_MASK(flags);
+
+ write_protection_region(&fdt_region, EARLY_FDT_MAP_REGION_NUMBER);
+ context_sync_mpu();
+
+ if ( fdt_magic(fdt_virt) != FDT_MAGIC )
+ return NULL;
+
+ end_paddr = round_pgup(fdt_paddr + fdt_totalsize(fdt_virt));
+
+ /*
+ * If the mapped range is not enough, map the rest of the DTB, pr_get_limit
+ * returns an inclusive address of the range, hence the increment.
+ */
+ if ( end_paddr > (pr_get_limit(&fdt_region) + 1) )
+ {
+ pr_set_limit(&fdt_region, end_paddr);
+
+ write_protection_region(&fdt_region, EARLY_FDT_MAP_REGION_NUMBER);
+ context_sync_mpu();
+ }
+
+ return fdt_virt;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
Implement early_fdt_map() function, that is responsible to map the device tree blob in the early stages of the boot process, since at this stage the MPU C data structure are not yet initialised, it is using low level APIs to write into the MPU registers at a fixed MPU region number. The MPU memory management is designed to work on pages of PAGE_SIZE in order to reuse helpers and macros already available on the Xen memory management system. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- xen/arch/arm/mpu/Makefile | 1 + xen/arch/arm/mpu/setup.c | 72 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 xen/arch/arm/mpu/setup.c