⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intr.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -