📄 int.s
字号:
;* REGISTERS MODIFIED
;*
;* None
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* C. March 07/15/2003 Released Version 1.14.9
;************************************************************************
;static VOID INT_Clear_BSS(VOID)
INT_Clear_BSS
; Get BSS start and end addresses
LDR r0,INT_bss_start
LDR r1,INT_bss_end
; Get a value to clear BSS
MOV r2,#0
; Clear the entire memory range
INT_BSS_Clear_Loop
CMP r0,r1 ; Are the start and end equal?
STRNE r2,[r0],#4 ; Clear 4-bytes and move to next 4-bytes
BNE INT_BSS_Clear_Loop ; Continue clearing until done
; Return to caller
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* INT_System_Initialize
;*
;* DESCRIPTION
;*
;* This function initializes Nucleus Plus system variables. This
;* includes global variables for: the RTOS System stack, the start
;* address for the timer HISR stack, the timer HISR stack size,
;* and the timer HISR priority.
;*
;* CALLED BY
;*
;* INT_Initialize
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* None
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* C. March 07/15/2003 Released Version 1.14.9
;************************************************************************
;static VOID INT_Sytem_Initialize(VOID)
INT_System_Initialize
MOV r4,lr ; Save lr in r4
; Set-up INT_Loaded_Flag (1 vectors loaded, 0 vectors not loaded)
MOV r0,#1 ; All vectors are assumed loaded
LDR r1,INT_Loaded_Flag1 ; Build address of loaded flag
STR r0,[r1] ; Initialize loaded flag
; Set-up the system stack
LDR r2,INT_System_Stack ; Get address of global variable for system stack
STR sp,[r2] ; Save system stack pointer
; Set-up the system stack limit (used for stack checking by ARM tools)
SUB r1,sp,#SYSTEM_STACK_SIZE ; Adjust stack pointer to get stack limit
BIC r1,r1,#0x03 ; Align on 4-byte boundry
MOV r10,r1 ; Put stack limit in stack limit register
LDR r2,INT_System_Limit ; Get address of global variable for system stack limit
STR r1,[r2] ; Save system stack limit
; Switch to IRQ mode
MRS r0,CPSR ; Pickup current CPSR
BIC r0,r0,#MODE_MASK ; Clear the mode bits
ORR r1,r0,#IRQ_MODE ; Set the IRQ mode bits
MSR CPSR_cxsf,r1 ; Switch to IRQ mode
; Set-up IRQ stack
LDR sp,=INT_Irq_SP ; Get address of IRQ stack pointer
; Switch to FIQ mode
ORR r1,r0,#FIQ_MODE ; Set the FIQ mode bits
MSR CPSR_cxsf,r1 ; Switch to FIQ mode
; Set-up FIQ stack
LDR sp,=INT_Fiq_SP ; Get address of FIQ stack pointer
; Switch to Abort mode
ORR r1,r0,#ABT_MODE ; Set the ABT mode bits
MSR CPSR_cxsf,r1 ; Switch to ABT mode
; Set-up Abort stack
LDR sp,=INT_Abort_SP ; Get address of Abort stack pointer
; Switch to Undefined mode
ORR r1,r0,#UNDEF_MODE ; Set the UNDEF mode bits
MSR CPSR_cxsf,r1 ; Switch to UNDEF mode
; Set-up UNDEF stack
LDR sp,=INT_Undefined_SP ; Get address of Undefined stack pointer
; Switch to Undefined mode
ORR r1,r0,#SYS_MODE ; Set the System mode bits
MSR CPSR_cxsf,r1 ; Switch to System mode
; Set-up System/User stack
LDR sp,=INT_System_User_SP ; Get address of System/User stack pointer
; Switch back to supervisor mode
IF NU_SUPERV_USER_MODE
ORR r1,r0,#SYS_MODE ; Set the Supervisor mode bits
ELSE
ORR r1,r0,#SUP_MODE ; Set the Supervisor mode bits
ENDIF
MSR CPSR_cxsf,r1 ; Switch to Supervisor mode
; Get address of HISR stack memory
LDR r0,=INT_HISR_Stack_Start ; Get start address of HISR stack
LDR r1,INT_HISR_Stack_Ptr ; Pickup global variable's address
STR r0,[r1] ; Setup timer HISR stack pointer variable
; Get size of HISR stack
MOV r0,#HISR_STACK_SIZE ; Get size of HISR stack
LDR r1,INT_HISR_Stack_Size ; Get address of HISR stack size variable
STR r0,[r1] ; Store HISR stack size
; Get priority of HISR
MOV r0,#HISR_PRIORITY ; Pickup timer HISR priority (0-2)
LDR r1,INT_HISR_Priority ; Get address of HISR priority variable
STR r0,[r1] ; Store HISR priority
; Return to caller
BX r4
;************************************************************************
;*
;* FUNCTION
;*
;* __user_initial_stackheap
;*
;* DESCRIPTION
;*
;* This assembly function returns the start address of the heap.
;* This function is needed by applications utilizing certain
;* ARM Developer Suite Tools library calls.
;*
;* CALLED BY
;*
;* Applications
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* r0 - start address of heap
;*
;* REGISTERS MODIFIED
;*
;* r0
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* C. March 07/15/2003 Released Version 1.14.9
;************************************************************************
;VOID *__user_initial_stackheap(void)
EXPORT __user_initial_stackheap
__user_initial_stackheap
; Get address of bottom of heap in return register
LDR r0, =bottom_of_heap
; Return to caller
BX lr
;*****************************
;* TARGET SPECIFIC FUNCTIONS *
;*****************************
;************************************************************************
;*
;* FUNCTION
;*
;* INT_IRQ
;*
;* DESCRIPTION
;*
;* This assembly function is responsible for handling all IRQ
;* interrupts produced on the ARM architecture
;*
;* CALLED BY
;*
;* IRQ Interrupt
;*
;* CALLS
;*
;* Interrupt Handler
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* r0 - vector number
;*
;* REGISTERS MODIFIED
;*
;* r1, r2, r3, r4, r5 (saved on stack before modification)
;* IRQ SP - IRQ stack pointer
;* lr - link register adjusted for return
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* C. March 07/15/2003 Released Version 1.14.9
;************************************************************************
;static VOID INT_IRQ(VOID)
INT_IRQ
; This Code is used to correctly handle interrupts and
; is necessary due to the nature of the ARM7 architecture
STMDB sp!, {r1}
MRS r1, SPSR
TST r1, #IRQ_BIT
LDMIA sp!, {r1}
SUBNES pc,lr,#4
; Disable MMU if running with MMU Module Support
IF NU_MMU_MODE
MMU_DISABLE
ENDIF
; Save space on stack for interrupt mask / interrupt mask register addresses
SUB sp,sp,#MASK_REG_SPACE
; Save working registers on IRQ stack
STMDB sp!,{r0-r5}
; Adjust link register to interrupt return address
SUB lr,lr,#4
; Begin Board Specific Section
; Get base address of IRQ registers
LDR r3, =INT_Module_IRQ_Base
LDR r3, [r3]
; Get IRQ enable register value and save it on the bottom of the stack.
LDR r4, [r3,#INT_ENABLE_OFFSET]
STR r4, [sp,#MASK1_STACK_OFFSET]
STR r3, [sp,#INT_BASE_STACK_OFFSET]
; Get the value of the IRQ status register
LDR r2, [r3,#INT_STATUS_OFFSET]
; Compare value to 0 to make sure that an interrupt actually fired. If not
; branch to a spurrious interrupt handler.
CMP r2, #0
BEQ INT_Spurious_Interrupt
; Get the priority table address.
LDR r3, =INT_Interrupt_Priority
; Loop until the correct vector from the priority table matches the
; Interrupt pending bit.
IRQ_Vector_Loop
; Load first vector to be checked from priority table
LDR r0, [r3,#0]
; Build mask based on vector number
MOV r1, #1
MOV r1, r1, LSL r0
; Test if this interrupt is pending
TST r1, r2
BNE IRQ_Vector_Found
; Clear enable bit so higher priority interrupts remain active
BIC r4,r4,r1
; Move to next entry in table
ADD r3, r3, #4
; Keep looping until vector found
B IRQ_Vector_Loop
IRQ_Vector_Found
; Get base address of IRQ registers
LDR r3, =INT_Module_IRQ_Base
LDR r3,[r3]
; Disable lower priority interrupts
STR r4,[r3,#INT_CLEAR_OFFSET] ; Disable all lower priority
; interrupts
; End Board Specific Section
; Load the branch address from the vector table
LDR r3,=INT_IRQ_Vectors ; Get IRQ vector table address
MOV r2, r0, LSL #2 ; Multiply vector by 4 to get
; offset into table
ADD r3, r3, r2 ; Adjust vector table address to
; correct offset
LDR r2, [r3,#0] ; Load branch address from vector
; table
MOV PC, r2 ; Jump to correct branch location
; based on vector table
;************************************************************************
;*
;* FUNCTION
;*
;* INT_FIQ
;*
;* DESCRIPTION
;*
;* This assembly function is responsible for handling all FIQ
;* interrupts produced on the ARM architecture
;*
;* CALLED BY
;*
;* FIQ Interrupt
;*
;* CALLS
;*
;* Interrupt Handler
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* r0 - vector number
;*
;* REGISTERS MODIFIED
;*
;* FIQ SP - FIQ stack pointer
;* lr - link register adjusted for return
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* C. March 07/15/2003 Released Version 1.14.9
;************************************************************************
;static VOID INT_FIQ(VOID)
INT_FIQ
IF NU_FIQ_SUPPORT
; This Code is used to correctly handle interrupts and
; is necessary due to the nature of the ARM7 architecture
STMDB sp!, {r1}
MRS r1, SPSR
TST r1, #FIQ_BIT
LDMIA sp!, {r1}
SUBNES pc,lr,#4
IF NU_MMU_MODE
MMU_DISABLE
ENDIF
SUB sp,sp,#4 ; Save a space for the interrupt
; enable register
STMDB sp!,{r0-r5} ; Save r0-r5 on temporary IRQ stack
SUB lr,lr,#4 ; Adjust FIQ return address
; Start Board Specific Section
; Get FIQ enable register value and save it on the bottom of the stack.
LDR r3, Module_FIQ_Base
LDR r4, [r3,#INT_ENABLE_OFFSET]
STR r4, [sp,#24]
; Get the value of the FIQ status register
LDR r2, [r3,#INT_STATUS_OFFSET]
; Compare value to 0 to make sure that an interrupt actually fired. If not
; branch to a spurrious interrupt handler.
CMP r2, #0
BEQ INT_Spurrious_Interrupt
; Get the priority table address.
LDR r3,=INT_FIQ_Priority
; Loop until the correct vector from the priority table matches the
; Interrupt pending bit.
FIQ_Vector_Loop
; Load first vector to be checked from priority table
LDR r0, [r3,#0]
; Build mask based on vector number
MOV r1, #1
MOV r1, r1, LSL r0
; Test if this interrupt is pending
TST r1, r2
BNE FIQ_Vector_Found
; Clear enable bit so higher priority interrupts remain active
BIC r4,r4,r1
; Move to next entry in table
ADD r3, r3, #4
; Keep looping until vector found
B FIQ_Vector_Loop
FIQ_Vector_Found
; Disable lower priority interrupts
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -