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 + -
显示快捷键?