2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/hal/x86/time.c
5 * PURPOSE: Getting time information
9 /* INCLUDES *****************************************************************/
11 #include <ddk/ntddk.h>
17 #include <internal/debug.h>
19 /* MACROS and CONSTANTS ******************************************************/
21 /* macro BCD_INT : convert bcd to int */
22 #define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
24 /* macro INT_BCD : convert int to bcd */
25 #define INT_BCD(int) (((int / 10) << 4) + (int % 10))
28 #define RTC_REGISTER_A 0x0A
29 #define RTC_REG_A_UIP 0x80 /* Update In Progress bit */
31 #define RTC_REGISTER_B 0x0B
33 #define RTC_REGISTER_CENTURY 0x32
36 /* FUNCTIONS *****************************************************************/
40 HalpQueryCMOS(UCHAR Reg)
47 __asm__("cli\n"); // AP unsure as to whether to do this here
48 WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
49 Val = READ_PORT_UCHAR((PUCHAR)0x71);
50 WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
58 HalpSetCMOS(UCHAR Reg,
65 __asm__("cli\n"); // AP unsure as to whether to do this here
66 WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
67 WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
68 WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
74 HalpQueryECMOS(USHORT Reg)
80 __asm__("cli\n"); // AP unsure as to whether to do this here
81 WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
82 WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
83 Val = READ_PORT_UCHAR((PUCHAR)0x76);
91 HalpSetECMOS(USHORT Reg,
97 __asm__("cli\n"); // AP unsure as to whether to do this here
98 WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
99 WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
100 WRITE_PORT_UCHAR((PUCHAR)0x76, Val);
106 HalQueryRealTimeClock(PTIME_FIELDS Time)
108 /* check 'Update In Progress' bit */
109 while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
112 Time->Second = BCD_INT(HalpQueryCMOS (0));
113 Time->Minute = BCD_INT(HalpQueryCMOS (2));
114 Time->Hour = BCD_INT(HalpQueryCMOS (4));
115 Time->Weekday = BCD_INT(HalpQueryCMOS (6));
116 Time->Day = BCD_INT(HalpQueryCMOS (7));
117 Time->Month = BCD_INT(HalpQueryCMOS (8));
118 Time->Year = BCD_INT(HalpQueryCMOS (9));
127 Time->Year += BCD_INT(HalpQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
131 DbgPrint ("HalQueryRealTimeClock() %d:%d:%d %d/%d/%d\n",
141 Time->Milliseconds = 0;
146 HalSetRealTimeClock(PTIME_FIELDS Time)
148 /* check 'Update In Progress' bit */
149 while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
152 HalpSetCMOS (0, INT_BCD(Time->Second));
153 HalpSetCMOS (2, INT_BCD(Time->Minute));
154 HalpSetCMOS (4, INT_BCD(Time->Hour));
155 HalpSetCMOS (6, INT_BCD(Time->Weekday));
156 HalpSetCMOS (7, INT_BCD(Time->Day));
157 HalpSetCMOS (8, INT_BCD(Time->Month));
158 HalpSetCMOS (9, INT_BCD(Time->Year % 100));
162 HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
168 HalGetEnvironmentVariable(PCH Name,
172 if (_stricmp(Name, "LastKnownGood") != 0)
177 if (HalpQueryCMOS(RTC_REGISTER_B) & 0x01)
179 strncpy(Value, "FALSE", ValueLength);
183 strncpy(Value, "TRUE", ValueLength);
191 HalSetEnvironmentVariable(PCH Name,
196 if (_stricmp(Name, "LastKnownGood") != 0)
199 Val = HalpQueryCMOS(RTC_REGISTER_B);
201 if (_stricmp(Value, "TRUE") == 0)
202 HalpSetCMOS(RTC_REGISTER_B, Val | 0x01);
203 else if (_stricmp(Value, "FALSE") == 0)
204 HalpSetCMOS(RTC_REGISTER_B, Val & ~0x01);
213 HalpGetCmosData(PBUS_HANDLER BusHandler,
221 ULONG Address = SlotNumber;
224 DPRINT("HalpGetCmosData() called.\n");
225 DPRINT(" BusNumber %lu\n", BusNumber);
226 DPRINT(" SlotNumber %lu\n", SlotNumber);
227 DPRINT(" Offset 0x%lx\n", Offset);
228 DPRINT(" Length 0x%lx\n", Length);
236 while ((Len > 0) && (Address < 0x100))
238 *Ptr = HalpQueryCMOS((UCHAR)Address);
244 else if (BusNumber == 1)
247 while ((Len > 0) && (Address < 0x1000))
249 *Ptr = HalpQueryECMOS((USHORT)Address);
256 return(Length - Len);
261 HalpSetCmosData(PBUS_HANDLER BusHandler,
268 PUCHAR Ptr = (PUCHAR)Buffer;
269 ULONG Address = SlotNumber;
272 DPRINT("HalpSetCmosData() called.\n");
273 DPRINT(" BusNumber %lu\n", BusNumber);
274 DPRINT(" SlotNumber %lu\n", SlotNumber);
275 DPRINT(" Offset 0x%lx\n", Offset);
276 DPRINT(" Length 0x%lx\n", Length);
284 while ((Len > 0) && (Address < 0x100))
286 HalpSetCMOS((UCHAR)Address, *Ptr);
292 else if (BusNumber == 1)
295 while ((Len > 0) && (Address < 0x1000))
297 HalpSetECMOS((USHORT)Address, *Ptr);
304 return(Length - Len);