@@ -446,258 +446,26 @@ ENDPROC(__irq_usr)
446446__und_usr:
447447 usr_entry uaccess= 0
448448
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-
462449 @ IRQs must be enabled before attempting to read the instruction from
463450 @ user space since th at could cause a page/translation fault if the
464451 @ page table was modified by another CPU .
465452 enable_irq
466453
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
503460#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
510463 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
531466 UNWIND(.fnend)
532467ENDPROC(__und_usr)
533468
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-
701469 . align 5
702470__pabt_usr:
703471 usr_entry
0 commit comments