3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/generic/timer.c
5 * PURPOSE: HAL Timer Routines
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* GLOBALS *******************************************************************/
17 BOOLEAN HalpClockSetMSRate
;
18 ULONG HalpCurrentTimeIncrement
;
19 ULONG HalpCurrentRollOver
;
20 ULONG HalpNextMSRate
= 14;
21 ULONG HalpLargestClockMS
= 15;
23 LARGE_INTEGER HalpRolloverTable
[15] =
42 /* PRIVATE FUNCTIONS *********************************************************/
46 HalpInitializeClock(VOID
)
48 PKPRCB Prcb
= KeGetCurrentPrcb();
52 TIMER_CONTROL_PORT_REGISTER TimerControl
;
54 /* Check the CPU Type */
55 if (Prcb
->CpuType
<= 4)
57 /* 486's or equal can't go higher then 10ms */
58 HalpLargestClockMS
= 10;
62 /* Get increment and rollover for the largest time clock ms possible */
63 Increment
= HalpRolloverTable
[HalpLargestClockMS
- 1].HighPart
;
64 RollOver
= (USHORT
)HalpRolloverTable
[HalpLargestClockMS
- 1].LowPart
;
66 /* Set the maximum and minimum increment with the kernel */
67 HalpCurrentTimeIncrement
= Increment
;
68 KeSetTimeIncrement(Increment
, HalpRolloverTable
[0].HighPart
);
70 /* Disable interrupts */
71 Flags
= __readeflags();
75 // Program the PIT for binary mode
77 TimerControl
.BcdMode
= FALSE
;
80 // Program the PIT to generate a normal rate wave (Mode 3) on channel 0.
81 // Channel 0 is used for the IRQ0 clock interval timer, and channel
82 // 1 is used for DRAM refresh.
84 // Mode 2 gives much better accuracy than Mode 3.
86 TimerControl
.OperatingMode
= PitOperatingMode2
;
87 TimerControl
.Channel
= PitChannel0
;
90 // Set the access mode that we'll use to program the reload value.
92 TimerControl
.AccessMode
= PitAccessModeLowHigh
;
95 // Now write the programming bits
97 __outbyte(TIMER_CONTROL_PORT
, TimerControl
.Bits
);
100 // Next we write the reload value for channel 0
102 __outbyte(TIMER_CHANNEL0_DATA_PORT
, RollOver
& 0xFF);
103 __outbyte(TIMER_CHANNEL0_DATA_PORT
, RollOver
>> 8);
105 /* Restore interrupts if they were previously enabled */
106 __writeeflags(Flags
);
108 /* Save rollover and return */
109 HalpCurrentRollOver
= RollOver
;
115 HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame
)
120 KiEnterInterruptTrap(TrapFrame
);
122 /* Start the interrupt */
123 if (HalBeginSystemInterrupt(CLOCK2_LEVEL
, PRIMARY_VECTOR_BASE
, &Irql
))
125 /* Update the performance counter */
126 HalpPerfCounter
.QuadPart
+= HalpCurrentRollOver
;
128 /* Check if someone changed the time rate */
129 if (HalpClockSetMSRate
)
131 /* Not yet supported */
136 /* Update the system time -- the kernel will exit this trap */
137 KeUpdateSystemTime(TrapFrame
, HalpCurrentTimeIncrement
, Irql
);
140 /* Spurious, just end the interrupt */
141 KiEoiHelper(TrapFrame
);
146 HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame
)
151 KiEnterInterruptTrap(TrapFrame
);
153 /* Start the interrupt */
154 if (HalBeginSystemInterrupt(PROFILE_LEVEL
, PRIMARY_VECTOR_BASE
+ 8, &Irql
))
156 /* Profiling isn't yet enabled */
161 /* Spurious, just end the interrupt */
162 KiEoiHelper(TrapFrame
);
167 /* PUBLIC FUNCTIONS ***********************************************************/
174 HalCalibratePerformanceCounter(IN
volatile PLONG Count
,
175 IN ULONGLONG NewCount
)
179 /* Disable interrupts */
180 Flags
= __readeflags();
183 /* Do a decrement for this CPU */
184 _InterlockedDecrement(Count
);
186 /* Wait for other CPUs */
189 /* Restore interrupts if they were previously enabled */
190 __writeeflags(Flags
);
198 HalSetTimeIncrement(IN ULONG Increment
)
200 /* Round increment to ms */
203 /* Normalize between our minimum (1 ms) and maximum (variable) setting */
204 if (Increment
> HalpLargestClockMS
) Increment
= HalpLargestClockMS
;
205 if (Increment
<= 0) Increment
= 1;
207 /* Set the rate and tell HAL we want to change it */
208 HalpNextMSRate
= Increment
;
209 HalpClockSetMSRate
= TRUE
;
211 /* Return the increment */
212 return HalpRolloverTable
[Increment
- 1].HighPart
;