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

📄 intdrv.s

📁 Sunplus 8202S source code.
💻 S
📖 第 1 页 / 共 2 页
字号:
                b        __interrupt_service
                
__entry_srv0:
#ifdef DVD_SERVO
                la        k1, ServoDecoderISR_1
#endif
#ifdef SPHE1000
				la        k1, intr_dispatch_mipz
#endif
                b        __interrupt_service

__entry_dsp:
                la        k1,dsp_intr
                b        __interrupt_service

//
// interrupt vectors #1
//
__entry_risc4:
                la        k1, intr_risc4
                b        __interrupt_service

__entry_risc3:
                la        k1, intr_risc3
                b        __interrupt_service

__entry_risc2:
                la        k1, intr_risc2
                b        __interrupt_service

__entry_risc1:
                la        k1, intr_risc1
                b        __interrupt_service
                
__entry_risc0:
                la        k1, intr_risc0
                b        __interrupt_service

__entry_timer2a:
                la        k1, intr_timer2a
                b        __interrupt1_service

__entry_timer2b:
                la        k1, intr_timer2b
                b        __interrupt1_service

__entry_timer3a:
                la        k1, intr_timer3a
                b        __interrupt1_service

__entry_timer3b:
                la        k1, intr_timer3b
                b        __interrupt1_service
#ifdef    SPHE8202
__entry_usb:
                la        k1, uhci_USBISR
                b        __interrupt1_service
#endif

/*
** SAVE_REG/LOAD_REG
*/
#include "regloc.h"

#define    SAVE_REG(a,b,c)        sw    a, 4*b(c)
#define    LOAD_REG(a,b,c)        lw    a, 4*b(c)

/*
** INTR_SAVE_REG
** save AT/v0~v1/a0~a3/t0~t9/s6/gp/ra/EPC registers
*/
#define INTR_SAVE_REG()     \
        subu    sp, +4*REGLOCi_NUM;     \
        .set noat;                      \
        SAVE_REG(AT, REGLOCi_AT, sp);   \
        .set at;                        \
        SAVE_REG(v0, REGLOCi_v0, sp);   \
        SAVE_REG(v1, REGLOCi_v1, sp);   \
        mfc0    v0, C0_EPC;             \
        SAVE_REG(a0, REGLOCi_a0, sp);   \
        SAVE_REG(a1, REGLOCi_a1, sp);   \
        SAVE_REG(a2, REGLOCi_a2, sp);   \
        SAVE_REG(a3, REGLOCi_a3, sp);   \
        SAVE_REG(t0, REGLOCi_t0, sp);   \
        SAVE_REG(t1, REGLOCi_t1, sp);   \
        SAVE_REG(t2, REGLOCi_t2, sp);   \
        SAVE_REG(t3, REGLOCi_t3, sp);   \
        SAVE_REG(t4, REGLOCi_t4, sp);   \
        SAVE_REG(t5, REGLOCi_t5, sp);   \
        SAVE_REG(t6, REGLOCi_t6, sp);   \
        SAVE_REG(t7, REGLOCi_t7, sp);   \
        SAVE_REG(t8, REGLOCi_t8, sp);   \
        SAVE_REG(t9, REGLOCi_t9, sp);   \
        SAVE_REG(s6, REGLOCi_s6, sp);   \
        SAVE_REG(gp, REGLOCi_gp, sp);   \
        SAVE_REG(ra, REGLOCi_ra, sp);   \
        SAVE_REG(v0, REGLOCi_EPC, sp); 


/*
** INTR_LOAD_REG
** load AT/v0~v1/a0~a3/t0~t9/s6/gp/ra registers
** load EPC to k1
*/
#define INTR_LOAD_REG()     \
        .set noat;                      \
        LOAD_REG(AT, REGLOCi_AT, sp);   \
        .set at;                        \
        LOAD_REG(v0, REGLOCi_v0, sp);   \
        LOAD_REG(v1, REGLOCi_v1, sp);   \
        LOAD_REG(a0, REGLOCi_a0, sp);   \
        LOAD_REG(a1, REGLOCi_a1, sp);   \
        LOAD_REG(a2, REGLOCi_a2, sp);   \
        LOAD_REG(a3, REGLOCi_a3, sp);   \
        LOAD_REG(t0, REGLOCi_t0, sp);   \
        LOAD_REG(t1, REGLOCi_t1, sp);   \
        LOAD_REG(t2, REGLOCi_t2, sp);   \
        LOAD_REG(t3, REGLOCi_t3, sp);   \
        LOAD_REG(t4, REGLOCi_t4, sp);   \
        LOAD_REG(t5, REGLOCi_t5, sp);   \
        LOAD_REG(t6, REGLOCi_t6, sp);   \
        LOAD_REG(t7, REGLOCi_t7, sp);   \
        LOAD_REG(t8, REGLOCi_t8, sp);   \
        LOAD_REG(t9, REGLOCi_t9, sp);   \
        LOAD_REG(s6, REGLOCi_s6, sp);   \
        LOAD_REG(gp, REGLOCi_gp, sp);   \
        LOAD_REG(ra, REGLOCi_ra, sp);   \
        LOAD_REG(k1, REGLOCi_EPC, sp);  \
        addiu    sp, +4*REGLOCi_NUM;


#define TASK_LOAD_REG(r)       \
        .set noat;                      \
        LOAD_REG(k1, REGLOC_EPC, r);    \
        LOAD_REG(AT, REGLOC_AT, r);     \
        LOAD_REG(v0, REGLOC_v0, r);     \
        LOAD_REG(v1, REGLOC_v1, r);     \
        LOAD_REG(a0, REGLOC_a0, r);     \
        LOAD_REG(a1, REGLOC_a1, r);     \
        LOAD_REG(a2, REGLOC_a2, r);     \
        LOAD_REG(a3, REGLOC_a3, r);     \
        LOAD_REG(t0, REGLOC_t0, r);     \
        LOAD_REG(t1, REGLOC_t1, r);     \
        LOAD_REG(t2, REGLOC_t2, r);     \
        LOAD_REG(t3, REGLOC_t3, r);     \
        LOAD_REG(t4, REGLOC_t4, r);     \
        LOAD_REG(t5, REGLOC_t5, r);     \
        LOAD_REG(t6, REGLOC_t6, r);     \
        LOAD_REG(t7, REGLOC_t7, r);     \
        LOAD_REG(s0, REGLOC_s0, r);     \
        LOAD_REG(s1, REGLOC_s1, r);     \
        LOAD_REG(s2, REGLOC_s2, r);     \
        LOAD_REG(s3, REGLOC_s3, r);     \
        LOAD_REG(s4, REGLOC_s4, r);     \
        LOAD_REG(s5, REGLOC_s5, r);     \
        LOAD_REG(s6, REGLOC_s6, r);     \
        LOAD_REG(s7, REGLOC_s7, r);     \
        LOAD_REG(t8, REGLOC_t8, r);     \
        LOAD_REG(t9, REGLOC_t9, r);     \
        LOAD_REG(gp, REGLOC_gp, r);     \
        LOAD_REG(sp, REGLOC_sp, r);     \
        LOAD_REG(fp, REGLOC_fp, r);     \
        LOAD_REG(ra, REGLOC_ra, r);     \
        .set at

/*
** __interrupt_service:
**
** when entering this point:
**    k0: interrupt_flag (to be cleared)
**    k1: interrupt routine
**
** save only caller-saved registers
** AT
** v0/v1
** a0/a1/a2/a3
** t0/t1/t2/t3/t4/t5/t6/t7/t8/t9
** s6 (load with register-pointer)
** gp (load with global-pointer)
** ra
*/
                .global __interrupt_service
                .ent    __interrupt_service
__interrupt_service:

                INTR_SAVE_REG()

                lw      gp, s_gp                        /* setup $gp                    */
                li      s6, RGST_BASE                   /* load global pointer (s6)     */
                lw      v0, RF_INTR_FLAG(s6)            /* load interrupt flag in v0    */
                sw      k0, RF_INTR_FLAG(s6)            /* clear interrupt flag         */

__interruptXXX:
#ifdef  DVDRELEASE
                jalr    k1                              /* call to service routine      */
#else
                move    a0, k1
                addiu   sp, -8

                lw      v0, RF_INTR_MASK(s6)
                lw      v1, RF_INTR1_MASK(s6)
                sw      v0, 4(sp)
                sw      v1, 0(sp)
                li      v0, INTR_RI_WATCHDOG
#ifdef ENABLE_SDRAM_OV_RANGE_INTR
                li      v1, INTR1_SD|INTR1_LSWITCH_INTR_FLAG|INTR1_TIMERW
#else
                li      v1, INTR1_LSWITCH_INTR_FLAG|INTR1_TIMERW
#endif

                sw      v0, RF_INTR_MASK(s6)
                sw      v1, RF_INTR1_MASK(s6)

                // enable interrupt
                mfc0    v1, C0_STATUS     
                ori     v1, STATUS_IEc
                mtc0    v1, C0_STATUS
                jalr    a0

                // disable interrupt
                mfc0    v1, C0_STATUS     
                ori     v1, STATUS_IEc
                xori    v1, STATUS_IEc
                mtc0    v1, C0_STATUS

                // restore mask
                lw      v0, 4(sp)
                lw      v1, 0(sp)
                sw      v0, RF_INTR_MASK(s6)
                sw      v1, RF_INTR1_MASK(s6)
                addiu   sp, 8
#endif

                INTR_LOAD_REG()
                ERET(k1)
                .end    __interrupt_service


/*
** __interrupt1_service:
**
** when entering this point:
**    k0: interrupt_flag (to be cleared)
**    k1: interrupt routine
**
** save only caller-saved registers
** AT
** v0/v1
** a0/a1/a2/a3
** t0/t1/t2/t3/t4/t5/t6/t7/t8/t9
** s6 (load with register-pointer)
** gp (load with global-pointer)
** ra
*/

                .global __interrupt1_service
                .ent    __interrupt1_service
__interrupt1_service:

                INTR_SAVE_REG()

                lw      gp, s_gp                    /* setup $gp                    */
                li      s6, RGST_BASE                /* load global pointer (s6)        */
                lw      v0, RF_INTR1_FLAG(s6)        /* load interrupt flag in v0    */
                sw      k0, RF_INTR1_FLAG(s6)        /* clear interrupt flag            */
                b       __interruptXXX
#if 0
                jalr    k1                            /* call to service routine        */

                INTR_LOAD_REG()
                ERET(k1)
#endif
                .end    __interrupt1_service



/*
** __taskX_service:
**
** when entering this point:
**    k0: interrupt_flag (to be cleared)
**    k1: interrupt routine
**
** save ALL registers
** fp/ra
*/
#ifndef	DVDRELEASE
                .extern task_state;
                .global __taskX_service
                .ent    __taskX_service
__taskX_service:
                sw      t0, -4(sp)

                la      t0, task_state
                lw      t0, TASK_ENTRY(t0)    /* task_table_entry        */

                SAVE_REG(v0, REGLOC_v0, t0)
                SAVE_REG(v1, REGLOC_v1, t0)
        
                move    v0, t0
                lw      t0, -4(sp)

                .set    noat
                SAVE_REG(AT, REGLOC_AT, v0)
                .set    at

                mfc0    v1, C0_EPC        /* load EPC in v1        */
__taskX_service2:
                SAVE_REG(a0, REGLOC_a0, v0)
                SAVE_REG(a1, REGLOC_a1, v0)
                SAVE_REG(a2, REGLOC_a2, v0)
                SAVE_REG(a3, REGLOC_a3, v0)
                SAVE_REG(t0, REGLOC_t0, v0)
                SAVE_REG(t1, REGLOC_t1, v0)
                SAVE_REG(t2, REGLOC_t2, v0)
                SAVE_REG(t3, REGLOC_t3, v0)
                SAVE_REG(t4, REGLOC_t4, v0)
                SAVE_REG(t5, REGLOC_t5, v0)
                SAVE_REG(t6, REGLOC_t6, v0)
                SAVE_REG(t7, REGLOC_t7, v0)
                SAVE_REG(s0, REGLOC_s0, v0)
                SAVE_REG(s1, REGLOC_s1, v0)
                SAVE_REG(s2, REGLOC_s2, v0)
                SAVE_REG(s3, REGLOC_s3, v0)
                SAVE_REG(s4, REGLOC_s4, v0)
                SAVE_REG(s5, REGLOC_s5, v0)
                SAVE_REG(s6, REGLOC_s6, v0)
                SAVE_REG(s7, REGLOC_s7, v0)
                SAVE_REG(t8, REGLOC_t8, v0)
                SAVE_REG(t9, REGLOC_t9, v0)
                SAVE_REG(gp, REGLOC_gp, v0)
                SAVE_REG(sp, REGLOC_sp, v0)
                SAVE_REG(fp, REGLOC_fp, v0)
                SAVE_REG(ra, REGLOC_ra, v0)

                SAVE_REG(v1, REGLOC_EPC, v0)    /* save EPC            */

                lw      gp, s_gp                /* reload gp                */
                li      s6, RGST_BASE           /* load global pointer S6   */
                sw      k0, RF_INTR_FLAG(s6)    /* clear interrupt flag     */
                jalr    k1                      /* call to service routine  */

                la      k0, task_state
                lw      k0, TASK_ENTRY(k0)      /* task_table_entry         */

                TASK_LOAD_REG(k0)               /* load reg from k0 and write EPC to k1 */
                ERET(k1)
                .end    __taskX_service

#endif
/*
** __panic_service
**
** when entering this point:
**    k0: interrupt routine
**
** NOTE:
**   1. save ALL registers
**   2. no return
*/
                .ent    __panic_service
__panic_service:

#ifndef	DVDRELEASE
                la    k1, task_state
                lw    k1, TASK_ENTRY(k1)            /* load task_table_entry */

                SAVE_REG(v0, REGLOC_v0, k1)
                SAVE_REG(v1, REGLOC_v1, k1)
        
                mfc0 v1, C0_EPC                     /* load EPC in v1        */
                move v0, k1

                lw   zero, 0(v1)                    /* load in d-cache      */
                lw   zero, 16(v1)                   /* load in d-cache      */
                lw   zero, 32(v1)                   /* load in d-cache      */
                lw   zero, 48(v1)                   /* load in d-cache      */

                .set    noat
                SAVE_REG(AT, REGLOC_AT, v0)
                .set    at
                SAVE_REG(a0, REGLOC_a0, v0)
                SAVE_REG(a1, REGLOC_a1, v0)
                SAVE_REG(a2, REGLOC_a2, v0)
                SAVE_REG(a3, REGLOC_a3, v0)
                SAVE_REG(t0, REGLOC_t0, v0)
                SAVE_REG(t1, REGLOC_t1, v0)
                SAVE_REG(t2, REGLOC_t2, v0)
                SAVE_REG(t3, REGLOC_t3, v0)
                SAVE_REG(t4, REGLOC_t4, v0)
                SAVE_REG(t5, REGLOC_t5, v0)
                SAVE_REG(t6, REGLOC_t6, v0)
                SAVE_REG(t7, REGLOC_t7, v0)
                SAVE_REG(s0, REGLOC_s0, v0)
                SAVE_REG(s1, REGLOC_s1, v0)
                SAVE_REG(s2, REGLOC_s2, v0)
                SAVE_REG(s3, REGLOC_s3, v0)
                SAVE_REG(s4, REGLOC_s4, v0)
                SAVE_REG(s5, REGLOC_s5, v0)
                SAVE_REG(s6, REGLOC_s6, v0)
                SAVE_REG(s7, REGLOC_s7, v0)
                SAVE_REG(t8, REGLOC_t8, v0)
                SAVE_REG(t9, REGLOC_t9, v0)
                SAVE_REG(gp, REGLOC_gp, v0)
                SAVE_REG(sp, REGLOC_sp, v0)
                SAVE_REG(fp, REGLOC_fp, v0)
                SAVE_REG(ra, REGLOC_ra, v0)
                SAVE_REG(v1, REGLOC_EPC, v0)        /* save EPC            */

#endif
                lw      gp, s_gp                    // reload gp
                li      s6, RGST_BASE               // load global pointer s6
                jalr    k0                          // jump to target
                // no return
                .end    __panic_service


#ifndef	DVDRELEASE
//
// SYSCALL handler
//
__exception_chk_syscall:
                la      k0, task_state
                lw      k0, TASK_ENTRY(k0)        // k0: task_table_entry

                // save at/v0/v1 into task-table
                .set    noat
                SAVE_REG(v0, REGLOC_v0, k0)
                SAVE_REG(v1, REGLOC_v1, k0)
                move v0, k0
                SAVE_REG(AT, REGLOC_AT, v0)
                .set    at

                //
                // call to task-switching routine
                //
                // v0/v1/at saved
                // k0: flag
                // k1: intr-vect
                // v1: EPC
                //
                mfc0    v1, C0_EPC              // load EPC in v1
                li      k0, 0                   // FLAG: 0
                la      k1, intr_timer0         // INTR: timer0
                addiu   v1, 4                   // v1=v1+4
                b       __taskX_service2
#endif

⌨️ 快捷键说明

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