intx20t.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 186 行
C
186 行
/* -*-C-*-
*
* $Revision: 1.3 $
* $Author: kwelton $
* $Date: 2000/08/08 21:45:52 $
*
* intx20.c - ARMX20 (X = 7, 9, 10) platform interrupt service routine
*
* Copyright (c) ARM Limited 1998, 1999
* Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
* All Rights Reserved.
*/
#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include <bldver.h> // Needed for CE_MAJOR_VER.
#include "drv_glob.h"
#include "win_plat.h"
#if (CE_MAJOR_VER == 0x0003)
extern DWORD AlarmTime, ticksleft, dwSleepMin, dwPreempt;
extern DWORD DiffMSec;
#else
extern DWORD AlarmTime, dwReschedTime;
#endif
extern DWORD CurMSec;
extern volatile LARGE_INTEGER CurTicks;
extern DWORD dwReschedIncrement;
extern int (*PProfileInterrupt)(void);
extern void pHALir_ClearTimerInterrupt(DWORD timer);
extern DWORD dwIsrTime1, dwIsrTime2;
extern BOOL fIntrTime, fIntrTimeToggle;
extern WORD wNumInterrupts; // Reset by a read of the ISR times from the IST
extern DWORD PerfCountSinceTick();
extern BOOL fInterruptFlag;
extern ULONG Logic2SysIntr[LOGINTR_MAX];
extern ULONG SysIntr2Logic[SYSINTR_MAX];
unsigned int MyEPC;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void OEMInterruptHandlerFIQ()
{
}
int OEMInterruptHandler(unsigned int ra)
{
DWORD retval;
DWORD intstatus = *(DWORD *)ARMX20_CPUISR;
static int intsignalled = 0;
UCHAR nIRQ = 0;
ULONG nSysIntr = 0;
#define NUM_INT_STATUS_BITS 22
// Fake CPUEnterIdle needs to know about interrupt firing.
fInterruptFlag = TRUE;
if (fIntrTime)
{
// Subtract off dwReschedIncrment since interrupt hasn't been cleared
dwIsrTime1 = PerfCountSinceTick() - dwReschedIncrement;
wNumInterrupts++;
}
// Check the timer interrupt.
if (intstatus & (1 << OS_TIMERINT))
{
// Update the global variables.
CurMSec += RESCHED_PERIOD;
#if (CE_MAJOR_VER == 0x0003)
DiffMSec += RESCHED_PERIOD;
#endif
CurTicks.QuadPart += dwReschedIncrement;
// Clear the interrupt
pHALir_ClearTimerInterrupt(OS_TIMER);
if (PProfileInterrupt)
{
MyEPC = ra;
retval = PProfileInterrupt();
}
else if (fIntrTime)
{
//
// We're doing interrupt timing. Every other tick is a RESCHED.
//
if (fIntrTimeToggle)
{
wNumInterrupts = 0;
fIntrTimeToggle = FALSE;
dwIsrTime2 = PerfCountSinceTick();
return (SYSINTR_TIMING);
}
else
{
fIntrTimeToggle = TRUE;
#if (CE_MAJOR_VER == 0x0003)
if (ticksleft || (dwSleepMin && (dwSleepMin <= DiffMSec)) || (dwPreempt && (dwPreempt <= DiffMSec)))
{
#else
if ((int) (CurMSec - dwReschedTime) >= 0)
{
#endif
return (SYSINTR_RESCHED);
}
}
}
else
{
// Check the alarm interrupt.
if (AlarmTime <= CurMSec)
{
// Reset the alarm by setting it to the largest possible integer.
AlarmTime = 0xFFFFFFFF;
return SYSINTR_RTC_ALARM;
}
#if (CE_MAJOR_VER == 0x0003)
if (ticksleft || (dwSleepMin && (dwSleepMin <= DiffMSec)) || (dwPreempt && (dwPreempt <= DiffMSec)))
{
#else
if ((int) (CurMSec - dwReschedTime) >= 0)
{
#endif
return SYSINTR_RESCHED;
}
}
}
else
{
//
// This was not a timer interrupt, must be a device interrupt.
//
// TODO: Can multiple interrupt status bits be set? If so, we're implicitely
// prioritizing by searing the lower-order bits in the status register first.
// Look up SYSINTR for asserted IRQ by finding lowest bit set and using
// it to look up SYSINTR in table.
intstatus &= (~intstatus + 1);
for (nIRQ = 0 ; nIRQ < NUM_INT_STATUS_BITS ; nIRQ++)
if (intstatus & (1 << nIRQ))
break;
// TODO - what to do about this?
if (nIRQ == NUM_INT_STATUS_BITS)
{
return(SYSINTR_NOP);
}
// Lookup SYSINTR.
nSysIntr = Logic2SysIntr[nIRQ];
// If we've found a valid interrupt, disable it and return SYSINTR
if (nSysIntr != SYSINTR_NOP)
{
OEMInterruptDisable(nSysIntr);
}
// Clear interrupt?
// Return SYSINTR.
return(nSysIntr);
}
return(SYSINTR_NOP);
}
/* EOF intx20.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?