⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlundef.s

📁 realview22.rar
💻 S
📖 第 1 页 / 共 2 页
字号:
;*
;* tlundef.s: Top-level undefined instruction handler.
;* supervisor stack version
;* Copyright (C) ARM Limited, 1998-2002. All rights reserved.
;*

;* This file contains the first layer of the undefined instruction handler
;* used for the VFP support code. It is responsible for:
;*
;*    - Preserving the ARM processor state.
;*    - Decoding the instruction sufficiently to determine whether it is a
;*      coprocessor instruction, and if so, for what coprocessor.
;*    - Calling a second layer handler for the correct coprocessor (or for
;*      genuine undefined instructions) with the instruction and (a
;*      sufficient amount of) the ARM processor state as parameters.
;*      The prototype for this call is defined in the file "slundef.h".
;*    - On return from the second layer, restoring the ARM processor state
;*      (which may have been modified by emulation of the instruction) and
;*      resuming execution of the original program at an address specified
;*      by the second layer. (This allows the second layer to determine
;*      whether the original instruction should be retried.)

;* CHANGES
;* 0. initial implementation

; Definitions of some important PSR bits:

Flags_mask      EQU     0xF8000000

Java_bit        EQU     0x01000000
Endian_bit      EQU     0x200
Idisable_bit    EQU     0x80
Fdisable_bit    EQU     0x40
Thumb_bit       EQU     0x20

Mode_mask       EQU     0x1F

Mode_Usr32      EQU     0x10
Mode_Svc        EQU     0x13
Mode_Undef      EQU     0x1b

        GBLL ARCH_V6_OR_LATER
  if "6" <= {ARCHITECTURE} ; ok until architecture 10
ARCH_V6_OR_LATER SETL {TRUE}
  else
ARCH_V6_OR_LATER SETL {FALSE}
  endif

        GBLL ARCH_HAS_THUMB2
  if "6T2" <= {ARCHITECTURE} ; ok until architecture 10
ARCH_HAS_THUMB2  SETL {TRUE}
  else
ARCH_HAS_THUMB2  SETL {FALSE}
  endif

        GBLL V6_ENDIAN_SWAP
  if ARCH_V6_OR_LATER :LAND: {ENDIAN} = "big" :LAND: :LNOT: :DEF: ENDIAN_BE_32
V6_ENDIAN_SWAP SETL {TRUE}
  else
V6_ENDIAN_SWAP SETL {FALSE}
  endif


        IMPORT Unknown_Thumb_Handler
        IMPORT Unknown_Java_Handler
        IMPORT Unknown_ARM_Handler

; Main entry point - should be branched to directly from the hardware
; undefined instruction vector.

        AREA    |TLUndef$$code|, CODE, READONLY

        PRESERVE8

TLUndef_Handler
        EXPORT TLUndef_Handler

; On entry the core is in Undef mode with IRQs disabled
; The return state is saved in R14_und and SPSR_und

; Save two registers on the Undef stack to make some workspace,
; and then switch to Supervisor Mode with IRQ enable restored.

                STMDB   R13!,{R0,R1}
                MRS     R0,CPSR
                MRS     R1,SPSR
                ASSERT  Mode_Svc = (Mode_Undef :AND: :NOT: 8)
                BIC     R0,R0,#(Idisable_bit :OR: 8)
                AND     R1,R1,#Idisable_bit
                ORR     R0,R0,R1
                MSR     CPSR_c,R0

; Start constructing the register dump by reserving space on the stack.
; Save the unbanked registers R2-R7.
; Reserve space also for R14_svc and SPSR_svc.

                SUB     R13,R13,#9*4    ; R8-R14,PC,CPSR
                STMDB   R13!,{R2-R7}
                SUB     R13,R13,#4*4    ; R14_svc,SPSR_svc,R0,R1
                ADD     R4,R13,#17*4    ; R4 -> PC,CPSR

                BIC     R13,R13,#7      ; Force 8-byte stack alignment

; Then switch back to Undef mode.

                ORR     R1,R0,#8
                MSR     CPSR_c,R1

; Pop the saved R0,R1 from the Undef stack, into unbanked R2,R3.
; Copy R14_und to unbanked R6, and SPSR_und to R7.

                LDMIA   R13!,{R2,R3}  ; pop saved values of R0,R1
                MOV     R6,R14
                MRS     R7,SPSR

; Return to Supervisor Mode.
; Copy the saved values of R0,R1 to the register dump

                MSR     CPSR_c,R0
                STR     R2,[R4,#-15*4]
                STR     R3,[R4,#-14*4]

; At this point:
;   R4 -> final 2 words of register dump (just above banked registers)
;   R6 contains the original R14_undef value, and
;   R7 contains the original SPSR_undef value
;   R0 contains the current CPSR


; Now the banked registers. The strategy for this depends on whether
; we were called from a user mode: if so, we use a "user mode STM";
; otherwise, we must switch to a sanitised version of the mode we were
; called from (to be found in the SPSR), store the registers and switch
; back. "Sanitised" means that we must not unintentionally switch into
; Thumb state or Java state.
; Note: If called from Supervisor Mode this will save the current R13.

                AND     R5,R7,#Mode_mask

; At this point:
;   R0 = the current CPSR
;   R4 -> final 2 words of register dump (just above banked registers)
;   R5 = the Mode_mask bits of SPSR_und
;   R6 = R14_und value
;   R7 = SPSR_und value

                TEQ     R5,#Mode_Usr32
                STMEQDB R4,{R8-R14}^            ; User mode case
                BEQ     BankedSaveDone

                BIC     R2,R0,#Mode_mask        ; Non-user mode case
                ORR     R2,R2,R5
                MSR     CPSR_c,R2
                STMDB   R4,{R8-R14}
                MSR     CPSR_c,R0

BankedSaveDone

; Finish the register dump construction by synthesising R15 and CPSR
; values (= address of undefined instruction plus 8 for ARM, 4 for Thumb,
; and SPSR_und)
; and storing them.

                TST     R7, #Thumb_bit
                ADDEQ   R1,R6,#4
                ADDNE   R1,R6,#2
                STMIA   R4,{R1,R7}

; Finally save the Supervisor Mode R14 and SPSR on the stack.

                STR     R14,[R4,#-17*4]
                MRS     R14,SPSR
                STR     R14,[R4,#-16*4]

; Prepare for a call to a handler function

                SUB     R1,R4,#15*4             ;R1 -> register dump
                ADR     R14,ReturnFromHandler   ;Create return address

; Check for Java mode
; Not strictly necessary because the processor never signals
; Undef exceptions in Java state.

                TST     R7, #Java_bit
                BNE     Unknown_Java_Handler   ; R14 -> ReturnFromHandler

; Check for Thumb mode

                TST     R7, #Thumb_bit
                BNE     ThumbStateBounce  ; R14 -> ReturnFromHandler
        KEEP
ArmStateBounce

; Now get the instruction that bounced. Security note: we don't have
; to be careful about whether the original program was in user mode:
; if the memory area concerned is inaccessible from user mode, any
; attempt to execute an instruction from it in user mode would cause a
; prefetch abort, not an undefined instruction exception.

                LDR     R0,[R6,#-4]
  if V6_ENDIAN_SWAP
                REV     r0, r0
  endif

; Is it a coprocessor instruction? To avoid the need to change this
; code in the future, this is checked carefully. (A check of instr[27]
; is sufficient in all hardware-generated cases, but some people like
; to "fake" undefined instruction trap entries when another exception
; handler cannot deal with an illegal instruction.)
;   So we test for instruction bits 27:24 = 1100, 1101 or 1110, done
; as an optimised range check on (instruction << 4).

                MOV     R2,R0,LSL #4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -