# # startup.s - starup code for the lpc2220 # # author: hackbard@hackdaworld.org # # # some definitions # # sram .equ sram_size, (64*1024) .equ sram_addr, 0x40000000 .equ sram_top, (sram_addr+sram_size-4) # stack .equ stack_size, (4*1024) .equ stack_top, sram_top .equ stack_limit, (sram_top-stack_size) .equ stack_size_fiq, 64 .equ stack_size_irq, 256 .equ stack_size_supervisor, 64 .equ stack_size_abort, 64 .equ stack_size_undefined, 64 .equ stack_size_system, 1024 # arm modes - control bits of the program status register # ref: chapter 2.8, arm7tdmi-s technical reference manual .equ mode_user, 0x10 .equ mode_fiq, 0x11 .equ mode_irq, 0x12 .equ mode_supervisor, 0x13 .equ mode_abort, 0x17 .equ mode_undefined, 0x1b .equ mode_system, 0x1f .equ fiq_disable, 0x40 .equ irq_disable, 0x80 .equ vic_vect_addr, 0xfffff030 # # the startup code # .text .arm # exception handling must go to the very beginning # # concerning irq: # - the ldr is at 0x18 # - pc will be 0x18 + 8 at the moment of ldr (pipeline) # - substract 0xff0 => 0xfffff030 # - that's the vectored address register # - the vic put in there the address of our service routine exception_vectors: ldr pc, handler_reset ldr pc, handler_undef_instruction ldr pc, handler_soft_ir ldr pc, handler_prefetch_abort ldr pc, handler_data_abort nop ldr pc, [pc, #-0xff0] #ldr pc, handler_irq ldr pc, handler_fiq handler_reset: .word handle_reset handler_undef_instruction: .word interrupt_handler_undef_instruction handler_soft_ir: .word interrupt_handler_soft_ir handler_prefetch_abort: .word interrupt_handler_prefetch_abort handler_data_abort: .word interrupt_handler_data_abort handler_irq: .word vic_vect_addr handler_fiq: .word interrupt_handler_fiq # reset handling goes here handle_reset: # init stack pointer for each mode + set stack limit ldr r0, =sram_top msr cpsr_c, #mode_undefined|irq_disable|fiq_disable mov sp, r0 sub r0, r0, #stack_size_undefined msr cpsr_c, #mode_abort|irq_disable|fiq_disable mov sp, r0 sub r0, r0, #stack_size_abort msr cpsr_c, #mode_fiq|irq_disable|fiq_disable mov sp, r0 sub r0, r0, #stack_size_fiq msr cpsr_c, #mode_irq|irq_disable|fiq_disable mov sp, r0 sub r0, r0, #stack_size_irq msr cpsr_c, #mode_supervisor|irq_disable|fiq_disable mov sp, r0 sub r0, r0, #stack_size_supervisor msr cpsr_c, #mode_system|irq_disable|fiq_disable mov sp, r0 sub r0, r0, #stack_size_system ldr r0, =stack_limit mov sl, r0 # enable irq and fiq msr cpsr_c, #mode_system # copy data section (only if we are in flash <=> _etext != _data) ldr r1, =_etext ldr r2, =_data ldr r3, =_edata cmp r1, r2 beq copy_exception_vectors copy_data_loop: cmp r2, r3 ldrlo r0, [r1], #4 strlo r0, [r2], #4 blo copy_data_loop b start_of_c_code # copy exception vectors (only if we are in ram <=> _etext = _data) copy_exception_vectors: mov r0, #sram_addr ldr r1, =exception_vectors ldmia r1!, {r2-r9} stmia r0!, {r2-r9} ldmia r1!, {r2-r8} stmia r0!, {r2-r8} # jump to c code start_of_c_code: adr lr, loop_forever mov r0, #0 mov r1, #0 ldr r2, =main bx r2 loop_forever: b loop_forever