📄 intr.c
字号:
//
// Copyright (c) Special Computing. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//------------------------------------------------------------------------------
//
// File: intr.c
//
// This file implement major part of interrupt module for OMAP3 SoC.
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <oal.h>
#include <omap2420.h>
#include <bsp_menelaus.h>
#ifdef OAL_FAKE_IDLE
extern volatile UINT32 g_oalLastSysIntr;
#endif
//------------------------------------------------------------------------------
//
// Extern: g_oalIrq2SysIntr
//
// IRQ to SYSINTR mapping table
//
extern UINT32 g_oalIrq2SysIntr[];
//------------------------------------------------------------------------------
//
// Global: g_oalTimerIrq
//
// This variable contains IRQ of timer used for system clock. It is
// set in timer initialization function OALTimerInit.
//
UINT32 g_oalTimerIrq = OAL_INTR_IRQ_UNDEFINED;
//------------------------------------------------------------------------------
//
// Static: g_pIntcRegs
//
// This value contains virtual uncached address of interrupt controller
// unit registers.
//
static OMAP3_MPUINTC_REGS *g_pIntcRegs;
//------------------------------------------------------------------------------
//
// Static: g_pIntcRegs
//
// This value contains virtual uncached address of interrupt controller
// unit registers.
//
static OMAP3_GPIO_REGS *g_pGPIORegs[6];
//------------------------------------------------------------------------------
//
// Static: g_intcLxLevel
//
// Following arrays contain interrupt routing and priority
// initialization values for ILR interrupt controller registers.
// Level initialization is not performed here for the OMAP2420.
//
static UINT32 g_intcPriorityLevel[] = {
ILR_FIQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 0
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 2
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 4
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 6
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 8
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 10
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 12
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 14
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 16
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 18
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 20
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 22
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 24
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 26
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 28
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 30
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 32/0
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 34/2
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 36/4
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 38/6
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 40/8
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 42/10
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 44/12
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 46/14
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 48/16
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 50/18
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 52/20
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 54/22
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 56/24
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 58/26
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 60/28
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 62/30
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 64/32
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 66/34
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 68/36
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 70/38
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 72/40
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 74/42
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 76/44
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 78/46
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 80/48
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 82/50
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 84/52
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 86/54
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 88/56
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 90/58
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16, // 92/60
ILR_IRQ|ILR_PRI16, ILR_IRQ|ILR_PRI16 // 94/62
};
static UINT32 g_GPIO_LEVELDETECT0[] = {
0x0000, //GPIO0-31
0x0000, //GPIO32-63
0x0000, //GPIO64-95
0x0000, //GPIO96-127
0x0000, //GPIO128-159
0x0000 //GPIO160-191
};
static UINT32 g_GPIO_LEVELDETECT1[] = {
0x0000, //GPIO0-31
0x0000, //GPIO32-63
0x0000, //GPIO64-95
0x0000, //GPIO96-127
0x0000, //GPIO128-159
0x0000 //GPIO160-191
};
static UINT32 g_GPIO_RISINGDETECT[] = {
0x0000, //GPIO0-31
0x0000, //GPIO32-63
0x0000, //GPIO64-95
0x0000, //GPIO96-127
0x0000, //GPIO128-159
0x0000 //GPIO160-191
};
static UINT32 g_GPIO_FALLINGDETECT[] = {
0x0000, //GPIO0-31
0x0000, //GPIO32-63
0x0000, //GPIO64-95
0x0000, //GPIO96-127
0x0000, //GPIO128-159
0x0000 //GPIO160-191
};
//------------------------------------------------------------------------------
//
// Function: OALIntrInit
//
// This function initialize OMAP2420 interrupt subsystem. Implementation must
// use its own mapping structure because general implementation limits
// number of IRQ to 64 but OMAP2420 has 96 IRQs.
//
BOOL OALIntrInit()
{
BOOL rc = FALSE;
UINT32 i;
OALMSG(OAL_INTR&&OAL_FUNC, (L"+OALInterruptInit\r\n"));
// Initialize interrupt mapping
OALIntrMapInit();
// Get interrupt controller and GPIO registers' virtual uncached addresses
g_pIntcRegs = OALPAtoUA(OMAP3_INTC_MPU_REGS_PA);
g_pGPIORegs[0] = OALPAtoUA(OMAP3_GPIO1_REGS_PA);
g_pGPIORegs[1] = OALPAtoUA(OMAP3_GPIO2_REGS_PA);
g_pGPIORegs[2] = OALPAtoUA(OMAP3_GPIO3_REGS_PA);
g_pGPIORegs[3] = OALPAtoUA(OMAP3_GPIO4_REGS_PA);
g_pGPIORegs[4] = OALPAtoUA(OMAP3_GPIO5_REGS_PA);
g_pGPIORegs[5] = OALPAtoUA(OMAP3_GPIO6_REGS_PA);
//Reset the MPU INTC and wait until reset is complete
SETREG32(&g_pIntcRegs->ulINTC_SYSCONFIG, OMAP3_MPUINTC_RESETBIT);
while ((INREG32(&g_pIntcRegs->ulINTC_SYSSTATUS)& OMAP3_MPUINTC_RESETSTATUS) == 0);
// Disable all interrupts and clear the ISR - for all for GPIO banks, too.
OUTREG32(&g_pIntcRegs->ulINTC_MIR_SET0, OMAP3_MPUINTC_MASKALL);
OUTREG32(&g_pIntcRegs->ulINTC_MIR_SET1, OMAP3_MPUINTC_MASKALL);
OUTREG32(&g_pIntcRegs->ulINTC_MIR_SET2, OMAP3_MPUINTC_MASKALL);
for (i = 0; i < 6; i++) {
OUTREG32(&g_pGPIORegs[i]->ulGPIO_CLEARIRQENABLE1, 0xFFFFFFFF);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_CLEARIRQENABLE2, 0xFFFFFFFF);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_IRQSTATUS1, 0xFFFFFFFF);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_IRQSTATUS2, 0xFFFFFFFF);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_LEVELDETECT0, g_GPIO_LEVELDETECT0[i]);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_LEVELDETECT1, g_GPIO_LEVELDETECT1[i]);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_RISINGDETECT, g_GPIO_RISINGDETECT[i]);
OUTREG32(&g_pGPIORegs[i]->ulGPIO_FALLINGDETECT, g_GPIO_FALLINGDETECT[i]);
}
// Initialize interrupt routing and priority
for (i = 0; i < 96; i++) {
OUTREG32(&g_pIntcRegs->ulINTC_ILR[i], g_intcPriorityLevel[i]);
}
// Allow interrupts
INTERRUPTS_ON();
// Allocate SYSINTR_RESCHED to a timer for the system tick
// OALIntrStaticTranslate( SYSINTR_RESCHED, IRQ_GPT1 );
OALIntrStaticTranslate( SYSINTR_RESCHED, IRQ_GPT12 );
OEMInterruptEnable( SYSINTR_RESCHED, NULL, 0 );
// Call board specific initialization
rc = BSPIntrInit();
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALInterruptInit(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OALIntrRequestIrq
//
// This function returns IRQs for CPU/SoC devices based on their
// physical address.
//
BOOL OALIntrRequestIrqs(DEVICE_LOCATION *pDevLoc, UINT32 *pCount, UINT32 *pIrqs)
{
BOOL rc = FALSE;
OALMSG(OAL_INTR&&OAL_FUNC, (
L"+OALIntrRequestIrqs(0x%08x->%d/%d/0x%08x/%d, 0x%08x, 0x%08x)\r\n",
pDevLoc, pDevLoc->IfcType, pDevLoc->BusNumber, pDevLoc->LogicalLoc,
pDevLoc->Pin, pCount, pIrqs
));
// This shouldn't happen
if (*pCount < 1) goto cleanUp;
#if 0
switch (pDevLoc->IfcType) {
case Internal:
switch ((ULONG)pDevLoc->LogicalLoc) {
case OMAP2420_USBD_REGS_PA:
*pCount = 1;
pIrqs[0] = IRQ_USB_GENI;
rc = TRUE;
break;
}
break;
}
#endif
#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 irq, i;
OALMSG(OAL_INTR, (L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs));
for (i = 0; i < count; i++) {
irq = pIrqs[i];
if (irq < 32) {
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR0, 1 << irq);
} else if (irq < 64) {
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR1, 1 << (irq - 32));
} else if (irq < 96) {
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR2, 1 << (irq - 64));
} else if (irq < IRQ_GPIO_32) {
OALMSG(OAL_INTR, (L"OALIntrEnableIrqs(Irq GPIO1 %d)\r\n", irq - IRQ_GPIO_0));
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR0, 1 << IRQ_GPIO1_MPU);
OUTREG32(&g_pGPIORegs[0]->ulGPIO_IRQSTATUS1, 1<<(irq - IRQ_GPIO_0)); // clear IRQ
SETREG32(&g_pGPIORegs[0]->ulGPIO_IRQENABLE1, 1<<(irq - IRQ_GPIO_0)); // unmask IRQ
} else if (irq < IRQ_GPIO_64) {
OALMSG(OAL_INTR, (L"OALIntrEnableIrqs(Irq GPIO2 %d)\r\n", irq - IRQ_GPIO_32));
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR0, 1 << IRQ_GPIO2_MPU);
OUTREG32(&g_pGPIORegs[1]->ulGPIO_IRQSTATUS1, 1<<(irq - IRQ_GPIO_32)); // clear IRQ
SETREG32(&g_pGPIORegs[1]->ulGPIO_IRQENABLE1, 1<<(irq - IRQ_GPIO_32)); // unmask IRQ
} else if (irq < IRQ_GPIO_96) {
OALMSG(OAL_INTR, (L"OALIntrEnableIrqs(Irq GPIO3 %d)\r\n", irq - IRQ_GPIO_64));
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR0, 1 << IRQ_GPIO3_MPU);
OUTREG32(&g_pGPIORegs[2]->ulGPIO_IRQSTATUS1, 1<<(irq - IRQ_GPIO_64)); // clear IRQ
SETREG32(&g_pGPIORegs[2]->ulGPIO_IRQENABLE1, 1<<(irq - IRQ_GPIO_64)); // unmask IRQ
} else if (irq < IRQ_GPIO_128) {
OALMSG(OAL_INTR, (L"OALIntrEnableIrqs(Irq GPIO4 %d)\r\n", irq - IRQ_GPIO_96));
OUTREG32(&g_pIntcRegs->ulINTC_MIR_CLEAR1, 1<<(IRQ_GPIO4_MPU-32));
OUTREG32(&g_pGPIORegs[3]->ulGPIO_IRQSTATUS1, 1<<(irq - IRQ_GPIO_96)); // clear IRQ
SETREG32(&g_pGPIORegs[3]->ulGPIO_IRQENABLE1, 1<<(irq - IRQ_GPIO_96)); // unmask IRQ
} else if (irq < IRQ_GPIO_160) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -