@@ -446,106 +446,32 @@ ENDPROC(__irq_usr)
446
446
__und_usr:
447
447
usr_entry uaccess= 0
448
448
449
- mov r2 , r4
450
- mov r3 , r5
451
-
452
- @ r2 = regs - >ARM_pc , which is either 2 or 4 bytes ahead of the
453
- @ faulting instruction depending on Thumb mode.
454
- @ r3 = regs - >ARM_cpsr
455
- @
456
- @ The emulation code returns using r9 if it has emulated the
457
- @ instruction , or the more conventional lr if we are to tre at
458
- @ this as a real undefined instruction
459
- @
460
- badr r9 , ret_from_exception
461
-
462
449
@ IRQs must be enabled before attempting to read the instruction from
463
450
@ user space since th at could cause a page/translation fault if the
464
451
@ page table was modified by another CPU .
465
452
enable_irq
466
453
467
- tst r3 , #PSR_T_BIT @ Thumb mode?
468
- bne __und_usr_thumb
469
- sub r4 , r2 , # 4 @ ARM instr at LR - 4
470
- 1 : ldrt r0 , [ r4 ]
471
- ARM_BE8(rev r0 , r0) @ little endian instruction
472
-
454
+ tst r5 , #PSR_T_BIT @ Thumb mode?
455
+ mov r1 , # 2 @ set insn size to 2 for Thumb
456
+ bne 0f @ handle as Thumb undef exception
457
+ adr r9 , ret_from_exception
458
+ bl call_fpe @ returns via R9 on success
459
+ mov r1 , # 4 @ set insn size to 4 for ARM
460
+ 0 : mov r0 , sp
473
461
uaccess_disable ip
474
-
475
- @ r0 = 32 - bit ARM instruction which caused the exception
476
- @ r2 = PC value for the following instruction (:= regs - >ARM_pc)
477
- @ r4 = PC value for the faulting instruction
478
- @ lr = 32 - bit undefined instruction function
479
- badr lr , __und_usr_fault_32
480
- b call_fpe
481
-
482
- __und_usr_thumb:
483
- @ Thumb instruction
484
- sub r4 , r2 , # 2 @ First half of thumb instr at LR - 2
485
- #if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
486
- / *
487
- * Thumb - 2 instruction handling. Note th at because pre - v6 and >= v6 platforms
488
- * can never be supported in a single kernel , this code is not applicable at
489
- * all when __LINUX_ARM_ARCH__ < 6 . This allows simplifying assumptions to be
490
- * made about .arch directives.
491
- * /
492
- #if __LINUX_ARM_ARCH__ < 7
493
- / * If the target CPU may not be Thumb - 2 - capable , a run - time check is needed: * /
494
- ldr_va r5 , cpu_architecture
495
- cmp r5 , #CPU_ARCH_ARMv7
496
- blo __und_usr_fault_16 @ 16bit undefined instruction
497
- / *
498
- * The following code won't get run unless the running CPU really is v7 , so
499
- * coding round the lack of ldrht on older arches is pointless. Temporarily
500
- * override the assembler target arch with the minimum required instead:
501
- * /
502
- .arch armv6t2
503
- #endif
504
- 2 : ldrht r5 , [ r4 ]
505
- ARM_BE8(rev16 r5 , r5) @ little endian instruction
506
- cmp r5 , # 0xe800 @ 32bit instruction if xx != 0
507
- blo __und_usr_fault_16_pan @ 16bit undefined instruction
508
- 3 : ldrht r0 , [ r2 ]
509
- ARM_BE8(rev16 r0 , r0) @ little endian instruction
510
- uaccess_disable ip
511
- add r2 , r2 , # 2 @ r2 is PC + 2 , make it PC + 4
512
- str r2 , [ sp , #S_PC ] @ it's a 2x16bit instr , update
513
- orr r0 , r0 , r5 , lsl # 16
514
- badr lr , __und_usr_fault_32
515
- @ r0 = the two 16 - bit Thumb instructions which caused the exception
516
- @ r2 = PC value for the following Thumb instruction (:= regs - >ARM_pc)
517
- @ r4 = PC value for the first 16 - bit Thumb instruction
518
- @ lr = 32bit undefined instruction function
519
-
520
- #if __LINUX_ARM_ARCH__ < 7
521
- / * If the target arch was overridden , change it back: * /
522
- #ifdef CONFIG_CPU_32v6K
523
- .arch armv6k
524
- #else
525
- .arch armv6
526
- #endif
527
- #endif / * __LINUX_ARM_ARCH__ < 7 * /
528
- #else / * !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) * /
529
- b __und_usr_fault_16
530
- #endif
462
+ bl __und_fault
463
+ b ret_from_exception
531
464
UNWIND(.fnend)
532
465
ENDPROC(__und_usr)
533
466
534
467
/ *
535
- * The out of line fixup for the ldrt instructions above .
468
+ * The out of line fixup for the ldrt instruction below .
536
469
* /
537
470
.pushsection .text.fixup , "ax"
538
471
. align 2
539
472
4 : str r4 , [ sp , #S_PC ] @ retry current instruction
540
473
ret r9
541
474
.popsection
542
- .pushsection __ex_table , "a"
543
- .long 1b , 4b
544
- #if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
545
- .long 2b , 4b
546
- .long 3b , 4b
547
- #endif
548
- .popsection
549
475
550
476
/ *
551
477
* Check whether the instruction is a co - processor instruction.
@@ -558,20 +484,22 @@ ENDPROC(__und_usr)
558
484
* for the ARM6/ARM7 SWI bug.
559
485
*
560
486
* Emulators may wish to make use of the following registers:
561
- * r0 = instruction opcode ( 32 - bit ARM or two 16 - bit Thumb)
562
- * r2 = PC value to resume execution after successful emulation
487
+ * r4 = PC value to resume execution after successful emulation
563
488
* r9 = normal "successful" return address
564
489
* r10 = this threads thread_info structure
565
490
* lr = unrecognised instruction return address
566
491
* IRQs enabled , FIQs enabled.
567
492
* /
568
- @
569
- @ Fall - through from Thumb - 2 __und_usr
570
- @
571
493
call_fpe:
494
+ mov r2 , r4
495
+ sub r4 , r4 , # 4 @ ARM instruction at user PC - 4
496
+ USERL( 4b , ldrt r0 , [ r4 ] ) @ load opcode from user space
497
+ ARM_BE8(rev r0 , r0) @ little endian instruction
498
+
499
+ uaccess_disable ip
500
+
572
501
get_thread_info r10 @ get current thread
573
502
tst r0 , # 0x08000000 @ only CDP/CPRT/LDC/ STC have bit 27
574
- tstne r0 , # 0x04000000 @ bit 26 set on both ARM and Thumb - 2
575
503
reteq lr
576
504
and r8 , r0 , # 0x00000f00 @ mask out CP number
577
505
#ifdef CONFIG_IWMMXT
@@ -626,19 +554,6 @@ ENTRY(no_fp)
626
554
ret lr
627
555
ENDPROC(no_fp)
628
556
629
- __und_usr_fault_32:
630
- mov r1 , # 4
631
- b 1f
632
- __und_usr_fault_16_pan:
633
- uaccess_disable ip
634
- __und_usr_fault_16:
635
- mov r1 , # 2
636
- 1 : mov r0 , sp
637
- badr lr , ret_from_exception
638
- b __und_fault
639
- ENDPROC(__und_usr_fault_32)
640
- ENDPROC(__und_usr_fault_16)
641
-
642
557
. align 5
643
558
__pabt_usr:
644
559
usr_entry
0 commit comments