⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vectors.s

📁 ecos在三星44b0上的移植
💻 S
📖 第 1 页 / 共 3 页
字号:
        ldr     r1,.__exception_handlers
        ldr     r2,[r1,#0x00]    // reset vector intstruction
        str     r2,[r0,#0x00]
        ldr     r2,=warm_reset
        str     r2,[r0,#0x20]
        // Relocate [copy] data from ROM to RAM
        ldr     r3,.__rom_data_start
        ldr     r4,.__ram_data_start
        ldr     r5,.__ram_data_end
        cmp     r4,r5           // jump if no data to move
        beq     2f
        sub     r3,r3,#4        // loop adjustments
        sub     r4,r4,#4
1:      ldr     r0,[r3,#4]!     // copy info
        str     r0,[r4,#4]!
        cmp     r4,r5
        bne     1b
2:
#endif

        // initialize interrupt/exception environments
        ldr     sp,.__startup_stack
        mov     r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_IRQ_MODE)
        msr     cpsr,r0
        ldr     sp,.__exception_stack
        mov     r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE)
        msr     cpsr,r0
        ldr     sp,.__exception_stack

        // initialize CPSR (machine state register)
        mov     r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE)
        msr     cpsr,r0

        // Note: some functions in LIBGCC1 will cause a "restore from SPSR"!!
        msr     spsr,r0

        // initialize stack
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        // use interrupt stack for system initialization since it's bigger 
        // than the "startup" stack in this configuration                                
        ldr     sp,.__interrupt_stack
#else        
        ldr     sp,.__startup_stack
#endif        

        // clear BSS
        ldr     r1,.__bss_start
        ldr     r2,.__bss_end
        mov     r0,#0
        cmp     r1,r2
        beq     2f
1:      str     r0,[r1],#4
        cmp     r1,r2
        bls     1b
2:

        // Run kernel + application in THUMB mode
        THUMB_MODE(r1,10)

        LED 3
        
        // Call platform specific hardware initialization
        bl      hal_hardware_init

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        bl      initialize_stub

        // Now that stub is initialized, change vector. It is possible
        // to single-step through most of the init code, except the below.
        // Put a breakpoint at the call to cyg_hal_invoke_constructors to
        // pass over this bit (s-s depends on internal state in the stub).
#endif

#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) || \
    defined(CYGIMP_HAL_PROCESS_ALL_EXCEPTIONS)
        mov     r0,#0           // move vectors
        ldr     r1,=__exception_handlers
        ldr     r2,[r1,#0x04]   // undefined instruction
        str     r2,[r0,#0x04]
        ldr     r2,[r1,#0x24]   
        str     r2,[r0,#0x24]
#endif

#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
        .extern hal_ctrlc_isr_init
        bl      hal_ctrlc_isr_init
#endif

        LED 2
        
        // Run through static constructors
        bl      cyg_hal_invoke_constructors

        LED 1
        
        // This starts up the eCos kernel
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        ldr     sp,.__startup_stack
#endif        
        bl      cyg_start
_start_hang:
        b       _start_hang
        .code   32
        
        .global reset_platform
        .type   reset_platform,function
reset_platform:         
#ifdef CYGSEM_HAL_ROM_MONITOR
        // initialize CPSR (machine state register)
        mov     r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE)
        msr     cpsr,r0
        b       warm_reset
#else
        mov     r0,#0
        mov     pc,r0           // Jump to reset vector        
#endif                   

init_done:
        .long   0xDEADB00B

//
// Exception handlers
// Assumption: get here from a non-user context [mode]
//
        .code   32
undefined_instruction:
        ldr     sp,.__undef_exception_stack     // get good stack
        stmfd   sp!,{r0-r5}                     // save some supervisor regs
        mrs     r1,spsr
        tst     r1,#CPSR_THUMB_ENABLE
        subeq   r0,lr,#4                // PC at time of interrupt (ARM)
        subne   r0,lr,#2                // PC at time of interrupt (thumb)
        mov     r2,#CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
        mov     r3,sp
        b       call_exception_handler

        .code   32
software_interrupt:
        stmfd   sp!,{r8}
        ldr     r8,.__undef_exception_stack     // get good stack
        stmfd   r8!,{r0-r5}                     // save some supervisor regs
        mov     r3,r8
        ldmfd   sp!,{r8}
        mrs     r1,spsr
        tst     r1,#CPSR_THUMB_ENABLE
        subeq   r0,lr,#4                // PC at time of SWI (ARM)
        subne   r0,lr,#2                // PC at time of SWI (thumb)
        mov     r2,#CYGNUM_HAL_EXCEPTION_INTERRUPT
        b       call_exception_handler

        .code   32
abort_prefetch:
        ldr     sp,.__undef_exception_stack     // get good stack
        stmfd   sp!,{r0-r5}                     // save some supervisor regs
        sub     r0,lr,#4                        // PC at time of interrupt
        mrs     r1,spsr
        mov     r2,#CYGNUM_HAL_EXCEPTION_CODE_ACCESS
        mov     r3,sp
        b       call_exception_handler

        .code   32
abort_data:
        ldr     sp,.__undef_exception_stack     // get good stack
        stmfd   sp!,{r0-r5}                     // save some supervisor regs
        sub     r0,lr,#4                        // PC at time of interrupt
        mrs     r1,spsr
        mov     r2,#CYGNUM_HAL_EXCEPTION_DATA_ACCESS
        mov     r3,sp
        b       call_exception_handler
        
//
// Dispatch an exception handler.

        .code   32
call_exception_handler:
        //
        // On Entry:
        //
        // r4,r5 = scratch
        // r3 = pointer to temp save area
        // r2 = vector number
        // r1 = exception psr
        // r0 = exception pc
        // 
        // [r3+20]: exception r5
        // [r3+16]: exception r4
        // [r3+12]: exception r3
        // [r3+8] : exception r2
        // [r3+4] : exception r1
        // [r3]   : exception r0
        
        mrs     r4,cpsr                 // switch to Supervisor Mode
        bic     r4,r4,#CPSR_MODE_BITS
        orr     r4,r4,#CPSR_SUPERVISOR_MODE
        msr     cpsr,r4

        mov     r5,sp                   // save original svc sp
        mov	r4,lr                   // and original svc lr
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        // Make sure we use the GDB stack.
        ldr     sp,.__GDB_stack
        cmp     r5,sp                   // already on GDB stack?
        bhi     10f     
        ldr     r4,.__GDB_stack_base            
        cmp     r5,r4
        movhi   sp,r5
10:
#endif
        //
        // r5 holds original svc sp, current sp is stack to use
        // r4 holds original svc lr, which must also be preserved
        //

        stmfd   sp!,{r0-r2,r4,r5}       // push svc_sp, svc_lr, vector, psr, pc
        
        // switch to pre-exception mode to get banked regs
        mov     r0,sp                   // r0 survives mode switch
        mrs     r2,cpsr                 // Save current psr for return
        orr     r1,r1,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        bic     r1,r1,#CPSR_THUMB_ENABLE
        msr     cpsr,r1
        stmfd   r0!,{r8-r12,sp,lr}
        msr     cpsr,r2                 // back to svc mode
        mov     sp,r0                   // update stack pointer

        // now save pre-exception r0-r7 on current stack
        ldmfd   r3,{r0-r5}
        stmfd   sp!,{r0-r7}

        // SP needs fixing if exception occured in SVC mode.
        // The original SVC LR is still in place so that 
        // does not need to be fixed here.
        ldr     r1,[sp,#armreg_cpsr]
        and     r1,r1,#CPSR_MODE_BITS
        cmp     r1,#CPSR_SUPERVISOR_MODE
        ldreq   r1,[sp,#armreg_svcsp]
        streq   r1,[sp,#armreg_sp]

#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        ldr     r1,.__dump_procs
        ldr     r2,[sp,#armreg_vector]
        mov     lr,pc
        ldr     pc,[r1,r2,lsl #2]
#endif

        // call exception handler
        mov     r0,sp
        THUMB_MODE(r9,10)
        bl      exception_handler

#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        bl      cyg_hal_report_exception_handler_returned
#endif

        ARM_MODE(r1,10)

        //
        // Return from exception
        //
return_from_exception:

        ldr     r0,[sp,#armreg_cpsr]
        msr     spsr,r0

        // return to supervisor mode is simple
        and     r1,r0,#CPSR_MODE_BITS
        cmp     r1,#CPSR_SUPERVISOR_MODE
        ldmeqfd sp,{r0-r14,pc}^

        //
        // return to other non-user modes is a little trickier
        //

        // switch to pre-exception mode and restore r8-r14
        add     r2,sp,#armreg_r8
        mrs     r1,cpsr
        orr     r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        bic     r0,r0,#CPSR_THUMB_ENABLE
        msr     cpsr,r0
        ldmfd   r2,{r8-r14}
        msr     cpsr, r1        // back to svc mode

        // move sp,lr and pc for final load
        ldr     r0,[sp,#armreg_svcsp]
        str     r0,[sp,#armreg_r8]
        ldr     r0,[sp,#armreg_svclr]	
        str     r0,[sp,#armreg_r9]
        ldr     r0,[sp,#armreg_pc]
        str     r0,[sp,#armreg_r10]

        // restore r0-r7,sp,lr and return from exception
        ldmfd   sp,{r0-r7,sp,lr,pc}^

#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
__dump_procs:
        .word  0    // placeholder for reset
        .word  cyg_hal_report_undefined_instruction
        .word  cyg_hal_report_software_interrupt
        .word  cyg_hal_report_abort_prefetch
        .word  cyg_hal_report_abort_data
        .word  0    // reserved
#endif


// Handle device interrupts
// This is slightly more complicated than the other exception handlers because
// it needs to interface with the kernel (if present).

        .code   32
FIQ:
        // We can get here from any non-user mode.
        mrs     r8,spsr                 // CPSR at time of interrupt
        and     r9,r8,#CPSR_MODE_BITS   // isolate pre-interrupt mode
        cmp	r9,#CPSR_IRQ_MODE
        bne	1f
        // If FIQ interrupted IRQ mode, just return with FIQ disabled.
        // The common interrupt handling takes care of the rest.
        orr	r8,r8,#CPSR_FIQ_DISABLE
        msr	spsr,r8
        subs	pc,lr,#4
    1:
        // If FIQ interrupted other non-user mode, switch to IRQ mode and
        // fall through to IRQ handler.
        ldr     sp,.__exception_stack   // get good stack to save lr and spsr
        stmdb   sp,{r8,lr}
        mov     r8,#CPSR_IRQ_MODE|CPSR_FIQ_DISABLE|CPSR_IRQ_DISABLE
        msr     cpsr,r8			// switch to IRQ mode
        ldr     sp,.__exception_stack   // get regs saved in FIQ mode
        ldmdb	sp,{sp,lr}
        msr     spsr,sp

        // now it looks like we got an IRQ instead of an FIQ except that
        // FIQ is disabled so we don't recurse.
IRQ:
        // Note: I use this exception stack while saving the context because
        // the current SP does not seem to be always valid in this CPU mode.
        ldr     sp,.__exception_stack   // get good stack
        stmfd   sp!,{r0-r5}             // save some supervisor regs
        sub     r0,lr,#4                // PC at time of interrupt
        mrs     r1,spsr
        mov     r2,#CYGNUM_HAL_VECTOR_IRQ
        mov     r3,sp
	
handle_IRQ_or_FIQ:

        mrs     r4,cpsr                 // switch to Supervisor Mode
        bic     r4,r4,#CPSR_MODE_BITS
        orr     r4,r4,#CPSR_SUPERVISOR_MODE
        msr     cpsr,r4

        mov     r5,sp                   // save original svc sp
	mov	r4,lr			// save original svc lr
        stmfd   sp!,{r0-r2,r4,r5}       // push svc_sp, svc_lr, vector, psr, pc
		
        // switch to pre-exception mode to get banked regs
        mov     r0,sp                   // r0 survives mode switch
        mrs     r2,cpsr                 // Save current psr for return
        orr     r1,r1,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        bic     r1,r1,#CPSR_THUMB_ENABLE
        msr     cpsr,r1
        stmfd   r0!,{r8-r12,sp,lr}
        msr     cpsr,r2                 // back to svc mode
        mov     sp,r0                   // update stack pointer
	
        // now save pre-exception r0-r7 on current stack
        ldmfd   r3,{r0-r5}
        stmfd   sp!,{r0-r7}

        // sp needs fixing if exception occured in SVC mode.
        ldr     r1,[sp,#armreg_cpsr]
        and     r1,r1,#CPSR_MODE_BITS
        cmp     r1,#CPSR_SUPERVISOR_MODE
        ldreq   r1,[sp,#armreg_svcsp]
        streq   r1,[sp,#armreg_sp]

        mov     v6,sp                   // Save pointer to register frame

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -