3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/generic/cmos.c
5 * PURPOSE: CMOS Access Routines (Real Time Clock and LastKnownGood)
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl (ekohl@abo.rhein-zeitung.de)
10 /* INCLUDES ******************************************************************/
16 /* GLOBALS *******************************************************************/
18 KSPIN_LOCK HalpSystemHardwareLock
;
20 /* PRIVATE FUNCTIONS *********************************************************/
24 HalpReadCmos(IN UCHAR Reg
)
26 /* Select the register */
27 WRITE_PORT_UCHAR(CMOS_CONTROL_PORT
, Reg
);
30 return READ_PORT_UCHAR(CMOS_DATA_PORT
);
35 HalpWriteCmos(IN UCHAR Reg
,
38 /* Select the register */
39 WRITE_PORT_UCHAR(CMOS_CONTROL_PORT
, Reg
);
42 WRITE_PORT_UCHAR(CMOS_DATA_PORT
, Value
);
47 HalpGetCmosData(IN ULONG BusNumber
,
52 PUCHAR Ptr
= (PUCHAR
)Buffer
;
53 ULONG Address
= SlotNumber
;
56 /* FIXME: Acquire CMOS Lock */
58 /* Do nothing if we don't have a length */
59 if (!Length
) return 0;
61 /* Check if this is simple CMOS */
64 /* Loop the buffer up to 0xFF */
65 while ((Len
> 0) && (Address
< 0x100))
68 *Ptr
= HalpReadCmos((UCHAR
)Address
);
70 /* Update position and length */
76 else if (BusNumber
== 1)
78 /* Loop the buffer up to 0xFFFF */
79 while ((Len
> 0) && (Address
< 0x10000))
82 *Ptr
= HalpReadCmos((UCHAR
)Address
);
84 /* Update position and length */
91 /* FIXME: Release the CMOS Lock */
93 /* Return length read */
99 HalpSetCmosData(IN ULONG BusNumber
,
104 PUCHAR Ptr
= (PUCHAR
)Buffer
;
105 ULONG Address
= SlotNumber
;
108 /* FIXME: Acquire CMOS Lock */
110 /* Do nothing if we don't have a length */
111 if (!Length
) return 0;
113 /* Check if this is simple CMOS */
116 /* Loop the buffer up to 0xFF */
117 while ((Len
> 0) && (Address
< 0x100))
120 HalpWriteCmos((UCHAR
)Address
, *Ptr
);
122 /* Update position and length */
128 else if (BusNumber
== 1)
130 /* Loop the buffer up to 0xFFFF */
131 while ((Len
> 0) && (Address
< 0x10000))
134 HalpWriteCmos((UCHAR
)Address
, *Ptr
);
136 /* Update position and length */
143 /* FIXME: Release the CMOS Lock */
145 /* Return length read */
149 /* PUBLIC FUNCTIONS **********************************************************/
156 HalGetEnvironmentVariable(IN PCH Name
,
157 IN USHORT ValueLength
,
162 /* Only variable supported on x86 */
163 if (_stricmp(Name
, "LastKnownGood")) return ENOENT
;
165 /* FIXME: Acquire CMOS Lock */
167 /* Query the current value */
168 Val
= HalpReadCmos(RTC_REGISTER_B
) & 0x01;
170 /* FIXME: Release CMOS lock */
176 strncpy(Value
, "FALSE", ValueLength
);
181 strncpy(Value
, "TRUE", ValueLength
);
193 HalSetEnvironmentVariable(IN PCH Name
,
198 /* Only variable supported on x86 */
199 if (_stricmp(Name
, "LastKnownGood")) return ENOMEM
;
201 /* Check if this is true or false */
202 if (!_stricmp(Value
, "TRUE"))
204 /* It's true, acquire CMOS lock (FIXME) */
206 /* Read the current value and add the flag */
207 Val
= HalpReadCmos(RTC_REGISTER_B
) | 1;
209 else if (!_stricmp(Value
, "FALSE"))
211 /* It's false, acquire CMOS lock (FIXME) */
213 /* Read the current value and mask out the flag */
214 Val
= HalpReadCmos(RTC_REGISTER_B
) & ~1;
222 /* Write new value */
223 HalpWriteCmos(RTC_REGISTER_B
, Val
);
225 /* Release the lock and return success */
234 HalQueryRealTimeClock(OUT PTIME_FIELDS Time
)
236 /* FIXME: Acquire CMOS Lock */
238 /* Loop while update is in progress */
239 while ((HalpReadCmos(RTC_REGISTER_A
)) & RTC_REG_A_UIP
);
241 /* Set the time data */
242 Time
->Second
= BCD_INT(HalpReadCmos(0));
243 Time
->Minute
= BCD_INT(HalpReadCmos(2));
244 Time
->Hour
= BCD_INT(HalpReadCmos(4));
245 Time
->Weekday
= BCD_INT(HalpReadCmos(6));
246 Time
->Day
= BCD_INT(HalpReadCmos(7));
247 Time
->Month
= BCD_INT(HalpReadCmos(8));
248 Time
->Year
= BCD_INT(HalpReadCmos(9));
249 Time
->Milliseconds
= 0;
251 /* FIXME: Check century byte */
253 /* Compensate for the century field */
254 Time
->Year
+= (Time
->Year
> 80) ? 1900: 2000;
256 /* FIXME: Release CMOS Lock */
258 /* Always return TRUE */
267 HalSetRealTimeClock(IN PTIME_FIELDS Time
)
269 /* FIXME: Acquire CMOS Lock */
271 /* Loop while update is in progress */
272 while ((HalpReadCmos(RTC_REGISTER_A
)) & RTC_REG_A_UIP
);
274 /* Write time fields to CMOS RTC */
275 HalpWriteCmos(0, INT_BCD(Time
->Second
));
276 HalpWriteCmos(2, INT_BCD(Time
->Minute
));
277 HalpWriteCmos(4, INT_BCD(Time
->Hour
));
278 HalpWriteCmos(6, INT_BCD(Time
->Weekday
));
279 HalpWriteCmos(7, INT_BCD(Time
->Day
));
280 HalpWriteCmos(8, INT_BCD(Time
->Month
));
281 HalpWriteCmos(9, INT_BCD(Time
->Year
% 100));
283 /* FIXME: Set the century byte */
285 /* FIXME: Release the CMOS Lock */
287 /* Always return TRUE */