📄 universe_dy4.c
字号:
/* * Get DMA interrupt status from Universe II. */ lint_status = vmeIntLvl; /* * See if we have a DMA interrupt. If we do, release the semaphore * to signal to the waiting driver task that the interrupt has * been detected. All interrupt processing takes place within the * DMA driver itself so there is no need to enter the "standard" * checker below (and hence potentially off to an installed vector). */ if ((lint_status & LINT_EN_DMA) == LINT_EN_DMA) { /* Save the current LINT_EN mask */ prevIntLvl = LONGSWAP( *UNIVERSE_LINT_EN ); /* Mask the current interrupt level and lower */ maskLevel(LINT_MASK_DMA); if (vmeDmaInitialised) { STATUS sem_result; /* * Check to see if the task is using the non-blocking DMA * functions. If non-blocking functions are being used, * the sysVmeDmaRoutine pointer will be something other * than NULL. Therefore call user handler if this is detected. * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * NOTE NOTE NOTE: The mixed use of blocking and non-blocking * DMA functions is NOT RECOMMENDED. If this is required, the * task using non-block calls MUST DISCONNECT the sysVmeDmaRoutine * after DMA use by connecting a NULL vector using the * sysVmeDmaConnect() function. This MUST be done BEFORE a * blocking call is used. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * NOTE NOTE NOTE: Since the user function is executing at * interrupt level, the user should be aware that this function * might have a significant impact on interrupt performance. It * is advisable to execute as little as possible in the user * function. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * */ if (sysVmeDmaRoutine != NULL) { /* * Vector to the interrupt rountine specified by the user. */ (* sysVmeDmaRoutine) (); } /* * Signal that the interrupt has been seen by releasing the * binary synchronizing semaphore. */ sem_result = semGive (vmeDmaSyncSem); if( sem_result != OK ) { logMsg ("sysUniverseIntr: Cannot give vmeDmaSyncSem semaphore\n", 0, 0, 0, 0, 0, 0); } } else { logMsg ("Uninitialized VMEbus DMA interrupt\n", 0, 0, 0, 0, 0, 0); } /* * Clear the interrupt . */ *UNIVERSE_LINT_STAT = LONGSWAP(LINT_EN_DMA); /* restore the previous LINT_EN mask */ sysOutLong((UINT32)UNIVERSE_LINT_EN, prevIntLvl); } /* * If the DMA was not the source of the interrupt, enter the * "standard" interrupt handler code below. */ else {#endif /* defined(INCLUDE_VME_DMA) */ /* VME interrupt priority is handled in the ifelse statement in the following order: UNIVERSE_ACFAIL_INT MAILBOX0 UNIVERSE_SYSFAIL_INT UNIVERSE_VERR_INT UNIVERSE_LERR_INT UNIVERSE_VME_SW_IACK_INT LM0 LM1 LM2 LM3 MAILBOX1 MAILBOX2 MAILBOX3 LVL7 LVL6 LVL5 LVL4 LVL3 LVL2 LVL1 0*/ /* Save the current LINT_EN mask */ prevIntLvl = LONGSWAP( *UNIVERSE_LINT_EN ); if (vmeIntLvl & UNIVERSE_ACFAIL_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_ACFAIL); vec_num = UNIV_ACFAIL_INT_VEC; clearInt = LONGSWAP(UNIVERSE_ACFAIL_INT); } else if (vmeIntLvl & UNIVERSE_MBOX0_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_MB0); vec_num = UNIV_MBOX0_INT_VEC; clearInt = LONGSWAP(UNIVERSE_MBOX0_INT); sysMailbox0 = *UNIVERSE_MBOX0; } else if (vmeIntLvl & UNIVERSE_SYSFAIL_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_SYSFAIL); vec_num = UNIV_SYSFAIL_INT_VEC; clearInt = LONGSWAP(UNIVERSE_SYSFAIL_INT); } else if (vmeIntLvl & UNIVERSE_VERR_INT) { /*Mask the current interrupt level and lower*/ /* added by fzz for test */ #ifdef VME_INT_DEBUG logMsg ("received VERR interrupt, enter VERR ISR. \n", 0, 0,0,0,0,0); #endif maskLevel( LINT_MASK_VERR); vec_num = UNIV_VERR_INT_VEC; clearInt = LONGSWAP(UNIVERSE_VERR_INT); } else if (vmeIntLvl & UNIVERSE_LERR_INT) { /*Mask the current interrupt level and lower*/ maskLevel( LINT_MASK_LERR); vec_num = UNIV_LERR_INT_VEC; clearInt = LONGSWAP(UNIVERSE_LERR_INT); } else if (vmeIntLvl & UNIVERSE_PCI_SW_INT) { /* This interrupt is disabled by default */ vec_num = UNIV_PCI_SW_INT_VEC; clearInt = LONGSWAP(UNIVERSE_PCI_SW_INT); } else if (vmeIntLvl & UNIVERSE_VME_SW_IACK_INT) { /*Mask the current interrupt level and lower*/ maskLevel( LINT_MASK_SW_IACK); vec_num = UNIV_VME_SW_IACK_INT_VEC; clearInt = LONGSWAP(UNIVERSE_VME_SW_IACK_INT); }/* * Note: * The DMA interrupts are handled in the first part of the function and the * following lines are used to handle an unexpected VME DMA interrupt if VME_DMA * is not included */#ifndef INCLUDE_VME_DMA else if (vmeIntLvl & UNIVERSE_DMA_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_DMA); vec_num = UNIV_DMA_INT_VEC; clearInt = LONGSWAP(UNIVERSE_DMA_INT); }#endif else if (vmeIntLvl & UNIVERSE_LM0_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_LM0); vec_num = UNIV_LM0_INT_VEC; clearInt = LONGSWAP(UNIVERSE_LM0_INT); } else if (vmeIntLvl & UNIVERSE_LM1_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_LM1); vec_num = UNIV_LM1_INT_VEC; clearInt = LONGSWAP(UNIVERSE_LM1_INT); } else if (vmeIntLvl & UNIVERSE_LM2_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_LM2); vec_num = UNIV_LM2_INT_VEC; clearInt = LONGSWAP(UNIVERSE_LM2_INT); } else if (vmeIntLvl & UNIVERSE_LM3_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_LM3); vec_num = UNIV_LM3_INT_VEC; clearInt = LONGSWAP(UNIVERSE_LM3_INT); } else if (vmeIntLvl & UNIVERSE_MBOX1_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_MB1); vec_num = UNIV_MBOX1_INT_VEC; clearInt = LONGSWAP(UNIVERSE_MBOX1_INT); sysMailbox1 = *UNIVERSE_MBOX1; } else if (vmeIntLvl & UNIVERSE_MBOX2_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_MB2); vec_num = UNIV_MBOX2_INT_VEC; clearInt = LONGSWAP(UNIVERSE_MBOX2_INT); sysMailbox2 = *UNIVERSE_MBOX2; } else if (vmeIntLvl & UNIVERSE_MBOX3_INT) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_MB3); vec_num = UNIV_MBOX3_INT_VEC; clearInt = LONGSWAP(UNIVERSE_MBOX3_INT); sysMailbox3 = *UNIVERSE_MBOX3; } /* * for VME level 1-7 interrupts, * get the vector number by reading the appropriate STATID reg. */ else if (vmeIntLvl & LVL7) { /*Mask the current interrupt level and lower*/ maskLevel( LINT_MASK_VIRQ7); vec_num = LONGSWAP(*UNIVERSE_V7_STATID); clearInt = LONGSWAP(LVL7); /* clear the vme intr */ } else if (vmeIntLvl & LVL6) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_VIRQ6); vec_num = LONGSWAP(*UNIVERSE_V6_STATID); clearInt = LONGSWAP(LVL6); /* clear the vme intr */ } else if (vmeIntLvl & LVL5) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_VIRQ5) ; vec_num = LONGSWAP(*UNIVERSE_V5_STATID); clearInt = LONGSWAP(LVL5); /* clear the vme intr */ } else if (vmeIntLvl & LVL4) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_VIRQ4); vec_num = LONGSWAP(*UNIVERSE_V4_STATID); clearInt = LONGSWAP(LVL4); /* clear the vme intr */ } else if (vmeIntLvl & LVL3) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_VIRQ3); vec_num = LONGSWAP(*UNIVERSE_V3_STATID); clearInt = LONGSWAP(LVL3); /* clear the vme intr */ } else if (vmeIntLvl & LVL2) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_VIRQ2); vec_num = LONGSWAP(*UNIVERSE_V2_STATID); clearInt = LONGSWAP(LVL2); /* clear the vme intr */ } else if (vmeIntLvl & LVL1) { /*Mask the current interrupt level and lower*/ maskLevel(LINT_MASK_VIRQ1); vec_num = LONGSWAP(*UNIVERSE_V1_STATID); clearInt = LONGSWAP(LVL1); /* clear the vme intr */ } else { /* Unknown interrupt... */ vec_num = 0; logMsg ("received unknown interrupt %d\n", 0, 0,0,0,0,0); clearInt = LONGSWAP(0xffff); } /*added by fzz for test */ #ifdef VME_INT_DEBUG logMsg ("The vec_num read from STATID is %#x\n", vec_num, 0,0,0,0,0); #endif vec_num &= 0xff; intVecNum = vec_num; if (vec_num == 0) { logMsg ("bad vme interrupt %d\n", intVecNum, 0,0,0,0,0); return; } if ((currHandler = sysIntTbl [intVecNum]) == NULL) {#ifdef INCLUDE_VME_DMA if(intVecNum != UNIV_DMA_INT_VEC)#endif logMsg ("Default handler for vector%d\n", intVecNum, 0,0,0,0,0); } else { while (currHandler != NULL) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } /* Clear the interrupt from the UNIVERSE and reset the lint reg*/ *UNIVERSE_LINT_STAT = clearInt; /* restore the previous LINT_EN mask */ sysOutLong((UINT32)UNIVERSE_LINT_EN, prevIntLvl); /* *UNIVERSE_LINT_EN = LONGSWAP(prevIntLvl); */ /* If the DMA code is include and we found a DMA interrupt, don't enter the * normal section (above) which will tell us we have hit the default * handler for vector 32 (since we don't set these values in the DMA section). */#if defined(INCLUDE_VME_DMA) }#endif}/********************************************************************************* maskLevel - Masks the current interrupt and lower** This routine masks the current interrupt and all other lower priority* universe related interrupts. It takes the given mask and writes it to the* LINT_EN register.** RETURNS: N/A.** NOMANUAL*/void maskLevel(int IntMask){ int temp; temp = intLock(); /* Lock the interrupts before changing the Mask*/ sysOutLong((UINT32)UNIVERSE_LINT_EN, IntMask); intUnlock(temp); return;}#ifdef INCLUDE_VME_SHOW/******************************************************************************** sysVmeMapShow - display VME access windows** This routine prints the mapped VME slave and master access windows and the* Universe Register acces window.* The slave access windows are mapped with the Universe VME slave images.* The master access windows are mapped with the Universe PCI slave images.* Note: This function supports only the default BSP VME slave images and* VME slave images created by sysUniverseSlaveImageSet()* RETURNS: N/A** SEE ALSO: sysVmeA32MstrSet*/void sysVmeMapShow (void){ int image; UINT32 vraiCtlRegVal; UINT32 uniIOLocalAdrs; printf ("\t\t\tVME SLAVE ACCESS WINDOWS\n"); printf ("\t\t\t========================\n\n"); printf("VME\tImage\t\tVME Base\t Size\t\tLocal Base\n"); printf("---\t-----\t\t--------\t ----\t\t----------\n"); printf("A24\t"); printf("VME %2d\t\t",0); /* printf("0x%.8x\t",(int)sysVmeA24AddrGet()); printf("0x%.8x\t",(int)VME_A24_SLV_SIZE); printf("0x%.8x\n",(int)VME_A24_SLV_LOCAL); */ printf("0x%.8x\t",LONGSWAP(*sysVmeSlaveDesc[0].bs)); printf("0x%.8x\t",LONGSWAP(*sysVmeSlaveDesc[0].bd)-LONGSWAP(*sysVmeSlaveDesc[0].bs)); printf("0x%.8x\n",LONGSWAP(*sysVmeSlaveDesc[0].bs)+LONGSWAP(*sy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -