?? irq.c
字號:
/* SCCSID @(#)irq.c 1.9 7/9/98 */ /************************************************************************** * * Copyright 1996, ESS Technology, Inc. * Module: irq.c * *************************************************************************/ #include "../mvd.h"#include "../common.h"#include "../dsc.h"#include "util.h"#include "../timedef.h"#ifdef IRQSHARE#include "../irqshare.h"extern unsigned int dbgirq ;#endif IRQSHARE/* Globals */#define PSW_ENABLE_IRQ 0x1FC3 /* EEEEevVsS all on */extern int pcring;/* * Since we are not saving all the registers, there is no point to * reserve 32*4 bytes in stack for registers. Following macros define * where each register is saved. */#define _REG_1 0#define _REG_2 1#define _REG_3 2#define _REG_4 3#define _REG_5 4#define _REG_6 5#define _REG_7 6#define _REG_8 7#define _REG_9 8#define _REG_10 9#define _REG_11 10#define _REG_12 11#define _REG_13 12#define _REG_14 13#define _REG_15 14#define _REG_16 15#define _REG_17 16#define _REG_18 17#define _REG_19 18#define _REG_22 19#define _REG_23 20#define _REG_24 21#define _REG_26 22#define _REG_28 23#define _REG_32 24 #define _REG_33 25 #define _REG_34 26 #define _TOTAL_REG (_REG_34 + 1)#define INTERVAL 500 /* In msec (i.e. timer will be .5 sec) *//************************************************************************ * Imported routines. * ************************************************************************/IMPORT void EXTIRQ_interrupt_service(void);/* * Real-time clock is always at DRAM location 0x12. The format is: 00hhmmss * where hh is hour (0-23), mm is minute (0-59), ss is half second (0-119) * * Since this variable is always changing, I'll make sure the cache copy * is consistent with the DRAM version even though we only use the DRAM * version (otherwise, old cache data may destroy DRAM data by accident) */extern unsigned int *RISC_ptr_realtime;extern unsigned int *RISC_cache_realtime;/* Set timer2 interrupt period */int vcx_timer_val = (0x0 - (INTERVAL * CPUCLK * 100));/*------------------------------------------------------------------------ Description: This function is called on every video vertical sync and to increase the glbTimer variable. If the output mode is PAL, we will add two to the glbTimer. Thus, we only have one the glbTimer which is 1/60 second if the output mode is NTSC, or roughly 1/60 if the output mode is PAL.------------------------------------------------------------------------*//* No need to save R23, R24 , which are code base register . Min*//* * Interrupt service routine when ucos is not used. */EVD_Interrupt(){ register unsigned pc0 asm("r20"), pc1 asm("r21"), pc2 asm("r22"); unsigned utemp; int interupt_enabled; int savepsw; int irqmask_save; int rdmadonemask_save; int regtable[_TOTAL_REG]; /* Save registers */ asm("st %0,r1" : : "m" (regtable[_REG_1])); asm("st %0,r2" : : "m" (regtable[_REG_2])); asm("st %0,r3" : : "m" (regtable[_REG_3])); asm("st %0,r4" : : "m" (regtable[_REG_4])); asm("st %0,r5" : : "m" (regtable[_REG_5])); asm("st %0,r6" : : "m" (regtable[_REG_6])); asm("st %0,r7" : : "m" (regtable[_REG_7])); asm("st %0,r8" : : "m" (regtable[_REG_8])); asm("st %0,r9" : : "m" (regtable[_REG_9])); asm("st %0,r10" : : "m" (regtable[_REG_10])); asm("st %0,r11" : : "m" (regtable[_REG_11])); asm("st %0,r12" : : "m" (regtable[_REG_12])); asm("st %0,r13" : : "m" (regtable[_REG_13])); asm("st %0,r14" : : "m" (regtable[_REG_14])); asm("st %0,r15" : : "m" (regtable[_REG_15])); asm("st %0,r16" : : "m" (regtable[_REG_16])); asm("st %0,r17" : : "m" (regtable[_REG_17])); asm("st %0,r18" : : "m" (regtable[_REG_18])); asm("st %0,r19" : : "m" (regtable[_REG_19])); asm("st %0,r22" : : "m" (regtable[_REG_22])); asm("st %0,r26" : : "m" (regtable[_REG_26])); asm("st %0,r28" : : "m" (regtable[_REG_28])); /* 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)); interupt_enabled = 0; /* The S bit (PC chain shifting enable) must be 0. */ if (utemp & 1) DSC_dead(0xbad1); /* Alignment error. */ if (utemp & 0x8000000) DSC_dead(0xbad2); 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++; } asm("st %0,r20" : : "m" (regtable[_REG_32])); asm("st %0,r21" : : "m" (regtable[_REG_33])); asm("st %0,r22" : : "m" (regtable[_REG_34]));#if 1 /* Interrupt dispatcher */ if (mvd[riface_irqstatus] & buscon_irq) {#if 1 /* enabling interupt in audio, might cause 2 levels */ /* enable interrupt */ if (!interupt_enabled) { interupt_enabled = 1; asm volatile("movfrs psw,%0" : "=r" (utemp) ); savepsw = utemp; rdmadonemask_save = mvd[rdma_donemask]; mvd[rdma_donemask] = rdma_audiow_enable; irqmask_save = mvd[riface_irqmask];#ifdef IR mvd[riface_irqmask] = RIFACE_LD_IRQSUPRESS | vout_irq | debug_irq;#else mvd[riface_irqmask] = RIFACE_LD_IRQSUPRESS | vout_irq;#endif asm("addi r0,#8,r2"); /* disable interrupts */ asm("st %0,r2" : : "m" (mvd[riface_irqsuppress])); asm("nop"); asm("addi r0,#(%0),r2" : : "I" (PSW_ENABLE_IRQ)); /* reenable IRQs */ asm("movtos r2,psw"); /* and PC Chain shifting */ }#endif EVD_BUSCON_interrupt_service();#if 1 mvd[riface_irqsuppress] =0; asm("nop"); asm("nop"); if (interupt_enabled) { asm volatile("movtos %0,psw" : : "r" (savepsw)); mvd[riface_irqmask] = irqmask_save; mvd[rdma_donemask] = rdmadonemask_save; }#endif }#endif#ifdef CD_LOAD if (mvd[riface_irqstatus] & xport_irq) { XPORT_interrupt_service(); } if (mvd[riface_irqstatus] & tdm_irq) { TDM_interrupt_service(); }#endif if (mvd[riface_irqstatus] & vout_irq) { if (mvd[vid_scn_status] & 0x10) update_glbTimer(); EVD_DISP_interrupt_service(); } if (mvd[riface_irqstatus] & tim2_irq) { RISC_timer2_interrupt_service(); }#ifdef SERVO2545 if (mvd[riface_irqstatus] & tim1_irq) { RISC_timer1_interrupt_service(); }#endif#ifdef IR if (mvd[riface_irqstatus] & debug_irq) EXTIRQ_interrupt_service();#endif /* IR */ /*InterruptLevel--;*/ /* restore PC chain */ asm("ld %0,r20" : : "m" (regtable[_REG_32])); asm("ld %0,r21" : : "m" (regtable[_REG_33])); asm("ld %0,r22" : : "m" (regtable[_REG_34])); asm volatile("movtos %0,pcm1" : : "r" (pc0)); asm volatile("movtos %0,pcm1" : : "r" (pc1)); asm volatile("movtos %0,pcm1" : : "r" (pc2)); asm("ld 16[r29],r2"); /* load r31 return address to r2 */ asm("st 0[r30],r2"); /* store it somewhere in prev stack frame */ /* asm("addi r24,#_hack_leave,r2"); /* put it the new return address */ asm("ld ret_addr[r25],r2"); /* put it the new return address */ asm("st 16[r29],r2"); /* restore registers */ asm("ld %0,r1" : : "m" (regtable[_REG_1])); asm("ld %0,r2" : : "m" (regtable[_REG_2])); asm("ld %0,r3" : : "m" (regtable[_REG_3])); asm("ld %0,r4" : : "m" (regtable[_REG_4])); asm("ld %0,r5" : : "m" (regtable[_REG_5])); asm("ld %0,r6" : : "m" (regtable[_REG_6])); asm("ld %0,r7" : : "m" (regtable[_REG_7])); asm("ld %0,r8" : : "m" (regtable[_REG_8])); asm("ld %0,r9" : : "m" (regtable[_REG_9])); asm("ld %0,r10" : : "m" (regtable[_REG_10])); asm("ld %0,r11" : : "m" (regtable[_REG_11])); asm("ld %0,r12" : : "m" (regtable[_REG_12])); asm("ld %0,r13" : : "m" (regtable[_REG_13])); asm("ld %0,r14" : : "m" (regtable[_REG_14])); asm("ld %0,r15" : : "m" (regtable[_REG_15])); asm("ld %0,r16" : : "m" (regtable[_REG_16])); asm("ld %0,r17" : : "m" (regtable[_REG_17])); asm("ld %0,r18" : : "m" (regtable[_REG_18])); asm("ld %0,r19" : : "m" (regtable[_REG_19])); asm("ld %0,r22" : : "m" (regtable[_REG_22])); asm("ld %0,r26" : : "m" (regtable[_REG_26])); asm("ld %0,r28" : : "m" (regtable[_REG_28]));}asm("\n.data");asm("\nret_addr:");asm("\n.word _hack_leave");asm("\n.text");/* ******** Interrupt return routine ******** */asm("\n.noreorg");asm("\n_hack_leave:");asm("st 0x4028[r27],r0");asm("ld 0[r29],r31"); /* put back r31 */asm("nop");asm("jpcrs"); /* jump pc/restore states */asm("jpc"); /* jump pc */asm("jpc"); /* jump pc */asm(".reorgon");/* Interrupt startup code */ asm("\n.globl _evd_trap0"); asm("\n_evd_trap0:"); asm("\n.noreorg"); asm("nop"); asm("jspci r24,#_EVD_Interrupt,r0"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("\n.end");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -