📄 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 the Intel PXA27x SoC.
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <bulverde.h>
#include "oal_log.h"
#include "oal_memory.h"
#include "oal_io.h"
#include "oal_timer.h"
#include "oal_intr.h"
#include <intr.h>
//------------------------------------------------------------------------------
// External Functions
// External Variables
// Defines
#define NUM_INT_PRIOS 32
// Types
// Global Variables
PFN_PROFILER_ISR g_pProfilerISR = NULL;
static volatile BULVERDE_INTR_REG *g_pICReg = NULL;
static UINT32 g_IntPriorities[NUM_INT_PRIOS] =
{
IRQ_OSMR0, // M0 - Scheduler - ID 26
IRQ_PMU, // PMU - ID 12
IRQ_OSMR2, // M2 - Profiler - ID 28
IRQ_OSMR3, // M3 - DVM - ID 29
IRQ_GPIO1, // GPIO1 edge detect - Suspend/Resume - ID 9
IRQ_RTCALARM, // RTC Alarm - ID 31
IRQ_BASEBAND, // Baseband - ID 1
IRQ_DMAC, // DMA Controller - ID 25
0x00000020, // Trusted Platform Module (Caddo) - ID 32
0x00000021, // Camera Capture - ID 33
IRQ_USBFN, // UDC - ID 11
IRQ_USBOHCI, // USB Host (OHCI) - ID 3
IRQ_USBNONOHCI, // USB Host Non-OHCI - ID 2
IRQ_OSMRXX_4, // M4-M11 - ID 7
IRQ_FFUART, // FFUART - ID 22
IRQ_STUART, // STDUART - ID 20
IRQ_BTUART, // BTUART - ID 21
IRQ_AC97, // AC97 - UCB1400 - ID 14
IRQ_OSMR1, // M1 - Touch Timer (Draw) - ID 27
IRQ_GPIO0, // GPIO0 - FPGA - ID 8
IRQ_MMC, // MMC - ID 23
IRQ_MEMSTICK, // Memstick - ID 5
IRQ_USIM, // USIM (Smart Card) - ID 15
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
};
static UINT32 g_IntPriorities2[2] =
{
0x00000000, // Priorities configured in priorit 2 register.
IRQ_KEYPAD // "
};
// Local Variables
// Local Functions
//------------------------------------------------------------------------------
//
// Function: OALIntrInit
//
// This function initialize interrupt mapping, hardware and call platform
// specific initialization.
//
BOOL OALIntrInit()
{
BOOL rc = FALSE;
UINT8 nIntPrio;
OALMSG( OAL_FUNC&&OAL_INTR, (L"+OALInterruptInit\r\n") );
// Initialize interrupt mapping
OALIntrMapInit();
// Map a pointer to the interrupt controller.
//
g_pICReg = (volatile BULVERDE_INTR_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_INTC, FALSE);
// Configure interrupt priorities.
//
for (nIntPrio = 0 ; nIntPrio < NUM_INT_PRIOS ; nIntPrio++)
{
g_pICReg->ipr[nIntPrio] = ((1 << 31) | g_IntPriorities[nIntPrio]);
}
g_pICReg->ipr2[0] = ((1 << 31) | g_IntPriorities2[0]);
g_pICReg->ipr2[1] = ((1 << 31) | g_IntPriorities2[1]);
//
// Set DIM, the only bit in the ICCR.
// The effect is that only enabled and unmasked
// interrupts bring the processor out of IDLE mode.
//
g_pICReg->iccr = 0x1;
#ifdef OAL_BSP_CALLBACKS
// Give BSP change to initialize subordinate controller
rc = BSPIntrInit();
#else
rc = TRUE;
#endif
// Setup static interrupt mappings (first one isn't really needed)
OALIntrStaticTranslate(SYSINTR_RESCHED, IRQ_OSMR0);
OALIntrStaticTranslate(SYSINTR_RTC_ALARM, IRQ_RTCALARM);
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALInterruptInit(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OALIntrRequestIrqs
//
// This function returns IRQ 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;
#ifdef OAL_BSP_CALLBACKS
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_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]);
if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
#endif
if (irq <= IRQ_RTCALARM) {
// Enable the primary IRQ
SETREG32(&g_pICReg->icmr, (1 << 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 irq, i;
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 <= IRQ_RTCALARM) {
// Enable the primary IRQ
CLRREG32(&g_pICReg->icmr, (1 << irq));
}
}
OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrDisableIrqs\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OALIntrDoneIrqs
//
VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
UINT32 irq, i;
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]);
if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
#endif
if (irq <= IRQ_RTCALARM) {
// Enable the primary IRQ
SETREG32(&g_pICReg->icmr, (1 << irq));
}
}
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALIntrDoneIrqs\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OEMInterruptHandler
//
ULONG OEMInterruptHandler(ULONG ra)
{
UINT32 irq = OAL_INTR_IRQ_UNDEFINED;
UINT32 sysIntr = SYSINTR_NOP;
if (!g_pICReg) {
return(SYSINTR_NOP);
}
// Determine the IRQ of the highest priority pending interrupt
irq = (UINT16)((g_pICReg->ichp >> 16) & 0x3F);
if (irq == 0)
{
return(SYSINTR_NOP);
}
// System timer interrupt?
if (irq == IRQ_OSMR0)
{
// The rest is up to the timer interrupt handler.
//
sysIntr = OALTimerIntrHandler();
}
// Profiling timer interrupt?
else if (irq == IRQ_OSMR2)
{
// Mask the interrupt
CLRREG32(&g_pICReg->icmr, (1 << irq));
// The rest is up to the profiling interrupt handler (if profiling
// is enabled).
//
if (g_pProfilerISR) {
sysIntr = g_pProfilerISR(ra);
}
}
// Board-level interrupts
else
{
#ifdef OAL_BSP_CALLBACKS
UINT32 origIrq = irq; // save the original so we can tell if it's BSP specific irq
if (irq == IRQ_GPIO0 || irq == IRQ_GPIO1 || irq == IRQ_GPIOXX_2)
{
// 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);
}
else
#endif
{
// Mask the interrupt
CLRREG32(&g_pICReg->icmr, (1 << irq));
}
// First find if IRQ is claimed by chain
sysIntr = (UINT16)NKCallIntChain((UCHAR)irq);
if (sysIntr == (UINT16)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
if (origIrq != irq) {
// BSP specific irq
BSPIntrEnableIrq (irq);
} else
#endif
{
// Unmask the interrupt
SETREG32(&g_pICReg->icmr, (1 << irq));
}
}
}
return (sysIntr);
}
//------------------------------------------------------------------------------
//
// Function: OEMInterruptHandlerFIQ
//
void OEMInterruptHandlerFIQ()
{
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -