diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S index 34ab14a9e228..99d7d4aa63d1 100644 --- a/xen/arch/arm/arm32/head.S +++ b/xen/arch/arm/arm32/head.S @@ -98,10 +98,6 @@ past_zImage: b enable_boot_cpu_mm primary_switched: -#ifdef CONFIG_EARLY_PRINTK - /* Use a virtual address to access the UART. */ - mov_w r11, EARLY_UART_VIRTUAL_ADDRESS -#endif bl zero_bss PRINT("- Ready -\r\n") /* Setup the arguments for start_xen and jump to C world */ @@ -142,12 +138,7 @@ GLOBAL(init_secondary) mov_w lr, secondary_switched b enable_secondary_cpu_mm - secondary_switched: -#ifdef CONFIG_EARLY_PRINTK - /* Use a virtual address to access the UART. */ - mov_w r11, EARLY_UART_VIRTUAL_ADDRESS -#endif PRINT("- Ready -\r\n") /* Jump to C world */ mov_w r2, start_secondary diff --git a/xen/arch/arm/arm32/mmu/head.S b/xen/arch/arm/arm32/mmu/head.S index bb3980843ad0..1e2bbf0c82e9 100644 --- a/xen/arch/arm/arm32/mmu/head.S +++ b/xen/arch/arm/arm32/mmu/head.S @@ -298,6 +298,21 @@ enable_mmu: mcr CP32(r0, HSCTLR) /* now paging is enabled */ isb /* Now, flush the icache */ + /* + * At this stage, the UART address will depend on whether the + * temporary mapping was created or not. + * + * If it was, then the UART will be mapped in the temporary + * area. Otherwise, it will be mapped at runtime virtual + * mapping. + */ +#ifdef CONFIG_EARLY_PRINTK + teq r12, #1 /* Was the temporary mapping created? */ + mov_w_on_cond eq, r11, TEMPORARY_EARLY_UART_VIRTUAL_ADDRESS + mov_w_on_cond ne, r11, EARLY_UART_VIRTUAL_ADDRESS +#endif + PRINT_ID("- Paging turned on -\r\n") + /* * The MMU is turned on and we are in the 1:1 mapping. Switch * to the runtime mapping. @@ -307,6 +322,17 @@ enable_mmu: b switch_to_runtime_mapping 1: mov lr, r5 /* Restore LR */ + + /* + * Now we are running at the runtime address. The UART can + * be accessed using its runtime virtual address. + */ +#ifdef CONFIG_EARLY_PRINTK + mov_w r11, EARLY_UART_VIRTUAL_ADDRESS +#endif + + PRINT("- Switched to the runtime mapping -\r\n") + /* * At this point, either the 1:1 map or the temporary mapping * will be present. The former may clash with other parts of the @@ -348,12 +374,14 @@ switch_to_runtime_mapping: teq r12, #0 beq ready_to_switch + PRINT_ID("- Switching to the temporary mapping -\r\n") /* We are still in the 1:1 mapping. Jump to the temporary Virtual address. */ mov_w r0, 1f add r0, r0, #XEN_TEMPORARY_OFFSET /* r0 := address in temporary mapping */ mov pc, r0 1: + PRINT("- Running on the temporary mapping -\r\n") /* Remove boot_second_id */ mov r2, #0 mov r3, #0 @@ -364,6 +392,8 @@ switch_to_runtime_mapping: flush_xen_tlb_local r0 + PRINT("- 1:1 mapping removed -\r\n") + /* Map boot_second into boot_pgtable */ mov_w r0, XEN_VIRT_START create_table_entry boot_pgtable, boot_second, r0, 1 @@ -376,7 +406,10 @@ switch_to_runtime_mapping: */ isb + PRINT("- Runtime mapping mapped -\r\n") ready_to_switch: + PRINT_ID("- Jumping to runtime address -\r\n") + mov pc, lr ENDPROC(switch_to_runtime_mapping) @@ -404,6 +437,8 @@ ENTRY(enable_secondary_cpu_mm) mov_w lr, 1f b enable_mmu 1: + PRINT("- Switching to the runtime page-tables -\r\n") + /* * Non-boot CPUs need to move on to the proper pagetables, which were * setup in prepare_secondary_mm. @@ -469,6 +504,8 @@ ENDPROC(enable_boot_cpu_mm) * Clobbers r0 - r3 */ remove_identity_mapping: + PRINT("- Removing the identity mapping -\r\n") + /* r2:r3 := invalid page-table entry */ mov r2, #0x0 mov r3, #0x0 @@ -489,6 +526,8 @@ ENDPROC(remove_identity_mapping) * Clobbers r0 - r3 */ remove_temporary_mapping: + PRINT("- Removing the temporary mapping -\r\n") + /* r2:r3 := invalid page-table entry */ mov r2, #0 mov r3, #0 diff --git a/xen/arch/arm/include/asm/arm32/macros.h b/xen/arch/arm/include/asm/arm32/macros.h index b84666c764d4..db681a7c7eaa 100644 --- a/xen/arch/arm/include/asm/arm32/macros.h +++ b/xen/arch/arm/include/asm/arm32/macros.h @@ -9,9 +9,13 @@ * Move an immediate constant into a 32-bit register using movw/movt * instructions. */ +.macro mov_w_on_cond cond, reg, word + movw\cond \reg, #:lower16:\word + movt\cond \reg, #:upper16:\word +.endm + .macro mov_w reg, word - movw \reg, #:lower16:\word - movt \reg, #:upper16:\word + mov_w_on_cond al, \reg, \word .endm /* @@ -29,16 +33,26 @@ #ifdef CONFIG_EARLY_PRINTK /* - * Macro to print a string to the UART, if there is one. + * Macros to print a string to the UART, if there is one. + * + * There are multiple flavors: + * - PRINT_SECT(section, string): The @string will be located in @section + * - PRINT(): The string will be located in .rodata.str. + * - PRINT_ID(): When Xen is running on the Identity Mapping, it is + * only possible to have a limited amount of Xen. This will create + * the string in .rodata.idmap which will always be mapped. * * Clobbers r0 - r3 */ -#define PRINT(_s) \ - mov r3, lr ;\ - adr_l r0, 98f ;\ - bl asm_puts ;\ - mov lr, r3 ;\ - RODATA_STR(98, _s) +#define PRINT_SECT(section, string) \ + mov r3, lr ;\ + adr_l r0, 98f ;\ + bl asm_puts ;\ + mov lr, r3 ;\ + RODATA_SECT(section, 98, string) + +#define PRINT(string) PRINT_SECT(.rodata.str, string) +#define PRINT_ID(string) PRINT_SECT(.rodata.idmap, string) /* * Macro to print the value of register \rb @@ -54,6 +68,7 @@ #else /* CONFIG_EARLY_PRINTK */ #define PRINT(s) +#define PRINT_ID(s) .macro print_reg rb .endm diff --git a/xen/arch/arm/include/asm/asm_defns.h b/xen/arch/arm/include/asm/asm_defns.h index 29a9dbb002fa..ec803c0a370c 100644 --- a/xen/arch/arm/include/asm/asm_defns.h +++ b/xen/arch/arm/include/asm/asm_defns.h @@ -22,11 +22,13 @@ # error "unknown ARM variant" #endif -#define RODATA_STR(label, msg) \ -.pushsection .rodata.str, "aMS", %progbits, 1 ; \ +#define RODATA_SECT(section, label, msg) \ +.pushsection section, "aMS", %progbits, 1 ; \ label: .asciz msg; \ .popsection +#define RODATA_STR(label, msg) RODATA_SECT(.rodata.str, label, msg) + #define ASM_INT(label, val) \ .p2align 2; \ label: .long (val); \ diff --git a/xen/arch/arm/include/asm/early_printk.h b/xen/arch/arm/include/asm/early_printk.h index c5149b2976da..c1e84f8b0009 100644 --- a/xen/arch/arm/include/asm/early_printk.h +++ b/xen/arch/arm/include/asm/early_printk.h @@ -19,6 +19,9 @@ #define EARLY_UART_VIRTUAL_ADDRESS \ (FIXMAP_ADDR(FIXMAP_CONSOLE) + (CONFIG_EARLY_UART_BASE_ADDRESS & ~PAGE_MASK)) +#define TEMPORARY_EARLY_UART_VIRTUAL_ADDRESS \ + (TEMPORARY_FIXMAP_ADDR(FIXMAP_CONSOLE) + (CONFIG_EARLY_UART_BASE_ADDRESS & ~PAGE_MASK)) + #endif /* !CONFIG_EARLY_PRINTK */ #endif diff --git a/xen/arch/arm/include/asm/mmu/layout.h b/xen/arch/arm/include/asm/mmu/layout.h index eac7eef885d6..a3b546465b5a 100644 --- a/xen/arch/arm/include/asm/mmu/layout.h +++ b/xen/arch/arm/include/asm/mmu/layout.h @@ -116,6 +116,10 @@ (TEMPORARY_AREA_FIRST_SLOT << XEN_PT_LEVEL_SHIFT(1))) #define TEMPORARY_XEN_VIRT_START TEMPORARY_AREA_ADDR(XEN_VIRT_START) +#define TEMPORARY_FIXMAP_VIRT_START TEMPORARY_AREA_ADDR(FIXMAP_VIRT_START) + +#define TEMPORARY_FIXMAP_ADDR(n) \ + (TEMPORARY_FIXMAP_VIRT_START + (n) * PAGE_SIZE) #else /* ARM_64 */ diff --git a/xen/arch/arm/mmu/setup.c b/xen/arch/arm/mmu/setup.c index d5264e51bc44..72725840b6b7 100644 --- a/xen/arch/arm/mmu/setup.c +++ b/xen/arch/arm/mmu/setup.c @@ -120,7 +120,10 @@ static void __init __maybe_unused build_assertions(void) #ifdef CONFIG_ARM_32 CHECK_SAME_SLOT(first, TEMPORARY_XEN_VIRT_START, DOMHEAP_VIRT_START); CHECK_DIFFERENT_SLOT(first, XEN_VIRT_START, TEMPORARY_XEN_VIRT_START); + CHECK_SAME_SLOT(first, TEMPORARY_XEN_VIRT_START, + TEMPORARY_FIXMAP_VIRT_START); CHECK_SAME_SLOT(second, XEN_VIRT_START, TEMPORARY_XEN_VIRT_START); + CHECK_SAME_SLOT(second, FIXMAP_VIRT_START, TEMPORARY_FIXMAP_VIRT_START); #endif #undef CHECK_SAME_SLOT diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index 59b80d122fd0..20598c6963ce 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -35,6 +35,7 @@ SECTIONS _idmap_start = .; *(.text.header) *(.text.idmap) + *(.rodata.idmap) _idmap_end = .; *(.text.cold)