📄 intr.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// File: intr.c
//
// This file implement major part of interrupt module for OMAP7xx SoC.
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <oal.h>
#include <omap730.h>
//------------------------------------------------------------------------------
//
// 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 OMAP730_INTC_REGS *g_pIntcL1Regs;
static OMAP730_INTC_REGS *g_pIntcL2ARegs;
static OMAP730_INTC_REGS *g_pIntcL2BRegs;
static OMAP730_GPIO_REGS *g_pGPIO1Regs;
static OMAP730_GPIO_REGS *g_pGPIO2Regs;
static OMAP730_GPIO_REGS *g_pGPIO3Regs;
static OMAP730_GPIO_REGS *g_pGPIO4Regs;
static OMAP730_GPIO_REGS *g_pGPIO5Regs;
static OMAP730_GPIO_REGS *g_pGPIO6Regs;
//------------------------------------------------------------------------------
//
// Static: g_intcLxLevel
//
// Following arrays contain interrupt routing, level and priority
// initialization values for ILR interrupt controller registers.
//
static UINT32 g_intcL1Level[] = {
ILR_FIQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 0
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 2
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 4
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 6
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 8
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 10
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 12
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 14
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 16
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 18
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 20
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 22
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 24
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 26
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 28
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16 // 30
};
static UINT32 g_intcL2ALevel[] = {
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 32/0
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 34/2
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 36/4
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 38/6
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 40/8
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 42/10
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 44/12
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 46/14
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 48/16
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 50/18
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 52/20
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 54/22
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 56/24
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 58/26
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 60/28
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16 // 62/30
};
static UINT32 g_intcL2BLevel[] = {
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 64/32
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 66/34
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 68/36
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 70/38
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 72/40
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 74/42
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 76/44
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 78/46
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 80/48
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 82/50
ILR_IRQ|ILR_LEVEL|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 84/52
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 86/54
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 88/56
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 90/58
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_EDGE|ILR_PRI16, // 92/60
ILR_IRQ|ILR_EDGE|ILR_PRI16, ILR_IRQ|ILR_LEVEL|ILR_PRI16, // 94/62
};
//------------------------------------------------------------------------------
//
// Function: OALIntrInit
//
// This function initialize OMAP730 interrupt subsystem. Implementation must
// use its own mapping structure because general implementation limits
// number of IRQ to 64 but OMAP730 has 96 IRQs.
//
BOOL OALIntrInit()
{
BOOL rc = FALSE;
UINT32 irq, i;
OALMSG(OAL_INTR&&OAL_FUNC, (L"+OALInterruptInit\r\n"));
// Initialize interrupt mapping
OALIntrMapInit();
// Get interrupt controller registers virtual uncached addresses
g_pIntcL1Regs = OALPAtoUA(OMAP730_INTC_L1_REGS_PA);
g_pIntcL2ARegs = OALPAtoUA(OMAP730_INTC_L2A_REGS_PA);
g_pIntcL2BRegs = OALPAtoUA(OMAP730_INTC_L2B_REGS_PA);
g_pGPIO1Regs = OALPAtoUA(OMAP730_GPIO1_REGS_PA);
g_pGPIO2Regs = OALPAtoUA(OMAP730_GPIO2_REGS_PA);
g_pGPIO3Regs = OALPAtoUA(OMAP730_GPIO3_REGS_PA);
g_pGPIO4Regs = OALPAtoUA(OMAP730_GPIO4_REGS_PA);
g_pGPIO5Regs = OALPAtoUA(OMAP730_GPIO5_REGS_PA);
g_pGPIO6Regs = OALPAtoUA(OMAP730_GPIO6_REGS_PA);
// Disable all interrupts
OUTREG32(&g_pIntcL1Regs->MIR, 0xFFFFFFFF);
OUTREG32(&g_pIntcL2ARegs->MIR, 0xFFFFFFFF);
OUTREG32(&g_pIntcL2BRegs->MIR, 0xFFFFFFFF);
OUTREG32(&g_pGPIO1Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&g_pGPIO2Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&g_pGPIO3Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&g_pGPIO4Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&g_pGPIO5Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&g_pGPIO6Regs->INTMASK, 0xFFFFFFFF);
// Initialize interrupt routing, level and priority
for (i = 0; i < 32; i++) {
OUTREG32(&g_pIntcL1Regs->ILR[i], g_intcL1Level[i]);
OUTREG32(&g_pIntcL2ARegs->ILR[i], g_intcL2ALevel[i]);
OUTREG32(&g_pIntcL2BRegs->ILR[i], g_intcL2BLevel[i]);
}
// Enable interrupts from L2 controllers
irq = IRQ_L2FIQ; OALIntrEnableIrqs(1, &irq);
irq = IRQ_L2IRQ; OALIntrEnableIrqs(1, &irq);
// Add static mapping for RTC alarm
OALIntrStaticTranslate(SYSINTR_RTC_ALARM, IRQ_RTC_ALARM);
// And enable it (it will not occur until it is set in OEMSetAlarmTime)
OEMInterruptEnable(SYSINTR_RTC_ALARM, 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;
switch (pDevLoc->IfcType) {
case Internal:
switch ((ULONG)pDevLoc->LogicalLoc) {
case OMAP730_USBD_REGS_PA:
*pCount = 1;
pIrqs[0] = IRQ_USB;
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 irq, i;
OALMSG(OAL_INTR&&OAL_VERBOSE, (
L"+OALntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs
));
for (i = 0; i < count; i++) {
irq = pIrqs[i];
if (irq < 32) {
CLRREG32(&g_pIntcL1Regs->MIR, 1 << irq);
} else if (irq < 64) {
CLRREG32(&g_pIntcL2ARegs->MIR, 1 << (irq - 32));
} else if (irq < 96) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -