📄 intr.c
字号:
case CSP_BASE_REG_PA_EPIT1:
pIrqs[0] = IRQ_EPIT1;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_GPT:
pIrqs[0] = IRQ_GPT;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_UART2:
pIrqs[0] = IRQ_UART2;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_NANDFC:
pIrqs[0] = IRQ_NANDFC;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_SDMA:
pIrqs[0] = IRQ_SDMA;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_USBOTG:
// Check if output array can hold all IRQs
if (*pCount >= 3)
{
pIrqs[0] = IRQ_USB_HOST1;
pIrqs[1] = IRQ_USB_HOST2;
pIrqs[2] = IRQ_USB_OTG;
*pCount = 3;
rc = TRUE;
}
break;
case CSP_BASE_REG_PA_MSHC1:
pIrqs[0] = IRQ_MSHC1;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_MSHC2:
pIrqs[0] = IRQ_MSHC2;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_UART1:
pIrqs[0] = IRQ_UART1;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_IPU:
pIrqs[0] = IRQ_IPU_GENERAL; // Slammed IPU IRQ
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_UART4:
pIrqs[0] = IRQ_UART4;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_UART5:
pIrqs[0] = IRQ_UART5;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_ECT:
pIrqs[0] = IRQ_ECT;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_SCC:
// Check if output array can hold all IRQs
if (*pCount >= 2)
{
pIrqs[0] = IRQ_SCC_SCM;
pIrqs[1] = IRQ_SCC_SMN;
*pCount = 2;
rc = TRUE;
}
break;
case CSP_BASE_REG_PA_GPIO2:
pIrqs[0] = IRQ_GPIO2;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_GPIO1:
pIrqs[0] = IRQ_GPIO1;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_CCM:
pIrqs[0] = IRQ_CCM;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_PCMCIA:
pIrqs[0] = IRQ_PCMCIA;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_WDOG:
pIrqs[0] = IRQ_WDOG;
*pCount = 1;
rc = TRUE;
break;
case CSP_BASE_REG_PA_GPIO3:
pIrqs[0] = IRQ_GPIO3;
*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;
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 < OAL_INTR_IRQ_MAXIMUM)
{
// Enable the IRQ using entries in translation tables
OAL_IRQ_ENABLE(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;
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;
OAL_IRQ_DISABLE(irq);
}
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrDisableIrqs\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OALIntrDoneIrqs
//
VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
UINT32 i, irq;
BOOL bEnable;
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);
OAL_IRQ_ENABLE(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;
irq = EXTREG32(&g_pAVIC->NIVECSR, CSP_BITFMASK(AVIC_NIVECSR_NIVECTOR),
AVIC_NIVECSR_NIVECTOR_LSH);
// Make sure interrupt is pending
if (irq >= AVIC_IRQ_SOURCES_MAX)
{
OALMSGS(OAL_ERROR,
(TEXT("OEMInterrupHandler: No pending interrupt!\r\n")));
}
// If system timer interrupt
else if (irq == IRQ_EPIT1)
{
// Call timer interrupt handler
sysIntr = OALTimerIntrHandler();
}
// If profile timer interrupt
else if (g_pProfilerISR && (irq == IRQ_GPT))
{
// Call profiling interupt handler
sysIntr = g_pProfilerISR(ra);
}
// Else not system timer interrupt
else
{
#ifdef OAL_ILTIMING
if (g_oalILT.active) {
g_oalILT.isrTime1 = OALTimerCountsSinceSysTick();
g_oalILT.savedPC = 0;
g_oalILT.interrupts++;
}
#endif
// GPIO1 special case: Interrupts from module are ORed together
// so we cannot disable the IRQ_GPIO1 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_GPIO1)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO1->ISR)
& INREG32(&g_pGPIO1->IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
irq = g_oalGpioTranslate[0][31 - line];
}
else
{
irq = OAL_INTR_IRQ_UNDEFINED;
}
} // GPIO1 special case
// GPIO2 special case: Interrupts from module are ORed together
// so we cannot disable the IRQ_GPIO2 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.
else if (irq == IRQ_GPIO2)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO2->ISR)
& INREG32(&g_pGPIO2->IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
irq = g_oalGpioTranslate[1][31 - line];
}
else
{
irq = OAL_INTR_IRQ_UNDEFINED;
}
} // GPIO2 special case
// GPIO3 special case: Interrupts from module are ORed together
// so we cannot disable the IRQ_GPIO3 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.
else if (irq == IRQ_GPIO3)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO3->ISR)
& INREG32(&g_pGPIO3->IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
irq = g_oalGpioTranslate[2][31 - line];
}
else
{
irq = OAL_INTR_IRQ_UNDEFINED;
}
} // GPIO3 special case
// SDMA special case: Interrupts from SDMA are ORed together
// so we cannot disable the SDMA_IRQ since this would block other
// drivers relying on SDMA interrupts. Instead we just clear the
// interrupt at the SDMA
else if (irq == IRQ_SDMA)
{
// Detect SDMA channel that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pSDMA->INTR));
// If at least one SDMA channel interrupt is asserted
if (line < 32)
{
line = 31 - line;
// Clear the pending interrupt at the SDMA (ISR is w1c)
OUTREG32(&g_pSDMA->INTR, 1 << line);
irq = g_oalSdmaTranslate[line];
}
else
{
irq = OAL_INTR_IRQ_UNDEFINED;
}
} // SDMA special case
// Normal case: An interrupt other than the special cases handled above
// has occurred. We use our tables to determine the corresponding SYSINTR
// and disable all associated interrupt sources.
else
{
irq = g_oalIrqTranslate[irq];
} // normal 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 IRQ assigned to this GPIO is defined
if (irq != OAL_INTR_IRQ_UNDEFINED)
{
OAL_IRQ_DISABLE(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);
}
}
else
{
OALMSGS(OAL_ERROR,
(TEXT("OEMInterrupHandler: undefined IRQ (%d)!\r\n"),
EXTREG32(&g_pAVIC->NIVECSR, CSP_BITFMASK(AVIC_NIVECSR_NIVECTOR),
AVIC_NIVECSR_NIVECTOR_LSH)));
}
} // Else not system timer interrupt
return sysIntr;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -