📄 bvdisrs.c
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
/*++
Module Name: $Workfile: bvdisrs.c $
Abstract:
Intel XScale Microarchitecture platform interrupt service routines for
the Bulverde processor.
Notes:
Created: May 8, 2002
--*/
#include <windows.h>
#include <bldver.h>
#include <nkintr.h>
#include <oalintr.h>
#include "drv_glob.h"
#include "bvd1.h"
#include "bvd1bd.h"
#include "timer.h"
#include "pmu.h"
#include "dmacbits.h"
#include "xllp_dmac.h"
#define CLEAR_INT(reg,mask) reg &= ~mask
extern DWORD CurMSec;
extern volatile ULARGE_INTEGER CurTicks;
#if (WINCEOSVER <= 300)
extern DWORD DiffMSec;
extern DWORD ticksleft, dwSleepMin, dwPreempt;
#else
extern DWORD dwReschedTime;
#endif
#if (WINCEOSVER > 400)
extern DWORD dwProfilerIncrement;
extern void ProfilerHit(DWORD);
//
// For Interrupt Latency Support
//
extern DWORD dwIsrTime1, dwIsrTime2;
extern BOOL fIntrTime;
extern WORD wNumInterrupts;
extern DWORD dwIntrTimeCountdown;
extern DWORD dwIntrTimeCountdownRef;
extern DWORD PerfCountSinceTick();
#else
extern int (*PProfileInterrupt)(void);
#endif
extern XSC1GetSPSR(void);
unsigned int MyEPC;
//
// OSTM0TimerISR
//
// Timer M0 - Scheduler
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM0TimerISR(unsigned int ra)
{
unsigned long reschedIncrement = RESCHED_INCREMENT;
unsigned long reschedPeriod = RESCHED_PERIOD;
volatile XLLP_OST_T *v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
#ifdef BSP_USE_OSCR4
TIMER_M0_INT_DIS(v_pOSTReg->oier); // Disable the M0 interrupt
return SYSINTR_NOP;
#else
TIMER_M0_INT_DIS(v_pOSTReg->oier); // Disable the M0 interrupt
#if (WINCEOSVER <= 400)
if (PProfileInterrupt)
{
MyEPC=ra;
//
// The profiler rearms and enables the match timer
//
return PProfileInterrupt();
}
else
#endif
{
//
// Update match register for next timer firing
//
v_pOSTReg->osmr0 += reschedIncrement;
#if (WINCEOSVER > 400)
//
// For ILTiming, track when this one came in
//
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
//
// Increment the global variables
//
CurTicks.QuadPart += reschedIncrement;
#if (CE_MAJOR_VER <= 0x0003)
DiffMSec += reschedPeriod;
#endif
CurMSec += reschedPeriod;
//
// Adjust M0 if too close to oscr
// Delta value based on 2x worst case ISR latency
//
if ( ((long)(v_pOSTReg->osmr0 - v_pOSTReg->oscr0)) < 20 )
{
v_pOSTReg->osmr0 = v_pOSTReg->oscr0 + reschedIncrement;
#if (WINCEOSVER <= 300)
DiffMSec += reschedPeriod;
#endif
CurMSec += reschedPeriod;
}
//Clear and enable the interrupt
TIMER_M0_INT_CLR(v_pOSTReg->ossr);
TIMER_M0_INT_EN(v_pOSTReg->oier);
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIntrTimeCountdown--;
if (dwIntrTimeCountdown == 0)
{
dwIntrTimeCountdown = dwIntrTimeCountdownRef;
wNumInterrupts = 0;
dwIsrTime2 = PerfCountSinceTick();
return SYSINTR_TIMING;
}
}
#endif
//
// Reschedule for threads on sleep queue (ticksleft);
// Sleep timer expiring and we need to check the sleep queue (dwSleepMin);
// Thread is close to being preempted (dwPreempt).
//
#if (WINCEOSVER <= 300)
if (ticksleft || (dwSleepMin && (DiffMSec >= dwSleepMin))
|| (dwPreempt && (DiffMSec >= dwPreempt)))
#else
if ((int) (CurMSec - dwReschedTime) >= 0)
#endif
{
return SYSINTR_RESCHED;
}
}
return SYSINTR_NOP;
#endif
}
//
// OSTM1TimerISR
//
// Timer M1 - Touch
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM1TimerISR(unsigned int ra)
{
volatile XLLP_OST_T *v_pOSTReg;
volatile XLLP_INTC_T *v_pICReg;
PDRIVER_GLOBALS v_pDrvGlob;
v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
INTC_M1_INT_DIS(v_pICReg->icmr);
TIMER_M1_INT_CLR(v_pOSTReg->ossr);
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
return SYSINTR_TOUCH_CHANGED;
}
//
// OSTM2TimerISR
//
// Timer M2 - Profiler - only for WINCEOSVER > 400
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM2TimerISR(unsigned int ra)
{
volatile XLLP_OST_T *v_pOSTReg;
v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
#if (WINCEOSVER > 400)
//
// Service the profiler interrupt.
//
TIMER_M2_INT_DIS(v_pOSTReg->oier); // Disable the M0 interrupt
v_pOSTReg->osmr2 = v_pOSTReg->oscr0 + dwProfilerIncrement;
//Clear and enable the interrupt
TIMER_M2_INT_CLR(v_pOSTReg->ossr);
TIMER_M2_INT_EN(v_pOSTReg->oier);
ProfilerHit(ra);
#endif
return SYSINTR_NOP;
}
//
// OSTM3TimerISR
//
// Timer M3 - DVM/DFM
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM3TimerISR(unsigned int ra)
{
volatile XLLP_OST_T *v_pOSTReg;
volatile XLLP_INTC_T *v_pICReg;
volatile BLR_REGS *v_pBLReg = (volatile BLR_REGS *) FPGA_REGS_BASE_U_VIRTUAL;
PDRIVER_GLOBALS v_pDrvGlob;
v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
TIMER_M3_INT_DIS(v_pOSTReg->oier);
INTC_M3_INT_DIS(v_pICReg->icmr);
TIMER_M3_INT_CLR(v_pOSTReg->ossr);
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
//while (1)
// WRITE_HEX_LEDS(0xFFFFFFFF);
return SYSINTR_DVM;
}
//
// OSTM4_11TimerISR
//
// Timer Match Registers M4-M11
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM4_11TimerISR(unsigned int ra)
{
#ifdef BSP_USE_OSCR4
unsigned long reschedIncrement = RESCHED_INCREMENT;
unsigned long reschedPeriod = RESCHED_PERIOD;
volatile XLLP_OST_T *v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
volatile BLR_REGS *v_pBLReg = (volatile BLR_REGS *) FPGA_REGS_BASE_U_VIRTUAL;
if(v_pOSTReg->ossr & XLLP_OSSR_M4)
{
WRITE_HEX_LEDS(0x55555555);
TIMER_M4_INT_DIS(v_pOSTReg->oier); // Disable the M4 interrupt
TIMER_M0_INT_DIS(v_pOSTReg->oier); // Disable the M0 interrupt
//
// Update match register for next timer firing
//
v_pOSTReg->osmr4 += reschedIncrement;
//
// Increment the global variables
//
CurTicks.QuadPart += reschedIncrement;
CurMSec += reschedPeriod;
//
// Adjust M4 if too close to oscr
// Delta value based on 2x worst case ISR latency
//
if ( ((long)(v_pOSTReg->osmr4 - v_pOSTReg->oscr4)) < 1 )
{
v_pOSTReg->osmr4 = v_pOSTReg->oscr4 + reschedIncrement;
CurMSec += reschedPeriod;
}
WRITE_HEX_LEDS(v_pOSTReg->oier);
// Clear and enable the interrupt
v_pOSTReg->omcr4 = XLLP_OMCR_CRES_1MSEC | XLLP_OMCR_C | XLLP_OMCR_P;
TIMER_M4_INT_CLR(v_pOSTReg->ossr);
TIMER_M4_INT_EN(v_pOSTReg->oier);
//
// Reschedule for threads on sleep queue (ticksleft);
// Sleep timer expiring and we need to check the sleep queue (dwSleepMin);
// Thread is close to being preempted (dwPreempt).
//
if ((int) (CurMSec - dwReschedTime) >= 0)
{
return SYSINTR_RESCHED;
}
}
#endif
return SYSINTR_NOP;
}
//
// RTCAlarmISR
//
// Inputs:
// ra - return address of the interrupted routine
//
int RTCAlarmISR(unsigned int ra)
{
volatile XLLP_RTC_T *v_pRTCReg;
v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
RT_ALARM_INT_DIS(v_pRTCReg->rtsr); // mask interrupt
RT_ALARM_INT_CLR(v_pRTCReg->rtsr); // clear the interrupt
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
return SYSINTR_RTC_ALARM;
}
//
// GPIO1ISR - Power OFF ISR
//
// Inputs:
// ra - return address of the interrupted routine
//
int GPIO1ISR(unsigned int ra)
{
volatile XLLP_INTC_T *v_pICReg;
volatile XLLP_GPIO_T *v_pGPIOReg;
PDRIVER_GLOBALS v_pDrvGlob;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
//
// Power OFF interrupt
// mask interrupt & clear the edge detection
//
#if 0 //hzh
INTC_GPIO1_INT_DIS (v_pICReg->icmr);
GEDR_GPIO1_EDGE_CLR (v_pGPIOReg->GEDR0);
#else
v_pICReg->icmr &= ~(1<<9); //GPIO1
v_pGPIOReg->GRER0 &= ~2;
v_pGPIOReg->GFER0 &= ~2;
v_pGPIOReg->GEDR0 = 2;
RETAILMSG(1,(TEXT("GP1 Irq\r\n")));
#endif
if (bPMURunning)
{
//
// If PMU is currently sampling, we can't sleep,
// else the PMU counters will be turned off
//
return SYSINTR_NOP;
}
else
{
v_pDrvGlob->uninit_misc.offButton = DRVG_OFFBTN_PWRBUTTON;
return SYSINTR_POWER;
}
}
//
// MMCISR
//
// MMC ISR
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -