ReactOS  0.4.14-dev-376-gaedba84
tsc.c File Reference
#include <hal.h>
#include <debug.h>
#include "tsc.h"
Include dependency graph for tsc.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define RTC_MODE   6 /* Mode 6 is 1024 Hz */
 
#define SAMPLE_FREQENCY   ((32768 << 1) >> RTC_MODE)
 

Functions

static ULONG64 DoLinearRegression (ULONG XMax, ULONG64 *ArrayY)
 
VOID NTAPI HalpInitializeTsc (VOID)
 
VOID NTAPI HalpCalibrateStallExecution (VOID)
 
LARGE_INTEGER NTAPI KeQueryPerformanceCounter (OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
 
VOID NTAPI KeStallExecutionProcessor (ULONG MicroSeconds)
 
VOID NTAPI HalCalibratePerformanceCounter (IN volatile PLONG Count, IN ULONGLONG NewCount)
 

Variables

LARGE_INTEGER HalpCpuClockFrequency = {{INITIAL_STALL_COUNT * 1000000}}
 
UCHAR TscCalibrationPhase
 
ULONG64 TscCalibrationArray [NUM_SAMPLES]
 
UCHAR HalpRtcClockVector = 0xD1
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file tsc.c.

◆ RTC_MODE

#define RTC_MODE   6 /* Mode 6 is 1024 Hz */

Definition at line 23 of file tsc.c.

◆ SAMPLE_FREQENCY

#define SAMPLE_FREQENCY   ((32768 << 1) >> RTC_MODE)

Definition at line 24 of file tsc.c.

Function Documentation

◆ DoLinearRegression()

static ULONG64 DoLinearRegression ( ULONG  XMax,
ULONG64 ArrayY 
)
static

Definition at line 30 of file tsc.c.

33 {
34  ULONG X, SumXX;
35  ULONG64 SumXY;
36 
37  /* Calculate the sum of the squares of X */
38  SumXX = (XMax * (XMax + 1) * (2*XMax + 1)) / 6;
39 
40  /* Calculate the sum of the differences to the first value
41  weighted by x */
42  for (SumXY = 0, X = 1; X <= XMax; X++)
43  {
44  SumXY += X * (ArrayY[X] - ArrayY[0]);
45  }
46 
47  /* Account for sample frequency */
48  SumXY *= SAMPLE_FREQENCY;
49 
50  /* Return the quotient of the sums */
51  return (SumXY + (SumXX/2)) / SumXX;
52 }
#define SAMPLE_FREQENCY
Definition: tsc.c:24
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned int ULONG
Definition: retypes.h:1
#define X(b, s)

Referenced by HalpInitializeTsc().

◆ HalCalibratePerformanceCounter()

VOID NTAPI HalCalibratePerformanceCounter ( IN volatile PLONG  Count,
IN ULONGLONG  NewCount 
)

Definition at line 174 of file tsc.c.

177 {
179  ASSERT(FALSE);
180 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define UNIMPLEMENTED
Definition: debug.h:114

◆ HalpCalibrateStallExecution()

VOID NTAPI HalpCalibrateStallExecution ( VOID  )

Definition at line 123 of file tsc.c.

124 {
125  // Timer interrupt is now active
126 
128 
129  KeGetPcr()->StallScaleFactor = (ULONG)(HalpCpuClockFrequency.QuadPart / 1000000);
130 }
VOID NTAPI HalpInitializeTsc(VOID)
Definition: tsc.c:56
#define KeGetPcr()
Definition: ke.h:25
unsigned int ULONG
Definition: retypes.h:1
LARGE_INTEGER HalpCpuClockFrequency
Definition: tsc.c:17
LONGLONG QuadPart
Definition: typedefs.h:112

◆ HalpInitializeTsc()

VOID NTAPI HalpInitializeTsc ( VOID  )

Definition at line 56 of file tsc.c.

57 {
59  KIDTENTRY OldIdtEntry, *IdtPointer;
60  PKPCR Pcr = KeGetPcr();
61  UCHAR RegisterA, RegisterB;
62 
63  /* Check if the CPU supports RDTSC */
64  if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC))
65  {
66  KeBugCheck(HAL_INITIALIZATION_FAILED);
67  }
68 
69  /* Save flags and disable interrupts */
70  Flags = __readeflags();
71  _disable();
72 
73  /* Enable the periodic interrupt in the CMOS */
74  RegisterB = HalpReadCmos(RTC_REGISTER_B);
76 
77  /* Modify register A to RTC_MODE to get SAMPLE_FREQENCY */
78  RegisterA = HalpReadCmos(RTC_REGISTER_A);
79  RegisterA = (RegisterA & 0xF0) | RTC_MODE;
80  HalpWriteCmos(RTC_REGISTER_A, RegisterA);
81 
82  /* Save old IDT entry */
83  IdtPointer = KiGetIdtEntry(Pcr, HalpRtcClockVector);
84  OldIdtEntry = *IdtPointer;
85 
86  /* Set the calibration ISR */
88 
89  /* Reset TSC value to 0 */
91 
92  /* Enable the timer interrupt */
94 
95  /* Read register C, so that the next interrupt can happen */
97 
98  /* Wait for completion */
99  _enable();
101  _disable();
102 
103  /* Disable the periodic interrupt in the CMOS */
105 
106  /* Disable the timer interrupt */
108 
109  /* Restore old IDT entry */
110  *IdtPointer = OldIdtEntry;
111 
112  /* Calculate an average, using simplified linear regression */
115 
116  /* Restore flags */
118 
119 }
VOID FORCEINLINE HalpWriteCmos(IN UCHAR Reg, IN UCHAR Value)
Definition: cmos.c:35
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
#define RTC_MODE
Definition: tsc.c:23
#define _ReadWriteBarrier()
Definition: intrin_arm.h:36
#define RTC_REG_B_PI
Definition: halp.h:55
UCHAR HalpRtcClockVector
Definition: tsc.c:21
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define KF_RDTSC
Definition: ketypes.h:144
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
#define MSR_RDTSC
Definition: tsc.h:6
Definition: ke.h:280
#define KeGetPcr()
Definition: ke.h:25
UCHAR TscCalibrationPhase
Definition: tsc.c:19
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define CLOCK_LEVEL
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1555
#define NUM_SAMPLES
Definition: tsc.h:5
UCHAR FORCEINLINE HalpReadCmos(IN UCHAR Reg)
Definition: cmos.c:24
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
#define RTC_REGISTER_B
Definition: halp.h:17
void __cdecl TscCalibrationISR(void)
unsigned char UCHAR
Definition: xmlstorage.h:181
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1550
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:242
#define RTC_REGISTER_C
Definition: halp.h:56
ULONG64 TscCalibrationArray[NUM_SAMPLES]
Definition: tsc.c:20
#define KiGetIdtEntry(Pcr, Vector)
Definition: tsc.h:17
#define RTC_REGISTER_A
Definition: xboxrtc.c:21
void __cdecl _disable(void)
Definition: intrin_arm.h:365
LARGE_INTEGER HalpCpuClockFrequency
Definition: tsc.c:17
static ULONG64 DoLinearRegression(ULONG XMax, ULONG64 *ArrayY)
Definition: tsc.c:30
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by HalpCalibrateStallExecution().

◆ KeQueryPerformanceCounter()

LARGE_INTEGER NTAPI KeQueryPerformanceCounter ( OUT PLARGE_INTEGER PerformanceFrequency  OPTIONAL)

Definition at line 136 of file tsc.c.

138 {
140 
141  /* Make sure it's calibrated */
143 
144  /* Does the caller want the frequency? */
145  if (PerformanceFrequency)
146  {
147  /* Return tsc frequency */
148  *PerformanceFrequency = HalpCpuClockFrequency;
149  }
150 
151  /* Return the current value */
152  Result.QuadPart = __rdtsc();
153  return Result;
154 }
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
LARGE_INTEGER HalpCpuClockFrequency
Definition: tsc.c:17
LONGLONG QuadPart
Definition: typedefs.h:112

◆ KeStallExecutionProcessor()

VOID NTAPI KeStallExecutionProcessor ( ULONG  MicroSeconds)

Definition at line 158 of file tsc.c.

159 {
160  ULONG64 StartTime, EndTime;
161 
162  /* Get the initial time */
163  StartTime = __rdtsc();
164 
165  /* Calculate the ending time */
166  EndTime = StartTime + KeGetPcr()->StallScaleFactor * MicroSeconds;
167 
168  /* Loop until time is elapsed */
169  while (__rdtsc() < EndTime);
170 }
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
static LARGE_INTEGER StartTime
Definition: sys_arch.c:18
#define KeGetPcr()
Definition: ke.h:25
unsigned __int64 ULONG64
Definition: imports.h:198

Variable Documentation

◆ HalpCpuClockFrequency

LARGE_INTEGER HalpCpuClockFrequency = {{INITIAL_STALL_COUNT * 1000000}}

◆ HalpRtcClockVector

UCHAR HalpRtcClockVector = 0xD1

Definition at line 21 of file tsc.c.

Referenced by HalpInitializeTsc().

◆ TscCalibrationArray

ULONG64 TscCalibrationArray[NUM_SAMPLES]

Definition at line 20 of file tsc.c.

Referenced by HalpInitializeTsc().

◆ TscCalibrationPhase

UCHAR TscCalibrationPhase

Definition at line 19 of file tsc.c.

Referenced by HalpInitializeTsc().