[ARM] nommu: start-up code

This patch adds nommu version start-up code head-nommu.S.
The common part of the start-up codes is moved to head-common.S.

Signed-off-by: Hyok S. Choi <hyok.choi@samsung.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Hyok S. Choi and committed by
Russell King
75d90832 10c2df65

+302 -207
+1 -1
arch/arm/Makefile
··· 69 69 CHECKFLAGS += -D__arm__ 70 70 71 71 #Default value 72 - head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o 72 + head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o 73 73 textofs-y := 0x00008000 74 74 75 75 machine-$(CONFIG_ARCH_RPC) := rpc
+217
arch/arm/kernel/head-common.S
··· 1 + /* 2 + * linux/arch/arm/kernel/head-common.S 3 + * 4 + * Copyright (C) 1994-2002 Russell King 5 + * Copyright (c) 2003 ARM Limited 6 + * All Rights Reserved 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + */ 13 + 14 + .type __switch_data, %object 15 + __switch_data: 16 + .long __mmap_switched 17 + .long __data_loc @ r4 18 + .long __data_start @ r5 19 + .long __bss_start @ r6 20 + .long _end @ r7 21 + .long processor_id @ r4 22 + .long __machine_arch_type @ r5 23 + .long cr_alignment @ r6 24 + .long init_thread_union + THREAD_START_SP @ sp 25 + 26 + /* 27 + * The following fragment of code is executed with the MMU on in MMU mode, 28 + * and uses absolute addresses; this is not position independent. 29 + * 30 + * r0 = cp#15 control register 31 + * r1 = machine ID 32 + * r9 = processor ID 33 + */ 34 + .type __mmap_switched, %function 35 + __mmap_switched: 36 + adr r3, __switch_data + 4 37 + 38 + ldmia r3!, {r4, r5, r6, r7} 39 + cmp r4, r5 @ Copy data segment if needed 40 + 1: cmpne r5, r6 41 + ldrne fp, [r4], #4 42 + strne fp, [r5], #4 43 + bne 1b 44 + 45 + mov fp, #0 @ Clear BSS (and zero fp) 46 + 1: cmp r6, r7 47 + strcc fp, [r6],#4 48 + bcc 1b 49 + 50 + ldmia r3, {r4, r5, r6, sp} 51 + str r9, [r4] @ Save processor ID 52 + str r1, [r5] @ Save machine type 53 + bic r4, r0, #CR_A @ Clear 'A' bit 54 + stmia r6, {r0, r4} @ Save control register values 55 + b start_kernel 56 + 57 + /* 58 + * Exception handling. Something went wrong and we can't proceed. We 59 + * ought to tell the user, but since we don't have any guarantee that 60 + * we're even running on the right architecture, we do virtually nothing. 61 + * 62 + * If CONFIG_DEBUG_LL is set we try to print out something about the error 63 + * and hope for the best (useful if bootloader fails to pass a proper 64 + * machine ID for example). 65 + */ 66 + 67 + .type __error_p, %function 68 + __error_p: 69 + #ifdef CONFIG_DEBUG_LL 70 + adr r0, str_p1 71 + bl printascii 72 + b __error 73 + str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" 74 + .align 75 + #endif 76 + 77 + .type __error_a, %function 78 + __error_a: 79 + #ifdef CONFIG_DEBUG_LL 80 + mov r4, r1 @ preserve machine ID 81 + adr r0, str_a1 82 + bl printascii 83 + mov r0, r4 84 + bl printhex8 85 + adr r0, str_a2 86 + bl printascii 87 + adr r3, 3f 88 + ldmia r3, {r4, r5, r6} @ get machine desc list 89 + sub r4, r3, r4 @ get offset between virt&phys 90 + add r5, r5, r4 @ convert virt addresses to 91 + add r6, r6, r4 @ physical address space 92 + 1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type 93 + bl printhex8 94 + mov r0, #'\t' 95 + bl printch 96 + ldr r0, [r5, #MACHINFO_NAME] @ get machine name 97 + add r0, r0, r4 98 + bl printascii 99 + mov r0, #'\n' 100 + bl printch 101 + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc 102 + cmp r5, r6 103 + blo 1b 104 + adr r0, str_a3 105 + bl printascii 106 + b __error 107 + str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" 108 + str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" 109 + str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" 110 + .align 111 + #endif 112 + 113 + .type __error, %function 114 + __error: 115 + #ifdef CONFIG_ARCH_RPC 116 + /* 117 + * Turn the screen red on a error - RiscPC only. 118 + */ 119 + mov r0, #0x02000000 120 + mov r3, #0x11 121 + orr r3, r3, r3, lsl #8 122 + orr r3, r3, r3, lsl #16 123 + str r3, [r0], #4 124 + str r3, [r0], #4 125 + str r3, [r0], #4 126 + str r3, [r0], #4 127 + #endif 128 + 1: mov r0, r0 129 + b 1b 130 + 131 + 132 + /* 133 + * Read processor ID register (CP#15, CR0), and look up in the linker-built 134 + * supported processor list. Note that we can't use the absolute addresses 135 + * for the __proc_info lists since we aren't running with the MMU on 136 + * (and therefore, we are not in the correct address space). We have to 137 + * calculate the offset. 138 + * 139 + * r9 = cpuid 140 + * Returns: 141 + * r3, r4, r6 corrupted 142 + * r5 = proc_info pointer in physical address space 143 + * r9 = cpuid (preserved) 144 + */ 145 + .type __lookup_processor_type, %function 146 + __lookup_processor_type: 147 + adr r3, 3f 148 + ldmda r3, {r5 - r7} 149 + sub r3, r3, r7 @ get offset between virt&phys 150 + add r5, r5, r3 @ convert virt addresses to 151 + add r6, r6, r3 @ physical address space 152 + 1: ldmia r5, {r3, r4} @ value, mask 153 + and r4, r4, r9 @ mask wanted bits 154 + teq r3, r4 155 + beq 2f 156 + add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) 157 + cmp r5, r6 158 + blo 1b 159 + mov r5, #0 @ unknown processor 160 + 2: mov pc, lr 161 + 162 + /* 163 + * This provides a C-API version of the above function. 164 + */ 165 + ENTRY(lookup_processor_type) 166 + stmfd sp!, {r4 - r7, r9, lr} 167 + mov r9, r0 168 + bl __lookup_processor_type 169 + mov r0, r5 170 + ldmfd sp!, {r4 - r7, r9, pc} 171 + 172 + /* 173 + * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for 174 + * more information about the __proc_info and __arch_info structures. 175 + */ 176 + .long __proc_info_begin 177 + .long __proc_info_end 178 + 3: .long . 179 + .long __arch_info_begin 180 + .long __arch_info_end 181 + 182 + /* 183 + * Lookup machine architecture in the linker-build list of architectures. 184 + * Note that we can't use the absolute addresses for the __arch_info 185 + * lists since we aren't running with the MMU on (and therefore, we are 186 + * not in the correct address space). We have to calculate the offset. 187 + * 188 + * r1 = machine architecture number 189 + * Returns: 190 + * r3, r4, r6 corrupted 191 + * r5 = mach_info pointer in physical address space 192 + */ 193 + .type __lookup_machine_type, %function 194 + __lookup_machine_type: 195 + adr r3, 3b 196 + ldmia r3, {r4, r5, r6} 197 + sub r3, r3, r4 @ get offset between virt&phys 198 + add r5, r5, r3 @ convert virt addresses to 199 + add r6, r6, r3 @ physical address space 200 + 1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type 201 + teq r3, r1 @ matches loader number? 202 + beq 2f @ found 203 + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc 204 + cmp r5, r6 205 + blo 1b 206 + mov r5, #0 @ unknown machine 207 + 2: mov pc, lr 208 + 209 + /* 210 + * This provides a C-API version of the above function. 211 + */ 212 + ENTRY(lookup_machine_type) 213 + stmfd sp!, {r4 - r6, lr} 214 + mov r1, r0 215 + bl __lookup_machine_type 216 + mov r0, r5 217 + ldmfd sp!, {r4 - r6, pc}
+83
arch/arm/kernel/head-nommu.S
··· 1 + /* 2 + * linux/arch/arm/kernel/head-nommu.S 3 + * 4 + * Copyright (C) 1994-2002 Russell King 5 + * Copyright (C) 2003-2006 Hyok S. Choi 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + * Common kernel startup code (non-paged MM) 12 + * for 32-bit CPUs which has a process ID register(CP15). 13 + * 14 + */ 15 + #include <linux/config.h> 16 + #include <linux/linkage.h> 17 + #include <linux/init.h> 18 + 19 + #include <asm/assembler.h> 20 + #include <asm/mach-types.h> 21 + #include <asm/procinfo.h> 22 + #include <asm/ptrace.h> 23 + #include <asm/constants.h> 24 + #include <asm/system.h> 25 + 26 + #define PROCINFO_INITFUNC 12 27 + 28 + /* 29 + * Kernel startup entry point. 30 + * --------------------------- 31 + * 32 + * This is normally called from the decompressor code. The requirements 33 + * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, 34 + * r1 = machine nr. 35 + * 36 + * See linux/arch/arm/tools/mach-types for the complete list of machine 37 + * numbers for r1. 38 + * 39 + */ 40 + __INIT 41 + .type stext, %function 42 + ENTRY(stext) 43 + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode 44 + @ and irqs disabled 45 + mrc p15, 0, r9, c0, c0 @ get processor id 46 + bl __lookup_processor_type @ r5=procinfo r9=cpuid 47 + movs r10, r5 @ invalid processor (r5=0)? 48 + beq __error_p @ yes, error 'p' 49 + bl __lookup_machine_type @ r5=machinfo 50 + movs r8, r5 @ invalid machine (r5=0)? 51 + beq __error_a @ yes, error 'a' 52 + 53 + ldr r13, __switch_data @ address to jump to after 54 + @ the initialization is done 55 + adr lr, __after_proc_init @ return (PIC) address 56 + add pc, r10, #PROCINFO_INITFUNC 57 + 58 + /* 59 + * Set the Control Register and Read the process ID. 60 + */ 61 + .type __after_proc_init, %function 62 + __after_proc_init: 63 + mrc p15, 0, r0, c1, c0, 0 @ read control reg 64 + #ifdef CONFIG_ALIGNMENT_TRAP 65 + orr r0, r0, #CR_A 66 + #else 67 + bic r0, r0, #CR_A 68 + #endif 69 + #ifdef CONFIG_CPU_DCACHE_DISABLE 70 + bic r0, r0, #CR_C 71 + #endif 72 + #ifdef CONFIG_CPU_BPREDICT_DISABLE 73 + bic r0, r0, #CR_Z 74 + #endif 75 + #ifdef CONFIG_CPU_ICACHE_DISABLE 76 + bic r0, r0, #CR_I 77 + #endif 78 + mcr p15, 0, r0, c1, c0, 0 @ write control reg 79 + 80 + mov pc, r13 @ clear the BSS and jump 81 + @ to start_kernel 82 + 83 + #include "head-common.S"
+1 -206
arch/arm/kernel/head.S
··· 103 103 adr lr, __enable_mmu @ return (PIC) address 104 104 add pc, r10, #PROCINFO_INITFUNC 105 105 106 - .type __switch_data, %object 107 - __switch_data: 108 - .long __mmap_switched 109 - .long __data_loc @ r4 110 - .long __data_start @ r5 111 - .long __bss_start @ r6 112 - .long _end @ r7 113 - .long processor_id @ r4 114 - .long __machine_arch_type @ r5 115 - .long cr_alignment @ r6 116 - .long init_thread_union + THREAD_START_SP @ sp 117 - 118 - /* 119 - * The following fragment of code is executed with the MMU on, and uses 120 - * absolute addresses; this is not position independent. 121 - * 122 - * r0 = cp#15 control register 123 - * r1 = machine ID 124 - * r9 = processor ID 125 - */ 126 - .type __mmap_switched, %function 127 - __mmap_switched: 128 - adr r3, __switch_data + 4 129 - 130 - ldmia r3!, {r4, r5, r6, r7} 131 - cmp r4, r5 @ Copy data segment if needed 132 - 1: cmpne r5, r6 133 - ldrne fp, [r4], #4 134 - strne fp, [r5], #4 135 - bne 1b 136 - 137 - mov fp, #0 @ Clear BSS (and zero fp) 138 - 1: cmp r6, r7 139 - strcc fp, [r6],#4 140 - bcc 1b 141 - 142 - ldmia r3, {r4, r5, r6, sp} 143 - str r9, [r4] @ Save processor ID 144 - str r1, [r5] @ Save machine type 145 - bic r4, r0, #CR_A @ Clear 'A' bit 146 - stmia r6, {r0, r4} @ Save control register values 147 - b start_kernel 148 - 149 106 #if defined(CONFIG_SMP) 150 107 .type secondary_startup, #function 151 108 ENTRY(secondary_startup) ··· 325 368 mov pc, lr 326 369 .ltorg 327 370 328 - 329 - 330 - /* 331 - * Exception handling. Something went wrong and we can't proceed. We 332 - * ought to tell the user, but since we don't have any guarantee that 333 - * we're even running on the right architecture, we do virtually nothing. 334 - * 335 - * If CONFIG_DEBUG_LL is set we try to print out something about the error 336 - * and hope for the best (useful if bootloader fails to pass a proper 337 - * machine ID for example). 338 - */ 339 - 340 - .type __error_p, %function 341 - __error_p: 342 - #ifdef CONFIG_DEBUG_LL 343 - adr r0, str_p1 344 - bl printascii 345 - b __error 346 - str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" 347 - .align 348 - #endif 349 - 350 - .type __error_a, %function 351 - __error_a: 352 - #ifdef CONFIG_DEBUG_LL 353 - mov r4, r1 @ preserve machine ID 354 - adr r0, str_a1 355 - bl printascii 356 - mov r0, r4 357 - bl printhex8 358 - adr r0, str_a2 359 - bl printascii 360 - adr r3, 3f 361 - ldmia r3, {r4, r5, r6} @ get machine desc list 362 - sub r4, r3, r4 @ get offset between virt&phys 363 - add r5, r5, r4 @ convert virt addresses to 364 - add r6, r6, r4 @ physical address space 365 - 1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type 366 - bl printhex8 367 - mov r0, #'\t' 368 - bl printch 369 - ldr r0, [r5, #MACHINFO_NAME] @ get machine name 370 - add r0, r0, r4 371 - bl printascii 372 - mov r0, #'\n' 373 - bl printch 374 - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc 375 - cmp r5, r6 376 - blo 1b 377 - adr r0, str_a3 378 - bl printascii 379 - b __error 380 - str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" 381 - str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" 382 - str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" 383 - .align 384 - #endif 385 - 386 - .type __error, %function 387 - __error: 388 - #ifdef CONFIG_ARCH_RPC 389 - /* 390 - * Turn the screen red on a error - RiscPC only. 391 - */ 392 - mov r0, #0x02000000 393 - mov r3, #0x11 394 - orr r3, r3, r3, lsl #8 395 - orr r3, r3, r3, lsl #16 396 - str r3, [r0], #4 397 - str r3, [r0], #4 398 - str r3, [r0], #4 399 - str r3, [r0], #4 400 - #endif 401 - 1: mov r0, r0 402 - b 1b 403 - 404 - 405 - /* 406 - * Read processor ID register (CP#15, CR0), and look up in the linker-built 407 - * supported processor list. Note that we can't use the absolute addresses 408 - * for the __proc_info lists since we aren't running with the MMU on 409 - * (and therefore, we are not in the correct address space). We have to 410 - * calculate the offset. 411 - * 412 - * r9 = cpuid 413 - * Returns: 414 - * r3, r4, r6 corrupted 415 - * r5 = proc_info pointer in physical address space 416 - * r9 = cpuid (preserved) 417 - */ 418 - .type __lookup_processor_type, %function 419 - __lookup_processor_type: 420 - adr r3, 3f 421 - ldmda r3, {r5 - r7} 422 - sub r3, r3, r7 @ get offset between virt&phys 423 - add r5, r5, r3 @ convert virt addresses to 424 - add r6, r6, r3 @ physical address space 425 - 1: ldmia r5, {r3, r4} @ value, mask 426 - and r4, r4, r9 @ mask wanted bits 427 - teq r3, r4 428 - beq 2f 429 - add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) 430 - cmp r5, r6 431 - blo 1b 432 - mov r5, #0 @ unknown processor 433 - 2: mov pc, lr 434 - 435 - /* 436 - * This provides a C-API version of the above function. 437 - */ 438 - ENTRY(lookup_processor_type) 439 - stmfd sp!, {r4 - r7, r9, lr} 440 - mov r9, r0 441 - bl __lookup_processor_type 442 - mov r0, r5 443 - ldmfd sp!, {r4 - r7, r9, pc} 444 - 445 - /* 446 - * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for 447 - * more information about the __proc_info and __arch_info structures. 448 - */ 449 - .long __proc_info_begin 450 - .long __proc_info_end 451 - 3: .long . 452 - .long __arch_info_begin 453 - .long __arch_info_end 454 - 455 - /* 456 - * Lookup machine architecture in the linker-build list of architectures. 457 - * Note that we can't use the absolute addresses for the __arch_info 458 - * lists since we aren't running with the MMU on (and therefore, we are 459 - * not in the correct address space). We have to calculate the offset. 460 - * 461 - * r1 = machine architecture number 462 - * Returns: 463 - * r3, r4, r6 corrupted 464 - * r5 = mach_info pointer in physical address space 465 - */ 466 - .type __lookup_machine_type, %function 467 - __lookup_machine_type: 468 - adr r3, 3b 469 - ldmia r3, {r4, r5, r6} 470 - sub r3, r3, r4 @ get offset between virt&phys 471 - add r5, r5, r3 @ convert virt addresses to 472 - add r6, r6, r3 @ physical address space 473 - 1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type 474 - teq r3, r1 @ matches loader number? 475 - beq 2f @ found 476 - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc 477 - cmp r5, r6 478 - blo 1b 479 - mov r5, #0 @ unknown machine 480 - 2: mov pc, lr 481 - 482 - /* 483 - * This provides a C-API version of the above function. 484 - */ 485 - ENTRY(lookup_machine_type) 486 - stmfd sp!, {r4 - r6, lr} 487 - mov r1, r0 488 - bl __lookup_machine_type 489 - mov r0, r5 490 - ldmfd sp!, {r4 - r6, pc} 371 + #include "head-common.S"