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

📄 vartick.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.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

   vartick.c

Abstract:

   This module implements the code necessary to handle SA1100 tiemr interrupt and
   Kernel interface routines.

Notes:


--*/

#include <windows.h>
#include <nkintr.h>
#include <pkfuncs.h>

//
// OST (os timer)
//
typedef struct _OST_REGS
{
    DWORD osmr0;          //OS timer match register 0
    DWORD osmr1;          //OS timer match register 1
    DWORD osmr2;          //OS timer match register 2
    DWORD osmr3;          //OS timer match register 3
    DWORD oscr;           //OS timer counter register
    DWORD ossr;           //OS timer status register
    DWORD ower;           //OS timer watchdog enable register
    DWORD oier;           //OS timer interrupt enable register
} OST_REGS;
typedef volatile OST_REGS *PVOST_REGS;

PVOST_REGS pOSTreg;

//
// OSSR Bits
//
#define OSSR_M0 (0x1 << 0)
#define OSSR_M1 (0x1 << 1)
#define OSSR_M2 (0x1 << 2)
#define OSSR_M3 (0x1 << 3)

//
// OIER Bits
//
#define OIER_E0 (0x1 << 0)
#define OIER_E1 (0x1 << 1)
#define OIER_E2 (0x1 << 2)
#define OIER_E3 (0x1 << 3)

// OEM constants
extern const DWORD OEMTimerFreq;		// timer frequency
extern const int OEMMinTickDistance;	// minimum distance between compare and count register while updating compare register
extern const DWORD OEMOSTBaseAddr;
void (* pOEMUpdateTimerLED) (DWORD dwMSec);

// constants derived from OEM constants
int ARMMaxSchedMSec;
int ARMCount1MS;						// # of tick per MS

void FakedCPUEnterIdle (DWORD dwIdleParam);

// BSP specific function
void (* pCPUEnterIdle) (DWORD dwIdleParam) = FakedCPUEnterIdle;


// variables
int nMaxSchedMSec;						

DWORD dwTimer2Ticks;                    // timer2 increment

// flags indicating states
volatile BOOL fInterruptFlag, fIntrTime, fProfilerRunning;
extern DWORD dwIsrTime1;
extern DWORD dwIsrTime2;
extern DWORD dwSPC;
extern WORD  wNumInterrupts;

//
// Kernel global variables 
//
extern DWORD curridlehigh, curridlelow, idleconv;
extern volatile DWORD CurMSec, dwReschedTime;

//
// set pointers to OEM functions
extern BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount);
extern BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpliPerformanceFreq);


volatile ULARGE_INTEGER CurTicks = { 0, 0 };
volatile ULARGE_INTEGER * pCurTicks = &CurTicks;

#define	LastINTMSec			CurMSec

extern void (*pOEMUpdateRescheduleTime) (DWORD dwTime);

volatile DWORD NextINTMSec;

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD PerfCountSinceTick(void)
{
	return (pOSTreg->oscr - CurTicks.LowPart);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD PerfCountFreq (void)
{
	return OEMTimerFreq;
}

//------------------------------------------------------------------------------
//
//  OEMQueryPerformanceCounter
//  
//      The OEMQueryPerformanceCounter function retrieves the current value of 
//      the high-resolution performance counter, if one exists. 
//  
//  BOOL QueryPerformanceCounter(
//  
//      LARGE_INTEGER  *lpliPerformanceCount    // address of current counter value
//     );   
//  
//  Parameters
//  
//  lpliPerformanceCount
//  
//      Points to a variable that the function sets, in counts, to the current 
//      performance-counter value. If the installed hardware does not support 
//      a high-resolution performance counter, this parameter can be to zero. 
//  
//  Return Value
//  
//      If the installed hardware supports a high-resolution performance 
//      counter, the return value is TRUE.
//      If the installed hardware does not support a high-resolution 
//      performance counter, the return value is FALSE.   
//  
//  If this function is implemented by the OEM, the pointer pQueryPerformanceCounter
//  should be initialized as follows:
//  
//  BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
//
//------------------------------------------------------------------------------
BOOL 
OEMQueryPerformanceCounter(
    LARGE_INTEGER *lpliPerformanceCount
    )
{
    ULARGE_INTEGER liBase;
    DWORD dwCurCount;

    if (!lpliPerformanceCount) return FALSE;

    // Make sure CurTicks is the same before and after read of counter to account for
    // possible rollover
    do {
        liBase = CurTicks;
        dwCurCount = PerfCountSinceTick();
    } while  (liBase.LowPart != CurTicks.LowPart) ;  

    lpliPerformanceCount->QuadPart = liBase.QuadPart + dwCurCount;
    
    return TRUE;
}



//------------------------------------------------------------------------------
//
//  OEMQueryPerformanceFrequency
//  
//      The OEMQueryPerformanceFrequency function retrieves the frequency of 
//      the high-resolution performance counter, if one exists. 
//  
//  BOOL OEMQueryPerformanceFrequency(
//  
//      LARGE_INTEGER  *lpliPerformanceFreq     // address of current frequency
//     );   
//  
//  Parameters
//  
//  lpliPerformanceFreq
//  
//      Points to a variable that the function sets, in counts per second, to 
//      the current performance-counter frequency. If the installed hardware 
//      does not support a high-resolution performance counter, this parameter
//      can be to zero. 
//  
//  Return Value
//  
//      If the installed hardware supports a high-resolution performance 
//      counter, the return value is TRUE.
//      If the installed hardware does not support a high-resolution 
//      performance counter, the return value is FALSE.
//  
//  If this function is implemented by the OEM, the pointer pQueryPerformanceFrequency
//  should be initialized as follows:
//  
//  BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpPerformanceFrequency)=OEMQueryPerformanceFrequency;
//
//------------------------------------------------------------------------------
BOOL 
OEMQueryPerformanceFrequency(
    LARGE_INTEGER *lpliPerformanceFreq
    ) 
{
    extern DWORD PerfCountFreq();

    if (!lpliPerformanceFreq) return FALSE;
    
    lpliPerformanceFreq->HighPart = 0;
    lpliPerformanceFreq->LowPart  = OEMTimerFreq;
    return TRUE;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void ARMUpdateReschedTime (DWORD dwTime)
{
    DWORD dwPrev = LastINTMSec, dwNext = NextINTMSec;
    DWORD countReg, compareReg;
    int   nTicksFromCountReg, nDiffTick, nDiffMSec, nShiftTick;


	if (dwTime == NextINTMSec) {
		return;		// already setup correctly
	}

    // read count and compare registers
	compareReg = pOSTreg->osmr0;
	countReg   = pOSTreg->oscr;

    // if timer interrupts occurs, or within 1MS of the scheduled interrupt, just return
    // TimerISR will take care of it.
    if ((dwPrev != LastINTMSec) || ((int) (compareReg - countReg) < ARMCount1MS)) {
        return;
    }
    
    // we know we're not going to be interrupted by timer within 1MS if we reach here.

	// calculate the distance between the new time and the last timer interrupt
	nDiffMSec = dwTime - dwPrev;

    // trying to set reschedule time prior or equal to LastINTMSec? - this could happen if a thread is on its way to 
    // sleep while preempted before getting into the Sleep Queue
    if (nDiffMSec <= 0) {
        nDiffMSec = 0;
    }

	// account for hardware limitation
	if (nDiffMSec > nMaxSchedMSec) {
        nDiffMSec = nMaxSchedMSec;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -