1/* 2 * linux/arch/arm/kernel/entry-armv.S 3 * 4 * Copyright (C) 1996,1997,1998 Russell King. 5 * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) 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 * Low-level vector interface routines 12 * 13 * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes 14 * it to save wrong values... Be aware! 15 */ 16#include <linux/config.h> 17 18#include <asm/memory.h> 19#include <asm/glue.h> 20#include <asm/vfpmacros.h> 21#include <asm/arch/entry-macro.S> 22 23#include "entry-header.S" 24 25/* 26 * Interrupt handling. Preserves r7, r8, r9 27 */ 28 .macro irq_handler 291: get_irqnr_and_base r0, r6, r5, lr 30 movne r1, sp 31 @ 32 @ routine called with r0 = irq number, r1 = struct pt_regs * 33 @ 34 adrne lr, 1b 35 bne asm_do_IRQ 36 37#ifdef CONFIG_SMP 38 /* 39 * XXX 40 * 41 * this macro assumes that irqstat (r6) and base (r5) are 42 * preserved from get_irqnr_and_base above 43 */ 44 test_for_ipi r0, r6, r5, lr 45 movne r0, sp 46 adrne lr, 1b 47 bne do_IPI 48 49#ifdef CONFIG_LOCAL_TIMERS 50 test_for_ltirq r0, r6, r5, lr 51 movne r0, sp 52 adrne lr, 1b 53 bne do_local_timer 54#endif 55#endif 56 57 .endm 58 59/* 60 * Invalid mode handlers 61 */ 62 .macro inv_entry, reason 63 sub sp, sp, #S_FRAME_SIZE 64 stmib sp, {r1 - lr} 65 mov r1, #\reason 66 .endm 67 68__pabt_invalid: 69 inv_entry BAD_PREFETCH 70 b common_invalid 71 72__dabt_invalid: 73 inv_entry BAD_DATA 74 b common_invalid 75 76__irq_invalid: 77 inv_entry BAD_IRQ 78 b common_invalid 79 80__und_invalid: 81 inv_entry BAD_UNDEFINSTR 82 83 @ 84 @ XXX fall through to common_invalid 85 @ 86 87@ 88@ common_invalid - generic code for failed exception (re-entrant version of handlers) 89@ 90common_invalid: 91 zero_fp 92 93 ldmia r0, {r4 - r6} 94 add r0, sp, #S_PC @ here for interlock avoidance 95 mov r7, #-1 @ "" "" "" "" 96 str r4, [sp] @ save preserved r0 97 stmia r0, {r5 - r7} @ lr_<exception>, 98 @ cpsr_<exception>, "old_r0" 99 100 mov r0, sp 101 and r2, r6, #0x1f 102 b bad_mode 103 104/* 105 * SVC mode handlers 106 */ 107 .macro svc_entry 108 sub sp, sp, #S_FRAME_SIZE 109 stmib sp, {r1 - r12} 110 111 ldmia r0, {r1 - r3} 112 add r5, sp, #S_SP @ here for interlock avoidance 113 mov r4, #-1 @ "" "" "" "" 114 add r0, sp, #S_FRAME_SIZE @ "" "" "" "" 115 str r1, [sp] @ save the "real" r0 copied 116 @ from the exception stack 117 118 mov r1, lr 119 120 @ 121 @ We are now ready to fill in the remaining blanks on the stack: 122 @ 123 @ r0 - sp_svc 124 @ r1 - lr_svc 125 @ r2 - lr_<exception>, already fixed up for correct return/restart 126 @ r3 - spsr_<exception> 127 @ r4 - orig_r0 (see pt_regs definition in ptrace.h) 128 @ 129 stmia r5, {r0 - r4} 130 .endm 131 132 .align 5 133__dabt_svc: 134 svc_entry 135 136 @ 137 @ get ready to re-enable interrupts if appropriate 138 @ 139 mrs r9, cpsr 140 tst r3, #PSR_I_BIT 141 biceq r9, r9, #PSR_I_BIT 142 143 @ 144 @ Call the processor-specific abort handler: 145 @ 146 @ r2 - aborted context pc 147 @ r3 - aborted context cpsr 148 @ 149 @ The abort handler must return the aborted address in r0, and 150 @ the fault status register in r1. r9 must be preserved. 151 @ 152#ifdef MULTI_ABORT 153 ldr r4, .LCprocfns 154 mov lr, pc 155 ldr pc, [r4] 156#else 157 bl CPU_ABORT_HANDLER 158#endif 159 160 @ 161 @ set desired IRQ state, then call main handler 162 @ 163 msr cpsr_c, r9 164 mov r2, sp 165 bl do_DataAbort 166 167 @ 168 @ IRQs off again before pulling preserved data off the stack 169 @ 170 disable_irq 171 172 @ 173 @ restore SPSR and restart the instruction 174 @ 175 ldr r0, [sp, #S_PSR] 176 msr spsr_cxsf, r0 177 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 178 179 .align 5 180__irq_svc: 181 svc_entry 182 183#ifdef CONFIG_PREEMPT 184 get_thread_info tsk 185 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 186 add r7, r8, #1 @ increment it 187 str r7, [tsk, #TI_PREEMPT] 188#endif 189 190 irq_handler 191#ifdef CONFIG_PREEMPT 192 ldr r0, [tsk, #TI_FLAGS] @ get flags 193 tst r0, #_TIF_NEED_RESCHED 194 blne svc_preempt 195preempt_return: 196 ldr r0, [tsk, #TI_PREEMPT] @ read preempt value 197 str r8, [tsk, #TI_PREEMPT] @ restore preempt count 198 teq r0, r7 199 strne r0, [r0, -r0] @ bug() 200#endif 201 ldr r0, [sp, #S_PSR] @ irqs are already disabled 202 msr spsr_cxsf, r0 203 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 204 205 .ltorg 206 207#ifdef CONFIG_PREEMPT 208svc_preempt: 209 teq r8, #0 @ was preempt count = 0 210 ldreq r6, .LCirq_stat 211 movne pc, lr @ no 212 ldr r0, [r6, #4] @ local_irq_count 213 ldr r1, [r6, #8] @ local_bh_count 214 adds r0, r0, r1 215 movne pc, lr 216 mov r7, #0 @ preempt_schedule_irq 217 str r7, [tsk, #TI_PREEMPT] @ expects preempt_count == 0 2181: bl preempt_schedule_irq @ irq en/disable is done inside 219 ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS 220 tst r0, #_TIF_NEED_RESCHED 221 beq preempt_return @ go again 222 b 1b 223#endif 224 225 .align 5 226__und_svc: 227 svc_entry 228 229 @ 230 @ call emulation code, which returns using r9 if it has emulated 231 @ the instruction, or the more conventional lr if we are to treat 232 @ this as a real undefined instruction 233 @ 234 @ r0 - instruction 235 @ 236 ldr r0, [r2, #-4] 237 adr r9, 1f 238 bl call_fpe 239 240 mov r0, sp @ struct pt_regs *regs 241 bl do_undefinstr 242 243 @ 244 @ IRQs off again before pulling preserved data off the stack 245 @ 2461: disable_irq 247 248 @ 249 @ restore SPSR and restart the instruction 250 @ 251 ldr lr, [sp, #S_PSR] @ Get SVC cpsr 252 msr spsr_cxsf, lr 253 ldmia sp, {r0 - pc}^ @ Restore SVC registers 254 255 .align 5 256__pabt_svc: 257 svc_entry 258 259 @ 260 @ re-enable interrupts if appropriate 261 @ 262 mrs r9, cpsr 263 tst r3, #PSR_I_BIT 264 biceq r9, r9, #PSR_I_BIT 265 msr cpsr_c, r9 266 267 @ 268 @ set args, then call main handler 269 @ 270 @ r0 - address of faulting instruction 271 @ r1 - pointer to registers on stack 272 @ 273 mov r0, r2 @ address (pc) 274 mov r1, sp @ regs 275 bl do_PrefetchAbort @ call abort handler 276 277 @ 278 @ IRQs off again before pulling preserved data off the stack 279 @ 280 disable_irq 281 282 @ 283 @ restore SPSR and restart the instruction 284 @ 285 ldr r0, [sp, #S_PSR] 286 msr spsr_cxsf, r0 287 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 288 289 .align 5 290.LCcralign: 291 .word cr_alignment 292#ifdef MULTI_ABORT 293.LCprocfns: 294 .word processor 295#endif 296.LCfp: 297 .word fp_enter 298#ifdef CONFIG_PREEMPT 299.LCirq_stat: 300 .word irq_stat 301#endif 302 303/* 304 * User mode handlers 305 */ 306 .macro usr_entry 307 sub sp, sp, #S_FRAME_SIZE 308 stmib sp, {r1 - r12} 309 310 ldmia r0, {r1 - r3} 311 add r0, sp, #S_PC @ here for interlock avoidance 312 mov r4, #-1 @ "" "" "" "" 313 314 str r1, [sp] @ save the "real" r0 copied 315 @ from the exception stack 316 317#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) 318 @ make sure our user space atomic helper is aborted 319 cmp r2, #TASK_SIZE 320 bichs r3, r3, #PSR_Z_BIT 321#endif 322 323 @ 324 @ We are now ready to fill in the remaining blanks on the stack: 325 @ 326 @ r2 - lr_<exception>, already fixed up for correct return/restart 327 @ r3 - spsr_<exception> 328 @ r4 - orig_r0 (see pt_regs definition in ptrace.h) 329 @ 330 @ Also, separately save sp_usr and lr_usr 331 @ 332 stmia r0, {r2 - r4} 333 stmdb r0, {sp, lr}^ 334 335 @ 336 @ Enable the alignment trap while in kernel mode 337 @ 338 alignment_trap r0 339 340 @ 341 @ Clear FP to mark the first stack frame 342 @ 343 zero_fp 344 .endm 345 346 .align 5 347__dabt_usr: 348 usr_entry 349 350 @ 351 @ Call the processor-specific abort handler: 352 @ 353 @ r2 - aborted context pc 354 @ r3 - aborted context cpsr 355 @ 356 @ The abort handler must return the aborted address in r0, and 357 @ the fault status register in r1. 358 @ 359#ifdef MULTI_ABORT 360 ldr r4, .LCprocfns 361 mov lr, pc 362 ldr pc, [r4] 363#else 364 bl CPU_ABORT_HANDLER 365#endif 366 367 @ 368 @ IRQs on, then call the main handler 369 @ 370 enable_irq 371 mov r2, sp 372 adr lr, ret_from_exception 373 b do_DataAbort 374 375 .align 5 376__irq_usr: 377 usr_entry 378 379 get_thread_info tsk 380#ifdef CONFIG_PREEMPT 381 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 382 add r7, r8, #1 @ increment it 383 str r7, [tsk, #TI_PREEMPT] 384#endif 385 386 irq_handler 387#ifdef CONFIG_PREEMPT 388 ldr r0, [tsk, #TI_PREEMPT] 389 str r8, [tsk, #TI_PREEMPT] 390 teq r0, r7 391 strne r0, [r0, -r0] 392#endif 393 394 mov why, #0 395 b ret_to_user 396 397 .ltorg 398 399 .align 5 400__und_usr: 401 usr_entry 402 403 tst r3, #PSR_T_BIT @ Thumb mode? 404 bne fpundefinstr @ ignore FP 405 sub r4, r2, #4 406 407 @ 408 @ fall through to the emulation code, which returns using r9 if 409 @ it has emulated the instruction, or the more conventional lr 410 @ if we are to treat this as a real undefined instruction 411 @ 412 @ r0 - instruction 413 @ 4141: ldrt r0, [r4] 415 adr r9, ret_from_exception 416 adr lr, fpundefinstr 417 @ 418 @ fallthrough to call_fpe 419 @ 420 421/* 422 * The out of line fixup for the ldrt above. 423 */ 424 .section .fixup, "ax" 4252: mov pc, r9 426 .previous 427 .section __ex_table,"a" 428 .long 1b, 2b 429 .previous 430 431/* 432 * Check whether the instruction is a co-processor instruction. 433 * If yes, we need to call the relevant co-processor handler. 434 * 435 * Note that we don't do a full check here for the co-processor 436 * instructions; all instructions with bit 27 set are well 437 * defined. The only instructions that should fault are the 438 * co-processor instructions. However, we have to watch out 439 * for the ARM6/ARM7 SWI bug. 440 * 441 * Emulators may wish to make use of the following registers: 442 * r0 = instruction opcode. 443 * r2 = PC+4 444 * r10 = this threads thread_info structure. 445 */ 446call_fpe: 447 tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 448#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) 449 and r8, r0, #0x0f000000 @ mask out op-code bits 450 teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)? 451#endif 452 moveq pc, lr 453 get_thread_info r10 @ get current thread 454 and r8, r0, #0x00000f00 @ mask out CP number 455 mov r7, #1 456 add r6, r10, #TI_USED_CP 457 strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[] 458#ifdef CONFIG_IWMMXT 459 @ Test if we need to give access to iWMMXt coprocessors 460 ldr r5, [r10, #TI_FLAGS] 461 rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only 462 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) 463 bcs iwmmxt_task_enable 464#endif 465 enable_irq 466 add pc, pc, r8, lsr #6 467 mov r0, r0 468 469 mov pc, lr @ CP#0 470 b do_fpe @ CP#1 (FPE) 471 b do_fpe @ CP#2 (FPE) 472 mov pc, lr @ CP#3 473 mov pc, lr @ CP#4 474 mov pc, lr @ CP#5 475 mov pc, lr @ CP#6 476 mov pc, lr @ CP#7 477 mov pc, lr @ CP#8 478 mov pc, lr @ CP#9 479#ifdef CONFIG_VFP 480 b do_vfp @ CP#10 (VFP) 481 b do_vfp @ CP#11 (VFP) 482#else 483 mov pc, lr @ CP#10 (VFP) 484 mov pc, lr @ CP#11 (VFP) 485#endif 486 mov pc, lr @ CP#12 487 mov pc, lr @ CP#13 488 mov pc, lr @ CP#14 (Debug) 489 mov pc, lr @ CP#15 (Control) 490 491do_fpe: 492 ldr r4, .LCfp 493 add r10, r10, #TI_FPSTATE @ r10 = workspace 494 ldr pc, [r4] @ Call FP module USR entry point 495 496/* 497 * The FP module is called with these registers set: 498 * r0 = instruction 499 * r2 = PC+4 500 * r9 = normal "successful" return address 501 * r10 = FP workspace 502 * lr = unrecognised FP instruction return address 503 */ 504 505 .data 506ENTRY(fp_enter) 507 .word fpundefinstr 508 .text 509 510fpundefinstr: 511 mov r0, sp 512 adr lr, ret_from_exception 513 b do_undefinstr 514 515 .align 5 516__pabt_usr: 517 usr_entry 518 519 enable_irq @ Enable interrupts 520 mov r0, r2 @ address (pc) 521 mov r1, sp @ regs 522 bl do_PrefetchAbort @ call abort handler 523 /* fall through */ 524/* 525 * This is the return code to user mode for abort handlers 526 */ 527ENTRY(ret_from_exception) 528 get_thread_info tsk 529 mov why, #0 530 b ret_to_user 531 532/* 533 * Register switch for ARMv3 and ARMv4 processors 534 * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info 535 * previous and next are guaranteed not to be the same. 536 */ 537ENTRY(__switch_to) 538 add ip, r1, #TI_CPU_SAVE 539 ldr r3, [r2, #TI_TP_VALUE] 540 stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack 541 ldr r6, [r2, #TI_CPU_DOMAIN]! 542#if __LINUX_ARM_ARCH__ >= 6 543#ifdef CONFIG_CPU_MPCORE 544 clrex 545#else 546 strex r5, r4, [ip] @ Clear exclusive monitor 547#endif 548#endif 549#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) 550 mra r4, r5, acc0 551 stmia ip, {r4, r5} 552#endif 553#if defined(CONFIG_HAS_TLS_REG) 554 mcr p15, 0, r3, c13, c0, 3 @ set TLS register 555#elif !defined(CONFIG_TLS_REG_EMUL) 556 mov r4, #0xffff0fff 557 str r3, [r4, #-15] @ TLS val at 0xffff0ff0 558#endif 559 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 560#ifdef CONFIG_VFP 561 @ Always disable VFP so we can lazily save/restore the old 562 @ state. This occurs in the context of the previous thread. 563 VFPFMRX r4, FPEXC 564 bic r4, r4, #FPEXC_ENABLE 565 VFPFMXR FPEXC, r4 566#endif 567#if defined(CONFIG_IWMMXT) 568 bl iwmmxt_task_switch 569#elif defined(CONFIG_CPU_XSCALE) 570 add r4, r2, #40 @ cpu_context_save->extra 571 ldmib r4, {r4, r5} 572 mar acc0, r4, r5 573#endif 574 ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously 575 576 __INIT 577 578/* 579 * User helpers. 580 * 581 * These are segment of kernel provided user code reachable from user space 582 * at a fixed address in kernel memory. This is used to provide user space 583 * with some operations which require kernel help because of unimplemented 584 * native feature and/or instructions in many ARM CPUs. The idea is for 585 * this code to be executed directly in user mode for best efficiency but 586 * which is too intimate with the kernel counter part to be left to user 587 * libraries. In fact this code might even differ from one CPU to another 588 * depending on the available instruction set and restrictions like on 589 * SMP systems. In other words, the kernel reserves the right to change 590 * this code as needed without warning. Only the entry points and their 591 * results are guaranteed to be stable. 592 * 593 * Each segment is 32-byte aligned and will be moved to the top of the high 594 * vector page. New segments (if ever needed) must be added in front of 595 * existing ones. This mechanism should be used only for things that are 596 * really small and justified, and not be abused freely. 597 * 598 * User space is expected to implement those things inline when optimizing 599 * for a processor that has the necessary native support, but only if such 600 * resulting binaries are already to be incompatible with earlier ARM 601 * processors due to the use of unsupported instructions other than what 602 * is provided here. In other words don't make binaries unable to run on 603 * earlier processors just for the sake of not using these kernel helpers 604 * if your compiled code is not going to use the new instructions for other 605 * purpose. 606 */ 607 608 .align 5 609 .globl __kuser_helper_start 610__kuser_helper_start: 611 612/* 613 * Reference prototype: 614 * 615 * void __kernel_memory_barrier(void) 616 * 617 * Input: 618 * 619 * lr = return address 620 * 621 * Output: 622 * 623 * none 624 * 625 * Clobbered: 626 * 627 * the Z flag might be lost 628 * 629 * Definition and user space usage example: 630 * 631 * typedef void (__kernel_dmb_t)(void); 632 * #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0) 633 * 634 * Apply any needed memory barrier to preserve consistency with data modified 635 * manually and __kuser_cmpxchg usage. 636 * 637 * This could be used as follows: 638 * 639 * #define __kernel_dmb() \ 640 * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ 641 * : : : "lr","cc" ) 642 */ 643 644__kuser_memory_barrier: @ 0xffff0fa0 645 646#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP) 647 mcr p15, 0, r0, c7, c10, 5 @ dmb 648#endif 649 mov pc, lr 650 651 .align 5 652 653/* 654 * Reference prototype: 655 * 656 * int __kernel_cmpxchg(int oldval, int newval, int *ptr) 657 * 658 * Input: 659 * 660 * r0 = oldval 661 * r1 = newval 662 * r2 = ptr 663 * lr = return address 664 * 665 * Output: 666 * 667 * r0 = returned value (zero or non-zero) 668 * C flag = set if r0 == 0, clear if r0 != 0 669 * 670 * Clobbered: 671 * 672 * r3, ip, flags 673 * 674 * Definition and user space usage example: 675 * 676 * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); 677 * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) 678 * 679 * Atomically store newval in *ptr if *ptr is equal to oldval for user space. 680 * Return zero if *ptr was changed or non-zero if no exchange happened. 681 * The C flag is also set if *ptr was changed to allow for assembly 682 * optimization in the calling code. 683 * 684 * Note: this routine already includes memory barriers as needed. 685 * 686 * For example, a user space atomic_add implementation could look like this: 687 * 688 * #define atomic_add(ptr, val) \ 689 * ({ register unsigned int *__ptr asm("r2") = (ptr); \ 690 * register unsigned int __result asm("r1"); \ 691 * asm volatile ( \ 692 * "1: @ atomic_add\n\t" \ 693 * "ldr r0, [r2]\n\t" \ 694 * "mov r3, #0xffff0fff\n\t" \ 695 * "add lr, pc, #4\n\t" \ 696 * "add r1, r0, %2\n\t" \ 697 * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \ 698 * "bcc 1b" \ 699 * : "=&r" (__result) \ 700 * : "r" (__ptr), "rIL" (val) \ 701 * : "r0","r3","ip","lr","cc","memory" ); \ 702 * __result; }) 703 */ 704 705__kuser_cmpxchg: @ 0xffff0fc0 706 707#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) 708 709 /* 710 * Poor you. No fast solution possible... 711 * The kernel itself must perform the operation. 712 * A special ghost syscall is used for that (see traps.c). 713 */ 714 swi #0x9ffff0 715 mov pc, lr 716 717#elif __LINUX_ARM_ARCH__ < 6 718 719 /* 720 * Theory of operation: 721 * 722 * We set the Z flag before loading oldval. If ever an exception 723 * occurs we can not be sure the loaded value will still be the same 724 * when the exception returns, therefore the user exception handler 725 * will clear the Z flag whenever the interrupted user code was 726 * actually from the kernel address space (see the usr_entry macro). 727 * 728 * The post-increment on the str is used to prevent a race with an 729 * exception happening just after the str instruction which would 730 * clear the Z flag although the exchange was done. 731 */ 732 teq ip, ip @ set Z flag 733 ldr ip, [r2] @ load current val 734 add r3, r2, #1 @ prepare store ptr 735 teqeq ip, r0 @ compare with oldval if still allowed 736 streq r1, [r3, #-1]! @ store newval if still allowed 737 subs r0, r2, r3 @ if r2 == r3 the str occured 738 mov pc, lr 739 740#else 741 742#ifdef CONFIG_SMP 743 mcr p15, 0, r0, c7, c10, 5 @ dmb 744#endif 745 ldrex r3, [r2] 746 subs r3, r3, r0 747 strexeq r3, r1, [r2] 748 rsbs r0, r3, #0 749#ifdef CONFIG_SMP 750 mcr p15, 0, r0, c7, c10, 5 @ dmb 751#endif 752 mov pc, lr 753 754#endif 755 756 .align 5 757 758/* 759 * Reference prototype: 760 * 761 * int __kernel_get_tls(void) 762 * 763 * Input: 764 * 765 * lr = return address 766 * 767 * Output: 768 * 769 * r0 = TLS value 770 * 771 * Clobbered: 772 * 773 * the Z flag might be lost 774 * 775 * Definition and user space usage example: 776 * 777 * typedef int (__kernel_get_tls_t)(void); 778 * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0) 779 * 780 * Get the TLS value as previously set via the __ARM_NR_set_tls syscall. 781 * 782 * This could be used as follows: 783 * 784 * #define __kernel_get_tls() \ 785 * ({ register unsigned int __val asm("r0"); \ 786 * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \ 787 * : "=r" (__val) : : "lr","cc" ); \ 788 * __val; }) 789 */ 790 791__kuser_get_tls: @ 0xffff0fe0 792 793#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) 794 795 ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 796 mov pc, lr 797 798#else 799 800 mrc p15, 0, r0, c13, c0, 3 @ read TLS register 801 mov pc, lr 802 803#endif 804 805 .rep 5 806 .word 0 @ pad up to __kuser_helper_version 807 .endr 808 809/* 810 * Reference declaration: 811 * 812 * extern unsigned int __kernel_helper_version; 813 * 814 * Definition and user space usage example: 815 * 816 * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc) 817 * 818 * User space may read this to determine the curent number of helpers 819 * available. 820 */ 821 822__kuser_helper_version: @ 0xffff0ffc 823 .word ((__kuser_helper_end - __kuser_helper_start) >> 5) 824 825 .globl __kuser_helper_end 826__kuser_helper_end: 827 828 829/* 830 * Vector stubs. 831 * 832 * This code is copied to 0xffff0200 so we can use branches in the 833 * vectors, rather than ldr's. Note that this code must not 834 * exceed 0x300 bytes. 835 * 836 * Common stub entry macro: 837 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC 838 * 839 * SP points to a minimal amount of processor-private memory, the address 840 * of which is copied into r0 for the mode specific abort handler. 841 */ 842 .macro vector_stub, name, mode, correction=0 843 .align 5 844 845vector_\name: 846 .if \correction 847 sub lr, lr, #\correction 848 .endif 849 850 @ 851 @ Save r0, lr_<exception> (parent PC) and spsr_<exception> 852 @ (parent CPSR) 853 @ 854 stmia sp, {r0, lr} @ save r0, lr 855 mrs lr, spsr 856 str lr, [sp, #8] @ save spsr 857 858 @ 859 @ Prepare for SVC32 mode. IRQs remain disabled. 860 @ 861 mrs r0, cpsr 862 eor r0, r0, #(\mode ^ SVC_MODE) 863 msr spsr_cxsf, r0 864 865 @ 866 @ the branch table must immediately follow this code 867 @ 868 and lr, lr, #0x0f 869 mov r0, sp 870 ldr lr, [pc, lr, lsl #2] 871 movs pc, lr @ branch to handler in SVC mode 872 .endm 873 874 .globl __stubs_start 875__stubs_start: 876/* 877 * Interrupt dispatcher 878 */ 879 vector_stub irq, IRQ_MODE, 4 880 881 .long __irq_usr @ 0 (USR_26 / USR_32) 882 .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) 883 .long __irq_invalid @ 2 (IRQ_26 / IRQ_32) 884 .long __irq_svc @ 3 (SVC_26 / SVC_32) 885 .long __irq_invalid @ 4 886 .long __irq_invalid @ 5 887 .long __irq_invalid @ 6 888 .long __irq_invalid @ 7 889 .long __irq_invalid @ 8 890 .long __irq_invalid @ 9 891 .long __irq_invalid @ a 892 .long __irq_invalid @ b 893 .long __irq_invalid @ c 894 .long __irq_invalid @ d 895 .long __irq_invalid @ e 896 .long __irq_invalid @ f 897 898/* 899 * Data abort dispatcher 900 * Enter in ABT mode, spsr = USR CPSR, lr = USR PC 901 */ 902 vector_stub dabt, ABT_MODE, 8 903 904 .long __dabt_usr @ 0 (USR_26 / USR_32) 905 .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) 906 .long __dabt_invalid @ 2 (IRQ_26 / IRQ_32) 907 .long __dabt_svc @ 3 (SVC_26 / SVC_32) 908 .long __dabt_invalid @ 4 909 .long __dabt_invalid @ 5 910 .long __dabt_invalid @ 6 911 .long __dabt_invalid @ 7 912 .long __dabt_invalid @ 8 913 .long __dabt_invalid @ 9 914 .long __dabt_invalid @ a 915 .long __dabt_invalid @ b 916 .long __dabt_invalid @ c 917 .long __dabt_invalid @ d 918 .long __dabt_invalid @ e 919 .long __dabt_invalid @ f 920 921/* 922 * Prefetch abort dispatcher 923 * Enter in ABT mode, spsr = USR CPSR, lr = USR PC 924 */ 925 vector_stub pabt, ABT_MODE, 4 926 927 .long __pabt_usr @ 0 (USR_26 / USR_32) 928 .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) 929 .long __pabt_invalid @ 2 (IRQ_26 / IRQ_32) 930 .long __pabt_svc @ 3 (SVC_26 / SVC_32) 931 .long __pabt_invalid @ 4 932 .long __pabt_invalid @ 5 933 .long __pabt_invalid @ 6 934 .long __pabt_invalid @ 7 935 .long __pabt_invalid @ 8 936 .long __pabt_invalid @ 9 937 .long __pabt_invalid @ a 938 .long __pabt_invalid @ b 939 .long __pabt_invalid @ c 940 .long __pabt_invalid @ d 941 .long __pabt_invalid @ e 942 .long __pabt_invalid @ f 943 944/* 945 * Undef instr entry dispatcher 946 * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC 947 */ 948 vector_stub und, UND_MODE 949 950 .long __und_usr @ 0 (USR_26 / USR_32) 951 .long __und_invalid @ 1 (FIQ_26 / FIQ_32) 952 .long __und_invalid @ 2 (IRQ_26 / IRQ_32) 953 .long __und_svc @ 3 (SVC_26 / SVC_32) 954 .long __und_invalid @ 4 955 .long __und_invalid @ 5 956 .long __und_invalid @ 6 957 .long __und_invalid @ 7 958 .long __und_invalid @ 8 959 .long __und_invalid @ 9 960 .long __und_invalid @ a 961 .long __und_invalid @ b 962 .long __und_invalid @ c 963 .long __und_invalid @ d 964 .long __und_invalid @ e 965 .long __und_invalid @ f 966 967 .align 5 968 969/*============================================================================= 970 * Undefined FIQs 971 *----------------------------------------------------------------------------- 972 * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC 973 * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg. 974 * Basically to switch modes, we *HAVE* to clobber one register... brain 975 * damage alert! I don't think that we can execute any code in here in any 976 * other mode than FIQ... Ok you can switch to another mode, but you can't 977 * get out of that mode without clobbering one register. 978 */ 979vector_fiq: 980 disable_fiq 981 subs pc, lr, #4 982 983/*============================================================================= 984 * Address exception handler 985 *----------------------------------------------------------------------------- 986 * These aren't too critical. 987 * (they're not supposed to happen, and won't happen in 32-bit data mode). 988 */ 989 990vector_addrexcptn: 991 b vector_addrexcptn 992 993/* 994 * We group all the following data together to optimise 995 * for CPUs with separate I & D caches. 996 */ 997 .align 5 998 999.LCvswi: 1000 .word vector_swi 1001 1002 .globl __stubs_end 1003__stubs_end: 1004 1005 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start 1006 1007 .globl __vectors_start 1008__vectors_start: 1009 swi SYS_ERROR0 1010 b vector_und + stubs_offset 1011 ldr pc, .LCvswi + stubs_offset 1012 b vector_pabt + stubs_offset 1013 b vector_dabt + stubs_offset 1014 b vector_addrexcptn + stubs_offset 1015 b vector_irq + stubs_offset 1016 b vector_fiq + stubs_offset 1017 1018 .globl __vectors_end 1019__vectors_end: 1020 1021 .data 1022 1023 .globl cr_alignment 1024 .globl cr_no_alignment 1025cr_alignment: 1026 .space 4 1027cr_no_alignment: 1028 .space 4 1029