ReactOS 0.4.15-dev-7931-gfd331f1
tsc.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS HAL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/apic/tsc.c
5 * PURPOSE: HAL Routines for TSC handling
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <hal.h>
12#include "tsc.h"
13#include "apicp.h"
14#define NDEBUG
15#include <debug.h>
16
18
21
22#define RTC_MODE 6 /* Mode 6 is 1024 Hz */
23#define SAMPLE_FREQUENCY ((32768 << 1) >> RTC_MODE)
24
25/* PRIVATE FUNCTIONS *********************************************************/
26
27static
30 ULONG XMax,
31 ULONG64 *ArrayY)
32{
33 ULONG X, SumXX;
34 ULONG64 SumXY;
35
36 /* Calculate the sum of the squares of X */
37 SumXX = (XMax * (XMax + 1) * (2*XMax + 1)) / 6;
38
39 /* Calculate the sum of the differences to the first value
40 weighted by x */
41 for (SumXY = 0, X = 1; X <= XMax; X++)
42 {
43 SumXY += X * (ArrayY[X] - ArrayY[0]);
44 }
45
46 /* Account for sample frequency */
47 SumXY *= SAMPLE_FREQUENCY;
48
49 /* Return the quotient of the sums */
50 return (SumXY + (SumXX/2)) / SumXX;
51}
52
53VOID
56{
58 PVOID PreviousHandler;
59 UCHAR RegisterA, RegisterB;
60
61 /* Check if the CPU supports RDTSC */
62 if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC))
63 {
64 KeBugCheck(HAL_INITIALIZATION_FAILED);
65 }
66
67 /* Save flags and disable interrupts */
69 _disable();
70
71 /* Enable the periodic interrupt in the CMOS */
72 RegisterB = HalpReadCmos(RTC_REGISTER_B);
74
75 /* Modify register A to RTC_MODE to get SAMPLE_FREQUENCY */
76 RegisterA = HalpReadCmos(RTC_REGISTER_A);
77 RegisterA = (RegisterA & 0xF0) | RTC_MODE;
78 HalpWriteCmos(RTC_REGISTER_A, RegisterA);
79
80 /* Save old IDT entry */
82
83 /* Set the calibration ISR */
85
86 /* Reset TSC value to 0 */
88
89 /* Enable the timer interrupt */
91
92 /* Read register C, so that the next interrupt can happen */
94
95 /* Wait for completion */
96 _enable();
98 _disable();
99
100 /* Disable the periodic interrupt in the CMOS */
102
103 /* Disable the timer interrupt */
105
106 /* Restore the previous handler */
108
109 /* Calculate an average, using simplified linear regression */
112
113 /* Restore flags */
115
116}
117
118VOID
119NTAPI
121{
122 // Timer interrupt is now active
123
125
126 KeGetPcr()->StallScaleFactor = (ULONG)(HalpCpuClockFrequency.QuadPart / 1000000);
127}
128
129/* PUBLIC FUNCTIONS ***********************************************************/
130
132NTAPI
134 OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
135{
137
138 /* Make sure it's calibrated */
140
141 /* Does the caller want the frequency? */
142 if (PerformanceFrequency)
143 {
144 /* Return tsc frequency */
145 *PerformanceFrequency = HalpCpuClockFrequency;
146 }
147
148 /* Return the current value */
149 Result.QuadPart = __rdtsc();
150 return Result;
151}
152
153VOID
154NTAPI
156{
157 ULONG64 StartTime, EndTime;
158
159 /* Get the initial time */
160 StartTime = __rdtsc();
161
162 /* Calculate the ending time */
163 EndTime = StartTime + KeGetPcr()->StallScaleFactor * MicroSeconds;
164
165 /* Loop until time is elapsed */
166 while (__rdtsc() < EndTime);
167}
168
169VOID
170NTAPI
172 IN volatile PLONG Count,
173 IN ULONGLONG NewCount)
174{
176 ASSERT(FALSE);
177}
178
#define APIC_CLOCK_VECTOR
Definition: apicp.h:44
#define UNIMPLEMENTED
Definition: debug.h:115
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define FALSE
Definition: types.h:117
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
VOID NTAPI HalpWriteCmos(_In_ UCHAR Reg, _In_ UCHAR Value)
Definition: cmos.c:132
UCHAR NTAPI HalpReadCmos(_In_ UCHAR Reg)
Definition: cmos.c:123
#define RTC_REG_B_PI
Definition: halhw.h:16
#define RTC_REGISTER_B
Definition: halhw.h:15
#define RTC_REGISTER_C
Definition: halhw.h:17
#define X(b, s)
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define _ReadWriteBarrier()
Definition: intrin_arm.h:36
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1146
#define KF_RDTSC
Definition: ketypes.h:32
#define INITIAL_STALL_COUNT
Definition: ketypes.h:321
#define CLOCK_LEVEL
Definition: ketypes.h:16
#define KeGetPcr()
Definition: ketypes.h:81
int Count
Definition: noreturn.cpp:7
FORCEINLINE PVOID KeQueryInterruptHandler(IN ULONG Vector)
Definition: ke.h:327
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:301
@ Latched
Definition: miniport.h:81
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
static LARGE_INTEGER StartTime
Definition: sys_arch.c:13
UCHAR TscCalibrationPhase
Definition: tsc.c:19
LARGE_INTEGER HalpCpuClockFrequency
Definition: tsc.c:17
ULONG64 TscCalibrationArray[NUM_SAMPLES]
Definition: tsc.c:20
VOID NTAPI KeStallExecutionProcessor(ULONG MicroSeconds)
Definition: tsc.c:155
#define SAMPLE_FREQUENCY
Definition: tsc.c:23
VOID NTAPI HalpCalibrateStallExecution(VOID)
Definition: tsc.c:120
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
Definition: tsc.c:133
static ULONG64 DoLinearRegression(ULONG XMax, ULONG64 *ArrayY)
Definition: tsc.c:29
VOID NTAPI HalCalibratePerformanceCounter(IN volatile PLONG Count, IN ULONGLONG NewCount)
Definition: tsc.c:171
#define RTC_MODE
Definition: tsc.c:22
#define MSR_RDTSC
Definition: tsc.h:6
VOID NTAPI HalpInitializeTsc(void)
Definition: tsc.c:55
void __cdecl TscCalibrationISR(void)
#define NUM_SAMPLES
Definition: tsc.h:5
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
_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:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define RTC_REGISTER_A
Definition: xboxrtc.c:21
unsigned char UCHAR
Definition: xmlstorage.h:181