ReactOS  0.4.15-dev-2765-g10e48fa
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 /* GLOBALS ********************************************************************/
19 
20 const UCHAR HalpClockVector = 0xD1;
23 UCHAR HalpCurrentRate = 9; /* Initial rate 9: 128 Hz / 7.8 ms */
25 static UCHAR RtcMinimumClockRate = 8; /* Minimum rate 8: 256 Hz / 3.9 ms */
26 static UCHAR RtcMaximumClockRate = 12; /* Maximum rate 12: 16 Hz / 62.5 ms */
27 
52 ULONG
54 {
55  /* Calculate frequency */
56  ULONG Freqency = 32768 >> (Rate - 1);
57 
58  /* Calculate interval in 100ns interval: Interval = (1 / Frequency) * 10000000
59  This formula will round properly, instead of truncating. */
60  return (10000000 + (Freqency/2)) / Freqency;
61 }
62 
63 VOID
65 {
66  UCHAR RegisterA;
67 
68  /* Update the global values */
69  HalpCurrentRate = ClockRate;
71 
72  /* Acquire CMOS lock */
74 
75  // TODO: disable NMI
76 
77  /* Read value of register A */
78  RegisterA = HalpReadCmos(RTC_REGISTER_A);
79 
80  /* Change lower 4 bits to new rate */
81  RegisterA &= 0xF0;
82  RegisterA |= ClockRate;
83 
84  /* Write the new value */
85  HalpWriteCmos(RTC_REGISTER_A, RegisterA);
86 
87  /* Release CMOS lock */
89 }
90 
91 CODE_SEG("INIT")
92 VOID
93 NTAPI
95 {
96  ULONG_PTR EFlags;
97  UCHAR RegisterB;
98 
99  /* Save EFlags and disable interrupts */
100  EFlags = __readeflags();
101  _disable();
102 
103  // TODO: disable NMI
104 
105  /* Acquire CMOS lock */
107 
108  /* Enable the periodic interrupt in the CMOS */
109  RegisterB = HalpReadCmos(RTC_REGISTER_B);
111 
112  /* Release CMOS lock */
114 
115  /* Set initial rate */
117 
118  /* Restore interrupt state */
119  __writeeflags(EFlags);
120 
121  /* Notify the kernel about the maximum and minimum increment */
124 
125 
126  DPRINT1("Clock initialized\n");
127 }
128 
129 VOID
130 FASTCALL
132 {
133  ULONG LastIncrement;
134  KIRQL Irql;
135 
136  /* Enter trap */
137  KiEnterInterruptTrap(TrapFrame);
138 #ifdef _M_AMD64
139  /* This is for debugging */
140  TrapFrame->ErrorCode = 0xc10c4;
141 #endif
142 
143  /* Start the interrupt */
145  {
146  /* Spurious, just end the interrupt */
147  KiEoiHelper(TrapFrame);
148  }
149 
150  /* Read register C, so that the next interrupt can happen */
152 
153  /* Save increment */
154  LastIncrement = HalpCurrentTimeIncrement;
155 
156  /* Check if someone changed the time rate */
157  if (HalpClockSetMSRate)
158  {
159  /* Set new clock rate */
161 
162  /* We're done */
164  }
165 
166  /* Update the system time -- on x86 the kernel will exit this trap */
167  KeUpdateSystemTime(TrapFrame, LastIncrement, Irql);
168 }
169 
170 ULONG
171 NTAPI
173 {
174  UCHAR Rate;
175 
176  /* Lookup largest value below given Increment */
177  for (Rate = RtcMinimumClockRate; Rate <= RtcMaximumClockRate; Rate++)
178  {
179  /* Check if this is the largest rate possible */
180  if (RtcClockRateToIncrement(Rate + 1) > Increment) break;
181  }
182 
183  /* Set the rate and tell HAL we want to change it */
184  HalpNextMSRate = Rate;
186 
187  /* Return the real increment */
188  return RtcClockRateToIncrement(Rate);
189 }
#define IN
Definition: typedefs.h:39
VOID FORCEINLINE HalpWriteCmos(IN UCHAR Reg, IN UCHAR Value)
Definition: cmos.c:35
VOID FASTCALL HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: rtctimer.c:131
VOID NTAPI KeSetTimeIncrement(IN ULONG MaxIncrement, IN ULONG MinIncrement)
Definition: ntoskrnl.c:35
#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:26
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
VOID NTAPI HalpInitializeClock(VOID)
Definition: rtctimer.c:94
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
BOOLEAN HalpClockSetMSRate
Definition: rtctimer.c:21
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
VOID RtcSetClockRate(UCHAR ClockRate)
Definition: rtctimer.c:64
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:1675
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
UCHAR HalpCurrentRate
Definition: rtctimer.c:23
#define FALSE
Definition: types.h:117
VOID NTAPI HalpReleaseCmosSpinLock(VOID)
Definition: spinlock.c:244
unsigned char BOOLEAN
UCHAR FORCEINLINE HalpReadCmos(IN UCHAR Reg)
Definition: cmos.c:24
UCHAR HalpNextMSRate
Definition: rtctimer.c:22
ULONG NTAPI HalSetTimeIncrement(IN ULONG Increment)
Definition: rtctimer.c:172
const UCHAR HalpClockVector
Definition: rtctimer.c:20
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:1670
#define RTC_REGISTER_C
Definition: halhw.h:17
static UCHAR RtcMinimumClockRate
Definition: rtctimer.c:25
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
#define FORCEINLINE
Definition: wdftypes.h:67
FORCEINLINE ULONG RtcClockRateToIncrement(UCHAR Rate)
Converts the CMOS RTC rate into the time increment in 100ns intervals.
Definition: rtctimer.c:53
#define RTC_REGISTER_A
Definition: xboxrtc.c:21
#define DPRINT1
Definition: precomp.h:8
ULONG HalpCurrentTimeIncrement
Definition: rtctimer.c:24
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
static CODE_SEG("PAGE")
Definition: isapnp.c:1482