blob: 0eb6ee6842f4c4b108a028601c93dadeaea597fd [file] [log] [blame]
#define AIC 0xFC06E000
#define AIC_IVR 0x10
#define AIC_EOICR 0x38
/*
Exception vectors
*/
SECTION .ns_vectors:CODE:NOROOT(2)
PUBLIC NWVector
EXTERN TZ_FIQ_Handler
EXTERN TZ_Undefined_Handler
EXTERN TZ_SWI_Handler
EXTERN Prefetch_C_Handler
EXTERN Abort_C_Handler
ARM
__iar_init$$done: ; The interrupt vector is not needed
; until after copy initialization is done
NWVector:
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
LDR pc, =nw_start ; Reset
LDR pc, Undefined_Addr ; Undefined instructions
B . ; Software interrupt (SWI/SYS)
LDR pc, Prefetch_Addr ; Prefetch abort
LDR pc, Abort_Addr ; Data abort
B . ; RESERVED
LDR PC,IRQ_Addr ; 0x18 IRQ
LDR PC,FIQ_Addr ; 0x1c FIQ
Undefined_Addr: DCD TZ_Undefined_Handler
Prefetch_Addr: DCD Prefetch_C_Handler
Abort_Addr: DCD Abort_C_Handler
IRQ_Addr: DCD TZ_IRQ_Handler
FIQ_Addr: DCD TZ_FIQ_Handler
SECTION .cstartup:CODE:NOROOT(2)
SECTION IRQ_STACK:DATA:NOROOT(2)
SECTION NW_CSTACK:DATA:NOROOT(3)
PUBLIC nw_start
PUBLIC TZ_IRQ_Handler
EXTERN main_nw
EXTERN LowLevelInit
ARM
MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR
ARM_MODE_USR DEFINE 0x10
ARM_MODE_FIQ DEFINE 0x11
ARM_MODE_IRQ DEFINE 0x12
ARM_MODE_SVC DEFINE 0x13
ARM_MODE_MON DEFINE 0x16
ARM_MODE_ABT DEFINE 0x17
ARM_MODE_UND DEFINE 0x1B
ARM_MODE_SYS DEFINE 0x1F
#define I_BIT 0x80
#define F_BIT 0x40
nw_start:
;- Keep IRQ disable, Keep FIQ(F) disable and switch back in SVC mode
MSR CPSR_c, #ARM_MODE_SVC | I_BIT
LDR sp, =SFE(NW_CSTACK) ; End of CSTACK
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
MRS r0, cpsr ; Original PSR value
;; Set up the sys stack pointer.
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #ARM_MODE_SYS ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(NW_CSTACK-0x1900); End of CSTACK
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
;; Set up the sys stack pointer.
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #ARM_MODE_IRQ ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(IRQ_STACK); End of CSTACK
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
;; Set up the normal stack pointer.
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #ARM_MODE_SVC ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
CPSIE I
/* Branch to main() */
LDR r0, =main_nw
BLX r0
/*
Handles incoming interrupt requests by branching to the corresponding
handler, as defined in the AIC. Supports interrupt nesting.
*/
TZ_IRQ_Handler:
SUB lr, lr, #4
STMFD sp!, {lr}
MRS lr, SPSR
STMFD sp!, {r0, lr}
/* Write in the IVR to support Protect Mode */
LDR lr, =AIC
LDR r0, [r14, #AIC_IVR]
STR lr, [r14, #AIC_IVR]
/* Branch to interrupt handler in Supervisor mode */
MSR CPSR_c, #ARM_MODE_SVC
STMFD sp!, {r1-r3, r4, r12, lr}
/* Check for 8-byte alignment and save lr plus a */
/* word to indicate the stack adjustment used (0 or 4) */
AND r1, sp, #4
SUB sp, sp, r1
STMFD sp!, {r1, lr}
BLX r0
LDMIA sp!, {r1, lr}
ADD sp, sp, r1
LDMIA sp!, {r1-r3, r4, r12, lr}
;- Keep IRQ disable, Keep FIQ(F) disable and switch back in IRQ mode
MSR CPSR_c, #ARM_MODE_IRQ | I_BIT
/* Acknowledge interrupt */
LDR lr, =AIC
STR lr, [r14, #AIC_EOICR]
/* Restore interrupt context and branch back to calling code */
LDMIA sp!, {r0, lr}
MSR SPSR_cxsf, lr
LDMIA sp!, {pc}^
END