intdrv.S
上传用户:caisangzi8
上传日期:2013-10-25
资源大小:15756k
文件大小:28k
源码类别:

DVD

开发平台:

C/C++

  1. //
  2. // FILE
  3. // intdrv.S
  4. //
  5. // DESCRIPTION
  6. // interrupt service routines.
  7. //
  8. #include "ver.h"
  9. #include "regdef.h"
  10. #include "regmapa.h"
  11. #include "intdef.h"
  12. #include "pu8560.h"
  13. #include "user_init.h"
  14. #include "set.h"
  15. #define RGST_BASE    0xbffe8000
  16. #define TASK_ENTRY    4
  17. //#define SPURIOUS_PANIC
  18. #define SUPPORT_INTR_SW0
  19. #define SUPPORT_INTR_SW1
  20. #define SUPPORT_INTR_HW2
  21. #define SUPPORT_INTR_HW3
  22. #define SUPPORT_INTR_HW4
  23. #define SUPPORT_INTR_HW5
  24. #ifndef DVDRELEASE
  25. #define SUPPORT_UART0_FIFO
  26. #endif
  27. #define INTR_UART0_VECTOR   intr_uart0_null
  28. #define INTR_UART1_VECTOR   intr_uart1_null
  29. #ifdef  SUPPORT_UART0_FIFO
  30. #undef  INTR_UART0_VECTOR
  31. #define INTR_UART0_VECTOR   intr_uart0_fifo
  32. #endif
  33. #ifdef  SUPPORT_UART1_FIFO
  34. #undef  INTR_UART1_VECTOR
  35. #define INTR_UART1_VECTOR   intr_uart1_fifo
  36. #endif
  37. #define ERET(r)             
  38.         .set    noreorder;      
  39.         jr      r;              
  40.         rfe;                    
  41.         .set    reorder
  42. /*
  43. ** FUNCTION
  44. ** __exception_arise
  45. **
  46. ** DESCRIPTION
  47. ** first exception-handler
  48. ** 1. check C0_CAUSE for exception_cause [IP7-IP0]
  49. */
  50.                 .global    __exception_arise
  51.                 .ent    __exception_arise
  52. __exception_arise:
  53.                 mfc0    k0, C0_CAUSE            // load C0_CAUSE
  54.                 li      k1, EXCCODE_Int<<2    
  55.                 andi    k0, (0x001f<<2)         // extract exception-code field
  56.                                                 // .EEE-EE..
  57.                                                 // CP0_CAUSE[6:2]
  58.                 beq     k1, k0, __exception_chk_intr
  59. #ifndef DVDRELEASE                
  60.                 li      k1, EXCCODE_Sys<<2    
  61.                 beq     k1, k0, __exception_chk_syscall
  62. #endif
  63.                 
  64.                 li      k1, EXCCODE_RI<<2
  65.                 beq     k1, k0, __exception_chk_ri
  66.                 li      k1, EXCCODE_Bp<<2
  67.                 beq     k1, k0, __exception_chk_bp
  68.                 li      k1, EXCCODE_CpU<<2
  69.                 beq     k1, k0, __exception_chk_cpu        
  70.                 li      k1, EXCCODE_Ov<<2
  71.                 beq     k1, k0, __exception_chk_ov
  72.                 li      k1, EXCCODE_AdEL<<2
  73.                 beq     k1, k0, __exception_chk_adel
  74.                 li      k1, EXCCODE_AdES<<2
  75.                 beq     k1, k0, __exception_chk_ades
  76. __exception_chk_ri:
  77. __exception_chk_bp:
  78. __exception_chk_cpu:
  79. __exception_chk_ov:
  80. __exception_chk_adel:
  81. __exception_chk_ades:
  82.                 la      k0, exception_panic
  83.                 b       __panic_service
  84. __exception_mmu:
  85.                 la      k0, exception_mmu
  86.                 b       __panic_service
  87.     
  88. //
  89. // __exception_chk_intr:
  90. //
  91. // checking IP7-0
  92. // currently the external interrupt are all wired
  93. // into IntreqN[0] (IntreqN[5:0]), and that is mapped
  94. // into IP2.  Since there are no other interrupt enabled,
  95. // we simple jump to exception_intr
  96. //
  97. __exception_chk_intr:
  98.                 mfc0    k0, C0_CAUSE
  99. __exception_chk_intr7:
  100.                 andi    k1, k0, CAUSE_IP2            /* INT_GRP_0 */
  101.                 bnez    k1, check_inthw0_sources
  102.                 andi    k1, k0, CAUSE_IP3            /* INT_GRP_1 */
  103.                 bnez    k1, check_inthw1_sources
  104. #ifdef  SUPPORT_INTR_HW2
  105.                 andi    k1, k0, CAUSE_IP4          
  106.                 bnez    k1, check_inthw2_sources
  107. #endif
  108. #ifdef  SUPPORT_INTR_HW3
  109.                 andi    k1, k0, CAUSE_IP5         
  110.                 bnez    k1, check_inthw3_sources
  111. #endif
  112. #ifdef  SUPPORT_INTR_HW4
  113.                 andi    k1, k0, CAUSE_IP6        
  114.                 bnez    k1, check_inthw4_sources
  115. #endif
  116. #ifdef  SUPPORT_INTR_HW5
  117.                 andi    k1, k0, CAUSE_IP7       
  118.                 bnez    k1, check_inthw5_sources
  119. #endif
  120. #ifdef  SUPPORT_INTR_SW0
  121.                 andi    k1, k0, CAUSE_IP0      
  122.                 bnez    k1, check_intsw0_sources
  123. #endif
  124. #ifdef  SUPPORT_INTR_SW1
  125.                 andi    k1, k0, CAUSE_IP1      
  126.                 bnez    k1, check_intsw1_sources
  127. #endif
  128.                 b         __exception_leave
  129.         
  130. #ifdef  SUPPORT_INTR_SW0
  131. check_intsw0_sources:
  132.                 li      k0, 0
  133.                 la      k1, intr_sw0
  134.                 b        __interrupt_service
  135. #endif
  136. #ifdef  SUPPORT_INTR_SW1
  137. check_intsw1_sources:
  138.                 li      k0, 0
  139.                 la      k1, intr_sw1
  140.                 b        __interrupt_service
  141. #endif
  142. #ifdef  SUPPORT_INTR_HW2
  143. check_inthw2_sources:
  144.                 li      k0, 0
  145.                 la      k1, intr_hw2
  146.                 b        __interrupt_service
  147. #endif
  148. #ifdef  SUPPORT_INTR_HW3
  149. check_inthw3_sources:
  150.                 li      k0, 0
  151.                 la      k1, intr_hw3
  152.                 b        __interrupt_service
  153. #endif
  154. #ifdef  SUPPORT_INTR_HW4
  155. check_inthw4_sources:
  156.                 li      k0, 0
  157.                 la      k1, intr_hw4
  158.                 b        __interrupt_service
  159. #endif
  160. #ifdef  SUPPORT_INTR_HW5
  161. check_inthw5_sources:
  162.                 li      k0, 0
  163.                 la      k1, intr_hw5
  164.                 b        __interrupt_service
  165. #endif
  166. __exception_leave:
  167.                 mfc0    k0, C0_EPC
  168.                 ERET(k0)
  169.                 .end    __exception_arise
  170. /*
  171. ** ENTRY HW0 bit
  172. ** check_inthw0_sources:
  173. */
  174. check_inthw0_sources:
  175.                 li      k0, RGST_BASE                   // load register-file-base
  176.                 lw      k1, RF_INTR_MASKED_FLAG(k0)     // k1 = int-flag-0
  177.                 beqz    k1, __exception_leave
  178.                 andi    k0, k1, INTR_FIELD_END          // 10: field_end interrupt
  179.                 bnez    k0, __entry_field_end           // 
  180. #ifdef SPHE8202
  181.                 andi    k0, k1, INTR_SRV_INT0           // 1: SRVINT0
  182.                 bnez    k0, __entry_srv0
  183. #endif
  184.                 andi    k0, k1, INTR_DECERR             // 15: dec-err
  185.                 bnez    k0, __entry_decerr
  186.                 andi    k0, k1, INTR_PIC_END            // 5: v_pic_end interrupt
  187.                 bnez    k0, __entry_pic_end
  188.                 andi    k0, k1, INTR_FIELD_START        // 9: field_start interrupt
  189.                 bnez    k0, __entry_field_start         // 
  190.                 andi    k0, k1, INTR_TIMER0             // 12: timer0 interrupt
  191.                 bnez    k0, __entry_timer0
  192.                 andi    k0, k1, INTR_TIMER1             // 13: timer1 interrupt
  193.                 bnez    k0, __entry_timer1
  194. #if defined(SPHE1000) && defined(SUPPORT_USB)
  195.                 andi    k0, k1, INTR_USB             // 13: timer1 interrupt
  196.                 bnez    k0, __entry_usb
  197. #endif
  198.                 andi    k0, k1, INTR_H_PIO_INT          // 8: h_pio_int interrupt
  199.                 bnez    k0, __entry_h_pio
  200. #ifdef SPHE1000
  201. andi k0, k1, INTR_DISPATCH_MIPZ // 1: DISPATCH MIPZ
  202. bnez k0, __entry_srv0
  203. #else
  204. #ifndef SPHE8202
  205.                 andi    k0, k1, INTR_SRV_INT0           // 1: SRVINT0
  206.                 bnez    k0, __entry_srv0
  207. #endif
  208.                 andi    k0, k1, INTR_SRV_INT1           // 2: SRVINT1
  209.                 bnez    k0, __entry_srv1
  210.                 andi    k0, k1, INTR_SRV_INT2           // 3: SRVINT2
  211.                 bnez    k0, __entry_srv2 
  212.                 andi    k0, k1, INTR_SRV_INT3           // 4: SRVINT3
  213.                 bnez    k0, __entry_srv3 
  214. #endif
  215.                 andi    k0, k1, INTR_DSP_INT            // 0: dsp interrupt
  216.                 bnez    k0, __entry_dsp
  217.                         
  218.                 andi    k0, k1, INTR_UART0_INT          // 6: UART0
  219.                 bnez    k0, __entry_uart0
  220.                 andi    k0, k1, INTR_UART1_INT          // 7: UART1
  221.                 bnez    k0, __entry_uart1
  222.                 // this interrupts is FATAL-ERROR
  223.                 andi    k0, k1, INTR_RI_WATCHDOG
  224.                 bnez    k0, __entry_ri_watchdog
  225. #ifdef    SPURIOUS_PANIC
  226.                 b       spurious_panic
  227. #endif
  228.                 // clear this spurious int-flag (#0) and leave
  229.                 li      k0, RGST_BASE
  230.                 sw      k1, RF_INTR_FLAG(k0)
  231.                 b       __exception_leave
  232. /*
  233. ** spurious_panic
  234. */
  235. spurious_panic:
  236.                 la      k0, intr_panic                  // intr_panic(intr_flag, epc)
  237.                 b       __panic_service
  238. __entry_lswitch_intr:
  239.                 la      k0, intr_ls_watchdog
  240.                 b       __panic_service
  241. __entry_sdctrl:
  242. #ifdef SPHE8202
  243. #ifndef DVDRELEASE//terry,2004/4/13 01:43PM
  244.                 li      k0, RGST_BASE
  245.                 sw      k1, RF_INTR1_FLAG(k0)           // disable 
  246.                 lw      k1, (0x350+4*7)(k0)             // k1: signature
  247.                 li      k0, 5<<4
  248.                 andi    k1, ((0x0f)<<4)
  249.                 beq     k0, k1, intr_sd_leave
  250.                 li      k0, 6<<4
  251.                 beq     k0, k1, intr_sd_leave
  252.                 li      k1, 0
  253. #endif                
  254. #endif
  255.                 la      k0, intr_sd
  256.                 b       __panic_service
  257. #ifdef SPHE8202
  258. #ifndef DVDRELEASE//terry,2004/4/13 01:43PM
  259. intr_sd_leave:
  260.                 li      k0, RGST_BASE
  261.                 sw      zero, RF_SDCTRL_INT(k0)
  262.                 b       __exception_leave
  263. #endif                
  264. #endif
  265. __entry_ri_watchdog:
  266.                 la      k0, intr_ri_watchdog
  267.                 b       __panic_service
  268. __entry_watchdog:
  269.                 la      k0, intr_watchdog
  270.                 b       __panic_service
  271. /*
  272. ** ENTRY
  273. ** check_inthw1_sources:
  274. */
  275. check_inthw1_sources:
  276.                 li      k0, RGST_BASE                   // load register-file-base
  277.                 lw      k1, RF_INTR1_MASKED_FLAG(k0)    // k1 = int-flag-1
  278.                 beqz    k1, __exception_leave
  279.                 
  280. #ifdef SPHE1000
  281. andi k0, k1, INTR1_PCI0
  282. bnez k0, __entry_risc0
  283. #else
  284.                 andi    k0, k1, INTR1_RISC_INT0         // 12: RISCINT4
  285.                 bnez    k0, __entry_risc0
  286.                 andi    k0, k1, INTR1_RISC_INT1         // 11: RISCINT1
  287.                 bnez    k0, __entry_risc1
  288.                 andi    k0, k1, INTR1_RISC_INT2         // 10: RISCINT2
  289.                 bnez    k0, __entry_risc2
  290.                 andi    k0, k1, INTR1_RISC_INT3         // 9: RISCINT3
  291.                 bnez    k0, __entry_risc3
  292.                 
  293.                 andi    k0, k1, INTR1_RISC_INT4         // 12: RISCINT4
  294.                 bnez    k0, __entry_risc4
  295. #endif
  296.                 
  297.                 andi    k0, k1, INTR1_TIMERW
  298.                 bnez    k0, __entry_watchdog            // WATCHDOG
  299.                 andi    k0, k1, INTR1_TIMER2A
  300.                 bnez    k0, __entry_timer2a             // TIMER2a
  301.                 andi    k0, k1, INTR1_TIMER2B
  302.                 bnez    k0, __entry_timer2b             // TIMER2b
  303.                 andi    k0, k1, INTR1_TIMER3A
  304.                 bnez    k0, __entry_timer3a             // TIMER3a
  305.                 andi    k0, k1, INTR1_TIMER3B
  306.                 bnez    k0, __entry_timer3b             // TIMER3b
  307.                 // these interrupts are FATAL-ERROR
  308.                 andi    k0, k1, INTR1_LSWITCH_INTR_FLAG
  309.                 bnez    k0, __entry_ri_watchdog         // WATCHDOG
  310.                 
  311. #ifdef    SPHE8202
  312.                 andi    k0, k1, INTR1_USB
  313.                 bnez    k0, __entry_usb                 // USB
  314. #endif                
  315.                 andi    k0, k1, INTR1_SD
  316.                 bnez    k0, __entry_sdctrl              // SDRAM controller
  317. #ifdef    SPURIOUS_PANIC
  318.                 b        spurious_panic
  319. #endif
  320.                 // clear other unknown interrupt flags and leave
  321.                 li        k0, RGST_BASE            
  322.                 sw        k1, RF_INTR1_FLAG(k0)
  323.                 b        __exception_leave
  324. //
  325. // interrupt vectors #0
  326. //
  327. __entry_field_end:
  328.                 la        k1, intr_field_end
  329.                 b        __interrupt_service
  330. __entry_field_start:
  331.                 la        k1, intr_field_start
  332.                 b        __interrupt_service
  333. __entry_pic_end:
  334.                 la        k1, intr_pic_end
  335.                 b        __interrupt_service
  336. __entry_timer0:
  337. #ifdef DVDRELEASE
  338.                 la        k1, intr_timer0
  339.                 b        __interrupt_service
  340. #else
  341.                 la        k1, intr_timer0
  342.                 b        __taskX_service
  343. #endif
  344. __entry_h_pio:
  345.                 la        k1, intr_host_pio
  346.                 b        __interrupt_service
  347. __entry_timer1:
  348.                 la        k1, intr_timer1
  349.                 b        __interrupt_service
  350. __entry_decerr:
  351.                 la        k1, intr_decerr
  352.                 b        __interrupt_service
  353. __entry_uart0:
  354.                 la        k1, INTR_UART0_VECTOR
  355.                 b        __interrupt_service
  356. __entry_uart1:
  357.                 la        k1, INTR_UART1_VECTOR
  358.                 b        __interrupt_service
  359. #if defined(SPHE1000) && defined(SUPPORT_USB)
  360. __entry_usb:    la        k1, uhci_USBISR
  361. b  __interrupt_service
  362. #endif
  363. __entry_srv3:
  364. #ifdef DVD_SERVO
  365.                 la        k1, ServoDecoderISR_4
  366. #endif
  367.                 b        __interrupt_service
  368. __entry_srv2:
  369. #ifdef DVD_SERVO
  370.                 la        k1, ServoDecoderISR_3
  371. #endif
  372.                 b        __interrupt_service
  373. __entry_srv1:
  374. #ifdef DVD_SERVO
  375.                 la        k1, ServoDecoderISR_2
  376. #endif
  377.                 b        __interrupt_service
  378.                 
  379. __entry_srv0:
  380. #ifdef DVD_SERVO
  381.                 la        k1, ServoDecoderISR_1
  382. #endif
  383. #ifdef SPHE1000
  384. la        k1, intr_dispatch_mipz
  385. #endif
  386.                 b        __interrupt_service
  387. __entry_dsp:
  388.                 la        k1,dsp_intr
  389.                 b        __interrupt_service
  390. //
  391. // interrupt vectors #1
  392. //
  393. __entry_risc4:
  394.                 la        k1, intr_risc4
  395.                 b        __interrupt_service
  396. __entry_risc3:
  397.                 la        k1, intr_risc3
  398.                 b        __interrupt_service
  399. __entry_risc2:
  400.                 la        k1, intr_risc2
  401.                 b        __interrupt_service
  402. __entry_risc1:
  403.                 la        k1, intr_risc1
  404.                 b        __interrupt_service
  405.                 
  406. __entry_risc0:
  407.                 la        k1, intr_risc0
  408.                 b        __interrupt_service
  409. __entry_timer2a:
  410.                 la        k1, intr_timer2a
  411.                 b        __interrupt1_service
  412. __entry_timer2b:
  413.                 la        k1, intr_timer2b
  414.                 b        __interrupt1_service
  415. __entry_timer3a:
  416.                 la        k1, intr_timer3a
  417.                 b        __interrupt1_service
  418. __entry_timer3b:
  419.                 la        k1, intr_timer3b
  420.                 b        __interrupt1_service
  421. #ifdef    SPHE8202
  422. __entry_usb:
  423.                 la        k1, uhci_USBISR
  424.                 b        __interrupt1_service
  425. #endif
  426. /*
  427. ** SAVE_REG/LOAD_REG
  428. */
  429. #include "regloc.h"
  430. #define    SAVE_REG(a,b,c)        sw    a, 4*b(c)
  431. #define    LOAD_REG(a,b,c)        lw    a, 4*b(c)
  432. /*
  433. ** INTR_SAVE_REG
  434. ** save AT/v0~v1/a0~a3/t0~t9/s6/gp/ra/EPC registers
  435. */
  436. #define INTR_SAVE_REG()     
  437.         subu    sp, +4*REGLOCi_NUM;     
  438.         .set noat;                      
  439.         SAVE_REG(AT, REGLOCi_AT, sp);   
  440.         .set at;                        
  441.         SAVE_REG(v0, REGLOCi_v0, sp);   
  442.         SAVE_REG(v1, REGLOCi_v1, sp);   
  443.         mfc0    v0, C0_EPC;             
  444.         SAVE_REG(a0, REGLOCi_a0, sp);   
  445.         SAVE_REG(a1, REGLOCi_a1, sp);   
  446.         SAVE_REG(a2, REGLOCi_a2, sp);   
  447.         SAVE_REG(a3, REGLOCi_a3, sp);   
  448.         SAVE_REG(t0, REGLOCi_t0, sp);   
  449.         SAVE_REG(t1, REGLOCi_t1, sp);   
  450.         SAVE_REG(t2, REGLOCi_t2, sp);   
  451.         SAVE_REG(t3, REGLOCi_t3, sp);   
  452.         SAVE_REG(t4, REGLOCi_t4, sp);   
  453.         SAVE_REG(t5, REGLOCi_t5, sp);   
  454.         SAVE_REG(t6, REGLOCi_t6, sp);   
  455.         SAVE_REG(t7, REGLOCi_t7, sp);   
  456.         SAVE_REG(t8, REGLOCi_t8, sp);   
  457.         SAVE_REG(t9, REGLOCi_t9, sp);   
  458.         SAVE_REG(s6, REGLOCi_s6, sp);   
  459.         SAVE_REG(gp, REGLOCi_gp, sp);   
  460.         SAVE_REG(ra, REGLOCi_ra, sp);   
  461.         SAVE_REG(v0, REGLOCi_EPC, sp); 
  462. /*
  463. ** INTR_LOAD_REG
  464. ** load AT/v0~v1/a0~a3/t0~t9/s6/gp/ra registers
  465. ** load EPC to k1
  466. */
  467. #define INTR_LOAD_REG()     
  468.         .set noat;                      
  469.         LOAD_REG(AT, REGLOCi_AT, sp);   
  470.         .set at;                        
  471.         LOAD_REG(v0, REGLOCi_v0, sp);   
  472.         LOAD_REG(v1, REGLOCi_v1, sp);   
  473.         LOAD_REG(a0, REGLOCi_a0, sp);   
  474.         LOAD_REG(a1, REGLOCi_a1, sp);   
  475.         LOAD_REG(a2, REGLOCi_a2, sp);   
  476.         LOAD_REG(a3, REGLOCi_a3, sp);   
  477.         LOAD_REG(t0, REGLOCi_t0, sp);   
  478.         LOAD_REG(t1, REGLOCi_t1, sp);   
  479.         LOAD_REG(t2, REGLOCi_t2, sp);   
  480.         LOAD_REG(t3, REGLOCi_t3, sp);   
  481.         LOAD_REG(t4, REGLOCi_t4, sp);   
  482.         LOAD_REG(t5, REGLOCi_t5, sp);   
  483.         LOAD_REG(t6, REGLOCi_t6, sp);   
  484.         LOAD_REG(t7, REGLOCi_t7, sp);   
  485.         LOAD_REG(t8, REGLOCi_t8, sp);   
  486.         LOAD_REG(t9, REGLOCi_t9, sp);   
  487.         LOAD_REG(s6, REGLOCi_s6, sp);   
  488.         LOAD_REG(gp, REGLOCi_gp, sp);   
  489.         LOAD_REG(ra, REGLOCi_ra, sp);   
  490.         LOAD_REG(k1, REGLOCi_EPC, sp);  
  491.         addiu    sp, +4*REGLOCi_NUM;
  492. #define TASK_LOAD_REG(r)       
  493.         .set noat;                      
  494.         LOAD_REG(k1, REGLOC_EPC, r);    
  495.         LOAD_REG(AT, REGLOC_AT, r);     
  496.         LOAD_REG(v0, REGLOC_v0, r);     
  497.         LOAD_REG(v1, REGLOC_v1, r);     
  498.         LOAD_REG(a0, REGLOC_a0, r);     
  499.         LOAD_REG(a1, REGLOC_a1, r);     
  500.         LOAD_REG(a2, REGLOC_a2, r);     
  501.         LOAD_REG(a3, REGLOC_a3, r);     
  502.         LOAD_REG(t0, REGLOC_t0, r);     
  503.         LOAD_REG(t1, REGLOC_t1, r);     
  504.         LOAD_REG(t2, REGLOC_t2, r);     
  505.         LOAD_REG(t3, REGLOC_t3, r);     
  506.         LOAD_REG(t4, REGLOC_t4, r);     
  507.         LOAD_REG(t5, REGLOC_t5, r);     
  508.         LOAD_REG(t6, REGLOC_t6, r);     
  509.         LOAD_REG(t7, REGLOC_t7, r);     
  510.         LOAD_REG(s0, REGLOC_s0, r);     
  511.         LOAD_REG(s1, REGLOC_s1, r);     
  512.         LOAD_REG(s2, REGLOC_s2, r);     
  513.         LOAD_REG(s3, REGLOC_s3, r);     
  514.         LOAD_REG(s4, REGLOC_s4, r);     
  515.         LOAD_REG(s5, REGLOC_s5, r);     
  516.         LOAD_REG(s6, REGLOC_s6, r);     
  517.         LOAD_REG(s7, REGLOC_s7, r);     
  518.         LOAD_REG(t8, REGLOC_t8, r);     
  519.         LOAD_REG(t9, REGLOC_t9, r);     
  520.         LOAD_REG(gp, REGLOC_gp, r);     
  521.         LOAD_REG(sp, REGLOC_sp, r);     
  522.         LOAD_REG(fp, REGLOC_fp, r);     
  523.         LOAD_REG(ra, REGLOC_ra, r);     
  524.         .set at
  525. /*
  526. ** __interrupt_service:
  527. **
  528. ** when entering this point:
  529. **    k0: interrupt_flag (to be cleared)
  530. **    k1: interrupt routine
  531. **
  532. ** save only caller-saved registers
  533. ** AT
  534. ** v0/v1
  535. ** a0/a1/a2/a3
  536. ** t0/t1/t2/t3/t4/t5/t6/t7/t8/t9
  537. ** s6 (load with register-pointer)
  538. ** gp (load with global-pointer)
  539. ** ra
  540. */
  541.                 .global __interrupt_service
  542.                 .ent    __interrupt_service
  543. __interrupt_service:
  544.                 INTR_SAVE_REG()
  545.                 lw      gp, s_gp                        /* setup $gp                    */
  546.                 li      s6, RGST_BASE                   /* load global pointer (s6)     */
  547.                 lw      v0, RF_INTR_FLAG(s6)            /* load interrupt flag in v0    */
  548.                 sw      k0, RF_INTR_FLAG(s6)            /* clear interrupt flag         */
  549. __interruptXXX:
  550. #ifdef  DVDRELEASE
  551.                 jalr    k1                              /* call to service routine      */
  552. #else
  553.                 move    a0, k1
  554.                 addiu   sp, -8
  555.                 lw      v0, RF_INTR_MASK(s6)
  556.                 lw      v1, RF_INTR1_MASK(s6)
  557.                 sw      v0, 4(sp)
  558.                 sw      v1, 0(sp)
  559.                 li      v0, INTR_RI_WATCHDOG
  560. #ifdef ENABLE_SDRAM_OV_RANGE_INTR
  561.                 li      v1, INTR1_SD|INTR1_LSWITCH_INTR_FLAG|INTR1_TIMERW
  562. #else
  563.                 li      v1, INTR1_LSWITCH_INTR_FLAG|INTR1_TIMERW
  564. #endif
  565.                 sw      v0, RF_INTR_MASK(s6)
  566.                 sw      v1, RF_INTR1_MASK(s6)
  567.                 // enable interrupt
  568.                 mfc0    v1, C0_STATUS     
  569.                 ori     v1, STATUS_IEc
  570.                 mtc0    v1, C0_STATUS
  571.                 jalr    a0
  572.                 // disable interrupt
  573.                 mfc0    v1, C0_STATUS     
  574.                 ori     v1, STATUS_IEc
  575.                 xori    v1, STATUS_IEc
  576.                 mtc0    v1, C0_STATUS
  577.                 // restore mask
  578.                 lw      v0, 4(sp)
  579.                 lw      v1, 0(sp)
  580.                 sw      v0, RF_INTR_MASK(s6)
  581.                 sw      v1, RF_INTR1_MASK(s6)
  582.                 addiu   sp, 8
  583. #endif
  584.                 INTR_LOAD_REG()
  585.                 ERET(k1)
  586.                 .end    __interrupt_service
  587. /*
  588. ** __interrupt1_service:
  589. **
  590. ** when entering this point:
  591. **    k0: interrupt_flag (to be cleared)
  592. **    k1: interrupt routine
  593. **
  594. ** save only caller-saved registers
  595. ** AT
  596. ** v0/v1
  597. ** a0/a1/a2/a3
  598. ** t0/t1/t2/t3/t4/t5/t6/t7/t8/t9
  599. ** s6 (load with register-pointer)
  600. ** gp (load with global-pointer)
  601. ** ra
  602. */
  603.                 .global __interrupt1_service
  604.                 .ent    __interrupt1_service
  605. __interrupt1_service:
  606.                 INTR_SAVE_REG()
  607.                 lw      gp, s_gp                    /* setup $gp                    */
  608.                 li      s6, RGST_BASE                /* load global pointer (s6)        */
  609.                 lw      v0, RF_INTR1_FLAG(s6)        /* load interrupt flag in v0    */
  610.                 sw      k0, RF_INTR1_FLAG(s6)        /* clear interrupt flag            */
  611.                 b       __interruptXXX
  612. #if 0
  613.                 jalr    k1                            /* call to service routine        */
  614.                 INTR_LOAD_REG()
  615.                 ERET(k1)
  616. #endif
  617.                 .end    __interrupt1_service
  618. /*
  619. ** __taskX_service:
  620. **
  621. ** when entering this point:
  622. **    k0: interrupt_flag (to be cleared)
  623. **    k1: interrupt routine
  624. **
  625. ** save ALL registers
  626. ** fp/ra
  627. */
  628. #ifndef DVDRELEASE
  629.                 .extern task_state;
  630.                 .global __taskX_service
  631.                 .ent    __taskX_service
  632. __taskX_service:
  633.                 sw      t0, -4(sp)
  634.                 la      t0, task_state
  635.                 lw      t0, TASK_ENTRY(t0)    /* task_table_entry        */
  636.                 SAVE_REG(v0, REGLOC_v0, t0)
  637.                 SAVE_REG(v1, REGLOC_v1, t0)
  638.         
  639.                 move    v0, t0
  640.                 lw      t0, -4(sp)
  641.                 .set    noat
  642.                 SAVE_REG(AT, REGLOC_AT, v0)
  643.                 .set    at
  644.                 mfc0    v1, C0_EPC        /* load EPC in v1        */
  645. __taskX_service2:
  646.                 SAVE_REG(a0, REGLOC_a0, v0)
  647.                 SAVE_REG(a1, REGLOC_a1, v0)
  648.                 SAVE_REG(a2, REGLOC_a2, v0)
  649.                 SAVE_REG(a3, REGLOC_a3, v0)
  650.                 SAVE_REG(t0, REGLOC_t0, v0)
  651.                 SAVE_REG(t1, REGLOC_t1, v0)
  652.                 SAVE_REG(t2, REGLOC_t2, v0)
  653.                 SAVE_REG(t3, REGLOC_t3, v0)
  654.                 SAVE_REG(t4, REGLOC_t4, v0)
  655.                 SAVE_REG(t5, REGLOC_t5, v0)
  656.                 SAVE_REG(t6, REGLOC_t6, v0)
  657.                 SAVE_REG(t7, REGLOC_t7, v0)
  658.                 SAVE_REG(s0, REGLOC_s0, v0)
  659.                 SAVE_REG(s1, REGLOC_s1, v0)
  660.                 SAVE_REG(s2, REGLOC_s2, v0)
  661.                 SAVE_REG(s3, REGLOC_s3, v0)
  662.                 SAVE_REG(s4, REGLOC_s4, v0)
  663.                 SAVE_REG(s5, REGLOC_s5, v0)
  664.                 SAVE_REG(s6, REGLOC_s6, v0)
  665.                 SAVE_REG(s7, REGLOC_s7, v0)
  666.                 SAVE_REG(t8, REGLOC_t8, v0)
  667.                 SAVE_REG(t9, REGLOC_t9, v0)
  668.                 SAVE_REG(gp, REGLOC_gp, v0)
  669.                 SAVE_REG(sp, REGLOC_sp, v0)
  670.                 SAVE_REG(fp, REGLOC_fp, v0)
  671.                 SAVE_REG(ra, REGLOC_ra, v0)
  672.                 SAVE_REG(v1, REGLOC_EPC, v0)    /* save EPC            */
  673.                 lw      gp, s_gp                /* reload gp                */
  674.                 li      s6, RGST_BASE           /* load global pointer S6   */
  675.                 sw      k0, RF_INTR_FLAG(s6)    /* clear interrupt flag     */
  676.                 jalr    k1                      /* call to service routine  */
  677.                 la      k0, task_state
  678.                 lw      k0, TASK_ENTRY(k0)      /* task_table_entry         */
  679.                 TASK_LOAD_REG(k0)               /* load reg from k0 and write EPC to k1 */
  680.                 ERET(k1)
  681.                 .end    __taskX_service
  682. #endif
  683. /*
  684. ** __panic_service
  685. **
  686. ** when entering this point:
  687. **    k0: interrupt routine
  688. **
  689. ** NOTE:
  690. **   1. save ALL registers
  691. **   2. no return
  692. */
  693.                 .ent    __panic_service
  694. __panic_service:
  695. #ifndef DVDRELEASE
  696.                 la    k1, task_state
  697.                 lw    k1, TASK_ENTRY(k1)            /* load task_table_entry */
  698.                 SAVE_REG(v0, REGLOC_v0, k1)
  699.                 SAVE_REG(v1, REGLOC_v1, k1)
  700.         
  701.                 mfc0 v1, C0_EPC                     /* load EPC in v1        */
  702.                 move v0, k1
  703.                 lw   zero, 0(v1)                    /* load in d-cache      */
  704.                 lw   zero, 16(v1)                   /* load in d-cache      */
  705.                 lw   zero, 32(v1)                   /* load in d-cache      */
  706.                 lw   zero, 48(v1)                   /* load in d-cache      */
  707.                 .set    noat
  708.                 SAVE_REG(AT, REGLOC_AT, v0)
  709.                 .set    at
  710.                 SAVE_REG(a0, REGLOC_a0, v0)
  711.                 SAVE_REG(a1, REGLOC_a1, v0)
  712.                 SAVE_REG(a2, REGLOC_a2, v0)
  713.                 SAVE_REG(a3, REGLOC_a3, v0)
  714.                 SAVE_REG(t0, REGLOC_t0, v0)
  715.                 SAVE_REG(t1, REGLOC_t1, v0)
  716.                 SAVE_REG(t2, REGLOC_t2, v0)
  717.                 SAVE_REG(t3, REGLOC_t3, v0)
  718.                 SAVE_REG(t4, REGLOC_t4, v0)
  719.                 SAVE_REG(t5, REGLOC_t5, v0)
  720.                 SAVE_REG(t6, REGLOC_t6, v0)
  721.                 SAVE_REG(t7, REGLOC_t7, v0)
  722.                 SAVE_REG(s0, REGLOC_s0, v0)
  723.                 SAVE_REG(s1, REGLOC_s1, v0)
  724.                 SAVE_REG(s2, REGLOC_s2, v0)
  725.                 SAVE_REG(s3, REGLOC_s3, v0)
  726.                 SAVE_REG(s4, REGLOC_s4, v0)
  727.                 SAVE_REG(s5, REGLOC_s5, v0)
  728.                 SAVE_REG(s6, REGLOC_s6, v0)
  729.                 SAVE_REG(s7, REGLOC_s7, v0)
  730.                 SAVE_REG(t8, REGLOC_t8, v0)
  731.                 SAVE_REG(t9, REGLOC_t9, v0)
  732.                 SAVE_REG(gp, REGLOC_gp, v0)
  733.                 SAVE_REG(sp, REGLOC_sp, v0)
  734.                 SAVE_REG(fp, REGLOC_fp, v0)
  735.                 SAVE_REG(ra, REGLOC_ra, v0)
  736.                 SAVE_REG(v1, REGLOC_EPC, v0)        /* save EPC            */
  737. #endif
  738.                 lw      gp, s_gp                    // reload gp
  739.                 li      s6, RGST_BASE               // load global pointer s6
  740.                 jalr    k0                          // jump to target
  741.                 // no return
  742.                 .end    __panic_service
  743. #ifndef DVDRELEASE
  744. //
  745. // SYSCALL handler
  746. //
  747. __exception_chk_syscall:
  748.                 la      k0, task_state
  749.                 lw      k0, TASK_ENTRY(k0)        // k0: task_table_entry
  750.                 // save at/v0/v1 into task-table
  751.                 .set    noat
  752.                 SAVE_REG(v0, REGLOC_v0, k0)
  753.                 SAVE_REG(v1, REGLOC_v1, k0)
  754.                 move v0, k0
  755.                 SAVE_REG(AT, REGLOC_AT, v0)
  756.                 .set    at
  757.                 //
  758.                 // call to task-switching routine
  759.                 //
  760.                 // v0/v1/at saved
  761.                 // k0: flag
  762.                 // k1: intr-vect
  763.                 // v1: EPC
  764.                 //
  765.                 mfc0    v1, C0_EPC              // load EPC in v1
  766.                 li      k0, 0                   // FLAG: 0
  767.                 la      k1, intr_timer0         // INTR: timer0
  768.                 addiu   v1, 4                   // v1=v1+4
  769.                 b       __taskX_service2
  770. #endif