ReactOS 0.4.17-dev-117-g313be0c
delay.c File Reference
#include <hal.h>
#include <debug.h>
#include "delay.h"
Include dependency graph for delay.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define SAMPLE_FREQUENCY   1024
 

Functions

VOID __cdecl HalpTscCalibrationISR (VOID)
 
static VOID HalpPrepareStallExecution (VOID)
 
static ULONG64 HalpDoLinearRegression (_In_ ULONG XMax, _In_reads_(XMax+1) const ULONG64 *ArrayY)
 
VOID NTAPI HalpCalibrateStallExecution (VOID)
 

Variables

volatile ULONG TscCalibrationPhase
 
ULONG64 TscCalibrationArray [NUM_SAMPLES]
 
UCHAR HalpStallExecutionSerialize
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file delay.c.

◆ SAMPLE_FREQUENCY

#define SAMPLE_FREQUENCY   1024

Definition at line 20 of file delay.c.

Function Documentation

◆ HalpCalibrateStallExecution()

VOID NTAPI HalpCalibrateStallExecution ( VOID  )

Definition at line 95 of file delay.c.

96{
98 PVOID PreviousHandler;
99 TIMER_CONTROL_PORT_REGISTER TimerControl;
100 ULONG TimerFrequency;
102 ULONG64 CpuClockFrequency;
103
104 /* Check if the CPU supports RDTSC */
105 if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC))
106 {
107 KeBugCheck(HAL_INITIALIZATION_FAILED);
108 }
109
111 _disable();
112
113 PreviousHandler = KeQueryInterruptHandler(PIC_TIMER_IRQ);
115
116 /* Program the PIT for binary mode */
117 TimerControl.BcdMode = FALSE;
118 TimerControl.OperatingMode = PitOperatingMode2;
119 TimerControl.Channel = PitChannel0;
120 TimerControl.AccessMode = PitAccessModeLowHigh;
121
122 if (__inbyte(0x42) & 0x20)
123 TimerFrequency = TIMER_FREQUENCY_1;
124 else
125 TimerFrequency = TIMER_FREQUENCY_2;
126 Period = (TimerFrequency + (SAMPLE_FREQUENCY / 2)) / SAMPLE_FREQUENCY;
127
128 __outbyte(TIMER_CONTROL_PORT, TimerControl.Bits);
131
133
134 /* Collect the sample data */
135 _enable();
136 while (TscCalibrationPhase != (NUM_SAMPLES + 1))
137 NOTHING;
138 _disable();
139
142
143 /* Calculate an average, using simplified linear regression */
145 KeGetPcr()->StallScaleFactor = (ULONG)(CpuClockFrequency / 1000000);
146
148
150}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
#define FALSE
Definition: types.h:117
#define CLOCK2_LEVEL
Definition: env_spec_w32.h:700
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
ULONG64 TscCalibrationArray[NUM_SAMPLES]
Definition: tsc.c:20
VOID __cdecl HalpTscCalibrationISR(VOID)
static ULONG64 HalpDoLinearRegression(_In_ ULONG XMax, _In_reads_(XMax+1) const ULONG64 *ArrayY)
Definition: delay.c:69
#define SAMPLE_FREQUENCY
Definition: delay.c:20
static VOID HalpPrepareStallExecution(VOID)
Definition: delay.c:35
volatile ULONG TscCalibrationPhase
Definition: tsc.c:19
#define PRIMARY_VECTOR_BASE
Definition: halp.h:16
@ PitChannel0
Definition: halhw.h:102
#define TIMER_CONTROL_PORT
Definition: halhw.h:70
@ PitAccessModeLowHigh
Definition: halhw.h:97
#define PIC_TIMER_IRQ
Definition: halhw.h:155
@ PitOperatingMode2
Definition: halhw.h:84
#define TIMER_CHANNEL0_DATA_PORT
Definition: halhw.h:67
#define NOTHING
Definition: input_list.c:10
PPC_QUAL unsigned char __inbyte(const unsigned long Port)
Definition: intrin_ppc.h:539
PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
Definition: intrin_ppc.h:605
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1701
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1706
unsigned __int64 ULONG64
Definition: imports.h:198
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1187
#define KF_RDTSC
Definition: ketypes.h:32
#define KeGetPcr()
Definition: ketypes.h:81
FORCEINLINE PVOID KeQueryInterruptHandler(IN ULONG Vector)
Definition: ke.h:329
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:303
unsigned short USHORT
Definition: pedump.c:61
@ Latched
Definition: miniport.h:81
#define TIMER_FREQUENCY_1
Definition: pit.h:16
#define TIMER_FREQUENCY_2
Definition: pit.h:17
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define NUM_SAMPLES
Definition: tsc.h:5
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ LARGE_INTEGER _In_ ULONG Period
Definition: kefuncs.h:1313

◆ HalpDoLinearRegression()

static ULONG64 HalpDoLinearRegression ( _In_ ULONG  XMax,
_In_reads_(XMax+1) const ULONG64 ArrayY 
)
static

Definition at line 69 of file delay.c.

72{
73 ULONG X, SumXX;
74 ULONG64 SumXY;
75
76 /* Calculate the sum of the squares of X */
77 SumXX = (XMax * (XMax + 1) * (2 * XMax + 1)) / 6;
78
79 /* Calculate the sum of the differences to the first value weighted by X */
80 for (SumXY = 0, X = 1; X <= XMax; X++)
81 {
82 SumXY += X * (ArrayY[X] - ArrayY[0]);
83 }
84
85 /* Account for sample frequency */
86 SumXY *= SAMPLE_FREQUENCY;
87
88 /* Return the quotient of the sums */
89 return (SumXY + (SumXX / 2)) / SumXX;
90}
#define X(b, s)

Referenced by HalpCalibrateStallExecution().

◆ HalpPrepareStallExecution()

static VOID HalpPrepareStallExecution ( VOID  )
static

Definition at line 35 of file delay.c.

36{
38 PKPRCB Prcb = KeGetCurrentPrcb();
39
40 /* xor eax, eax; cpuid */
41 ASSERT((Instruction[1] == 0xC0) && // The byte [0] has different encodings
42 (Instruction[2] == 0x0F) &&
43 (Instruction[3] == 0xA2));
44
45 /*
46 * Starting with the Pentium Pro processor it is necessary to force
47 * the in-order execution of the RDTSC instruction using a serializing instruction.
48 * For more details, please refer to Section 3.1 of
49 * Intel "Using the RDTSC Instruction for Performance Monitoring".
50 *
51 * Patch the KeStallExecutionProcessor function to remove the serializing instruction
52 * for the Pentium and Pentium MMX processors because the CPUID instruction is slow.
53 */
54 if ((Prcb->CpuType < 6) && !strcmp(Prcb->VendorString, "GenuineIntel"))
55 {
56 /* Replace "xor eax, eax; cpuid" with "lea esi, [esi+0]" */
57 Instruction[0] = 0x8D;
58 Instruction[1] = 0x74;
59 Instruction[2] = 0x26;
60 Instruction[3] = 0x00;
61
63 }
64}
@ Instruction
Definition: asmpp.cpp:82
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
UCHAR HalpStallExecutionSerialize
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE VOID KeSweepICache(IN PVOID BaseAddress, IN SIZE_T FlushSize)
Definition: ke.h:282
CHAR CpuType
Definition: ketypes.h:678
UCHAR VendorString[13]
Definition: ketypes.h:895
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by HalpCalibrateStallExecution().

◆ HalpTscCalibrationISR()

VOID __cdecl HalpTscCalibrationISR ( VOID  )

Variable Documentation

◆ HalpStallExecutionSerialize

UCHAR HalpStallExecutionSerialize
extern

◆ TscCalibrationArray

ULONG64 TscCalibrationArray[NUM_SAMPLES]
extern

Definition at line 20 of file tsc.c.

Referenced by HalpCalibrateStallExecution(), and HalpInitializeTsc().

◆ TscCalibrationPhase

volatile ULONG TscCalibrationPhase
extern

Definition at line 19 of file tsc.c.

Referenced by HalpCalibrateStallExecution(), and HalpInitializeTsc().