📄 xp_osi_inter.c
字号:
static SHORT del_mask(GLOBAL_RESOURCES * pGlobal,ULONG ulMask,PFS notify_fn, INTERRUPT_INFO_PTR pInfo){ short i; short count=0; for (i=0; i<pInfo->wNotifyAlloc; i++) { if((ulMask == pInfo->pNotify[i].ulMask) && (notify_fn == pInfo->pNotify[i].notify_fn)) { pInfo->pNotify[i].ulMask = 0; pInfo->pNotify[i].notify_fn = NULL; pInfo->wNotifyCount--; count++; } } if(count == 0) { return(XP_ERROR_INTER_MASK); } return(0);}/*----------------------------------------------------------------------------+| reset_mask+----------------------------------------------------------------------------*/static void reset_mask(GLOBAL_RESOURCES *pGlobal,INTERRUPT_INFO_PTR pInfo){ if(pInfo->wNotifyAlloc > 0) { pInfo->wNotifyAlloc = 0; FREE(pInfo->pNotify); pInfo->pNotify = NULL; } pInfo->wNotifyCount = 0;}/*----------------------------------------------------------------------------+| XXXXXXX XXX XXX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX| XX X XX XX X XX X XX X XX XX XXX XX XXXX XX| XX X XXX XX XX X XX XX XXXX XX XX XX XX| XXXX X XX XXXX XXXXX XX XXXX XX XX XX| XX X XXX XX XX X XX XX XX XXX XXXXXX XX| XX X XX XX XX XX X XX XX XX XX XX XX XX XX| XXXXXXX XXX XXX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX+----------------------------------------------------------------------------*/void *xp_osi_task(QUEUE_T *pQueue){ XP_OS_MSG_TYPE msg; /* message received */ /*------------------------------------------------------------------------+ | Wait for and process messages +------------------------------------------------------------------------*/ while(os_irq_task_get_msg(pQueue, &msg) >= 0) { (*msg.notify_fn)(msg.pGlobal, msg.wChannelId, msg.ulInterrupt); } return (NULL);}/*----------------------------------------------------------------------------+| xp0_interrupt+-----------------------------------------------------------------------------+|| FUNCTION : xp0_interrupt|| DESCRIPTION : process all interrupts from transport|+----------------------------------------------------------------------------*/void xp_osi_interrupt(){ short i, j; unsigned long interrupt; /*------------------------------------------------------------------------+ | Read & clear the primary interrupts. | Process all the interrupt bits which were set +------------------------------------------------------------------------*/ if(pXp0Global == NULL) return; interrupt = xp_atom_dcr_read_interrupt(pXp0Global->uDeviceIndex); for(i=0, j=0; i<pXp0Global->InterInfo.XpInterPriInt.wNotifyAlloc && j<pXp0Global->InterInfo.XpInterPriInt.wNotifyCount; i++) { if(interrupt & pXp0Global->InterInfo.XpInterPriInt.pNotify[i].ulMask) { j++; if(pXp0Global->InterInfo.XpInterPriInt.pNotify[i].notify_fn) { (*pXp0Global->InterInfo.XpInterPriInt.pNotify[i].notify_fn)(pXp0Global, interrupt); } } } /*------------------------------------------------------------------------+ | Call primary handlers for interrupt hierarchy +------------------------------------------------------------------------*/ if(interrupt & XP_INTERRUPT_IR_QUE) { channel_interrupt(pXp0Global); } if(interrupt & XP_INTERRUPT_IR_FES) { status_interrupt(pXp0Global); } if(interrupt & XP_INTERRUPT_IR_VID) { video_interrupt(pXp0Global); } if(interrupt & XP_INTERRUPT_IR_AUD) { audio_interrupt(pXp0Global); }}void xp1_interrupt(GLOBAL_RESOURCES *pXp0Global, ULONG ulXp0Int){ short i, j; unsigned long interrupt; GLOBAL_RESOURCES *pGlobal; pGlobal = pXp1Global; if(pGlobal == NULL) { return; } /*------------------------------------------------------------------------+ | Read & clear the primary interrupts. | Process all the interrupt bits which were set +------------------------------------------------------------------------*/// flag = os_enter_critical_section(); interrupt = xp_atom_dcr_read_interrupt(pGlobal->uDeviceIndex);// os_leave_critical_section(flag); for(i=0, j=0; i<pGlobal->InterInfo.XpInterPriInt.wNotifyAlloc && j<pGlobal->InterInfo.XpInterPriInt.wNotifyCount; i++) { if(interrupt & pGlobal->InterInfo.XpInterPriInt.pNotify[i].ulMask) { j++; if(pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn) { (*pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn)(pGlobal, interrupt); } } } /*------------------------------------------------------------------------+ | Call primary handlers for interrupt hierarchy +------------------------------------------------------------------------*/ if(interrupt & XP_INTERRUPT_IR_QUE) { channel_interrupt(pGlobal); } if(interrupt & XP_INTERRUPT_IR_FES) { status_interrupt(pGlobal); }}void xp2_interrupt(GLOBAL_RESOURCES *pXp0Global, ULONG ulXp0Int){ short i, j; unsigned long interrupt; GLOBAL_RESOURCES *pGlobal; pGlobal = pXp2Global; if(pGlobal == NULL) { return; } /*------------------------------------------------------------------------+ | Read & clear the primary interrupts. | Process all the interrupt bits which were set +------------------------------------------------------------------------*/// flag = os_enter_critical_section(); interrupt = xp_atom_dcr_read_interrupt(pGlobal->uDeviceIndex);// os_leave_critical_section(flag); for(i=0, j=0; i<pGlobal->InterInfo.XpInterPriInt.wNotifyAlloc && j<pGlobal->InterInfo.XpInterPriInt.wNotifyCount; i++) { if(interrupt & pGlobal->InterInfo.XpInterPriInt.pNotify[i].ulMask) { j++; if(pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn) { (*pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn)(pGlobal, interrupt); } } } /*------------------------------------------------------------------------+ | Call primary handlers for interrupt hierarchy +------------------------------------------------------------------------*/ if(interrupt & XP_INTERRUPT_IR_QUE) { channel_interrupt(pGlobal); } if(interrupt & XP_INTERRUPT_IR_FES) { status_interrupt(pGlobal); }}/*----------------------------------------------------------------------------+| xp0_interrupt_init+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_init(GLOBAL_RESOURCES *pGlobal){ short rc = 0; UINT32 flag; PDEBUG("pGlobal->uDeviceIndex = %x\n",pGlobal->uDeviceIndex); switch(pGlobal->uDeviceIndex) { case 0: pXp0Global = pGlobal; break; case 1: pXp1Global = pGlobal; break; case 2: pXp2Global = pGlobal; break; default: break; } /*------------------------------------------------------------------------+ | Initialize all the interrupt structures +------------------------------------------------------------------------*/ memset(&pGlobal->InterInfo.XpInterStatInt, 0, sizeof(pGlobal->InterInfo.XpInterStatInt)); memset(&pGlobal->InterInfo.XpInterPriInt, 0, sizeof(pGlobal->InterInfo.XpInterPriInt)); memset(&pGlobal->InterInfo.XpInterChanInt, 0, sizeof(pGlobal->InterInfo.XpInterChanInt)); if(pGlobal->uDeviceIndex == 0) { flag = os_enter_critical_section(); xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_INTMASK, XP0_PRIMARY_SET_MASK); os_leave_critical_section(flag); } else { flag = os_enter_critical_section(); xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_INTMASK, XP12_PRIMARY_SET_MASK); os_leave_critical_section(flag); } pGlobal->InterInfo.XpInterChanMask = 0; pGlobal->InterInfo.XpInterPriMask = 0; if(pXp0Global == NULL) return -1; if(pGlobal->uDeviceIndex == 0) { if(os_add_irq_task(XP_IRQ,(void*)xp_osi_task,sizeof(XP_OS_MSG_TYPE),QUEUE_SIZE)) return -1; } if(pGlobal->uDeviceIndex == 1) rc = xp_osi_interrupt_notify(pXp0Global,XP_INTERRUPT_NOTIFY_ADD, XP_INTERRUPT_IR_X1INT, (PFS)xp1_interrupt); else if(pGlobal->uDeviceIndex == 2) rc = xp_osi_interrupt_notify(pXp0Global,XP_INTERRUPT_NOTIFY_ADD, XP_INTERRUPT_IR_X2INT, (PFS)xp2_interrupt); return(rc);}/*----------------------------------------------------------------------------+| xp0_interrupt_channel_control+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_channel_control(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId, XP_INTERRUPT_CONTROL_TYPE cmd){ unsigned long addr; unsigned long bit; unsigned long ireq; unsigned long new_ireq; UINT32 flag; if((wChannelId < 0) || (wChannelId >= XP_INTERRUPT_COUNT)) { return(XP_ERROR_CHANNEL_INVALID); } /*------------------------------------------------------------------------+ | Clear any interrupts which may be pending +------------------------------------------------------------------------*/ if(cmd == XP_INTERRUPT_CONTROL_RESET) { switch(wChannelId) { case XP_INTERRUPT_AUDIO: addr = XP_DCR_ADDR_ASTATUS; break; case XP_INTERRUPT_VIDEO: addr = XP_DCR_ADDR_VSTATUS; break; default: addr = XP_DCR_ADDR_BASE_QSTAT + wChannelId; break; } flag = os_enter_critical_section(); xp_atom_dcr_write(pGlobal->uDeviceIndex,addr, 0xFFFFFFFF); os_leave_critical_section(flag); } /*------------------------------------------------------------------------+ | Enable or disable any interrupts for a channel using the ireq register | Contruct the value used to control the ireq field +------------------------------------------------------------------------*/ else { if (wChannelId < XP_CHANNEL_COUNT) { bit = 1 << (31 - wChannelId); flag = os_enter_critical_section(); new_ireq = ireq = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_QINTMSK); os_leave_critical_section(flag); switch(cmd) { case XP_INTERRUPT_CONTROL_DISABLE: new_ireq &= ~bit; break; case XP_INTERRUPT_CONTROL_ENABLE: new_ireq |= bit; break; default: return(XP_ERROR_INTERNAL); } if(ireq != new_ireq) { flag = os_enter_critical_section(); xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_QINTMSK, new_ireq); os_leave_critical_section(flag); } } } return(0);}/*----------------------------------------------------------------------------+| xp0_interrupt_channel_free+----------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -