|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 14/18] xen/arm: Convert setting MMU page tables code into a routine
From: Saeed Nowshadi <saeed.nowshadi@xxxxxxxxxx>
The code that sets up MMU page tables during the boot is also
needed when the system resumes. Convert that code in head.S
into a routine so the resume code can use it as well. This patch
does not include any functional change.
Signed-off-by: Saeed Nowshadi <saeed.nowshadi@xxxxxxxxxx>
Signed-off-by: Mirela Simonovic <mirela.simonovic@xxxxxxxxxx>
---
xen/arch/arm/arm64/head.S | 265 ++++++++++++++++++++++++----------------------
1 file changed, 138 insertions(+), 127 deletions(-)
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index ef87b5c254..f95390dcfe 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -379,134 +379,10 @@ skip_bss:
* than SP_EL0. */
msr spsel, #1
- /* Rebuild the boot pagetable's first-level entries. The structure
- * is described in mm.c.
- *
- * After the CPU enables paging it will add the fixmap mapping
- * to these page tables, however this may clash with the 1:1
- * mapping. So each CPU must rebuild the page tables here with
- * the 1:1 in place. */
+ /* If setting up page_tables are not successful, fail to boot */
+ bl setup_page_tables
+ cbz x25, fail
- /* If Xen is loaded at exactly XEN_VIRT_START then we don't
- * need an additional 1:1 mapping, the virtual mapping will
- * suffice.
- */
- cmp x19, #XEN_VIRT_START
- cset x25, eq /* x25 := identity map in place, or not */
-
- /* Write Xen's PT's paddr into TTBR0_EL2 */
- load_paddr x4, boot_pgtable
- msr TTBR0_EL2, x4
-
- /* Setup boot_pgtable: */
- load_paddr x1, boot_first
-
- /* ... map boot_first in boot_pgtable[0] */
- mov x3, #PT_PT /* x2 := table map of boot_first */
- orr x2, x1, x3 /* + rights for linear PT */
- str x2, [x4, #0] /* Map it in slot 0 */
-
- /* ... map of paddr(start) in boot_pgtable+boot_first_id */
- lsr x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */
- cbz x1, 1f /* It's in slot 0, map in boot_first
- * or boot_second later on */
-
- /* Level zero does not support superpage mappings, so we have
- * to use an extra first level page in which we create a 1GB mapping.
- */
- load_paddr x2, boot_first_id
-
- mov x3, #PT_PT /* x2 := table map of boot_first_id */
- orr x2, x2, x3 /* + rights for linear PT */
- lsl x1, x1, #3 /* x1 := Slot offset */
- str x2, [x4, x1]
-
- load_paddr x4, boot_first_id
-
- lsr x1, x19, #FIRST_SHIFT /* x1 := Offset of base paddr in
boot_first_id */
- lsl x2, x1, #FIRST_SHIFT /* x2 := Base address for 1GB mapping */
- mov x3, #PT_MEM /* x2 := Section map */
- orr x2, x2, x3
- and x1, x1, #LPAE_ENTRY_MASK /* x1 := Slot offset */
- lsl x1, x1, #3
- str x2, [x4, x1] /* Mapping of paddr(start) */
- mov x25, #1 /* x25 := identity map now in place */
-
-1: /* Setup boot_first: */
- load_paddr x4, boot_first /* Next level into boot_first */
-
- /* ... map boot_second in boot_first[0] */
- load_paddr x1, boot_second
- mov x3, #PT_PT /* x2 := table map of boot_second */
- orr x2, x1, x3 /* + rights for linear PT */
- str x2, [x4, #0] /* Map it in slot 0 */
-
- /* ... map of paddr(start) in boot_first */
- cbnz x25, 1f /* x25 is set if already created */
- lsr x2, x19, #FIRST_SHIFT /* x2 := Offset of base paddr in
boot_first */
- and x1, x2, #LPAE_ENTRY_MASK /* x1 := Slot to use */
- cbz x1, 1f /* It's in slot 0, map in boot_second */
-
- lsl x2, x2, #FIRST_SHIFT /* Base address for 1GB mapping */
- mov x3, #PT_MEM /* x2 := Section map */
- orr x2, x2, x3
- lsl x1, x1, #3 /* x1 := Slot offset */
- str x2, [x4, x1] /* Create mapping of paddr(start)*/
- mov x25, #1 /* x25 := identity map now in place */
-
-1: /* Setup boot_second: */
- load_paddr x4, boot_second
-
- /* ... map boot_third in boot_second[1] */
- load_paddr x1, boot_third
- mov x3, #PT_PT /* x2 := table map of boot_third */
- orr x2, x1, x3 /* + rights for linear PT */
- str x2, [x4, #8] /* Map it in slot 1 */
-
- /* ... map of paddr(start) in boot_second */
- cbnz x25, 1f /* x25 is set if already created */
- lsr x2, x19, #SECOND_SHIFT /* x2 := Offset of base paddr in
boot_second */
- and x1, x2, #LPAE_ENTRY_MASK /* x1 := Slot to use */
- cmp x1, #1
- b.eq virtphys_clash /* It's in slot 1, which we cannot handle
*/
-
- lsl x2, x2, #SECOND_SHIFT /* Base address for 2MB mapping */
- mov x3, #PT_MEM /* x2 := Section map */
- orr x2, x2, x3
- lsl x1, x1, #3 /* x1 := Slot offset */
- str x2, [x4, x1] /* Create mapping of paddr(start)*/
- mov x25, #1 /* x25 := identity map now in place */
-
-1: /* Setup boot_third: */
- load_paddr x4, boot_third
-
- lsr x2, x19, #THIRD_SHIFT /* Base address for 4K mapping */
- lsl x2, x2, #THIRD_SHIFT
- mov x3, #PT_MEM_L3 /* x2 := Section map */
- orr x2, x2, x3
-
- /* ... map of vaddr(start) in boot_third */
- mov x1, xzr
-1: str x2, [x4, x1] /* Map vaddr(start) */
- add x2, x2, #PAGE_SIZE /* Next page */
- add x1, x1, #8 /* Next slot */
- cmp x1, #(LPAE_ENTRIES<<3) /* 512 entries per page */
- b.lt 1b
-
- /* Defer fixmap and dtb mapping until after paging enabled, to
- * avoid them clashing with the 1:1 mapping. */
-
- /* boot pagetable setup complete */
-
- cbnz x25, 1f /* Did we manage to create an identity
mapping ? */
- PRINT("Unable to build boot page tables - Failed to identity map
Xen.\r\n")
- b fail
-virtphys_clash:
- /* Identity map clashes with boot_third, which we cannot handle yet */
- PRINT("- Unable to build boot page tables - virt and phys addresses
clash. -\r\n")
- b fail
-
-1:
PRINT("- Turning on paging -\r\n")
/*
@@ -797,6 +673,141 @@ ENTRY(efi_xen_start)
b real_start_efi
ENDPROC(efi_xen_start)
+ENTRY(setup_page_tables)
+ ldr x0, =start
+ adr x19, start /* x19 := paddr (start) */
+ sub x20, x19, x0 /* x20 := phys-offset */
+
+ /* Rebuild the boot pagetable's first-level entries. The structure
+ * is described in mm.c.
+ *
+ * After the CPU enables paging it will add the fixmap mapping
+ * to these page tables, however this may clash with the 1:1
+ * mapping. So each CPU must rebuild the page tables here with
+ * the 1:1 in place. */
+
+ /* If Xen is loaded at exactly XEN_VIRT_START then we don't
+ * need an additional 1:1 mapping, the virtual mapping will
+ * suffice.
+ */
+ cmp x19, #XEN_VIRT_START
+ cset x25, eq /* x25 := identity map in place, or not */
+
+ /* Write Xen's PT's paddr into TTBR0_EL2 */
+ load_paddr x4, boot_pgtable
+ msr TTBR0_EL2, x4
+
+ /* Setup boot_pgtable: */
+ load_paddr x1, boot_first
+
+ /* ... map boot_first in boot_pgtable[0] */
+ mov x3, #PT_PT /* x2 := table map of boot_first */
+ orr x2, x1, x3 /* + rights for linear PT */
+ str x2, [x4, #0] /* Map it in slot 0 */
+
+ /* ... map of paddr(start) in boot_pgtable+boot_first_id */
+ lsr x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */
+ cbz x1, 1f /* It's in slot 0, map in boot_first
+ * or boot_second later on */
+
+ /* Level zero does not support superpage mappings, so we have
+ * to use an extra first level page in which we create a 1GB mapping.
+ */
+ load_paddr x2, boot_first_id
+
+ mov x3, #PT_PT /* x2 := table map of boot_first_id */
+ orr x2, x2, x3 /* + rights for linear PT */
+ lsl x1, x1, #3 /* x1 := Slot offset */
+ str x2, [x4, x1]
+
+ load_paddr x4, boot_first_id
+
+ lsr x1, x19, #FIRST_SHIFT /* x1 := Offset of base paddr in
boot_first_id */
+ lsl x2, x1, #FIRST_SHIFT /* x2 := Base address for 1GB mapping */
+ mov x3, #PT_MEM /* x2 := Section map */
+ orr x2, x2, x3
+ and x1, x1, #LPAE_ENTRY_MASK /* x1 := Slot offset */
+ lsl x1, x1, #3
+ str x2, [x4, x1] /* Mapping of paddr(start) */
+ mov x25, #1 /* x25 := identity map now in place */
+
+1: /* Setup boot_first: */
+ load_paddr x4, boot_first /* Next level into boot_first */
+
+ /* ... map boot_second in boot_first[0] */
+ load_paddr x1, boot_second
+ mov x3, #PT_PT /* x2 := table map of boot_second */
+ orr x2, x1, x3 /* + rights for linear PT */
+ str x2, [x4, #0] /* Map it in slot 0 */
+
+ /* ... map of paddr(start) in boot_first */
+ cbnz x25, 1f /* x25 is set if already created */
+ lsr x2, x19, #FIRST_SHIFT /* x2 := Offset of base paddr in
boot_first */
+ and x1, x2, #LPAE_ENTRY_MASK /* x1 := Slot to use */
+ cbz x1, 1f /* It's in slot 0, map in boot_second */
+
+ lsl x2, x2, #FIRST_SHIFT /* Base address for 1GB mapping */
+ mov x3, #PT_MEM /* x2 := Section map */
+ orr x2, x2, x3
+ lsl x1, x1, #3 /* x1 := Slot offset */
+ str x2, [x4, x1] /* Create mapping of paddr(start)*/
+ mov x25, #1 /* x25 := identity map now in place */
+
+1: /* Setup boot_second: */
+ load_paddr x4, boot_second
+
+ /* ... map boot_third in boot_second[1] */
+ load_paddr x1, boot_third
+ mov x3, #PT_PT /* x2 := table map of boot_third */
+ orr x2, x1, x3 /* + rights for linear PT */
+ str x2, [x4, #8] /* Map it in slot 1 */
+
+ /* ... map of paddr(start) in boot_second */
+ cbnz x25, 1f /* x25 is set if already created */
+ lsr x2, x19, #SECOND_SHIFT /* x2 := Offset of base paddr in
boot_second */
+ and x1, x2, #LPAE_ENTRY_MASK /* x1 := Slot to use */
+ cmp x1, #1
+ b.eq virtphys_clash /* It's in slot 1, which we cannot handle
*/
+
+ lsl x2, x2, #SECOND_SHIFT /* Base address for 2MB mapping */
+ mov x3, #PT_MEM /* x2 := Section map */
+ orr x2, x2, x3
+ lsl x1, x1, #3 /* x1 := Slot offset */
+ str x2, [x4, x1] /* Create mapping of paddr(start)*/
+ mov x25, #1 /* x25 := identity map now in place */
+
+1: /* Setup boot_third: */
+ load_paddr x4, boot_third
+
+ lsr x2, x19, #THIRD_SHIFT /* Base address for 4K mapping */
+ lsl x2, x2, #THIRD_SHIFT
+ mov x3, #PT_MEM_L3 /* x2 := Section map */
+ orr x2, x2, x3
+
+ /* ... map of vaddr(start) in boot_third */
+ mov x1, xzr
+1: str x2, [x4, x1] /* Map vaddr(start) */
+ add x2, x2, #PAGE_SIZE /* Next page */
+ add x1, x1, #8 /* Next slot */
+ cmp x1, #(LPAE_ENTRIES<<3) /* 512 entries per page */
+ b.lt 1b
+
+ /* Defer fixmap and dtb mapping until after paging enabled, to
+ * avoid them clashing with the 1:1 mapping. */
+
+ /* boot pagetable setup complete */
+
+ cbnz x25, 1f /* Did we manage to create an identity
mapping ? */
+ PRINT("Unable to build boot page tables - Failed to identity map
Xen.\r\n")
+ b 1f
+virtphys_clash:
+ /* Identity map clashes with boot_third, which we cannot handle yet */
+ PRINT("- Unable to build boot page tables - virt and phys addresses
clash. -\r\n")
+1:
+ ret
+
+ENDPROC(setup_page_tables)
+
/*
* Local variables:
* mode: ASM
--
2.13.0
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |