@@ -446,258 +446,26 @@ 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
-
473
- 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
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
+ #ifdef CONFIG_FPE_NWFPE
458
+ adr r9 , ret_from_exception
459
+ bl call_fpe @ returns via R9 on success
503
460
#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
461
+ mov r1 , # 4 @ set insn size to 4 for ARM
462
+ 0 : mov r0 , sp
510
463
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
464
+ bl __und_fault
465
+ b ret_from_exception
531
466
UNWIND(.fnend)
532
467
ENDPROC(__und_usr)
533
468
534
- / *
535
- * The out of line fixup for the ldrt instructions above.
536
- * /
537
- .pushsection .text.fixup , "ax"
538
- . align 2
539
- 4 : str r4 , [ sp , #S_PC ] @ retry current instruction
540
- ret r9
541
- .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
-
550
- / *
551
- * Check whether the instruction is a co - processor instruction.
552
- * If yes , we need to call the relevant co - processor handler.
553
- *
554
- * Note th at we don't do a full check here for the co - processor
555
- * instructions ; all instructions with bit 27 set are well
556
- * defined. The only instructions th at should fault are the
557
- * co - processor instructions. However , we have to watch out
558
- * for the ARM6/ARM7 SWI bug.
559
- *
560
- * NEON is a special case th at has to be handled here. Not all
561
- * NEON instructions are co - processor instructions , so we have
562
- * to make a special case of checking for them. Plus , there's
563
- * five groups of them , so we have a table of mask/opcode pairs
564
- * to check against , and if any match then we branch off into the
565
- * NEON handler code.
566
- *
567
- * Emulators may wish to make use of the following registers:
568
- * r0 = instruction opcode ( 32 - bit ARM or two 16 - bit Thumb)
569
- * r2 = PC value to resume execution after successful emulation
570
- * r9 = normal "successful" return address
571
- * r10 = this threads thread_info structure
572
- * lr = unrecognised instruction return address
573
- * IRQs enabled , FIQs enabled.
574
- * /
575
- @
576
- @ Fall - through from Thumb - 2 __und_usr
577
- @
578
- #ifdef CONFIG_NEON
579
- get_thread_info r10 @ get current thread
580
- adr r6 , .LCneon_thumb_opcodes
581
- b 2f
582
- #endif
583
- call_fpe:
584
- get_thread_info r10 @ get current thread
585
- #ifdef CONFIG_NEON
586
- adr r6 , .LCneon_arm_opcodes
587
- 2 : ldr r5 , [ r6 ], # 4 @ mask value
588
- ldr r7 , [ r6 ], # 4 @ opcode bits matching in mask
589
- cmp r5 , # 0 @ end mask?
590
- beq 1f
591
- and r8 , r0 , r5
592
- cmp r8 , r7 @ NEON instruction?
593
- bne 2b
594
- mov r7 , # 1
595
- strb r7 , [ r10 , #TI_USED_CP + 10 ] @ mark CP# 10 as used
596
- strb r7 , [ r10 , #TI_USED_CP + 11 ] @ mark CP# 11 as used
597
- b do_vfp @ let VFP handler handle this
598
- 1 :
599
- #endif
600
- tst r0 , # 0x08000000 @ only CDP/CPRT/LDC/ STC have bit 27
601
- tstne r0 , # 0x04000000 @ bit 26 set on both ARM and Thumb - 2
602
- reteq lr
603
- and r8 , r0 , # 0x00000f00 @ mask out CP number
604
- mov r7 , # 1
605
- add r6 , r10 , r8 , lsr # 8 @ add used_cp [] array offset first
606
- strb r7 , [ r6 , #TI_USED_CP ] @ set appropriate used_cp []
607
- #ifdef CONFIG_IWMMXT
608
- @ Test if we need to give access to iWMMXt coprocessors
609
- ldr r5 , [ r10 , #TI_FLAGS ]
610
- rsbs r7 , r8 , #( 1 << 8 ) @ CP 0 or 1 only
611
- movscs r7 , r5 , lsr #(TIF_USING_IWMMXT + 1 )
612
- bcs iwmmxt_task_enable
613
- #endif
614
- ARM( add pc , pc , r8 , lsr # 6 )
615
- THUMB( lsr r8 , r8 , # 6 )
616
- THUMB( add pc , r8 )
617
- nop
618
-
619
- ret .w lr @ CP# 0
620
- W(b) do_fpe @ CP# 1 (FPE)
621
- W(b) do_fpe @ CP# 2 (FPE)
622
- ret .w lr @ CP# 3
623
- ret .w lr @ CP# 4
624
- ret .w lr @ CP# 5
625
- ret .w lr @ CP# 6
626
- ret .w lr @ CP# 7
627
- ret .w lr @ CP# 8
628
- ret .w lr @ CP# 9
629
- #ifdef CONFIG_VFP
630
- W(b) do_vfp @ CP# 10 (VFP)
631
- W(b) do_vfp @ CP# 11 (VFP)
632
- #else
633
- ret .w lr @ CP# 10 (VFP)
634
- ret .w lr @ CP# 11 (VFP)
635
- #endif
636
- ret .w lr @ CP# 12
637
- ret .w lr @ CP# 13
638
- ret .w lr @ CP# 14 (Debug)
639
- ret .w lr @ CP# 15 (Control)
640
-
641
- #ifdef CONFIG_NEON
642
- . align 6
643
-
644
- .LCneon_arm_opcodes:
645
- . word 0xfe000000 @ mask
646
- . word 0xf2000000 @ opcode
647
-
648
- . word 0xff100000 @ mask
649
- . word 0xf4000000 @ opcode
650
-
651
- . word 0x00000000 @ mask
652
- . word 0x00000000 @ opcode
653
-
654
- .LCneon_thumb_opcodes:
655
- . word 0xef000000 @ mask
656
- . word 0xef000000 @ opcode
657
-
658
- . word 0xff100000 @ mask
659
- . word 0xf9000000 @ opcode
660
-
661
- . word 0x00000000 @ mask
662
- . word 0x00000000 @ opcode
663
- #endif
664
-
665
- do_fpe:
666
- add r10 , r10 , #TI_FPSTATE @ r10 = workspace
667
- ldr_va pc , fp_enter , tmp=r4 @ Call FP module USR entry point
668
-
669
- / *
670
- * The FP module is called with these registers set:
671
- * r0 = instruction
672
- * r2 = PC + 4
673
- * r9 = normal "successful" return address
674
- * r10 = FP workspace
675
- * lr = unrecognised FP instruction return address
676
- * /
677
-
678
- .pushsection .data
679
- . align 2
680
- ENTRY(fp_enter)
681
- . word no_fp
682
- .popsection
683
-
684
- ENTRY(no_fp)
685
- ret lr
686
- ENDPROC(no_fp)
687
-
688
- __und_usr_fault_32:
689
- mov r1 , # 4
690
- b 1f
691
- __und_usr_fault_16_pan:
692
- uaccess_disable ip
693
- __und_usr_fault_16:
694
- mov r1 , # 2
695
- 1 : mov r0 , sp
696
- badr lr , ret_from_exception
697
- b __und_fault
698
- ENDPROC(__und_usr_fault_32)
699
- ENDPROC(__und_usr_fault_16)
700
-
701
469
. align 5
702
470
__pabt_usr:
703
471
usr_entry
0 commit comments