|
/* for gnu as */
/* created by geweidog, 2005-11-06 */
.extern uart_isr, timer0_isr, adc0_isr
.global vic_init
.data
flag_undefined_instr:
.space 1
flag_data_abort:
.space 1
flag_prefetch_abort:
.space 1
.equ stack_size_usr, 0x200
.equ stack_size_svc, 0x100
.equ stack_size_irq, 0x100
.equ stack_size_und, 0x10
.equ stack_size_abt, 0x10
.equ stack_size_fiq, 0x10
.align 4
stack_usr:
.space stack_size_usr
stack_svc:
.space stack_size_svc
stack_irq:
.space stack_size_irq
stack_und:
.space stack_size_und
stack_abt:
.space stack_size_abt
stack_fiq:
.space stack_size_fiq
/* ******************************************************** */
.text
.arm
.global _start
.global _vic_init
.org 0x0
_start:
ldr pc, =mcu_init
ldr pc, =handle_undefined_instr
ldr pc, =handle_swi
ldr pc, =handle_prefetch_abort
ldr pc, =handle_data_abort
nop
ldr pc, [PC, #-0xff0]
ldr pc, =handle_fiq
handle_undefined_instr:
ldr r0, =flag_undefined_instr
mov r1, #1
strb r1, [r0]
trap_und:
b trap_und /* endless loop */
handle_prefetch_abort:
ldr r0, =flag_prefetch_abort
mov r1, #1
strb r1, [r0]
trap_pref_abort:
b trap_pref_abort /* endless loop */
handle_data_abort:
ldr r0, =flag_data_abort
mov r1, #1
strb r1, [r0]
trap_data_abort:
b trap_data_abort /* endless loop */
handle_swi:
stmfd sp!, {r0-r3, lr}
ldmfd sp!, {r0-r3, lr}
subs pc, lr, #4
handle_fiq:
stmfd sp!, {r0-r3, lr}
ldmfd sp!, {r0-r3, lr}
subs pc, lr, #4
mcu_init:
ldr r0, =flag_undefined_instr
mov r1, #0x55
strb r1, [r0]
strb r1, [r0,#1]!
strb r1, [r0] /* set these flags to 0 */
/* initialize stacks... */
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F
.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
/* Enter Undefined Instruction Mode and set its Stack Pointer */
MSR CPSR_c, #Mode_UND|I_Bit|F_Bit
ldr sp, =stack_und + stack_size_und - 4
/* Enter Abort Mode and set its Stack Pointer */
MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit
ldr sp, =stack_abt + stack_size_abt - 4
/* Enter FIQ Mode and set its Stack Pointer */
MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit
ldr sp, =stack_fiq + stack_size_fiq - 4
/* Enter IRQ Mode and set its Stack Pointer */
MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit
ldr sp, =stack_irq + stack_size_irq - 4
/* Enter Supervisor Mode and set its Stack Pointer */
MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit
ldr sp, =stack_svc + stack_size_svc - 4
/* Enter User Mode and set its Stack Pointer */
MSR CPSR_c, #Mode_USR /* IRQ and FIQ are enabled */
ldr sp, =stack_usr + stack_size_usr - 4
b main /* goto c code */
.equ VICVectAddr, 0xfffff030
entry_for_uart_intr:
sub lr, lr, #4
stmfd sp!, {r0-r3, lr}
bl uart0_isr /* uart0 interrupt service routine */
ldr r0, =VICVectAddr
str r1, [r0] /* write to VICVectAddr - service finished */
ldmfd sp!, {r0-r3, pc}^ /* restore registers and return */
entry_for_timer0_intr:
sub lr, lr, #4
stmfd sp!, {r0-r3, lr}
bl timer0_isr /* timer0 interrupt service routine */
ldr r0, =VICVectAddr
str r1, [r0] /* write to VICVectAddr - service finished */
ldmfd sp!, {r0-r3, pc}^ /* restore registers and return */
entry_for_adc0_intr:
sub lr, lr, #4
stmfd sp!, {r0-r3, lr}
bl adc0_isr /* adc0 converter completion isr */
ldr r0, =VICVectAddr
str r1, [r0] /* write to VICVectAddr - service finished */
ldmfd sp!, {r0-r3, pc}^ /* return */
.equ VICIntSelect, 0xfffff00c
.equ VICIntEnable, 0xfffff010
.equ VICDefVectAddr, 0xfffff034
.equ VICVectAddr0, 0xfffff100
.equ VICVectAddr1, 0xfffff104
.equ VICVectCntl0, 0xfffff200
.equ VICVectCntl1, 0xfffff204
vic_init:
ldr r0, =VICIntSelect
mov r1, #0 /* no interrupt is fiq */
str r1, [r0]
ldr r0, =VICDefVectAddr /* set default vector address for safety */
ldr r1, =def_isr
str r1, [r0]
ldr r0, =VICVectAddr0 /* set vectors */
ldr r1, =entry_for_uart_intr
str r1, [r0] /* slot 0 - uart0 */
ldr r1, =entry_for_timer0_intr
str r1, [r0, #4]! /* slot 1 - timer0 */
ldr r1, =entry_for_adc0_intr
str r1, [r0, #4]! /* slot 2 - adc0 */
ldr r0, =VICVectCntl0
mov r1, #0x26 /* slot 0 for uart0 */
str r1, [r0]
mov r1, #0x24 /* slot 1 for timer0 */
str r1, [r0, #4]!
mov r1, #0x32 /* slot 2 for adc0 */
str r1, [r0, #4]!
ldr r0, =VICIntEnable
ldr r1, =0x00040050 /* enables AD0, UART0 and Timer0 */
str r1, [r0]
mov pc, lr /* finished, return */
def_isr:
subs pc, lr, #4 /* return immediately */
/* code for security */
/* .org 0x1fc*/
/* .long 0x87654321*/
/* ************************************************************************** */
not_use_01:
mrs r0, spsr
stmfd sp!, {r0} /* store spsr then enable IRQ */
mrs r0, cpsr
bic r0, r0, #I_Bit /* I bit cleared, enable IRQ */
msr cpsr_c, r0
bl vic_init /* replace with an service function */
mrs r0, cpsr
orr r0, r0, #I_Bit /* disable IRQ for spsr restore */
ldmfd sp!, {r0}
msr spsr_cxsf, r0 /* restore spsr */
.ltorg
.end
|
|