📄 intdrv.s
字号:
//
// FILE
// intdrv.S
//
// DESCRIPTION
// interrupt service routines.
//
#include "ver.h"
#include "regdef.h"
#include "regmapa.h"
#include "intdef.h"
#include "pu8560.h"
#include "user_init.h"
#include "set.h"
#define RGST_BASE 0xbffe8000
#define TASK_ENTRY 4
//#define SPURIOUS_PANIC
#define SUPPORT_INTR_SW0
#define SUPPORT_INTR_SW1
#define SUPPORT_INTR_HW2
#define SUPPORT_INTR_HW3
#define SUPPORT_INTR_HW4
#define SUPPORT_INTR_HW5
#ifndef DVDRELEASE
#define SUPPORT_UART0_FIFO
#endif
#define INTR_UART0_VECTOR intr_uart0_null
#define INTR_UART1_VECTOR intr_uart1_null
#ifdef SUPPORT_UART0_FIFO
#undef INTR_UART0_VECTOR
#define INTR_UART0_VECTOR intr_uart0_fifo
#endif
#ifdef SUPPORT_UART1_FIFO
#undef INTR_UART1_VECTOR
#define INTR_UART1_VECTOR intr_uart1_fifo
#endif
#define ERET(r) \
.set noreorder; \
jr r; \
rfe; \
.set reorder
/*
** FUNCTION
** __exception_arise
**
** DESCRIPTION
** first exception-handler
** 1. check C0_CAUSE for exception_cause [IP7-IP0]
*/
.global __exception_arise
.ent __exception_arise
__exception_arise:
mfc0 k0, C0_CAUSE // load C0_CAUSE
li k1, EXCCODE_Int<<2
andi k0, (0x001f<<2) // extract exception-code field
// .EEE-EE..
// CP0_CAUSE[6:2]
beq k1, k0, __exception_chk_intr
#ifndef DVDRELEASE
li k1, EXCCODE_Sys<<2
beq k1, k0, __exception_chk_syscall
#endif
li k1, EXCCODE_RI<<2
beq k1, k0, __exception_chk_ri
li k1, EXCCODE_Bp<<2
beq k1, k0, __exception_chk_bp
li k1, EXCCODE_CpU<<2
beq k1, k0, __exception_chk_cpu
li k1, EXCCODE_Ov<<2
beq k1, k0, __exception_chk_ov
li k1, EXCCODE_AdEL<<2
beq k1, k0, __exception_chk_adel
li k1, EXCCODE_AdES<<2
beq k1, k0, __exception_chk_ades
__exception_chk_ri:
__exception_chk_bp:
__exception_chk_cpu:
__exception_chk_ov:
__exception_chk_adel:
__exception_chk_ades:
la k0, exception_panic
b __panic_service
__exception_mmu:
la k0, exception_mmu
b __panic_service
//
// __exception_chk_intr:
//
// checking IP7-0
// currently the external interrupt are all wired
// into IntreqN[0] (IntreqN[5:0]), and that is mapped
// into IP2. Since there are no other interrupt enabled,
// we simple jump to exception_intr
//
__exception_chk_intr:
mfc0 k0, C0_CAUSE
__exception_chk_intr7:
andi k1, k0, CAUSE_IP2 /* INT_GRP_0 */
bnez k1, check_inthw0_sources
andi k1, k0, CAUSE_IP3 /* INT_GRP_1 */
bnez k1, check_inthw1_sources
#ifdef SUPPORT_INTR_HW2
andi k1, k0, CAUSE_IP4
bnez k1, check_inthw2_sources
#endif
#ifdef SUPPORT_INTR_HW3
andi k1, k0, CAUSE_IP5
bnez k1, check_inthw3_sources
#endif
#ifdef SUPPORT_INTR_HW4
andi k1, k0, CAUSE_IP6
bnez k1, check_inthw4_sources
#endif
#ifdef SUPPORT_INTR_HW5
andi k1, k0, CAUSE_IP7
bnez k1, check_inthw5_sources
#endif
#ifdef SUPPORT_INTR_SW0
andi k1, k0, CAUSE_IP0
bnez k1, check_intsw0_sources
#endif
#ifdef SUPPORT_INTR_SW1
andi k1, k0, CAUSE_IP1
bnez k1, check_intsw1_sources
#endif
b __exception_leave
#ifdef SUPPORT_INTR_SW0
check_intsw0_sources:
li k0, 0
la k1, intr_sw0
b __interrupt_service
#endif
#ifdef SUPPORT_INTR_SW1
check_intsw1_sources:
li k0, 0
la k1, intr_sw1
b __interrupt_service
#endif
#ifdef SUPPORT_INTR_HW2
check_inthw2_sources:
li k0, 0
la k1, intr_hw2
b __interrupt_service
#endif
#ifdef SUPPORT_INTR_HW3
check_inthw3_sources:
li k0, 0
la k1, intr_hw3
b __interrupt_service
#endif
#ifdef SUPPORT_INTR_HW4
check_inthw4_sources:
li k0, 0
la k1, intr_hw4
b __interrupt_service
#endif
#ifdef SUPPORT_INTR_HW5
check_inthw5_sources:
li k0, 0
la k1, intr_hw5
b __interrupt_service
#endif
__exception_leave:
mfc0 k0, C0_EPC
ERET(k0)
.end __exception_arise
/*
** ENTRY HW0 bit
** check_inthw0_sources:
*/
check_inthw0_sources:
li k0, RGST_BASE // load register-file-base
lw k1, RF_INTR_MASKED_FLAG(k0) // k1 = int-flag-0
beqz k1, __exception_leave
andi k0, k1, INTR_FIELD_END // 10: field_end interrupt
bnez k0, __entry_field_end //
#ifdef SPHE8202
andi k0, k1, INTR_SRV_INT0 // 1: SRVINT0
bnez k0, __entry_srv0
#endif
andi k0, k1, INTR_DECERR // 15: dec-err
bnez k0, __entry_decerr
andi k0, k1, INTR_PIC_END // 5: v_pic_end interrupt
bnez k0, __entry_pic_end
andi k0, k1, INTR_FIELD_START // 9: field_start interrupt
bnez k0, __entry_field_start //
andi k0, k1, INTR_TIMER0 // 12: timer0 interrupt
bnez k0, __entry_timer0
andi k0, k1, INTR_TIMER1 // 13: timer1 interrupt
bnez k0, __entry_timer1
#if defined(SPHE1000) && defined(SUPPORT_USB)
andi k0, k1, INTR_USB // 13: timer1 interrupt
bnez k0, __entry_usb
#endif
andi k0, k1, INTR_H_PIO_INT // 8: h_pio_int interrupt
bnez k0, __entry_h_pio
#ifdef SPHE1000
andi k0, k1, INTR_DISPATCH_MIPZ // 1: DISPATCH MIPZ
bnez k0, __entry_srv0
#else
#ifndef SPHE8202
andi k0, k1, INTR_SRV_INT0 // 1: SRVINT0
bnez k0, __entry_srv0
#endif
andi k0, k1, INTR_SRV_INT1 // 2: SRVINT1
bnez k0, __entry_srv1
andi k0, k1, INTR_SRV_INT2 // 3: SRVINT2
bnez k0, __entry_srv2
andi k0, k1, INTR_SRV_INT3 // 4: SRVINT3
bnez k0, __entry_srv3
#endif
andi k0, k1, INTR_DSP_INT // 0: dsp interrupt
bnez k0, __entry_dsp
andi k0, k1, INTR_UART0_INT // 6: UART0
bnez k0, __entry_uart0
andi k0, k1, INTR_UART1_INT // 7: UART1
bnez k0, __entry_uart1
// this interrupts is FATAL-ERROR
andi k0, k1, INTR_RI_WATCHDOG
bnez k0, __entry_ri_watchdog
#ifdef SPURIOUS_PANIC
b spurious_panic
#endif
// clear this spurious int-flag (#0) and leave
li k0, RGST_BASE
sw k1, RF_INTR_FLAG(k0)
b __exception_leave
/*
** spurious_panic
*/
spurious_panic:
la k0, intr_panic // intr_panic(intr_flag, epc)
b __panic_service
__entry_lswitch_intr:
la k0, intr_ls_watchdog
b __panic_service
__entry_sdctrl:
#ifdef SPHE8202
#ifndef DVDRELEASE//terry,2004/4/13 01:43PM
li k0, RGST_BASE
sw k1, RF_INTR1_FLAG(k0) // disable
lw k1, (0x350+4*7)(k0) // k1: signature
li k0, 5<<4
andi k1, ((0x0f)<<4)
beq k0, k1, intr_sd_leave
li k0, 6<<4
beq k0, k1, intr_sd_leave
li k1, 0
#endif
#endif
la k0, intr_sd
b __panic_service
#ifdef SPHE8202
#ifndef DVDRELEASE//terry,2004/4/13 01:43PM
intr_sd_leave:
li k0, RGST_BASE
sw zero, RF_SDCTRL_INT(k0)
b __exception_leave
#endif
#endif
__entry_ri_watchdog:
la k0, intr_ri_watchdog
b __panic_service
__entry_watchdog:
la k0, intr_watchdog
b __panic_service
/*
** ENTRY
** check_inthw1_sources:
*/
check_inthw1_sources:
li k0, RGST_BASE // load register-file-base
lw k1, RF_INTR1_MASKED_FLAG(k0) // k1 = int-flag-1
beqz k1, __exception_leave
#ifdef SPHE1000
andi k0, k1, INTR1_PCI0
bnez k0, __entry_risc0
#else
andi k0, k1, INTR1_RISC_INT0 // 12: RISCINT4
bnez k0, __entry_risc0
andi k0, k1, INTR1_RISC_INT1 // 11: RISCINT1
bnez k0, __entry_risc1
andi k0, k1, INTR1_RISC_INT2 // 10: RISCINT2
bnez k0, __entry_risc2
andi k0, k1, INTR1_RISC_INT3 // 9: RISCINT3
bnez k0, __entry_risc3
andi k0, k1, INTR1_RISC_INT4 // 12: RISCINT4
bnez k0, __entry_risc4
#endif
andi k0, k1, INTR1_TIMERW
bnez k0, __entry_watchdog // WATCHDOG
andi k0, k1, INTR1_TIMER2A
bnez k0, __entry_timer2a // TIMER2a
andi k0, k1, INTR1_TIMER2B
bnez k0, __entry_timer2b // TIMER2b
andi k0, k1, INTR1_TIMER3A
bnez k0, __entry_timer3a // TIMER3a
andi k0, k1, INTR1_TIMER3B
bnez k0, __entry_timer3b // TIMER3b
// these interrupts are FATAL-ERROR
andi k0, k1, INTR1_LSWITCH_INTR_FLAG
bnez k0, __entry_ri_watchdog // WATCHDOG
#ifdef SPHE8202
andi k0, k1, INTR1_USB
bnez k0, __entry_usb // USB
#endif
andi k0, k1, INTR1_SD
bnez k0, __entry_sdctrl // SDRAM controller
#ifdef SPURIOUS_PANIC
b spurious_panic
#endif
// clear other unknown interrupt flags and leave
li k0, RGST_BASE
sw k1, RF_INTR1_FLAG(k0)
b __exception_leave
//
// interrupt vectors #0
//
__entry_field_end:
la k1, intr_field_end
b __interrupt_service
__entry_field_start:
la k1, intr_field_start
b __interrupt_service
__entry_pic_end:
la k1, intr_pic_end
b __interrupt_service
__entry_timer0:
#ifdef DVDRELEASE
la k1, intr_timer0
b __interrupt_service
#else
la k1, intr_timer0
b __taskX_service
#endif
__entry_h_pio:
la k1, intr_host_pio
b __interrupt_service
__entry_timer1:
la k1, intr_timer1
b __interrupt_service
__entry_decerr:
la k1, intr_decerr
b __interrupt_service
__entry_uart0:
la k1, INTR_UART0_VECTOR
b __interrupt_service
__entry_uart1:
la k1, INTR_UART1_VECTOR
b __interrupt_service
#if defined(SPHE1000) && defined(SUPPORT_USB)
__entry_usb: la k1, uhci_USBISR
b __interrupt_service
#endif
__entry_srv3:
#ifdef DVD_SERVO
la k1, ServoDecoderISR_4
#endif
b __interrupt_service
__entry_srv2:
#ifdef DVD_SERVO
la k1, ServoDecoderISR_3
#endif
b __interrupt_service
__entry_srv1:
#ifdef DVD_SERVO
la k1, ServoDecoderISR_2
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -