ReactOS 0.4.16-dev-2633-g8dc9e50
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]
 

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 94 of file delay.c.

95{
97 PVOID PreviousHandler;
98 TIMER_CONTROL_PORT_REGISTER TimerControl;
99 ULONG TimerFrequency;
101 ULONG64 CpuClockFrequency;
102
103 /* Check if the CPU supports RDTSC */
104 if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC))
105 {
106 KeBugCheck(HAL_INITIALIZATION_FAILED);
107 }
108
110 _disable();
111
112 PreviousHandler = KeQueryInterruptHandler(PIC_TIMER_IRQ);
114
115 /* Program the PIT for binary mode */
116 TimerControl.BcdMode = FALSE;
117 TimerControl.OperatingMode = PitOperatingMode2;
118 TimerControl.Channel = PitChannel0;
119 TimerControl.AccessMode = PitAccessModeLowHigh;
120
121 if (__inbyte(0x42) & 0x20)
122 TimerFrequency = TIMER_FREQUENCY_1;
123 else
124 TimerFrequency = TIMER_FREQUENCY_2;
125 Period = (TimerFrequency + (SAMPLE_FREQUENCY / 2)) / SAMPLE_FREQUENCY;
126
127 __outbyte(TIMER_CONTROL_PORT, TimerControl.Bits);
130
132
133 /* Collect the sample data */
134 _enable();
135 while (TscCalibrationPhase != (NUM_SAMPLES + 1))
136 NOTHING;
137 _disable();
138
141
142 /* Calculate an average, using simplified linear regression */
144 KeGetPcr()->StallScaleFactor = (ULONG)(CpuClockFrequency / 1000000);
145
147
149}
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:68
#define SAMPLE_FREQUENCY
Definition: delay.c:20
static VOID HalpPrepareStallExecution(VOID)
Definition: delay.c:34
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 68 of file delay.c.

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

Referenced by HalpCalibrateStallExecution().

◆ HalpPrepareStallExecution()

static VOID HalpPrepareStallExecution ( VOID  )
static

Definition at line 34 of file delay.c.

35{
37 PKPRCB Prcb = KeGetCurrentPrcb();
38
39 /* xor eax, eax; cpuid */
40 ASSERT((Instruction[1] == 0xC0) && // The byte [0] has different encodings
41 (Instruction[2] == 0x0F) &&
42 (Instruction[3] == 0xA2));
43
44 /*
45 * Starting with the Pentium Pro processor it is necessary to force
46 * the in-order execution of the RDTSC instruction using a serializing instruction.
47 * For more details, please refer to Section 3.1 of
48 * Intel "Using the RDTSC Instruction for Performance Monitoring".
49 *
50 * Patch the KeStallExecutionProcessor function to remove the serializing instruction
51 * for the Pentium and Pentium MMX processors.
52 */
53 if ((Prcb->CpuType < 6) && !strcmp(Prcb->VendorString, "GenuineIntel"))
54 {
55 /* Replace "xor eax, eax; cpuid" with "lea esi, [esi+0]" */
56 Instruction[0] = 0x8D;
57 Instruction[1] = 0x74;
58 Instruction[2] = 0x26;
59 Instruction[3] = 0x00;
60
62 }
63}
@ Instruction
Definition: asmpp.cpp:82
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
#define ASSERT(a)
Definition: mode.c:44
#define KeStallExecutionProcessor(MicroSeconds)
Definition: precomp.h:27
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

◆ 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().