From 5085f3ff458521045f7e43da62b8c30ea7df2e82 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 1 Oct 2010 15:37:05 +0100 Subject: ARM: hotplug cpu: Keep processor information, startup code & __lookup_processor_type When hotplug CPU is enabled, we need to keep the list of supported CPUs, their setup functions, and __lookup_processor_type in place so that we can find and initialize secondary CPUs. Move these into the __CPUINIT section. Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 81 ++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 36 deletions(-) (limited to 'arch/arm/kernel/head-common.S') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index b9505aa267c0..6ad24d2cb14b 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -145,45 +145,14 @@ ENDPROC(__error) /* - * Read processor ID register (CP#15, CR0), and look up in the linker-built - * supported processor list. Note that we can't use the absolute addresses - * for the __proc_info lists since we aren't running with the MMU on - * (and therefore, we are not in the correct address space). We have to - * calculate the offset. - * - * r9 = cpuid - * Returns: - * r3, r4, r6 corrupted - * r5 = proc_info pointer in physical address space - * r9 = cpuid (preserved) - */ -__lookup_processor_type: - adr r3, 3f - ldmia r3, {r5 - r7} - add r3, r3, #8 - sub r3, r3, r7 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space -1: ldmia r5, {r3, r4} @ value, mask - and r4, r4, r9 @ mask wanted bits - teq r3, r4 - beq 2f - add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) - cmp r5, r6 - blo 1b - mov r5, #0 @ unknown processor -2: mov pc, lr -ENDPROC(__lookup_processor_type) - -/* - * This provides a C-API version of the above function. + * This provides a C-API version of __lookup_processor_type */ ENTRY(lookup_processor_type) - stmfd sp!, {r4 - r7, r9, lr} + stmfd sp!, {r4 - r6, r9, lr} mov r9, r0 bl __lookup_processor_type mov r0, r5 - ldmfd sp!, {r4 - r7, r9, pc} + ldmfd sp!, {r4 - r6, r9, pc} ENDPROC(lookup_processor_type) /* @@ -191,8 +160,6 @@ ENDPROC(lookup_processor_type) * more information about the __proc_info and __arch_info structures. */ .align 2 -3: .long __proc_info_begin - .long __proc_info_end 4: .long . .long __arch_info_begin .long __arch_info_end @@ -265,3 +232,45 @@ __vet_atags: 1: mov r2, #0 mov pc, lr ENDPROC(__vet_atags) + +/* + * Read processor ID register (CP#15, CR0), and look up in the linker-built + * supported processor list. Note that we can't use the absolute addresses + * for the __proc_info lists since we aren't running with the MMU on + * (and therefore, we are not in the correct address space). We have to + * calculate the offset. + * + * r9 = cpuid + * Returns: + * r3, r4, r6 corrupted + * r5 = proc_info pointer in physical address space + * r9 = cpuid (preserved) + */ + __CPUINIT +__lookup_processor_type: + adr r3, __lookup_processor_type_data + ldmia r3, {r4 - r6} + sub r3, r3, r4 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space +1: ldmia r5, {r3, r4} @ value, mask + and r4, r4, r9 @ mask wanted bits + teq r3, r4 + beq 2f + add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown processor +2: mov pc, lr +ENDPROC(__lookup_processor_type) + +/* + * Look in for information about the __proc_info structure. + */ + .align 2 + .type __lookup_processor_type_data, %object +__lookup_processor_type_data: + .long . + .long __proc_info_begin + .long __proc_info_end + .size __lookup_processor_type_data, . - __lookup_processor_type_data -- cgit v1.2.3 From a4ae41341fd39af6e25ec9861a6a4dc0c5c58b16 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Oct 2010 16:22:34 +0100 Subject: ARM: cleanup boot cpu calling __mmap_switched This allows us to relocate __mmap_switched and associated data away from the head section. Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 3 +-- arch/arm/kernel/head.S | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/kernel/head-common.S') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 6ad24d2cb14b..9f473ef2a64c 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -18,7 +18,6 @@ .align 2 .type __switch_data, %object __switch_data: - .long __mmap_switched .long __data_loc @ r4 .long _data @ r5 .long __bss_start @ r6 @@ -39,7 +38,7 @@ __switch_data: * r9 = processor ID */ __mmap_switched: - adr r3, __switch_data + 4 + adr r3, __switch_data ldmia r3!, {r4, r5, r6, r7} cmp r4, r5 @ Copy data segment if needed diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index eb62bf947212..aa6ab9d86461 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -95,13 +95,14 @@ ENTRY(stext) * above. On return, the CPU will be ready for the MMU to be * turned on, and r0 will hold the CPU control register value. */ - ldr r13, __switch_data @ address to jump to after + ldr r13, =__mmap_switched @ address to jump to after @ mmu has been enabled adr lr, BSYM(__enable_mmu) @ return (PIC) address ARM( add pc, r10, #PROCINFO_INITFUNC ) THUMB( add r12, r10, #PROCINFO_INITFUNC ) THUMB( mov pc, r12 ) ENDPROC(stext) + .ltorg #if defined(CONFIG_SMP) ENTRY(secondary_startup) -- cgit v1.2.3 From 17bb5e2c1706c7296eec96e97be0d760e59f282c Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Oct 2010 16:29:35 +0100 Subject: ARM: move __mmap_switched, C-API functions to init section Move these functions, which are only ever used during boot CPU initialization, to the init section. Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 142 +++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 70 deletions(-) (limited to 'arch/arm/kernel/head-common.S') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 9f473ef2a64c..24dfa14b0bf9 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -15,54 +15,6 @@ #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) - .align 2 - .type __switch_data, %object -__switch_data: - .long __data_loc @ r4 - .long _data @ r5 - .long __bss_start @ r6 - .long _end @ r7 - .long processor_id @ r4 - .long __machine_arch_type @ r5 - .long __atags_pointer @ r6 - .long cr_alignment @ r7 - .long init_thread_union + THREAD_START_SP @ sp - -/* - * The following fragment of code is executed with the MMU on in MMU mode, - * and uses absolute addresses; this is not position independent. - * - * r0 = cp#15 control register - * r1 = machine ID - * r2 = atags pointer - * r9 = processor ID - */ -__mmap_switched: - adr r3, __switch_data - - ldmia r3!, {r4, r5, r6, r7} - cmp r4, r5 @ Copy data segment if needed -1: cmpne r5, r6 - ldrne fp, [r4], #4 - strne fp, [r5], #4 - bne 1b - - mov fp, #0 @ Clear BSS (and zero fp) -1: cmp r6, r7 - strcc fp, [r6],#4 - bcc 1b - - ARM( ldmia r3, {r4, r5, r6, r7, sp}) - THUMB( ldmia r3, {r4, r5, r6, r7} ) - THUMB( ldr sp, [r3, #16] ) - str r9, [r4] @ Save processor ID - str r1, [r5] @ Save machine type - str r2, [r6] @ Save atags pointer - bic r4, r0, #CR_A @ Clear 'A' bit - stmia r7, {r0, r4} @ Save control register values - b start_kernel -ENDPROC(__mmap_switched) - /* * Exception handling. Something went wrong and we can't proceed. We * ought to tell the user, but since we don't have any guarantee that @@ -143,17 +95,6 @@ __error: ENDPROC(__error) -/* - * This provides a C-API version of __lookup_processor_type - */ -ENTRY(lookup_processor_type) - stmfd sp!, {r4 - r6, r9, lr} - mov r9, r0 - bl __lookup_processor_type - mov r0, r5 - ldmfd sp!, {r4 - r6, r9, pc} -ENDPROC(lookup_processor_type) - /* * Look in and arch/arm/kernel/arch.[ch] for * more information about the __proc_info and __arch_info structures. @@ -190,17 +131,6 @@ __lookup_machine_type: 2: mov pc, lr ENDPROC(__lookup_machine_type) -/* - * This provides a C-API version of the above function. - */ -ENTRY(lookup_machine_type) - stmfd sp!, {r4 - r6, lr} - mov r1, r0 - bl __lookup_machine_type - mov r0, r5 - ldmfd sp!, {r4 - r6, pc} -ENDPROC(lookup_machine_type) - /* Determine validity of the r2 atags pointer. The heuristic requires * that the pointer be aligned, in the first 16k of physical RAM and * that the ATAG_CORE marker is first and present. Future revisions @@ -232,6 +162,78 @@ __vet_atags: mov pc, lr ENDPROC(__vet_atags) +/* + * The following fragment of code is executed with the MMU on in MMU mode, + * and uses absolute addresses; this is not position independent. + * + * r0 = cp#15 control register + * r1 = machine ID + * r2 = atags pointer + * r9 = processor ID + */ + __INIT +__mmap_switched: + adr r3, __mmap_switched_data + + ldmia r3!, {r4, r5, r6, r7} + cmp r4, r5 @ Copy data segment if needed +1: cmpne r5, r6 + ldrne fp, [r4], #4 + strne fp, [r5], #4 + bne 1b + + mov fp, #0 @ Clear BSS (and zero fp) +1: cmp r6, r7 + strcc fp, [r6],#4 + bcc 1b + + ARM( ldmia r3, {r4, r5, r6, r7, sp}) + THUMB( ldmia r3, {r4, r5, r6, r7} ) + THUMB( ldr sp, [r3, #16] ) + str r9, [r4] @ Save processor ID + str r1, [r5] @ Save machine type + str r2, [r6] @ Save atags pointer + bic r4, r0, #CR_A @ Clear 'A' bit + stmia r7, {r0, r4} @ Save control register values + b start_kernel +ENDPROC(__mmap_switched) + + .align 2 + .type __mmap_switched_data, %object +__mmap_switched_data: + .long __data_loc @ r4 + .long _data @ r5 + .long __bss_start @ r6 + .long _end @ r7 + .long processor_id @ r4 + .long __machine_arch_type @ r5 + .long __atags_pointer @ r6 + .long cr_alignment @ r7 + .long init_thread_union + THREAD_START_SP @ sp + .size __mmap_switched_data, . - __mmap_switched_data + +/* + * This provides a C-API version of __lookup_machine_type + */ +ENTRY(lookup_machine_type) + stmfd sp!, {r4 - r6, lr} + mov r1, r0 + bl __lookup_machine_type + mov r0, r5 + ldmfd sp!, {r4 - r6, pc} +ENDPROC(lookup_machine_type) + +/* + * This provides a C-API version of __lookup_processor_type + */ +ENTRY(lookup_processor_type) + stmfd sp!, {r4 - r6, r9, lr} + mov r9, r0 + bl __lookup_processor_type + mov r0, r5 + ldmfd sp!, {r4 - r6, r9, pc} +ENDPROC(lookup_processor_type) + /* * Read processor ID register (CP#15, CR0), and look up in the linker-built * supported processor list. Note that we can't use the absolute addresses -- cgit v1.2.3 From c083c6609b290a650894f846270a9233401adc22 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Oct 2010 17:39:20 +0100 Subject: ARM: hotplug cpu: move __error and __error_p to cpuinit section __error and __error_p may be used by secondary CPUs, so these need to be in the cpuinit section. Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 67 +++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'arch/arm/kernel/head-common.S') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 24dfa14b0bf9..7c6f9ab47b95 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -24,21 +24,6 @@ * and hope for the best (useful if bootloader fails to pass a proper * machine ID for example). */ -__error_p: -#ifdef CONFIG_DEBUG_LL - adr r0, str_p1 - bl printascii - mov r0, r9 - bl printhex8 - adr r0, str_p2 - bl printascii - b __error -str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x" -str_p2: .asciz ").\n" - .align -#endif -ENDPROC(__error_p) - __error_a: #ifdef CONFIG_DEBUG_LL mov r4, r1 @ preserve machine ID @@ -76,25 +61,6 @@ str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" .align #endif -__error: -#ifdef CONFIG_ARCH_RPC -/* - * Turn the screen red on a error - RiscPC only. - */ - mov r0, #0x02000000 - mov r3, #0x11 - orr r3, r3, r3, lsl #8 - orr r3, r3, r3, lsl #16 - str r3, [r0], #4 - str r3, [r0], #4 - str r3, [r0], #4 - str r3, [r0], #4 -#endif -1: mov r0, r0 - b 1b -ENDPROC(__error) - - /* * Look in and arch/arm/kernel/arch.[ch] for * more information about the __proc_info and __arch_info structures. @@ -275,3 +241,36 @@ __lookup_processor_type_data: .long __proc_info_begin .long __proc_info_end .size __lookup_processor_type_data, . - __lookup_processor_type_data + +__error_p: +#ifdef CONFIG_DEBUG_LL + adr r0, str_p1 + bl printascii + mov r0, r9 + bl printhex8 + adr r0, str_p2 + bl printascii + b __error +str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x" +str_p2: .asciz ").\n" + .align +#endif +ENDPROC(__error_p) + +__error: +#ifdef CONFIG_ARCH_RPC +/* + * Turn the screen red on a error - RiscPC only. + */ + mov r0, #0x02000000 + mov r3, #0x11 + orr r3, r3, r3, lsl #8 + orr r3, r3, r3, lsl #16 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 +#endif +1: mov r0, r0 + b 1b +ENDPROC(__error) -- cgit v1.2.3 From 80924ac595f3ca32ec0a80cc1217c7019d3519ff Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Oct 2010 17:45:25 +0100 Subject: ARM: cleanup lookup_machine_type data and ensure these are placed in __HEAD Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'arch/arm/kernel/head-common.S') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 7c6f9ab47b95..c4effcfba1eb 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -24,6 +24,7 @@ * and hope for the best (useful if bootloader fails to pass a proper * machine ID for example). */ + __HEAD __error_a: #ifdef CONFIG_DEBUG_LL mov r4, r1 @ preserve machine ID @@ -33,7 +34,7 @@ __error_a: bl printhex8 adr r0, str_a2 bl printascii - adr r3, 4f + adr r3, __lookup_machine_type_data ldmia r3, {r4, r5, r6} @ get machine desc list sub r4, r3, r4 @ get offset between virt&phys add r5, r5, r4 @ convert virt addresses to @@ -61,15 +62,6 @@ str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" .align #endif -/* - * Look in and arch/arm/kernel/arch.[ch] for - * more information about the __proc_info and __arch_info structures. - */ - .align 2 -4: .long . - .long __arch_info_begin - .long __arch_info_end - /* * Lookup machine architecture in the linker-build list of architectures. * Note that we can't use the absolute addresses for the __arch_info @@ -82,7 +74,7 @@ str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" * r5 = mach_info pointer in physical address space */ __lookup_machine_type: - adr r3, 4b + adr r3, __lookup_machine_type_data ldmia r3, {r4, r5, r6} sub r3, r3, r4 @ get offset between virt&phys add r5, r5, r3 @ convert virt addresses to @@ -97,6 +89,18 @@ __lookup_machine_type: 2: mov pc, lr ENDPROC(__lookup_machine_type) +/* + * Look in arch/arm/kernel/arch.[ch] for information about the + * __arch_info structures. + */ + .align 2 + .type __lookup_machine_type_data, %object +__lookup_machine_type_data: + .long . + .long __arch_info_begin + .long __arch_info_end + .size __lookup_machine_type_data, . - __lookup_machine_type_data + /* Determine validity of the r2 atags pointer. The heuristic requires * that the pointer be aligned, in the first 16k of physical RAM and * that the ATAG_CORE marker is first and present. Future revisions -- cgit v1.2.3