📄 vectors.s
字号:
;**************************************************************************************************
; EDL RTOS Kernel
; (c) Copyright 2005, Wu Jun
; All Rights Reserved
; For further information, please visit http://www.enjoydigitallife.com
;
; Description: None
; History:
; Date Remarks
; 2005-01-06 Created initial version
; 2005-12-12 Finished the version 2.01
;**************************************************************************************************
;**************************************************************************************************
; Import/Export Symbols
;**************************************************************************************************
NO_INT EQU 0xC0 ; Mask used to disable interrupts (Both FIR and IRQ)
THUMB_BIT EQU 0x20
SVC32_MODE EQU 0x13
USR32_MODE EQU 0x10
SYS32_MODE EQU 0x1f
FIQ32_MODE EQU 0x11
IRQ32_MODE EQU 0x12
VICVectAddr EQU 0xFFFFF030
PINSEL2 EQU 0xE002C014
BCFG0 EQU 0xFFE00000
BCFG1 EQU 0xFFE00004
PINSEL0 EQU 0xE002C000
IO0DIR EQU 0xE0028008
SPI_IOCON EQU 0x00000150
; from cpu\stack.S
IMPORT StackSvc
IMPORT StackIrq
IMPORT StackFiq
IMPORT StackAbt
IMPORT StackUnd
IMPORT StackUsr
; from cpu\arm7\system.c
IMPORT sys_enterInterrupt
IMPORT sys_leaveInterrupt
; from board\easyarm2200\led.c for debuging
IMPORT start_kernel
IMPORT syscall_table
EXPORT comm_exit
EXPORT _undefined_instruction
EXPORT _software_interrupt
EXPORT _prefetch_abort
EXPORT _data_abort
EXPORT _not_used
EXPORT _irq
EXPORT _fiq
CODE32
AREA VECTOR_START,CODE,READONLY
;ENTRY
;**************************************************************************************************
; Interrupt vectors table
;**************************************************************************************************
_code_start
LDR PC, _bt_reset
LDR PC, _undefined_instruction
LDR PC, _software_interrupt
LDR PC, _prefetch_abort
LDR PC, _data_abort
LDR PC, _not_used
LDR PC, _irq
LDR PC, _fiq
;**************************************************************************************************
; Interrupt Service Routine Address Table
;**************************************************************************************************
_bt_reset DCD bt_reset
_undefined_instruction DCD undefined_instruction
_software_interrupt DCD software_interrupt
_prefetch_abort DCD prefetch_abort
_data_abort DCD data_abort
_not_used DCD not_used
_irq DCD irq
_fiq DCD fiq
AREA IRQ_HANDLER, CODE,READONLY
MACRO
$Label SAVE_IRQ_CONTEXT
STMFD SP!, {R0-R7} ; PUSH WORKING REGISTERS ONTO IRQ STACK
MOV R0, SP ; Save IRQ stack pointer
SUB R1, LR,#4 ; Adjust PC for return address to task
MRS R2, SPSR ; Copy SPSR (i.e. interrupted task's CPSR) to R2
ADD SP, SP,#32
MSR CPSR_c, #(NO_INT | SYS32_MODE)
; SAVE TASK'S CONTEXT ONTO TASK'S STACK
STMFD SP!, {R1} ; Push task's Return PC
STMFD SP!, {LR} ; Push task's LR
STMFD SP!, {R8-R12} ; Push task's R12-R8
MOV R12, R0
LDMFD R12!, {R3-R10} ; Move task's R0-R7 from IRQ stack to SVC stack
STMFD SP!, {R3-R10}
STMFD SP!, {R2} ; Push task's CPSR (i.e. IRQ's SPSR)
bl sys_enterInterrupt ; Start tracing the layers the interrupt has nested
MEND
MACRO
$Label RESTORE_IRQ_CONTEXT
MSR CPSR_c, #(NO_INT | SYS32_MODE) ; Disable interrupt
bl sys_leaveInterrupt ; Leave tracing and prepare quit
mov r0,sp
add sp,r0,#64
LDR LR, [SP, #-8] ; Manually restore register sp and lr in SYS32 mode,
; for the registers sp & lr are different in SYS32 mode
; from that in SVC32 mode
MSR CPSR_c, #(NO_INT | SVC32_MODE)
mov sp, r0
LDMFD SP!, {r0} ; Pop new task's CPSR
MSR SPSR_cxsf, r0
LDMFD SP!, {R0-R12,LR,pc}^ ; Pop new task's context
MEND
;**************************************************************************************************
; Reset
;**************************************************************************************************
bt_reset
ldr r0, =PINSEL2
ldr r1, =0x0f814914
str r1, [R0] ;Initialize flash
ldr r0, =BCFG0
ldr r1, =0x1000ffef
str r1, [R0] ;Initialize RAM
ldr r0, =BCFG1
ldr r1, =0x1000ffef
str r1, [R0]
BL relocate
BL initStack
BL start_kernel
undefined_instruction
B undefined_instruction
;**************************************************************************************************
; Software Interrupt Handler
;**************************************************************************************************
software_interrupt
ldr sp, =StackSvc ; Initialize SP in SVC mode
STMFD SP!, {R0-R7} ; PUSH WORKING REGISTERS ONTO IRQ STACK
MOV R0, SP ; Save IRQ stack pointer
MOV R1, LR ; Save PC for return address to task
MRS R2, SPSR ; Copy SPSR (i.e. interrupted task's CPSR) to R2
MSR CPSR_c, #(NO_INT | SYS32_MODE)
; SAVE TASK'S CONTEXT ONTO TASK'S STACK
STMFD SP!, {R1} ; Push task's Return PC
STMFD SP!, {LR} ; Push task's LR
STMFD SP!, {R8-R12} ; Push task's R12-R8
MOV R12, R0
LDMFD R12!, {R3-R10} ; Move task's R0-R7 from IRQ stack to SVC stack
STMFD SP!, {R3-R10}
STMFD SP!, {R2} ; Push task's CPSR (i.e. SVC's SPSR)
MSR CPSR_c, #(NO_INT | SVC32_MODE)
LDR R8, [R1,#-4] ; get SWI ID in ARM status
BIC R8, R8, #0xFF000000
LDMFD SP!, {R0-R7} ; Restore registers R0-R7, which are parameters from user mode
MSR CPSR_c, #SYS32_MODE ; Enter SYS32 mode and enable interrupt
ldr lr,=swi_exit
ldr R9,=syscall_table
ldr pc,[R9,R8,LSL#2]
swi_exit
mov r1,sp
str r0,[r1,#+4] ;Save the return value to stack to replace the previous
;value of r0 with the return value.
b comm_exit
;**************************************************************************************************
; Prefetch Abort Exception handler
;**************************************************************************************************
prefetch_abort
B prefetch_abort
;**************************************************************************************************
; Data Abort Exception handler
;**************************************************************************************************
data_abort
B data_abort
not_used
B not_used
;**************************************************************************************************
; IRQ handler
;**************************************************************************************************
irq
SAVE_IRQ_CONTEXT
ldr r0,=VICVectAddr
ldr lr,=comm_exit ; Set the return address
ldr r0, [r0]
MSR CPSR_c, #SYS32_MODE ; Enable interrupt
mov pc, r0 ; Call the ISR
comm_exit
RESTORE_IRQ_CONTEXT
;**************************************************************************************************
; FIQ handler
;**************************************************************************************************
fiq
B fiq
;**************************************************************************************************
; initialize stack in different mode
;**************************************************************************************************
initStack
MOV R0, LR
;set SVC mode stack
MSR CPSR_c, #0xd3
LDR SP, =StackSvc
;set IRQ mode stack
MSR CPSR_c, #0xd2
LDR SP, =StackIrq
;set FIRQ mode stack
MSR CPSR_c, #0xd1
LDR SP, =StackFiq
;set Abort mode stack
MSR CPSR_c, #0xd7
LDR SP, =StackAbt
;set Undefined mode stack
MSR CPSR_c, #0xdb
LDR SP, =StackUnd
;set SYS mode stack
MSR CPSR_c, #0x5f
LDR SP, =StackUsr
MOV PC, R0
;**************************************************************************************************
; Relocate code from ROM to RAM, including RO, RW,etc
;**************************************************************************************************
relocate
mov r7, lr
ldr r0, KERNEL_RW_DATA_rom_start
ldr r1, KERNEL_RW_DATA_ram_start
ldr r2, KERNEL_RW_DATA_ram_end
bl copy_mem
mov pc,r7
;**************************************************************************************************
;* Description: copy memory
;* Parameters: R0 source memory start address
; R1 destination memory start address
; R2 destination memory end address
;**************************************************************************************************
copy_mem
ldmia r0!, {r3-r6}
stmia r1!, {r3-r6}
cmp r1, r2
ble copy_mem
mov pc,lr
;**************************************************************************************************
; address used in relocation
;**************************************************************************************************
IMPORT |Load$$KERNEL_CODE$$Base|
IMPORT |Image$$KERNEL_CODE$$Base|
IMPORT |Image$$KERNEL_CODE$$Limit|
IMPORT |Load$$KERNEL_RW_DATA$$Base|
IMPORT |Image$$KERNEL_RW_DATA$$Base|
IMPORT |Image$$KERNEL_RW_DATA$$Limit|
IMPORT |Image$$KERNEL_UNIT_DATA$$ZI$$Limit|
EXPORT free_ram_start_addr
AREA ADDR_DATA,DATA,READONLY
; Kernel code start address in Flash
KERNEL_CODE_rom_start DCD |Load$$KERNEL_CODE$$Base|
; Kernel code start address in RAM
KERNEL_CODE_ram_start DCD |Image$$KERNEL_CODE$$Base|
; Kernel code end address in RAM
KERNEL_CODE_ram_end DCD |Image$$KERNEL_CODE$$Limit|
; Kernel data start address in Flash
KERNEL_RW_DATA_rom_start DCD |Load$$KERNEL_RW_DATA$$Base|
; Kernel data start address in RAM
KERNEL_RW_DATA_ram_start DCD |Image$$KERNEL_RW_DATA$$Base|
; Kernel data end address in RAM
KERNEL_RW_DATA_ram_end DCD |Image$$KERNEL_RW_DATA$$Limit|
free_ram_start_addr DCD |Image$$KERNEL_UNIT_DATA$$ZI$$Limit|
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -