ReactOS  0.4.15-dev-1039-gb9754fa
rtctimer.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS HAL
3  * LICENSE: GNU GPL - See COPYING in the top level directory
4  * FILE: hal/halx86/apic/rtctimer.c
5  * PURPOSE: HAL APIC Management and Control Code
6  * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7  * REFERENCES: https://wiki.osdev.org/RTC
8  * https://forum.osdev.org/viewtopic.php?f=13&t=20825&start=0
9  * http://www.bioscentral.com/misc/cmosmap.htm
10  */
11 
12 /* INCLUDES *******************************************************************/
13 
14 #include <hal.h>
15 #define NDEBUG
16 #include <debug.h>
17 
18 #if defined(ALLOC_PRAGMA) && !defined(_MINIHAL_)
19 #pragma alloc_text(INIT, HalpInitializeClock)
20 #endif
21 
22 /* GLOBALS ********************************************************************/
23 
24 const UCHAR HalpClockVector = 0xD1;
27 UCHAR HalpCurrentRate = 9; /* Initial rate 9: 128 Hz / 7.8 ms */
29 static UCHAR RtcMinimumClockRate = 8; /* Minimum rate 8: 256 Hz / 3.9 ms */
30 static UCHAR RtcMaximumClockRate = 12; /* Maximum rate 12: 16 Hz / 62.5 ms */
31 
56 ULONG
58 {
59  /* Calculate frequency */
60  ULONG Freqency = 32768 >> (Rate - 1);
61 
62  /* Calculate interval in 100ns interval: Interval = (1 / Frequency) * 10000000
63  This formula will round properly, instead of truncating. */
64  return (10000000 + (Freqency/2)) / Freqency;
65 }
66 
67 VOID
69 {
70  UCHAR RegisterA;
71 
72  /* Update the global values */
73  HalpCurrentRate = ClockRate;
75 
76  /* Acquire CMOS lock */
78 
79  // TODO: disable NMI
80 
81  /* Read value of register A */
82  RegisterA = HalpReadCmos(RTC_REGISTER_A);
83 
84  /* Change lower 4 bits to new rate */
85  RegisterA &= 0xF0;
86  RegisterA |= ClockRate;
87 
88  /* Write the new value */
89  HalpWriteCmos(RTC_REGISTER_A, RegisterA);
90 
91  /* Release CMOS lock */
93 }
94 
95 INIT_FUNCTION
96 VOID
97 NTAPI
99 {
100  ULONG_PTR EFlags;
101  UCHAR RegisterB;
102 
103  /* Save EFlags and disable interrupts */
104  EFlags = __readeflags();
105  _disable();
106 
107  // TODO: disable NMI
108 
109  /* Acquire CMOS lock */
111 
112  /* Enable the periodic interrupt in the CMOS */
113  RegisterB = HalpReadCmos(RTC_REGISTER_B);
115 
116  /* Release CMOS lock */
118 
119  /* Set initial rate */
121 
122  /* Restore interrupt state */
123  __writeeflags(EFlags);
124 
125  /* Notify the kernel about the maximum and minimum increment */
128 
129 
130  DPRINT1("Clock initialized\n");
131 }
132 
133 VOID
134 FASTCALL
136 {
137  ULONG LastIncrement;
138  KIRQL Irql;
139 
140  /* Enter trap */
141  KiEnterInterruptTrap(TrapFrame);
142 #ifdef _M_AMD64
143  /* This is for debugging */
144  TrapFrame->ErrorCode = 0xc10c4;
145 #endif
146 
147  /* Start the interrupt */
149  {
150  /* Spurious, just end the interrupt */
151  KiEoiHelper(TrapFrame);
152  }
153 
154  /* Read register C, so that the next interrupt can happen */
156 
157  /* Save increment */
158  LastIncrement = HalpCurrentTimeIncrement;
159 
160  /* Check if someone changed the time rate */
161  if (HalpClockSetMSRate)
162  {
163  /* Set new clock rate */
165 
166  /* We're done */
168  }
169 
170  /* Update the system time -- on x86 the kernel will exit this trap */
171  KeUpdateSystemTime(TrapFrame, LastIncrement, Irql);
172 }
173 
174 VOID
175 FASTCALL
177 {
178  __debugbreak();
179 }
180 
181 ULONG
182 NTAPI
184 {
185  UCHAR Rate;
186 
187  /* Lookup largest value below given Increment */
188  for (Rate = RtcMinimumClockRate; Rate <= RtcMaximumClockRate; Rate++)
189  {
190  /* Check if this is the largest rate possible */
191  if (RtcClockRateToIncrement(Rate + 1) > Increment) break;
192  }
193 
194  /* Set the rate and tell HAL we want to change it */
195  HalpNextMSRate = Rate;
197 
198  /* Return the real increment */
199  return RtcClockRateToIncrement(Rate);
200 }
#define IN
Definition: typedefs.h:39
VOID FORCEINLINE HalpWriteCmos(IN UCHAR Reg, IN UCHAR Value)
Definition: cmos.c:35
INIT_FUNCTION VOID NTAPI HalpInitializeClock(VOID)
Definition: rtctimer.c:98
VOID FASTCALL HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: rtctimer.c:135
VOID NTAPI KeSetTimeIncrement(IN ULONG MaxIncrement, IN ULONG MinIncrement)
Definition: ntoskrnl.c:42
#define TRUE
Definition: types.h:120
VOID FASTCALL KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, IN ULONG Increment, IN KIRQL OldIrql)
Definition: time.c:64
static UCHAR RtcMaximumClockRate
Definition: rtctimer.c:30
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
BOOLEAN HalpClockSetMSRate
Definition: rtctimer.c:25
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
VOID RtcSetClockRate(UCHAR ClockRate)
Definition: rtctimer.c:68
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define CLOCK_LEVEL
#define RTC_REG_B_PI
Definition: halhw.h:16
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1569
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
UCHAR HalpCurrentRate
Definition: rtctimer.c:27
#define FALSE
Definition: types.h:117
VOID NTAPI HalpReleaseCmosSpinLock(VOID)
Definition: spinlock.c:244
VOID FASTCALL HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: rtctimer.c:176
unsigned char BOOLEAN
#define FORCEINLINE
Definition: ntbasedef.h:216
UCHAR FORCEINLINE HalpReadCmos(IN UCHAR Reg)
Definition: cmos.c:24
UCHAR HalpNextMSRate
Definition: rtctimer.c:26
ULONG NTAPI HalSetTimeIncrement(IN ULONG Increment)
Definition: rtctimer.c:183
const UCHAR HalpClockVector
Definition: rtctimer.c:24
VOID NTAPI HalpAcquireCmosSpinLock(VOID)
Definition: spinlock.c:227
#define RTC_REGISTER_B
Definition: halp.h:17
unsigned char UCHAR
Definition: xmlstorage.h:181
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1564
#define RTC_REGISTER_C
Definition: halhw.h:17
static UCHAR RtcMinimumClockRate
Definition: rtctimer.c:29
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
FORCEINLINE ULONG RtcClockRateToIncrement(UCHAR Rate)
Converts the CMOS RTC rate into the time increment in 100ns intervals.
Definition: rtctimer.c:57
#define RTC_REGISTER_A
Definition: xboxrtc.c:21
#define DPRINT1
Definition: precomp.h:8
ULONG HalpCurrentTimeIncrement
Definition: rtctimer.c:28
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42