?? int.c
字號:
/* SCCSID @(#)int.c 1.34 8/28/98 *//* * Add in IRQSHARE for sharing debug_irq interrupt for Subcode and IR * requires an external GAL16V8 for interrupt sharing * * by Andy Ho */#include "common.h"#include "dsc.h"#include "util.h"#include "display.h"#include "buffer.h"#include "xport.h"#include "tdm.h"#include "servo.h"#ifdef IR#include "ir.h"#endif#ifdef SPDIF#include "spdif.h"#endif#if (CUST6 || TVM_MODULE) #include "config.h"#endif#ifdef IRQSHARE#include "irqshare.h"unsigned int dbgirq ;#endif IRQSHARE#ifdef CUST6extern unsigned int Timer5m;#endif#ifdef CUST8_5DISKIMPORT void RISC_timer1_interrupt_service(void);#endif#ifdef SERVO2545IMPORT void RISC_timer1_interrupt_service(void);#endifint pcring;#ifndef DRAM_GAMEPRIVATE #endifint regtable[32];#ifdef DSP2540extern void intr_tim1_act(void) ;#endif/************************************************************************ * Global functions. * ************************************************************************/extern void EXTIRQ_interrupt_service(void);/* * We have many compilation flags for this service yet VCD 3.0 has a * separate __interrupt() routine. In order to simplify maintainance, * I have common routine so 3.0 can share it as well. */void EXTIRQ_interrupt_service(){ unsigned int utemp;#ifdef IRQSHARE /* One shot deal for Andy's Submariner board */ READ_IRQ(dbgirq); /* * It has to be either IR or SERVO. However, SERVO (s0s1) interrupt * is much narrower, and we may miss it if interrupt latency is * too long. * * If nobody clears dbgirq, interrupt will keep on coming in. So * if it is not IR interrupt, we better just call * SERVO_interrupt_service instead of checking whether it is s0s1 * (if we check and found it is not s0s1, it is most likely that * we had a long interrupt latency.) */ if (IR_INT_HIGH(dbgirq)) IR_recv_interrupt_service(); else SERVO_interrupt_service();#else /* Normal ESS solutions */#ifndef DSC_IRQ#ifdef IR /* Older style: IR to 3210 */ IR_recv_interrupt_service();#endif /* IR */#else /* New style: interrupts are connected to 3881 */ utemp = DSC_cmd(dsc_sys_statusm, 0);#ifdef IR if (utemp & 0x04) IR_recv_interrupt_service(utemp);#endif /* IR */#ifdef DSC_ENABLE_S0S1 if (utemp & 0x08) SERVO_interrupt_service();#endif#ifdef DSC_ENABLE_C2PO if (utemp & 0x20) { C2PO_interrupt = 1; /* C2PO interrupt handler */ DSC_cmd(dsc_sys_status, 0x20); /* Clear 3881's interrupt */ mvd[riface_clear_dbgirq] = 0; /* Clear 3210's debug_irq */ }#endif#endif /* else of DSC_IRQ */#endif /* IRQSHARE */}/****************************************************************************** Interrupt service routine when ucos is not used. ******************************************************************************/__Interrupt(){ /* * The current compiler always saves r16 to r21 at a procedure * boundary if it want to use any of these register. Therefore, * it is safe to put pc0, pc1, pc2 in r19, r20 and r21 respectively. * * But these assignments are strongly compiler dependent. */ register unsigned pc0 asm("r19"), pc1 asm("r20"), pc2 asm("r21"); unsigned utemp; asm(".globl _Interrupt"); asm("\n_Interrupt:"); /* First save registers */ asm("st _regtable+1*4[r0],r1"); asm("st _regtable+2*4[r0],r2"); asm("st _regtable+3*4[r0],r3"); asm("st _regtable+4*4[r0],r4"); asm("st _regtable+5*4[r0],r5"); asm("st _regtable+6*4[r0],r6"); asm("st _regtable+7*4[r0],r7"); asm("st _regtable+8*4[r0],r8"); asm("st _regtable+9*4[r0],r9"); asm("st _regtable+10*4[r0],r10"); asm("st _regtable+11*4[r0],r11"); asm("st _regtable+12*4[r0],r12"); asm("st _regtable+13*4[r0],r13"); asm("st _regtable+14*4[r0],r14"); asm("st _regtable+15*4[r0],r15"); asm("st _regtable+16*4[r0],r16"); asm("st _regtable+17*4[r0],r17"); asm("st _regtable+18*4[r0],r18"); asm("st _regtable+19*4[r0],r19"); asm("st _regtable+20*4[r0],r20"); asm("st _regtable+21*4[r0],r21"); asm("st _regtable+22*4[r0],r22"); asm("st _regtable+26*4[r0],r26"); asm("st _regtable+28*4[r0],r28"); asm("st _regtable+29*4[r0],r29"); asm("st _regtable+30*4[r0],r30"); asm("st _regtable+31*4[r0],r31"); /* Save the PC chain */ asm volatile("movfrs pcm4,%0" : "=r" (pc0)); asm volatile("movfrs pcm4,%0" : "=r" (pc1)); asm volatile("movfrs pcm4,%0" : "=r" (pc2)); /* For debugging only */ asm volatile("movfrs psw,%0" : "=r" (utemp)); /* The S bit (PC chain shifting enable) must be 0. */ if (utemp & 1) DSC_dead(0xbad1); /* Alignment error. */ if (utemp & 0x8000000) DSC_dead(0xbad2);#if 0 /* Interrupt dispatcher */ { unsigned i, status, save_mask; IntVectorDesc *Vector; void (*service)(); Vector = &IntVector[0]; status = mvd[riface_irqstatus]; for (i=0; i<VectorNum; i++,Vector++) { if (status & Vector->TestBit) { save_mask = mvd[riface_irqmask]; service = Vector->service; mvd[riface_irqsuppress] = 0; mvd[riface_irqmask] = Vector->MaskBit; service(); mvd[riface_irqmask] = save_mask; } } }#endif if (mvd[riface_irqstatus] & buscon_irq) { BUSCON_interrupt_service(); } if (mvd[riface_irqstatus] & vout_irq) { if (mvd[vid_scn_status] & 0x10) update_glbTimer(); DISP_interrupt_service(); } if (mvd[riface_irqstatus] & tim2_irq) { RISC_timer2_interrupt_service(); }#ifdef DVD_VCD if (mvd[riface_irqstatus] & host_irq) { listen_to_hellen(); }#endif#ifdef MPEG1 if (mvd[riface_irqstatus] & xport_irq) {#ifdef DVD_VCD /* * Since there is no separate TDM interrupt, handle it now if * all the data is in. */ if (XPORT_interrupt_service()) TDM_interrupt_service();#else XPORT_interrupt_service();#endif } if (mvd[riface_irqstatus] & tdm_irq) { TDM_interrupt_service(); }#endif#ifdef CUST6 if(mvd[riface_irqstatus] & debug_irq) { if(scor_in_hh) Scor_Interrupt(); else IR_recv_interrupt_service(); } if (mvd[riface_irqstatus] & tim1_irq) { /* IR transmitting */ ++Timer5m; /* Timer_5msec();*/ mvd[riface_clear_timer1] = 0; if(IS_POWER_DOWN) mvd[riface_timer1] = 0x0 -5*IDLECLK*100; else mvd[riface_timer1] = 0x0 - 5*CPUCLK*100; /* * Since this routine will be called repeatedly, it is better * to enable interrupt outside. */ }#endif /* CUST6 */#ifdef TVM_MODULE#ifdef CUST8_5DISK /* 6 mili-second counter */ if (mvd[riface_irqstatus] & tim1_irq) RISC_timer1_interrupt_service(); #endif if(mvd[riface_irqstatus] & debug_irq) { if(DBG_RECEIVING_IR) IR_recv_interrupt_service(); else { sclk_isr(); mvd[riface_clear_dbgirq] = 0; /* Clear debug_irq */ } } #endif /* TVM_MODULE */#ifdef SERVO2545 /* N mili-second counter */ if (mvd[riface_irqstatus] & tim1_irq) RISC_timer1_interrupt_service(); #endif#ifdef IR#ifdef IRXMT if (mvd[riface_irqstatus] & tim1_irq) { /* IR transmitting */ IR_xmit_interrupt_service(); }#endif /* IRXMT */#if (!CUST6 && !TVM_MODULE) if (mvd[riface_irqstatus] & debug_irq) /* An external int. */ EXTIRQ_interrupt_service();#endif /* !CUST6 && !TVM_MODULE */#endif /* IR */#ifdef C80#ifdef DSP2540#ifdef SCOR_INT if (mvd[riface_irqstatus] & debug_irq) { s_scor_by_intrpt(); }#else if (mvd[riface_irqstatus] & tim1_irq) { intr_tim1_act() ; }#endif /* CSOR_INT */#endif /* DSP2540 */#endif /* C80 */#if 0#ifdef SPDIF if (mvd[riface_irqstatus] & debug_irq) { /* S/PDIF output */ SPDIF_out_interrupt_service(); }#endif#endif pcring = pc0 << 2; utemp = *((unsigned *)pcring); if ((utemp>>28)==9) pc0 = 0; /* Store */ if (!pc0 && !pc1) { /* Squashed branch */ utemp = *((int *)((pc2-2)<<2)); if (!(utemp & 0xc0000000)) pc2++; } /* We are stucked! (PC chain has the same value) */ if (pc0 == pc2) DSC_dead(0xbad3); /* restore PC chain */ asm volatile("movtos %0,pcm1" : : "r" (pc0)); asm volatile("movtos %0,pcm1" : : "r" (pc1)); asm volatile("movtos %0,pcm1" : : "r" (pc2)); /* restore registers */ asm("ld _regtable+1*4[r0],r1"); asm("ld _regtable+2*4[r0],r2"); asm("ld _regtable+3*4[r0],r3"); asm("ld _regtable+4*4[r0],r4"); asm("ld _regtable+5*4[r0],r5"); asm("ld _regtable+6*4[r0],r6"); asm("ld _regtable+7*4[r0],r7"); asm("ld _regtable+8*4[r0],r8"); asm("ld _regtable+9*4[r0],r9"); asm("ld _regtable+10*4[r0],r10"); asm("ld _regtable+11*4[r0],r11"); asm("ld _regtable+12*4[r0],r12"); asm("ld _regtable+13*4[r0],r13"); asm("ld _regtable+14*4[r0],r14"); asm("ld _regtable+15*4[r0],r15"); asm("ld _regtable+16*4[r0],r16"); asm("ld _regtable+17*4[r0],r17"); asm("ld _regtable+18*4[r0],r18"); asm("ld _regtable+19*4[r0],r19"); asm("ld _regtable+20*4[r0],r20"); asm("ld _regtable+21*4[r0],r21"); asm("ld _regtable+22*4[r0],r22"); asm("ld _regtable+26*4[r0],r26"); asm("ld _regtable+28*4[r0],r28"); asm("st 0x4028[r27],r0"); /* irqsupress */ asm("ld _regtable+29*4[r0],r29"); asm("ld _regtable+30*4[r0],r30"); asm("ld _regtable+31*4[r0],r31"); /* return from interrupt */ asm("\n.noreorg"); asm("jpcrs"); asm("jpc"); asm("jpc"); asm(".reorgon");}/****************************************************************************** INITIALIZE TRAP VECTOR ******************************************************************************/asm("\n.globl _trap0");asm("\n_trap0:");asm("\n.noreorg");asm("nop");asm("jspci r24,#_Interrupt,r0");asm("nop");asm("nop");asm("\n.end");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -