📄 intr.c
字号:
case CSP_BASE_REG_PA_VCM:
pIrqs[0] = IRQ_H264;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_USB:
// Check if output array can hold all IRQs
if (*pCount >= 3)
{
pIrqs[0] = IRQ_USBHS1;
pIrqs[1] = IRQ_USBHS2;
pIrqs[2] = IRQ_USBOTG;
*pCount = 3;
rc = TRUE;
}
break;
case CSP_BASE_REG_PA_SCC:
// Check if output array can hold all IRQs
if (*pCount >= 2)
{
pIrqs[0] = IRQ_SMN;
pIrqs[1] = IRQ_SCM;
*pCount = 2;
rc = TRUE;
}
break;
case CSP_BASE_REG_PA_SAHARA:
pIrqs[0] = IRQ_SAHARA;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_SLCDC:
pIrqs[0] = IRQ_SLCDC;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_LCDC:
pIrqs[0] = IRQ_LCDC;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_IIM:
pIrqs[0] = IRQ_IIM;
*pCount = 1;
rc = TRUE;
break;
}
break;
}
#ifdef OAL_BSP_CALLBACKS
if (!rc) rc = BSPIntrRequestIrqs(pDevLoc, pCount, pIrqs);
#endif
cleanUp:
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrRequestIrqs(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OALIntrEnableIrqs
//
BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
{
BOOL rc = TRUE;
UINT32 i, irq;
UINT32 pin;
GPIO_PORT port;
OALMSG(OAL_INTR&&OAL_FUNC, (
L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs
));
for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
irq = pIrqs[i];
#else
// Give BSP chance to enable irq on subordinate interrupt controller
irq = BSPIntrEnableIrq(pIrqs[i]);
#endif
if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
// If IRQ is valid
if (irq <= CSP_IRQ_GPIO_MAX)
{
if(irq >= CSP_IRQ_GPIO_MIN)
{
// Enable GPIO pin interrupt
pin = irq - CSP_IRQ_GPIO_MIN;
port = pin / 32;
pin %= 32;
SETREG32(&g_pGPIO->PORT[port].IMR,(1 << pin));
SETREG32(&g_pGPIO->PORT[port].ISR,(1 << pin));
irq = IRQ_GPIO;
}
// Enable the primary IRQ
OUTREG32(&g_pAITC->INTENNUM, irq);
} else {
rc = FALSE;
}
}
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrEnableIrqs(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OALIntrDisableIrqs
//
VOID OALIntrDisableIrqs(UINT32 count, const UINT32 *pIrqs)
{
UINT32 i, irq;
UINT32 pin;
GPIO_PORT port;
OALMSG(OAL_INTR&&OAL_FUNC, (
L"+OALIntrDisableIrqs(%d, 0x%08x)\r\n", count, pIrqs
));
for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
irq = pIrqs[i];
#else
// Give BSP chance to disable irq on subordinate interrupt controller
irq = BSPIntrDisableIrq(pIrqs[i]);
#endif
if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
// If IRQ is valid
if (irq <= CSP_IRQ_GPIO_MAX)
{
if(irq >= CSP_IRQ_GPIO_MIN)
{
// Disable GPIO pin interrupt
pin = irq - CSP_IRQ_GPIO_MIN;
port = pin / 32;
pin %= 32;
CLRREG32(&g_pGPIO->PORT[port].IMR,(1 << pin));
}
else
{
// Disable the primary IRQ
OUTREG32(&g_pAITC->INTDISNUM, irq);
}
}
}
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrDisableIrqs\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OALIntrDoneIrqs
//
VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
UINT32 i, irq;
UINT32 pin;
BOOL bEnable;
GPIO_PORT port;
OALMSG(OAL_INTR&&OAL_VERBOSE, (
L"+OALIntrDoneIrqs(%d, 0x%08x)\r\n", count, pIrqs
));
for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
irq = pIrqs[i];
#else
// Give BSP chance to finish irq on subordinate interrupt controller
irq = BSPIntrDoneIrq(pIrqs[i]);
#endif
if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
// Upper OAL layer is not disabling interrupts, but we
// need interrupts disabled for safe access to GPIO and
// AVIC registers
bEnable = INTERRUPTS_ENABLE(FALSE);
// If IRQ is valid
if (irq <= CSP_IRQ_GPIO_MAX)
{
if(irq >= CSP_IRQ_GPIO_MIN)
{
// Enable GPIO pin interrupt
pin = irq - CSP_IRQ_GPIO_MIN;
port = pin / 32;
pin %= 32;
SETREG32(&g_pGPIO->PORT[port].ISR,(1 << pin));
SETREG32(&g_pGPIO->PORT[port].IMR,(1 << pin));
irq = IRQ_GPIO;
}
// Enable the primary IRQ
OUTREG32(&g_pAITC->INTENNUM, irq);
}
INTERRUPTS_ENABLE(bEnable);
}
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALIntrDoneIrqs\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OEMInterruptHandler
//
ULONG OEMInterruptHandler(ULONG ra)
{
UINT32 sysIntr = SYSINTR_NOP;
UINT32 irq;
UINT32 line;
GPIO_PORT port;
irq = EXTREG32BF(&g_pAITC->NIVECSR, AITC_NIVECSR_NIVECTOR);
// Make sure interrupt is pending
if (irq >= AITC_IRQ_SOURCES_MAX)
{
OALMSGS(OAL_ERROR,
(TEXT("OEMInterrupHandler: No pending interrupt!\r\n")));
}
// If system timer interrupt
else if (irq == IRQ_GPT1)
{
// Call timer interrupt handler
sysIntr = OALTimerIntrHandler();
}
// If profile timer interrupt
else if (g_pProfilerISR && (irq == IRQ_GPT3))
{
// Mask the interrupt
OUTREG32(&g_pAITC->INTDISNUM, irq);
// Call profiling interupt handler
sysIntr = g_pProfilerISR(ra);
}
// Else not system timer interrupt
else
{
#ifdef OAL_ILTIMING
// Increment interrupt count
if (g_oalILT.active) g_oalILT.interrupts++;
#endif
// GPIO special case: Interrupts from module are ORed together
// so we cannot disable the IRQ_GPIO since this would block other
// drivers relying on GPIO interrupts. Instead we clear the interrupt
// at the GPIO and then disable all interrupts associated with the
// SYSINTR that owns this GPIO interrupt, including the GPIO line
// that caused the interrupt to occur.
if (irq == IRQ_GPIO)
{
for(port = GPIO_PORT_A; port < GPIO_PORT_MAX; port++)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO->PORT[port].ISR)
& INREG32(&g_pGPIO->PORT[port].IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
line = 31 - line;
irq = CSP_IRQ_GPIO_MIN + (port * 32 + line);
break;
}
}
// Invalid GPIO interrupt
if(irq == IRQ_GPIO)
irq = OAL_INTR_IRQ_UNDEFINED;
} // GPIO special case
#ifdef OAL_BSP_CALLBACKS
// Give BSP chance to translate IRQ -- if there is subordinate
// interrupt controller in BSP it give chance to decode its status
// and change IRQ
irq = BSPIntrActiveIrq(irq);
#endif
if(g_bBSPIrq) // If porcessed by BSP, We should clear the GPIO IRQ status
{
SETREG32(&g_pGPIO->PORT[port].ISR,(1 << line));
}
// if IRQ assigned to this GPIO is defined
if (irq != OAL_INTR_IRQ_UNDEFINED)
{
if(!g_bBSPIrq) // Not porcessed by BSP
{ if((irq >= CSP_IRQ_GPIO_MIN) && (irq <= CSP_IRQ_GPIO_MAX))
{
// Mask GPIO pin interrupt
CLRREG32(&g_pGPIO->PORT[port].IMR,(1 << line));
}
else
{
// Mask the AITC interrupt
OUTREG32(&g_pAITC->INTDISNUM, irq);
}
}
// First find if IRQ is claimed by chain
sysIntr = NKCallIntChain((UCHAR)irq);
if (sysIntr == SYSINTR_CHAIN || !NKIsSysIntrValid(sysIntr))
{
// IRQ wasn't claimed, use static mapping
sysIntr = OALIntrTranslateIrq(irq);
}
// unmask interrupts in case it's NOP or invalid
if (SYSINTR_NOP == sysIntr)
{
#ifdef OAL_BSP_CALLBACKS
// Have porcessed by BSP
if(g_bBSPIrq)
{
// BSP specific irq
BSPIntrEnableIrq (irq);
}
else
#endif
{
if((irq >= CSP_IRQ_GPIO_MIN) && (irq <= CSP_IRQ_GPIO_MAX))
{
// Enable GPIO pin interrupt
SETREG32(&g_pGPIO->PORT[port].ISR,(1 << line));
SETREG32(&g_pGPIO->PORT[port].IMR,(1 << line));
}
else
{
// Unmask the AITC interrupt
OUTREG32(&g_pAITC->INTENNUM, irq);
}
}
}
}
else
{
OALMSGS(OAL_ERROR,
(TEXT("OEMInterrupHandler: undefined IRQ (%d)!\r\n"),
EXTREG32BF(&g_pAITC->NIVECSR, AITC_NIVECSR_NIVECTOR)));
}
} // Else not system timer interrupt
return sysIntr;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -