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

📄 vectors.s

📁 ecos移植到R8H系列的源码。源码包来自http://www.cetoni.de/develop/develop_ecosh8s_en.html
💻 S
📖 第 1 页 / 共 3 页
字号:
SVECT_TBL_ENTRY 66
SVECT_TBL_ENTRY 67
SVECT_TBL_ENTRY 68
SVECT_TBL_ENTRY 69
SVECT_TBL_ENTRY 70    
SVECT_TBL_ENTRY 71
SVECT_TBL_ENTRY 72    
SVECT_TBL_ENTRY 73
SVECT_TBL_ENTRY 74
SVECT_TBL_ENTRY 75
SVECT_TBL_ENTRY 76
SVECT_TBL_ENTRY 77
SVECT_TBL_ENTRY 78
SVECT_TBL_ENTRY 79
SVECT_TBL_ENTRY 80    
SVECT_TBL_ENTRY 81
SVECT_TBL_ENTRY 82    
SVECT_TBL_ENTRY 83
SVECT_TBL_ENTRY 84
SVECT_TBL_ENTRY 85
SVECT_TBL_ENTRY 86
SVECT_TBL_ENTRY 87
SVECT_TBL_ENTRY 88
SVECT_TBL_ENTRY 89
SVECT_TBL_ENTRY 90    
SVECT_TBL_ENTRY 91
SVECT_TBL_ENTRY 92    
SVECT_TBL_ENTRY 93
SVECT_TBL_ENTRY 94
SVECT_TBL_ENTRY 95
SVECT_TBL_ENTRY 96
SVECT_TBL_ENTRY 97
SVECT_TBL_ENTRY 98
SVECT_TBL_ENTRY 99
SVECT_TBL_ENTRY 100   
SVECT_TBL_ENTRY 101
SVECT_TBL_ENTRY 102   
SVECT_TBL_ENTRY 103
SVECT_TBL_ENTRY 104
SVECT_TBL_ENTRY 105
SVECT_TBL_ENTRY 106
SVECT_TBL_ENTRY 107
SVECT_TBL_ENTRY 108
SVECT_TBL_ENTRY 109
SVECT_TBL_ENTRY 110   
SVECT_TBL_ENTRY 111
SVECT_TBL_ENTRY 112   
SVECT_TBL_ENTRY 113
SVECT_TBL_ENTRY 114
SVECT_TBL_ENTRY 115
SVECT_TBL_ENTRY 116
SVECT_TBL_ENTRY 117
SVECT_TBL_ENTRY 118
SVECT_TBL_ENTRY 119
SVECT_TBL_ENTRY 120   
SVECT_TBL_ENTRY 121
SVECT_TBL_ENTRY 122   
SVECT_TBL_ENTRY 123
SVECT_TBL_ENTRY 124
SVECT_TBL_ENTRY 125
SVECT_TBL_ENTRY 126
SVECT_TBL_ENTRY 127
#endif // #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) 


//=============================================================================
//                             INTERRUPT ENTRY ROUTINE
// DESCRIPTION:
//     We enter this routine by a call of jsr @interrupt_entry. This means
//     the PC,CCR and EXR are pushed onto the stack (4 byte and the pushed
//     PC value points to the interrupt_hook_table entry following
//     the just called entry. 
//     When we jump into default_vsr we have a saved machine state on stack
//     that looks like this:
// 
//     [SP -->]  [MACH  4]
//               [MACL  4]
//               ------------------------------------- 
//      SP -->   ER6   4         ER0 - ER6
//               ER5   4
//               ER4   4
//               ER3   4
//               ER2   4
//               ER1   4
//               ER0   4
//               SP    4         Pre-Exception Stack pointer
//               --------------------------------------------
//               EXR   1        EXR register
//               RSV   1        reserved
//               --------------------------------------------
//               CCR   1        CCR register
//               PC    4        program counter

//
// NOTES:
//     We come here with I0-I2 masked in EXR. 
//=============================================================================
    //
    // this trampoline code is required only for ROM or ROMRAM startup
    // 
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)   
    .section .text
interrupt_entry:
    //
    // first we disable all interrupts in order to process the following code
    // without danger of becoming interrupted
    // 
    orc #7, exr                                          
    //
    // we are here with PC + CCR + EXR pushed onto stack so we have to
    // push the remaining registers er0-er7 only. er7 is the stack pointer
    // and we would like to have the pre exception stack pointer in order to
    // enable GDB to display the correct stack. The JSR instruction that brought
    // us here stored PC+CCR on stack. We simply ignore it and use these 4 bytes
    // on stack to store our SP later there.
    // 
    stm.l   er0 - er3, @ - sp                         // push er0-er3 
    stm.l   er4 - er6, @ - sp                         // push er4-er6
    //
    // if we use the H8S/2600 MAC register then we have to store it now - the macro
    // hal_push_mac is only valid if it is configured
    //
    hal_push_mac                                    
    mov.l   @(SAVED_STATE_SP, sp), er5                // er5 is saved so we can store the PC before orc #7,exr and jsr @interrupt entry in er5
    extu.w  e5                                        // the high byte of e5 contains ccr - we clear this by extending the lower 8 bits
    //
    // Now we would execute the following two instructions
    // sub.l   #4, er0                                // get the PC before execution of jsr @interrupt entry
    // sub.l   #__ram_int_svect_tbl, er0              // now we get the interrupt entry * 8 because each entry is 8 byte long
    // We use only the following single instruction - this serves 3 states
    //
    sub.l   #__ram_int_svect_tbl+4, er5               // er5 now contains intvector * 4
    mov.l   er5, er1                                  // we store the er5 value because it contains invect*4 and we require this for index in hal_vsr_table
    shlr.l  #2, er5                                   // let's devide by 4 to get the real entry - er5 now contains interrupt vector number
    mov.l   sp, er0                                   // er0 is saved so we can modify it
    add.l   #SIZE_SAVED_STATE, er0                    // we need pre exception stack pointer er0-er7 = 8*4, EXR = 2, PAD = 2, PC+CCR = 4 --> 7*4+2+2+4 
    mov.l   er0, @(SAVED_STATE_SP, sp)                // save pre exception stack pointer bevore er0 on stack            
    //
    // Now lets get into hal_vsr_table. We take the vector number and 
    // multiply with 4 (because each entry is 4 byte long). We stored this value
    // before in er1 so we can simply take the er1 value now
    //
    mov.l   @(CYG_LABEL_DEFN(hal_vsr_table),er1), er0 // get vsr_table entry
    jmp     @er0                                      // and now jump to the default vsr
#endif // #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) 


//=============================================================================
//                            DEFAULT EXCEPTION VSR
// DESCRIPTION: 
//     Most synchronous exception VSR table entries will point to a default 
//     exception VSR which is responsible for handling all exceptions in 
//     a generic manner. The default VSR simply saves the CPU state, makes any
//     adjustments to the CPU state that is necessary, and calls 
//     cyg_hal_exception_handler().
//
// NOTES:
//     We call:
//        cyg_hal_exception_handler(HAL_SavedRegisters *regs, CYG_WORD vector)
//   
//     This means we have to store pointer to regs in er0 and vector in er1
//     We come into this VSR with the saved machine state on stack that looks
//     like this:
//     SP --->   ER6   4         ER0 - ER6
//               ER5   4
//               ER4   4
//               ER3   4
//               ER2   4
//               ER1   4
//               ER0   4
//               SP    4         pre exception SP
//               -------------------------------------
//               PAD   2         Padding byte
//               EXR   1         EXR register
//               RSV   1         reserved
//               -------------------------------------
//               CCR   1         CCR register
//               PC    3         program counter  
//=============================================================================                 
    .section .text
    .global CYG_LABEL_DEFN(__default_exception_vsr)
CYG_LABEL_DEFN(__default_exception_vsr):
    //
    // store interrupt vector from er5 in _hal_saved_intvec so we can use is later    
    // We have to do this here and not in trampoline code because if we do it
    // in trampoline code, the we cant use it in an application because the
    // trampoline code is only within the ROM monitor
    //             
    mov.l   er5, @CYG_LABEL_DEFN(_hal_saved_intvec)    
    mov.l   er5, er1                                    // store interrupt vector number as arg1 in er1
    mov.l   sp, er0                                     // store pointer to HAL_SavedRegisters in er0
    jsr     @CYG_LABEL_DEFN(cyg_hal_exception_handler)  // now lets call the exception handler
    //
    // 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


//=============================================================================
//                            DEFAULT INTERRUPT VSR
// DESCRIPTION: 
//     Most asynchronous external interrupt vectors will point to a default 
//     interrupt VSR which decodes the actual interrupt being delivered from 
//     the interrupt controller and invokes the appropriate ISR. The default 
//     interrupt VSR has a number of responsibilities if it is going to 
//     interact with the Kernel cleanly and allow interrupts to cause thread 
//     preemption. To support this VSR an ISR vector table is needed. 
//     For each valid vector three pointers need to be stored: the ISR, its 
//     data pointer and an opaque (to the HAL) interrupt object pointer needed 
//     by the kernel. It is implementation defined whether these are stored 
//     in a single table of triples, or in three separate tables. The VSR 
//     follows the following approximate plan:
//
// NOTES:
//     We come into this VSR with the saved machine state on stack that looks
//     like this:
//       
//     SP --->   ER6   0         ER0 - ER6
//               ER5   4
//               ER4   8
//               ER3   12
//               ER2   16
//               ER1   20
//               ER0   24
//               SP    28        pre exception SP
//               EXR   32        EXR register
//               PAD   33        reserved
//               CCR   34        CCR register
//               PC    35        program counter  
//============================================================================= 
    .section .text
    // 
    // We come here with all the registers pushed
    // onto the stack and all interrupts masked
    //
    .global CYG_LABEL_DEFN(__default_interrupt_vsr)
CYG_LABEL_DEFN(__default_interrupt_vsr):
    //
    // hal_diag_int_start is a macro defined in arch.inc or platform.inc
    //
    hal_diag_intr_start 
    //
    // The HAL can be configured to either support the full eCos kernel, or to support
    // only very simple applications which do not require a full kernel. If kernel 
    // support is not required then some of the startup, exception, and interrupt handling 
    // code can be eliminated.
    //
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT 
    //
    // Increment the scheduler lock
    //
    .extern CYG_LABEL_DEFN(cyg_scheduler_sched_lock)
    mov.l   @CYG_LABEL_DEFN(cyg_scheduler_sched_lock), er0
    inc.l   #1, er0
    mov.l   er0, @CYG_LABEL_DEFN(cyg_scheduler_sched_lock)
#endif
    //
    // (Optional) Switch to an interrupt stack if not already running on it. 
    // This allows nested interrupts to be delivered without needing every thread 
    // to have a stack large enough to take the maximum possible nesting. 
    // We have to check if it is a nested interrupt. We first inspect the stack pointer 
    // and switch only if it is not currently within the interrupt stack range
    // 
    //         __interrupt_stack_base
    //         .. 
    // SP ---> ..
    //         __interrupt_stack
    //
    // We switch only to interrupt stack, if SP < __interrupt_stack_base or
    // SP > __interrupt_stack
    //
    mov.l   sp, er4                                       // er4 = SP = pointer to saved thread state
    // invector already saved in interrupt_entry in er5   // er5 = int vector  
#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
    mov.l   #__interrupt_stack, er0                       // A1 = er0 = interrupt stack
    cmp.l   #__interrupt_stack_base, sp                   // compare sp with base of stack
    blt     switch_to_istack                              // if sp < base then switch to int stack
    cmp.l   er0, sp                                       // compare sp with stack 
    ble     already_on_istack                             // if <= top then already on istack
    //
    // now switch to interrupt stack
    //
switch_to_istack: 
    mov.l   er0, sp                                       // switch to new SP
    //
    // we are already running on interrupt stack
    //
already_on_istack:
    push.l er4                                            // save old SP    
#endif
//
// The various parts of the kernel will invoke instrumentation routines whenever 
// appropriate events occur, and these will be stored in a circular buffer for 
// later reference.
// This option controls whether or not instrumentation support is compiled 
// into the interrupt handling code.
//
#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
    //
    // Call cyg_instrument to record that this interrupt is being raised.
    // void cyg_instrument(cyg_uint32 type, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2)
    // 
    // type = 0x0301 = INTR.RAISE   (er0)
    // arg1 = vector number         (er1)
    // arg1 = interrupt number      (er2)
    //
    .extern CYG_LABEL_DEFN(cyg_instrument)
    mov.l   #0x0301, er0                             // type = INTR,RAISE
    mov.l   er5, er1                                 // arg1 = vector number
    mov.l   er1, er2                                 // arg2 = interrupt number
    jsr CYG_LABEL_DEFN(cyg_instrument)               // call instrumentation    
#endif      
//
// When an interrupt occurs the HAL interrupt handling code can either leave 
// interrupts disabled for the duration of the interrupt handling code, or by 
// doing some extra work it can reenable interrupts before invoking the 
// interrupt handler and thus allow nested interrupts to happen. 
// If all the interrupt handlers being used are small and do not involve any loops 
// then it is usually better to disallow nested interrupts. However if any of 
// the interrupt handlers are more complicated than nested interrupts will 
// usually be required.
//
#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
    //
    // To allow nested interrupts, we set the IE bits in exr. We do
    // not touch the IPL bits, so only higher priority interrupts
    // will be nested on top of us. Also, new interrupts will not
    // be delivered until the ISR calls 
    // Cyg_Interrupt::acknowledge_interrupt(). At some future point
    // we may want to do the ack stuff here to allow immediate nesting. 
    //
    mov.b   @(CYG_LABEL_DEFN(hal_int_prio_tbl), er5), r0l    // get priority of interrupt
    //
    // now set interrupt mask in exr
    //
    stc.b   exr, r0h                                         // get EXR
    and.b   #0xf8, r0h                                       // clear I0-I2 bits 
    or.b    r0l, r0h                                         // set I0-I2 bits
    ldc.b   r0h, exr                                         // store r0h back into exr - now nesting is possible
#endif
//
// If we have Ctrl-C support enabled, save a pointer to the
// saved CPU state here so we can plant a breakpoint there if
// this is a ^C.    
//
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \
    defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
    .extern CYG_LABEL_DEFN(hal_saved_interrupt_state)
    mov.l   er4, @CYG_LABEL_DEFN(hal_saved_interrupt_state)   // er4 contains pointer to saved state
#endif
    //
    // Now we need a pointer to the interrupt object and interrupt 
    // data in order to call the ISR
    // isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)  
    //
    mov.l   er5, er0                                           // get intvector from er5
    shll.l  #2, er0                                            // tables contain long entries so multiply with 4
    mov.l   @(CYG_LABEL_DEFN(hal_interrupt_handlers),er0), er2 // store address of ISR in er2   

⌨️ 快捷键说明

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