Hello,
I am trying to understand the source code of XEN on ARM to get a deeper understanding of how XEN works and I am facing some difficulties in understanding a section of the assembly code present in xen/arch/arm/arm32/head.S.
The snippet of the code is:
/* 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. */
/* Write Xen's PT's paddr into the HTTBR */
ldr r4, =boot_pgtable
add r4, r4, r10 /* r4 := paddr (boot_pagetable) */
mov r5, #0 /* r4:r5 is paddr (boot_pagetable) */
mcrr CP64(r4, r5, HTTBR)
/* Setup boot_pgtable: */
ldr r1, =boot_second
add r1, r1, r10 /* r1 := paddr (boot_second) */
mov r3, #0x0
/* ... map boot_second in boot_pgtable[0] */
orr r2, r1, #PT_UPPER(PT) /* r2:r3 := table map of boot_second */
orr r2, r2, #PT_LOWER(PT) /* (+ rights for linear PT) */
strd r2, r3, [r4, #0] /* Map it in slot 0 */
/* ... map of paddr(start) in boot_pgtable */
lsrs r1, r9, #30 /* Offset of base paddr in boot_pgtable */
beq 1f /* If it is in slot 0 then map in boot_second
* later on */
lsl r2, r1, #30 /* Base address for 1GB mapping */
orr r2, r2, #PT_UPPER(MEM) /* r2:r3 := section map */
orr r2, r2, #PT_LOWER(MEM)
lsl r1, r1, #3 /* r1 := Slot offset */
strd r2, r3, [r4, r1] /* Mapping of paddr(start) */
1: /* Setup boot_second: */
ldr r4, =boot_second
add r4, r4, r10 /* r1 := paddr (boot_second) */
lsr r2, r9, #20 /* Base address for 2MB mapping */
lsl r2, r2, #20
orr r2, r2, #PT_UPPER(MEM) /* r2:r3 := section map */
orr r2, r2, #PT_LOWER(MEM)
/* ... map of vaddr(start) in boot_second */
ldr r1, =start
lsr r1, #18 /* Slot for vaddr(start) */
strd r2, r3, [r4, r1] /* Map vaddr(start) */
/* ... map of paddr(start) in boot_second */
lsrs r1, r9, #30 /* Base paddr */
bne 1f /* If paddr(start) is not in slot 0
* then the mapping was done in
* boot_pgtable above */
mov r1, r9, lsr #18 /* Slot for paddr(start) */
strd r2, r3, [r4, r1] /* Map Xen there */
1:
/* Defer fixmap and dtb mapping until after paging enabled, to
* avoid them clashing with the 1:1 mapping. */
/* boot pagetable setup complete */
PRINT("- Turning on paging -\r\n")
ldr r1, =paging /* Explicit vaddr, not RIP-relative */
mrc CP32(r0, HSCTLR)
orr r0, r0, #(SCTLR_M|SCTLR_C) /* Enable MMU and D-cache */
dsb /* Flush PTE writes and finish reads */
mcr CP32(r0, HSCTLR) /* now paging is enabled */
isb /* Now, flush the icache */
mov pc, r1 /* Get a proper vaddr into PC */
paging:
/* Now we can install the fixmap and dtb mappings, since we
* don't need the 1:1 map any more */
dsb
#if defined(EARLY_PRINTK) /* Fixmap is only used by early printk */
/* Non-boot CPUs don't need to rebuild the fixmap itself, just
* the mapping from boot_second to xen_fixmap */
teq r12, #0
bne 1f
/* Add UART to the fixmap table */
ldr r1, =xen_fixmap /* r1 := vaddr (xen_fixmap) */
mov r3, #0
lsr r2, r11, #12
lsl r2, r2, #12 /* 4K aligned paddr of UART */
orr r2, r2, #PT_UPPER(DEV_L3)
orr r2, r2, #PT_LOWER(DEV_L3) /* r2:r3 := 4K dev map including UART */
strd r2, r3, [r1, #(FIXMAP_CONSOLE*8)] /* Map it in the first fixmap's slot */
1:
/* Map fixmap into boot_second */
ldr r1, =boot_second /* r1 := vaddr (xen_fixmap) */
ldr r2, =xen_fixmap
add r2, r2, r10 /* r2 := paddr (xen_fixmap) */
orr r2, r2, #PT_UPPER(PT)
orr r2, r2, #PT_LOWER(PT) /* r2:r3 := table map of xen_fixmap */
ldr r4, =FIXMAP_ADDR(0)
mov r4, r4, lsr #18 /* r4 := Slot for FIXMAP(0) */
strd r2, r3, [r1, r4] /* Map it in the fixmap's slot */
/* Use a virtual address to access the UART. */
ldr r11, =EARLY_UART_VIRTUAL_ADDRESS
#endif
/* Map the DTB in the boot misc slot */
teq r12, #0 /* Only on boot CPU */
bne 1f
ldr r1, =boot_second
mov r3, #0x0
lsr r2, r8, #21
lsl r2, r2, #21 /* r2: 2MB-aligned paddr of DTB */
orr r2, r2, #PT_UPPER(MEM)
orr r2, r2, #PT_LOWER(MEM) /* r2:r3 := 2MB RAM incl. DTB */
ldr r4, =BOOT_FDT_VIRT_START
mov r4, r4, lsr #18 /* Slot for BOOT_FDT_VIRT_START */
strd r2, r3, [r1, r4] /* Map it in the early fdt slot */
dsb
1:
It will be great help if anyone can throw some light on the function of the above piece of code.
Thanks & Regards
Shubham Khandelwal
I am trying to understand the source code of XEN on ARM to get a deeper understanding of how XEN works and I am facing some difficulties in understanding a section of the assembly code present in xen/arch/arm/arm32/head.S.
The snippet of the code is:
/* 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. */
/* Write Xen's PT's paddr into the HTTBR */
ldr r4, =boot_pgtable
add r4, r4, r10 /* r4 := paddr (boot_pagetable) */
mov r5, #0 /* r4:r5 is paddr (boot_pagetable) */
mcrr CP64(r4, r5, HTTBR)
/* Setup boot_pgtable: */
ldr r1, =boot_second
add r1, r1, r10 /* r1 := paddr (boot_second) */
mov r3, #0x0
/* ... map boot_second in boot_pgtable[0] */
orr r2, r1, #PT_UPPER(PT) /* r2:r3 := table map of boot_second */
orr r2, r2, #PT_LOWER(PT) /* (+ rights for linear PT) */
strd r2, r3, [r4, #0] /* Map it in slot 0 */
/* ... map of paddr(start) in boot_pgtable */
lsrs r1, r9, #30 /* Offset of base paddr in boot_pgtable */
beq 1f /* If it is in slot 0 then map in boot_second
* later on */
lsl r2, r1, #30 /* Base address for 1GB mapping */
orr r2, r2, #PT_UPPER(MEM) /* r2:r3 := section map */
orr r2, r2, #PT_LOWER(MEM)
lsl r1, r1, #3 /* r1 := Slot offset */
strd r2, r3, [r4, r1] /* Mapping of paddr(start) */
1: /* Setup boot_second: */
ldr r4, =boot_second
add r4, r4, r10 /* r1 := paddr (boot_second) */
lsr r2, r9, #20 /* Base address for 2MB mapping */
lsl r2, r2, #20
orr r2, r2, #PT_UPPER(MEM) /* r2:r3 := section map */
orr r2, r2, #PT_LOWER(MEM)
/* ... map of vaddr(start) in boot_second */
ldr r1, =start
lsr r1, #18 /* Slot for vaddr(start) */
strd r2, r3, [r4, r1] /* Map vaddr(start) */
/* ... map of paddr(start) in boot_second */
lsrs r1, r9, #30 /* Base paddr */
bne 1f /* If paddr(start) is not in slot 0
* then the mapping was done in
* boot_pgtable above */
mov r1, r9, lsr #18 /* Slot for paddr(start) */
strd r2, r3, [r4, r1] /* Map Xen there */
1:
/* Defer fixmap and dtb mapping until after paging enabled, to
* avoid them clashing with the 1:1 mapping. */
/* boot pagetable setup complete */
PRINT("- Turning on paging -\r\n")
ldr r1, =paging /* Explicit vaddr, not RIP-relative */
mrc CP32(r0, HSCTLR)
orr r0, r0, #(SCTLR_M|SCTLR_C) /* Enable MMU and D-cache */
dsb /* Flush PTE writes and finish reads */
mcr CP32(r0, HSCTLR) /* now paging is enabled */
isb /* Now, flush the icache */
mov pc, r1 /* Get a proper vaddr into PC */
paging:
/* Now we can install the fixmap and dtb mappings, since we
* don't need the 1:1 map any more */
dsb
#if defined(EARLY_PRINTK) /* Fixmap is only used by early printk */
/* Non-boot CPUs don't need to rebuild the fixmap itself, just
* the mapping from boot_second to xen_fixmap */
teq r12, #0
bne 1f
/* Add UART to the fixmap table */
ldr r1, =xen_fixmap /* r1 := vaddr (xen_fixmap) */
mov r3, #0
lsr r2, r11, #12
lsl r2, r2, #12 /* 4K aligned paddr of UART */
orr r2, r2, #PT_UPPER(DEV_L3)
orr r2, r2, #PT_LOWER(DEV_L3) /* r2:r3 := 4K dev map including UART */
strd r2, r3, [r1, #(FIXMAP_CONSOLE*8)] /* Map it in the first fixmap's slot */
1:
/* Map fixmap into boot_second */
ldr r1, =boot_second /* r1 := vaddr (xen_fixmap) */
ldr r2, =xen_fixmap
add r2, r2, r10 /* r2 := paddr (xen_fixmap) */
orr r2, r2, #PT_UPPER(PT)
orr r2, r2, #PT_LOWER(PT) /* r2:r3 := table map of xen_fixmap */
ldr r4, =FIXMAP_ADDR(0)
mov r4, r4, lsr #18 /* r4 := Slot for FIXMAP(0) */
strd r2, r3, [r1, r4] /* Map it in the fixmap's slot */
/* Use a virtual address to access the UART. */
ldr r11, =EARLY_UART_VIRTUAL_ADDRESS
#endif
/* Map the DTB in the boot misc slot */
teq r12, #0 /* Only on boot CPU */
bne 1f
ldr r1, =boot_second
mov r3, #0x0
lsr r2, r8, #21
lsl r2, r2, #21 /* r2: 2MB-aligned paddr of DTB */
orr r2, r2, #PT_UPPER(MEM)
orr r2, r2, #PT_LOWER(MEM) /* r2:r3 := 2MB RAM incl. DTB */
ldr r4, =BOOT_FDT_VIRT_START
mov r4, r4, lsr #18 /* Slot for BOOT_FDT_VIRT_START */
strd r2, r3, [r1, r4] /* Map it in the early fdt slot */
dsb
1:
It will be great help if anyone can throw some light on the function of the above piece of code.
Thanks & Regards
Shubham Khandelwal