📄 intdrv.s
字号:
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 + -