vectors.s

来自「ecos移植到R8H系列的源码。源码包来自http://www.cetoni.d」· S 代码 · 共 1,081 行 · 第 1/3 页

S
1,081
字号
    mov.l   @(CYG_LABEL_DEFN(hal_interrupt_data),er0), er1     // store pointer to data in er1
    shlr.l  #2,er0                                             // we need old vector
    jsr     @er2                                               // now call isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) 
    //  
    // er5 is defined to be saved across procedure calls, and
    // should still contain the vector byte index. Similarly,
    // er4 should still point to the saved machine state.
    //
#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
    //
    // If we are returning from the last nested interrupt, move back
    // to the thread stack. interrupt_end() must be called on the
    // thread stack since it potentially causes a context switch.
    //
    pop.l   sp                                 // pop old sp
#endif      

#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
    //
    // on return er0 bit 1 will indicate whether a DSR is
    // to be posted. Pass this together with a pointer to
    // the interrupt object we have just used to the
    // interrupt tidy up routine.
    //
    // We only need to call _interrupt_end() when there is a kernel
    // present to do any tidying up.
    //  
    // Using the vector offset in er5 for calculation of the interrupt object pointer
    // in er1.
    //
    mov.l   er5 ,er1                                          // move intvector from er5 to er1
    shll.l  #2, er1                                           // er1 = er * 4
    mov.l   @(CYG_LABEL_DEFN(hal_interrupt_objects),er1), er1 // get address of interrupt object
    //
    // Even when this is not the last nested interrupt, we must call
    // _interrupt_end() to post the DSR and decrement the scheduler
    // lock.
    // interrupt_end(cyg_uint32 isr_ret, cyg_interrupt *intr, HAL_SavedRegisters *regs)
    //  
    mov.l   er4, er2                                          // arg3 = saved state
    jsr @CYG_LABEL_DEFN(interrupt_end)                        // call interrupt end fn      
#endif
    //
    // hal_diag_restore is a macro defined in arch.inc or platform.inc
    //
    hal_diag_restore
    //
    // now restore the saved machine state from stack by the
    // macro hal_cpu_load all. This macro is defined in arch.inc
    // variant.inc or platform.inc
    //
    hal_cpu_load_all
    rte                                                 // and return


//=============================================================================
//                     CALL PENDING DSR ON INTERRUPT STACK
// DESCRIPTION:
//     Execute pending DSRs on the interrupt stack with interrupts enabled.
//     Note: this can only be called from code running on a thread stack
//=============================================================================     
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
    .extern CYG_LABEL_DEFN(cyg_interrupt_call_pending_DSRs)
    .global CYG_LABEL_DEFN(hal_interrupt_stack_call_pending_DSRs)
CYG_LABEL_DEFN(hal_interrupt_stack_call_pending_DSRs):
    push.l  er5                    // save some work registers
    push.l  er6
    mov.l   sp, er6                // save current SP
    mov.l   #__interrupt_stack,sp  // interrupt stack pointer
    stc     exr, r5l               // save PSW
    hal_cpu_int_enable             // enable interrupts
    //
    // Call kernel code to invoke DSRs.
    //
    jsr @CYG_LABEL_DEFN(cyg_interrupt_call_pending_DSRs)
    //
    // On return the old SP in er6 and the old PSW in er5 will 
    // have been preserved by the calling conventions.
    //
    ldc     r5l, exr               // Restore previous PSW
    mov.l   er6, sp                // restore old SP
    pop.l   er6                    // Retrieve old work regs
    pop.l   er5
    rts                            // and return
#endif  
        

//=============================================================================
//                                STARTUP CODE
// DESCRIPTION:
//     Execution normally begins at the reset vector with the machine in a 
//     minimal startup state. From here the HAL needs to get the machine 
//     running, set up the execution environment for the application, and 
//     finally invoke its entry point.
//
// NOTES:
//     The startup code resides in a special section called .startup. This 
//     section will always be in ROM - even if we do ROMRAM startup. Before
//     we can copy the ROM image into RAM we have to initialize hardware and
//     RAM - this will all be done within this .startup section.
//=============================================================================             
#if defined(CYG_HAL_STARTUP_ROMRAM)    
    .section .startup,"ax"
#else
    .section .text
#endif
    .global CYG_LABEL_DEFN(_start)
CYG_LABEL_DEFN(_start):
    //
    // Initialize hardware
    //
    hal_cpu_init              // innitialize various CPU status registers (CCR and EXR)
    hal_memc_init             // initialises memory controller for RAM, ROM and I/O access
    //
    // now the RAM should be initialized and we can setup stack
    //
    mov.l   #__interrupt_stack, sp 
    //
    // continue initialisation
    //
    hal_diag_init             // initialise diagnnostic mechanisms - LCD or LED
    hal_mmu_init              // initialise MMU 
    hal_cache_init            // initialise cache 
    hal_intc_init             // initialise interrupt controller 
    hal_timer_init            // initialise timers or clock
    hal_mon_init              // setup the vsr table
    
      
#if defined(CYGBLD_HAL_H8S_SHADOW_VECTOR_TABLE_POS_RAM)
    //
    // now copy the shadow vector table from ROM to its place in RAM if
    // we do ROM or ROMRAM startup and the shadow vector table should be placed
    // into RAM
    //
    mov.l #CYG_LABEL_DEFN(_svects_lma),      er0          
    mov.l #CYG_LABEL_DEFN(_svects_start),    er1
    mov.l #CYG_LABEL_DEFN(_svects_end),      er2
svects_ram_copy_loop:
    cmp   er2, er1
    bge   finished_svects_ram_copy
    mov.b @er0+, r3l
    mov.b r3l, @er1
    adds  #1, er1
    bra   svects_ram_copy_loop
finished_svects_ram_copy:
#endif // defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_ROM)

    
#if defined(CYG_HAL_STARTUP_ROMRAM)
    //
    // if we do ROMRAM startup then we copy the complete ROM image 
    // including the .data section into RAM. 
    //
    mov.l #CYG_LABEL_DEFN(_text_lma),        er0          
    mov.l #CYG_LABEL_DEFN(_stext),           er1
    mov.l #CYG_LABEL_DEFN(_ram_data_end),    er2
rom_ram_copy_loop:
    cmp   er2, er1
    bge   finished_rom_ram_copy
    mov.b @er0+, r3l
    mov.b r3l, @er1
    adds  #1, er1
    bra   rom_ram_copy_loop
finished_rom_ram_copy:
#elif defined(CYG_HAL_STARTUP_ROM)
    //
    // If the system is starting from ROM, we copy the ROM template of 
    // the .data section out to its correct position in RAM.
    //
    mov.l #CYG_LABEL_DEFN(_rom_data_start), er0          
    mov.l #CYG_LABEL_DEFN(_ram_data_start), er1
    mov.l #CYG_LABEL_DEFN(_ram_data_end),   er2
data_init_loop:
    cmp   er2, er1
    bge   finished_data_init
    mov.b @er0+, r3l
    mov.b r3l, @er1
    adds  #1, er1
    bra   data_init_loop
finished_data_init: 
#endif // End of #if defined(CYG_HAL_STARTUP_ROM)   

#if defined(CYG_HAL_STARTUP_ROMRAM)
    //
    // now that we have setup the rom image we can jump to the romram part of
    // the code
    //
    jmp   @CYG_LABEL_DEFN(_romram_code)
    .section .text
#endif // End of #if defined(CYG_HAL_STARTUP_ROMRAM)
    //
    // the following code will be executed from ROM or RAM dependig on
    // selected startup option
    //
    .global CYG_LABEL_DEFN(_romram_code)
CYG_LABEL_DEFN(_romram_code):    
    //
    // Zero the .bss section - it contains uninitialised data
    //
    mov.l #CYG_LABEL_DEFN(_bss_start), er0            
    mov.l #CYG_LABEL_DEFN(_bss_end),   er1
    mov.b #0, r2l
bss_init_loop:
    cmp   er1, er0
    bge   finished_bss_init
    mov.b r2l, @er0
    adds  #1, er0
    bra   bss_init_loop
finished_bss_init:  
    //
    // Call hal_variant_init() and hal_platform_init(). These will 
    // perform any additional initialization needed by the variant and platform. 
    // This typically includes further initialization of the interrupt controller,
    // PCI bus bridges, basic IO devices and enabling the caches.
    //
    .extern CYG_LABEL_DEFN(hal_variant_init)
    jsr @CYG_LABEL_DEFN(hal_variant_init)

    .extern CYG_LABEL_DEFN(hal_platform_init)
    jsr @CYG_LABEL_DEFN(hal_platform_init)

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
    //
    // If stubs are included in hal then we have to call initialize_stub in
    // common hal generic-stub.c. This is here so we can debug the constructors.
    //
    .extern CYG_LABEL_DEFN(initialize_stub)
    jsr @CYG_LABEL_DEFN(initialize_stub)
#endif 

    //
    // If CTRLC or BREAK support is enabled for GDB stub then we have
    // to call hal_ctrlc_isr_init in order to install the ISR for
    // asynchrounous breaks
    //    
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \
    defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
    .extern CYG_LABEL_DEFN(hal_ctrlc_isr_init)
     jsr CYG_LABEL_DEFN(hal_ctrlc_isr_init) 
#endif
    
    //
    // Call cyg_hal_invoke_constructors() to run any static constructors.
    //
    .extern CYG_LABEL_DEFN(cyg_hal_invoke_constructors)
     jsr @CYG_LABEL_DEFN(cyg_hal_invoke_constructors)
    //
    // we enter main with all registers cleared this is necessary if we do GDB debugging
    // in order to have a clean stack in GDB
    //
    sub.l er0, er0             
    sub.l er1, er1             
    sub.l er2, er2             
    sub.l er3, er3
    sub.l er4, er4
    sub.l er5, er5
    sub.l er6, er6
    //
    // Call cyg_start(). If cyg_start() returns, drop into an infinite loop.
    //  
    .extern CYG_LABEL_DEFN(cyg_start)
    jsr @CYG_LABEL_DEFN(cyg_start)
_exit:
    sleep                      // on return from cyg_start put the processor to sleep
    bra   _exit                // loop infinitely
    
    
//==========================================================================
//                              ISR TABLES
// DESCRIPTION:
//     The following three tables are required for interrupt processing 
//     CYG_ADDRESS  hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
//     CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
//     CYG_ADDRESS  hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
//==========================================================================    
    .data
    .extern CYG_LABEL_DEFN(hal_default_isr)

//=--------------------------------------------------------------------------
// Interrupt handlers
//  
    .global CYG_LABEL_DEFN(hal_interrupt_handlers)
CYG_LABEL_DEFN(hal_interrupt_handlers):
    .rept   CYGNUM_HAL_ISR_COUNT
    .long   CYG_LABEL_DEFN(hal_default_isr)
    .endr

//=--------------------------------------------------------------------------
// Interrupt data
//  
    .global CYG_LABEL_DEFN(hal_interrupt_data)
CYG_LABEL_DEFN(hal_interrupt_data):
    .rept   CYGNUM_HAL_ISR_COUNT
    .long   0
    .endr

//=--------------------------------------------------------------------------
// Interrupt objects
//
    .global CYG_LABEL_DEFN(hal_interrupt_objects)
CYG_LABEL_DEFN(hal_interrupt_objects):
    .rept   CYGNUM_HAL_ISR_COUNT
    .long   0
    .endr


//=============================================================================
//                               DIAGNOSTIC DATA
// DESCRIPTION:
//     Reserve some space for diagnostic data. This macro is defined in
//     arch.inc
//============================================================================= 
    .data
    hal_diag_data


//=============================================================================
//                               GLOBAL STORAGE
// DESCRIPTION:
//     The following variables store state information about interrupt
//     vectors and exr register
//=============================================================================
    .section .bss
    //
    // hal_saved_intvec stores the intvector when an external interrupt
    // occures
    //
    .global CYG_LABEL_DEFN(_hal_saved_intvec)
    .type	CYG_LABEL_DEFN(_hal_saved_intvec), @object
    .size	CYG_LABEL_DEFN(_hal_saved_intvec), 4
CYG_LABEL_DEFN(_hal_saved_intvec):
    .zero   4             		

//=============================================================================
//                               INTERRUPT STACK
// DESCRIPTION:
//     Temporary interrupt stack. The stack grows from stack base to top of
//     stack.
//============================================================================= 
    .balign 2
    .global _cyg_interrupt_stack_base
    .type	_cyg_interrupt_stack_base, @object
    .size	_cyg_interrupt_stack_base, CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
_cyg_interrupt_stack_base:
__interrupt_stack_base:
    .zero CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
    //
    // reserve space for interrupt stack
    //
    .balign 2
    .global _cyg_interrupt_stack
_cyg_interrupt_stack:
__interrupt_stack:
    .long   0,0,0,0,0,0,0,0 

//=-----------------------------------------------------------------------------
// end of vectors.S

⌨️ 快捷键说明

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