diff options
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 254 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-header.S | 7 | ||||
| -rw-r--r-- | arch/arm/kernel/setup.c | 52 |
3 files changed, 190 insertions, 123 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index e14278d59882..39a6c1b0b9a3 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -24,48 +24,91 @@ | |||
| 24 | #include "entry-header.S" | 24 | #include "entry-header.S" |
| 25 | 25 | ||
| 26 | /* | 26 | /* |
| 27 | * Interrupt handling. Preserves r7, r8, r9 | ||
| 28 | */ | ||
| 29 | .macro irq_handler | ||
| 30 | 1: get_irqnr_and_base r0, r6, r5, lr | ||
| 31 | movne r1, sp | ||
| 32 | @ | ||
| 33 | @ routine called with r0 = irq number, r1 = struct pt_regs * | ||
| 34 | @ | ||
| 35 | adrne lr, 1b | ||
| 36 | bne asm_do_IRQ | ||
| 37 | |||
| 38 | #ifdef CONFIG_SMP | ||
| 39 | /* | ||
| 40 | * XXX | ||
| 41 | * | ||
| 42 | * this macro assumes that irqstat (r6) and base (r5) are | ||
| 43 | * preserved from get_irqnr_and_base above | ||
| 44 | */ | ||
| 45 | test_for_ipi r0, r6, r5, lr | ||
| 46 | movne r0, sp | ||
| 47 | adrne lr, 1b | ||
| 48 | bne do_IPI | ||
| 49 | #endif | ||
| 50 | |||
| 51 | .endm | ||
| 52 | |||
| 53 | /* | ||
| 27 | * Invalid mode handlers | 54 | * Invalid mode handlers |
| 28 | */ | 55 | */ |
| 29 | .macro inv_entry, sym, reason | 56 | .macro inv_entry, reason |
| 30 | sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go | 57 | sub sp, sp, #S_FRAME_SIZE |
| 31 | stmia sp, {r0 - lr} @ Save XXX r0 - lr | 58 | stmib sp, {r1 - lr} |
| 32 | ldr r4, .LC\sym | ||
| 33 | mov r1, #\reason | 59 | mov r1, #\reason |
| 34 | .endm | 60 | .endm |
| 35 | 61 | ||
| 36 | __pabt_invalid: | 62 | __pabt_invalid: |
| 37 | inv_entry abt, BAD_PREFETCH | 63 | inv_entry BAD_PREFETCH |
| 38 | b 1f | 64 | b common_invalid |
| 39 | 65 | ||
| 40 | __dabt_invalid: | 66 | __dabt_invalid: |
| 41 | inv_entry abt, BAD_DATA | 67 | inv_entry BAD_DATA |
| 42 | b 1f | 68 | b common_invalid |
| 43 | 69 | ||
| 44 | __irq_invalid: | 70 | __irq_invalid: |
| 45 | inv_entry irq, BAD_IRQ | 71 | inv_entry BAD_IRQ |
| 46 | b 1f | 72 | b common_invalid |
| 47 | 73 | ||
| 48 | __und_invalid: | 74 | __und_invalid: |
| 49 | inv_entry und, BAD_UNDEFINSTR | 75 | inv_entry BAD_UNDEFINSTR |
| 76 | |||
| 77 | @ | ||
| 78 | @ XXX fall through to common_invalid | ||
| 79 | @ | ||
| 80 | |||
| 81 | @ | ||
| 82 | @ common_invalid - generic code for failed exception (re-entrant version of handlers) | ||
| 83 | @ | ||
| 84 | common_invalid: | ||
| 85 | zero_fp | ||
| 86 | |||
| 87 | ldmia r0, {r4 - r6} | ||
| 88 | add r0, sp, #S_PC @ here for interlock avoidance | ||
| 89 | mov r7, #-1 @ "" "" "" "" | ||
| 90 | str r4, [sp] @ save preserved r0 | ||
| 91 | stmia r0, {r5 - r7} @ lr_<exception>, | ||
| 92 | @ cpsr_<exception>, "old_r0" | ||
| 50 | 93 | ||
| 51 | 1: zero_fp | ||
| 52 | ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0 | ||
| 53 | add r4, sp, #S_PC | ||
| 54 | stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 | ||
| 55 | mov r0, sp | 94 | mov r0, sp |
| 56 | and r2, r6, #31 @ int mode | 95 | and r2, r6, #0x1f |
| 57 | b bad_mode | 96 | b bad_mode |
| 58 | 97 | ||
| 59 | /* | 98 | /* |
| 60 | * SVC mode handlers | 99 | * SVC mode handlers |
| 61 | */ | 100 | */ |
| 62 | .macro svc_entry, sym | 101 | .macro svc_entry |
| 63 | sub sp, sp, #S_FRAME_SIZE | 102 | sub sp, sp, #S_FRAME_SIZE |
| 64 | stmia sp, {r0 - r12} @ save r0 - r12 | 103 | stmib sp, {r1 - r12} |
| 65 | ldr r2, .LC\sym | 104 | |
| 66 | add r0, sp, #S_FRAME_SIZE | 105 | ldmia r0, {r1 - r3} |
| 67 | ldmia r2, {r2 - r4} @ get pc, cpsr | 106 | add r5, sp, #S_SP @ here for interlock avoidance |
| 68 | add r5, sp, #S_SP | 107 | mov r4, #-1 @ "" "" "" "" |
| 108 | add r0, sp, #S_FRAME_SIZE @ "" "" "" "" | ||
| 109 | str r1, [sp] @ save the "real" r0 copied | ||
| 110 | @ from the exception stack | ||
| 111 | |||
| 69 | mov r1, lr | 112 | mov r1, lr |
| 70 | 113 | ||
| 71 | @ | 114 | @ |
| @@ -82,7 +125,7 @@ __und_invalid: | |||
| 82 | 125 | ||
| 83 | .align 5 | 126 | .align 5 |
| 84 | __dabt_svc: | 127 | __dabt_svc: |
| 85 | svc_entry abt | 128 | svc_entry |
| 86 | 129 | ||
| 87 | @ | 130 | @ |
| 88 | @ get ready to re-enable interrupts if appropriate | 131 | @ get ready to re-enable interrupts if appropriate |
| @@ -129,28 +172,24 @@ __dabt_svc: | |||
| 129 | 172 | ||
| 130 | .align 5 | 173 | .align 5 |
| 131 | __irq_svc: | 174 | __irq_svc: |
| 132 | svc_entry irq | 175 | svc_entry |
| 176 | |||
| 133 | #ifdef CONFIG_PREEMPT | 177 | #ifdef CONFIG_PREEMPT |
| 134 | get_thread_info r8 | 178 | get_thread_info tsk |
| 135 | ldr r9, [r8, #TI_PREEMPT] @ get preempt count | 179 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count |
| 136 | add r7, r9, #1 @ increment it | 180 | add r7, r8, #1 @ increment it |
| 137 | str r7, [r8, #TI_PREEMPT] | 181 | str r7, [tsk, #TI_PREEMPT] |
| 138 | #endif | 182 | #endif |
| 139 | 1: get_irqnr_and_base r0, r6, r5, lr | 183 | |
| 140 | movne r1, sp | 184 | irq_handler |
| 141 | @ | ||
| 142 | @ routine called with r0 = irq number, r1 = struct pt_regs * | ||
| 143 | @ | ||
| 144 | adrne lr, 1b | ||
| 145 | bne asm_do_IRQ | ||
| 146 | #ifdef CONFIG_PREEMPT | 185 | #ifdef CONFIG_PREEMPT |
| 147 | ldr r0, [r8, #TI_FLAGS] @ get flags | 186 | ldr r0, [tsk, #TI_FLAGS] @ get flags |
| 148 | tst r0, #_TIF_NEED_RESCHED | 187 | tst r0, #_TIF_NEED_RESCHED |
| 149 | blne svc_preempt | 188 | blne svc_preempt |
| 150 | preempt_return: | 189 | preempt_return: |
| 151 | ldr r0, [r8, #TI_PREEMPT] @ read preempt value | 190 | ldr r0, [tsk, #TI_PREEMPT] @ read preempt value |
| 191 | str r8, [tsk, #TI_PREEMPT] @ restore preempt count | ||
| 152 | teq r0, r7 | 192 | teq r0, r7 |
| 153 | str r9, [r8, #TI_PREEMPT] @ restore preempt count | ||
| 154 | strne r0, [r0, -r0] @ bug() | 193 | strne r0, [r0, -r0] @ bug() |
| 155 | #endif | 194 | #endif |
| 156 | ldr r0, [sp, #S_PSR] @ irqs are already disabled | 195 | ldr r0, [sp, #S_PSR] @ irqs are already disabled |
| @@ -161,7 +200,7 @@ preempt_return: | |||
| 161 | 200 | ||
| 162 | #ifdef CONFIG_PREEMPT | 201 | #ifdef CONFIG_PREEMPT |
| 163 | svc_preempt: | 202 | svc_preempt: |
| 164 | teq r9, #0 @ was preempt count = 0 | 203 | teq r8, #0 @ was preempt count = 0 |
| 165 | ldreq r6, .LCirq_stat | 204 | ldreq r6, .LCirq_stat |
| 166 | movne pc, lr @ no | 205 | movne pc, lr @ no |
| 167 | ldr r0, [r6, #4] @ local_irq_count | 206 | ldr r0, [r6, #4] @ local_irq_count |
| @@ -169,9 +208,9 @@ svc_preempt: | |||
| 169 | adds r0, r0, r1 | 208 | adds r0, r0, r1 |
| 170 | movne pc, lr | 209 | movne pc, lr |
| 171 | mov r7, #0 @ preempt_schedule_irq | 210 | mov r7, #0 @ preempt_schedule_irq |
| 172 | str r7, [r8, #TI_PREEMPT] @ expects preempt_count == 0 | 211 | str r7, [tsk, #TI_PREEMPT] @ expects preempt_count == 0 |
| 173 | 1: bl preempt_schedule_irq @ irq en/disable is done inside | 212 | 1: bl preempt_schedule_irq @ irq en/disable is done inside |
| 174 | ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS | 213 | ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS |
| 175 | tst r0, #_TIF_NEED_RESCHED | 214 | tst r0, #_TIF_NEED_RESCHED |
| 176 | beq preempt_return @ go again | 215 | beq preempt_return @ go again |
| 177 | b 1b | 216 | b 1b |
| @@ -179,7 +218,7 @@ svc_preempt: | |||
| 179 | 218 | ||
| 180 | .align 5 | 219 | .align 5 |
| 181 | __und_svc: | 220 | __und_svc: |
| 182 | svc_entry und | 221 | svc_entry |
| 183 | 222 | ||
| 184 | @ | 223 | @ |
| 185 | @ call emulation code, which returns using r9 if it has emulated | 224 | @ call emulation code, which returns using r9 if it has emulated |
| @@ -209,7 +248,7 @@ __und_svc: | |||
| 209 | 248 | ||
| 210 | .align 5 | 249 | .align 5 |
| 211 | __pabt_svc: | 250 | __pabt_svc: |
| 212 | svc_entry abt | 251 | svc_entry |
| 213 | 252 | ||
| 214 | @ | 253 | @ |
| 215 | @ re-enable interrupts if appropriate | 254 | @ re-enable interrupts if appropriate |
| @@ -242,12 +281,8 @@ __pabt_svc: | |||
| 242 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr | 281 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr |
| 243 | 282 | ||
| 244 | .align 5 | 283 | .align 5 |
| 245 | .LCirq: | 284 | .LCcralign: |
| 246 | .word __temp_irq | 285 | .word cr_alignment |
| 247 | .LCund: | ||
| 248 | .word __temp_und | ||
| 249 | .LCabt: | ||
| 250 | .word __temp_abt | ||
| 251 | #ifdef MULTI_ABORT | 286 | #ifdef MULTI_ABORT |
| 252 | .LCprocfns: | 287 | .LCprocfns: |
| 253 | .word processor | 288 | .word processor |
| @@ -262,12 +297,16 @@ __pabt_svc: | |||
| 262 | /* | 297 | /* |
| 263 | * User mode handlers | 298 | * User mode handlers |
| 264 | */ | 299 | */ |
| 265 | .macro usr_entry, sym | 300 | .macro usr_entry |
| 266 | sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go | 301 | sub sp, sp, #S_FRAME_SIZE |
| 267 | stmia sp, {r0 - r12} @ save r0 - r12 | 302 | stmib sp, {r1 - r12} |
| 268 | ldr r7, .LC\sym | 303 | |
| 269 | add r5, sp, #S_PC | 304 | ldmia r0, {r1 - r3} |
| 270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr | 305 | add r0, sp, #S_PC @ here for interlock avoidance |
| 306 | mov r4, #-1 @ "" "" "" "" | ||
| 307 | |||
| 308 | str r1, [sp] @ save the "real" r0 copied | ||
| 309 | @ from the exception stack | ||
| 271 | 310 | ||
| 272 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) | 311 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
| 273 | @ make sure our user space atomic helper is aborted | 312 | @ make sure our user space atomic helper is aborted |
| @@ -284,13 +323,13 @@ __pabt_svc: | |||
| 284 | @ | 323 | @ |
| 285 | @ Also, separately save sp_usr and lr_usr | 324 | @ Also, separately save sp_usr and lr_usr |
| 286 | @ | 325 | @ |
| 287 | stmia r5, {r2 - r4} | 326 | stmia r0, {r2 - r4} |
| 288 | stmdb r5, {sp, lr}^ | 327 | stmdb r0, {sp, lr}^ |
| 289 | 328 | ||
| 290 | @ | 329 | @ |
| 291 | @ Enable the alignment trap while in kernel mode | 330 | @ Enable the alignment trap while in kernel mode |
| 292 | @ | 331 | @ |
| 293 | alignment_trap r7, r0, __temp_\sym | 332 | alignment_trap r0 |
| 294 | 333 | ||
| 295 | @ | 334 | @ |
| 296 | @ Clear FP to mark the first stack frame | 335 | @ Clear FP to mark the first stack frame |
| @@ -300,7 +339,7 @@ __pabt_svc: | |||
| 300 | 339 | ||
| 301 | .align 5 | 340 | .align 5 |
| 302 | __dabt_usr: | 341 | __dabt_usr: |
| 303 | usr_entry abt | 342 | usr_entry |
| 304 | 343 | ||
| 305 | @ | 344 | @ |
| 306 | @ Call the processor-specific abort handler: | 345 | @ Call the processor-specific abort handler: |
| @@ -329,30 +368,23 @@ __dabt_usr: | |||
| 329 | 368 | ||
| 330 | .align 5 | 369 | .align 5 |
| 331 | __irq_usr: | 370 | __irq_usr: |
| 332 | usr_entry irq | 371 | usr_entry |
| 333 | 372 | ||
| 373 | get_thread_info tsk | ||
| 334 | #ifdef CONFIG_PREEMPT | 374 | #ifdef CONFIG_PREEMPT |
| 335 | get_thread_info r8 | 375 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count |
| 336 | ldr r9, [r8, #TI_PREEMPT] @ get preempt count | 376 | add r7, r8, #1 @ increment it |
| 337 | add r7, r9, #1 @ increment it | 377 | str r7, [tsk, #TI_PREEMPT] |
| 338 | str r7, [r8, #TI_PREEMPT] | ||
| 339 | #endif | 378 | #endif |
| 340 | 1: get_irqnr_and_base r0, r6, r5, lr | 379 | |
| 341 | movne r1, sp | 380 | irq_handler |
| 342 | adrne lr, 1b | ||
| 343 | @ | ||
| 344 | @ routine called with r0 = irq number, r1 = struct pt_regs * | ||
| 345 | @ | ||
| 346 | bne asm_do_IRQ | ||
| 347 | #ifdef CONFIG_PREEMPT | 381 | #ifdef CONFIG_PREEMPT |
| 348 | ldr r0, [r8, #TI_PREEMPT] | 382 | ldr r0, [tsk, #TI_PREEMPT] |
| 383 | str r8, [tsk, #TI_PREEMPT] | ||
| 349 | teq r0, r7 | 384 | teq r0, r7 |
| 350 | str r9, [r8, #TI_PREEMPT] | ||
| 351 | strne r0, [r0, -r0] | 385 | strne r0, [r0, -r0] |
| 352 | mov tsk, r8 | ||
| 353 | #else | ||
| 354 | get_thread_info tsk | ||
| 355 | #endif | 386 | #endif |
| 387 | |||
| 356 | mov why, #0 | 388 | mov why, #0 |
| 357 | b ret_to_user | 389 | b ret_to_user |
| 358 | 390 | ||
| @@ -360,7 +392,7 @@ __irq_usr: | |||
| 360 | 392 | ||
| 361 | .align 5 | 393 | .align 5 |
| 362 | __und_usr: | 394 | __und_usr: |
| 363 | usr_entry und | 395 | usr_entry |
| 364 | 396 | ||
| 365 | tst r3, #PSR_T_BIT @ Thumb mode? | 397 | tst r3, #PSR_T_BIT @ Thumb mode? |
| 366 | bne fpundefinstr @ ignore FP | 398 | bne fpundefinstr @ ignore FP |
| @@ -476,7 +508,7 @@ fpundefinstr: | |||
| 476 | 508 | ||
| 477 | .align 5 | 509 | .align 5 |
| 478 | __pabt_usr: | 510 | __pabt_usr: |
| 479 | usr_entry abt | 511 | usr_entry |
| 480 | 512 | ||
| 481 | enable_irq @ Enable interrupts | 513 | enable_irq @ Enable interrupts |
| 482 | mov r0, r2 @ address (pc) | 514 | mov r0, r2 @ address (pc) |
| @@ -741,29 +773,41 @@ __kuser_helper_end: | |||
| 741 | * | 773 | * |
| 742 | * Common stub entry macro: | 774 | * Common stub entry macro: |
| 743 | * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC | 775 | * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC |
| 776 | * | ||
| 777 | * SP points to a minimal amount of processor-private memory, the address | ||
| 778 | * of which is copied into r0 for the mode specific abort handler. | ||
| 744 | */ | 779 | */ |
| 745 | .macro vector_stub, name, sym, correction=0 | 780 | .macro vector_stub, name, correction=0 |
| 746 | .align 5 | 781 | .align 5 |
| 747 | 782 | ||
| 748 | vector_\name: | 783 | vector_\name: |
| 749 | ldr r13, .LCs\sym | ||
| 750 | .if \correction | 784 | .if \correction |
| 751 | sub lr, lr, #\correction | 785 | sub lr, lr, #\correction |
| 752 | .endif | 786 | .endif |
| 753 | str lr, [r13] @ save lr_IRQ | 787 | |
| 788 | @ | ||
| 789 | @ Save r0, lr_<exception> (parent PC) and spsr_<exception> | ||
| 790 | @ (parent CPSR) | ||
| 791 | @ | ||
| 792 | stmia sp, {r0, lr} @ save r0, lr | ||
| 754 | mrs lr, spsr | 793 | mrs lr, spsr |
| 755 | str lr, [r13, #4] @ save spsr_IRQ | 794 | str lr, [sp, #8] @ save spsr |
| 795 | |||
| 756 | @ | 796 | @ |
| 757 | @ now branch to the relevant MODE handling routine | 797 | @ Prepare for SVC32 mode. IRQs remain disabled. |
| 758 | @ | 798 | @ |
| 759 | mrs r13, cpsr | 799 | mrs r0, cpsr |
| 760 | bic r13, r13, #MODE_MASK | 800 | bic r0, r0, #MODE_MASK |
| 761 | orr r13, r13, #SVC_MODE | 801 | orr r0, r0, #SVC_MODE |
| 762 | msr spsr_cxsf, r13 @ switch to SVC_32 mode | 802 | msr spsr_cxsf, r0 |
| 763 | 803 | ||
| 764 | and lr, lr, #15 | 804 | @ |
| 805 | @ the branch table must immediately follow this code | ||
| 806 | @ | ||
| 807 | mov r0, sp | ||
| 808 | and lr, lr, #0x0f | ||
| 765 | ldr lr, [pc, lr, lsl #2] | 809 | ldr lr, [pc, lr, lsl #2] |
| 766 | movs pc, lr @ Changes mode and branches | 810 | movs pc, lr @ branch to handler in SVC mode |
| 767 | .endm | 811 | .endm |
| 768 | 812 | ||
| 769 | .globl __stubs_start | 813 | .globl __stubs_start |
| @@ -771,7 +815,7 @@ __stubs_start: | |||
| 771 | /* | 815 | /* |
| 772 | * Interrupt dispatcher | 816 | * Interrupt dispatcher |
| 773 | */ | 817 | */ |
| 774 | vector_stub irq, irq, 4 | 818 | vector_stub irq, 4 |
| 775 | 819 | ||
| 776 | .long __irq_usr @ 0 (USR_26 / USR_32) | 820 | .long __irq_usr @ 0 (USR_26 / USR_32) |
| 777 | .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) | 821 | .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -794,7 +838,7 @@ __stubs_start: | |||
| 794 | * Data abort dispatcher | 838 | * Data abort dispatcher |
| 795 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC | 839 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC |
| 796 | */ | 840 | */ |
| 797 | vector_stub dabt, abt, 8 | 841 | vector_stub dabt, 8 |
| 798 | 842 | ||
| 799 | .long __dabt_usr @ 0 (USR_26 / USR_32) | 843 | .long __dabt_usr @ 0 (USR_26 / USR_32) |
| 800 | .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) | 844 | .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -817,7 +861,7 @@ __stubs_start: | |||
| 817 | * Prefetch abort dispatcher | 861 | * Prefetch abort dispatcher |
| 818 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC | 862 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC |
| 819 | */ | 863 | */ |
| 820 | vector_stub pabt, abt, 4 | 864 | vector_stub pabt, 4 |
| 821 | 865 | ||
| 822 | .long __pabt_usr @ 0 (USR_26 / USR_32) | 866 | .long __pabt_usr @ 0 (USR_26 / USR_32) |
| 823 | .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) | 867 | .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -840,7 +884,7 @@ __stubs_start: | |||
| 840 | * Undef instr entry dispatcher | 884 | * Undef instr entry dispatcher |
| 841 | * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC | 885 | * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC |
| 842 | */ | 886 | */ |
| 843 | vector_stub und, und | 887 | vector_stub und |
| 844 | 888 | ||
| 845 | .long __und_usr @ 0 (USR_26 / USR_32) | 889 | .long __und_usr @ 0 (USR_26 / USR_32) |
| 846 | .long __und_invalid @ 1 (FIQ_26 / FIQ_32) | 890 | .long __und_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -894,13 +938,6 @@ vector_addrexcptn: | |||
| 894 | .LCvswi: | 938 | .LCvswi: |
| 895 | .word vector_swi | 939 | .word vector_swi |
| 896 | 940 | ||
| 897 | .LCsirq: | ||
| 898 | .word __temp_irq | ||
| 899 | .LCsund: | ||
| 900 | .word __temp_und | ||
| 901 | .LCsabt: | ||
| 902 | .word __temp_abt | ||
| 903 | |||
| 904 | .globl __stubs_end | 941 | .globl __stubs_end |
| 905 | __stubs_end: | 942 | __stubs_end: |
| 906 | 943 | ||
| @@ -922,23 +959,6 @@ __vectors_end: | |||
| 922 | 959 | ||
| 923 | .data | 960 | .data |
| 924 | 961 | ||
| 925 | /* | ||
| 926 | * Do not reorder these, and do not insert extra data between... | ||
| 927 | */ | ||
| 928 | |||
| 929 | __temp_irq: | ||
| 930 | .word 0 @ saved lr_irq | ||
| 931 | .word 0 @ saved spsr_irq | ||
| 932 | .word -1 @ old_r0 | ||
| 933 | __temp_und: | ||
| 934 | .word 0 @ Saved lr_und | ||
| 935 | .word 0 @ Saved spsr_und | ||
| 936 | .word -1 @ old_r0 | ||
| 937 | __temp_abt: | ||
| 938 | .word 0 @ Saved lr_abt | ||
| 939 | .word 0 @ Saved spsr_abt | ||
| 940 | .word -1 @ old_r0 | ||
| 941 | |||
| 942 | .globl cr_alignment | 962 | .globl cr_alignment |
| 943 | .globl cr_no_alignment | 963 | .globl cr_no_alignment |
| 944 | cr_alignment: | 964 | cr_alignment: |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index a3d40a0e2b04..afef21273963 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
| @@ -59,11 +59,10 @@ | |||
| 59 | mov \rd, \rd, lsl #13 | 59 | mov \rd, \rd, lsl #13 |
| 60 | .endm | 60 | .endm |
| 61 | 61 | ||
| 62 | .macro alignment_trap, rbase, rtemp, sym | 62 | .macro alignment_trap, rtemp |
| 63 | #ifdef CONFIG_ALIGNMENT_TRAP | 63 | #ifdef CONFIG_ALIGNMENT_TRAP |
| 64 | #define OFF_CR_ALIGNMENT(x) cr_alignment - x | 64 | ldr \rtemp, .LCcralign |
| 65 | 65 | ldr \rtemp, [\rtemp] | |
| 66 | ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)] | ||
| 67 | mcr p15, 0, \rtemp, c1, c0 | 66 | mcr p15, 0, \rtemp, c1, c0 |
| 68 | #endif | 67 | #endif |
| 69 | .endm | 68 | .endm |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c2a7da3ac0f1..7ecdda3f1253 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
| @@ -92,6 +92,14 @@ struct cpu_user_fns cpu_user; | |||
| 92 | struct cpu_cache_fns cpu_cache; | 92 | struct cpu_cache_fns cpu_cache; |
| 93 | #endif | 93 | #endif |
| 94 | 94 | ||
| 95 | struct stack { | ||
| 96 | u32 irq[3]; | ||
| 97 | u32 abt[3]; | ||
| 98 | u32 und[3]; | ||
| 99 | } ____cacheline_aligned; | ||
| 100 | |||
| 101 | static struct stack stacks[NR_CPUS]; | ||
| 102 | |||
| 95 | char elf_platform[ELF_PLATFORM_SIZE]; | 103 | char elf_platform[ELF_PLATFORM_SIZE]; |
| 96 | EXPORT_SYMBOL(elf_platform); | 104 | EXPORT_SYMBOL(elf_platform); |
| 97 | 105 | ||
| @@ -307,8 +315,6 @@ static void __init setup_processor(void) | |||
| 307 | cpu_name, processor_id, (int)processor_id & 15, | 315 | cpu_name, processor_id, (int)processor_id & 15, |
| 308 | proc_arch[cpu_architecture()]); | 316 | proc_arch[cpu_architecture()]); |
| 309 | 317 | ||
| 310 | dump_cpu_info(smp_processor_id()); | ||
| 311 | |||
| 312 | sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); | 318 | sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); |
| 313 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); | 319 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); |
| 314 | elf_hwcap = list->elf_hwcap; | 320 | elf_hwcap = list->elf_hwcap; |
| @@ -316,6 +322,46 @@ static void __init setup_processor(void) | |||
| 316 | cpu_proc_init(); | 322 | cpu_proc_init(); |
| 317 | } | 323 | } |
| 318 | 324 | ||
| 325 | /* | ||
| 326 | * cpu_init - initialise one CPU. | ||
| 327 | * | ||
| 328 | * cpu_init dumps the cache information, initialises SMP specific | ||
| 329 | * information, and sets up the per-CPU stacks. | ||
| 330 | */ | ||
| 331 | void __init cpu_init(void) | ||
| 332 | { | ||
| 333 | unsigned int cpu = smp_processor_id(); | ||
| 334 | struct stack *stk = &stacks[cpu]; | ||
| 335 | |||
| 336 | if (cpu >= NR_CPUS) { | ||
| 337 | printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); | ||
| 338 | BUG(); | ||
| 339 | } | ||
| 340 | |||
| 341 | dump_cpu_info(cpu); | ||
| 342 | |||
| 343 | /* | ||
| 344 | * setup stacks for re-entrant exception handlers | ||
| 345 | */ | ||
| 346 | __asm__ ( | ||
| 347 | "msr cpsr_c, %1\n\t" | ||
| 348 | "add sp, %0, %2\n\t" | ||
| 349 | "msr cpsr_c, %3\n\t" | ||
| 350 | "add sp, %0, %4\n\t" | ||
| 351 | "msr cpsr_c, %5\n\t" | ||
| 352 | "add sp, %0, %6\n\t" | ||
| 353 | "msr cpsr_c, %7" | ||
| 354 | : | ||
| 355 | : "r" (stk), | ||
| 356 | "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), | ||
| 357 | "I" (offsetof(struct stack, irq[0])), | ||
| 358 | "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE), | ||
| 359 | "I" (offsetof(struct stack, abt[0])), | ||
| 360 | "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), | ||
| 361 | "I" (offsetof(struct stack, und[0])), | ||
| 362 | "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); | ||
| 363 | } | ||
| 364 | |||
| 319 | static struct machine_desc * __init setup_machine(unsigned int nr) | 365 | static struct machine_desc * __init setup_machine(unsigned int nr) |
| 320 | { | 366 | { |
| 321 | struct machine_desc *list; | 367 | struct machine_desc *list; |
| @@ -715,6 +761,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 715 | paging_init(&meminfo, mdesc); | 761 | paging_init(&meminfo, mdesc); |
| 716 | request_standard_resources(&meminfo, mdesc); | 762 | request_standard_resources(&meminfo, mdesc); |
| 717 | 763 | ||
| 764 | cpu_init(); | ||
| 765 | |||
| 718 | /* | 766 | /* |
| 719 | * Set up various architecture-specific pointers | 767 | * Set up various architecture-specific pointers |
| 720 | */ | 768 | */ |
