Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmos.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS HAL 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: hal/halx86/generic/cmos.c 00005 * PURPOSE: CMOS Access Routines (Real Time Clock and LastKnownGood) 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 * Eric Kohl 00008 */ 00009 00010 /* INCLUDES ******************************************************************/ 00011 00012 #include <hal.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* GLOBALS *******************************************************************/ 00017 00018 UCHAR HalpCmosCenturyOffset; 00019 00020 /* PRIVATE FUNCTIONS *********************************************************/ 00021 00022 UCHAR 00023 NTAPI 00024 HalpReadCmos(IN UCHAR Reg) 00025 { 00026 /* Select the register */ 00027 WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg); 00028 00029 /* Query the value */ 00030 return READ_PORT_UCHAR(CMOS_DATA_PORT); 00031 } 00032 00033 VOID 00034 NTAPI 00035 HalpWriteCmos(IN UCHAR Reg, 00036 IN UCHAR Value) 00037 { 00038 /* Select the register */ 00039 WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg); 00040 00041 /* Write the value */ 00042 WRITE_PORT_UCHAR(CMOS_DATA_PORT, Value); 00043 } 00044 00045 ULONG 00046 NTAPI 00047 HalpGetCmosData(IN ULONG BusNumber, 00048 IN ULONG SlotNumber, 00049 IN PVOID Buffer, 00050 IN ULONG Length) 00051 { 00052 PUCHAR Ptr = (PUCHAR)Buffer; 00053 ULONG Address = SlotNumber; 00054 ULONG Len = Length; 00055 00056 /* Do nothing if we don't have a length */ 00057 if (!Length) return 0; 00058 00059 /* Acquire CMOS Lock */ 00060 HalpAcquireCmosSpinLock(); 00061 00062 /* Check if this is simple CMOS */ 00063 if (BusNumber == 0) 00064 { 00065 /* Loop the buffer up to 0xFF */ 00066 while ((Len > 0) && (Address < 0x100)) 00067 { 00068 /* Read the data */ 00069 *Ptr = HalpReadCmos((UCHAR)Address); 00070 00071 /* Update position and length */ 00072 Ptr++; 00073 Address++; 00074 Len--; 00075 } 00076 } 00077 else if (BusNumber == 1) 00078 { 00079 /* Loop the buffer up to 0xFFFF */ 00080 while ((Len > 0) && (Address < 0x10000)) 00081 { 00082 /* Write the data */ 00083 *Ptr = HalpReadCmos((UCHAR)Address); 00084 00085 /* Update position and length */ 00086 Ptr++; 00087 Address++; 00088 Len--; 00089 } 00090 } 00091 00092 /* Release CMOS Lock */ 00093 HalpReleaseCmosSpinLock(); 00094 00095 /* Return length read */ 00096 return Length - Len; 00097 } 00098 00099 ULONG 00100 NTAPI 00101 HalpSetCmosData(IN ULONG BusNumber, 00102 IN ULONG SlotNumber, 00103 IN PVOID Buffer, 00104 IN ULONG Length) 00105 { 00106 PUCHAR Ptr = (PUCHAR)Buffer; 00107 ULONG Address = SlotNumber; 00108 ULONG Len = Length; 00109 00110 /* Do nothing if we don't have a length */ 00111 if (!Length) return 0; 00112 00113 /* Acquire CMOS Lock */ 00114 HalpAcquireCmosSpinLock(); 00115 00116 /* Check if this is simple CMOS */ 00117 if (BusNumber == 0) 00118 { 00119 /* Loop the buffer up to 0xFF */ 00120 while ((Len > 0) && (Address < 0x100)) 00121 { 00122 /* Write the data */ 00123 HalpWriteCmos((UCHAR)Address, *Ptr); 00124 00125 /* Update position and length */ 00126 Ptr++; 00127 Address++; 00128 Len--; 00129 } 00130 } 00131 else if (BusNumber == 1) 00132 { 00133 /* Loop the buffer up to 0xFFFF */ 00134 while ((Len > 0) && (Address < 0x10000)) 00135 { 00136 /* Write the data */ 00137 HalpWriteCmos((UCHAR)Address, *Ptr); 00138 00139 /* Update position and length */ 00140 Ptr++; 00141 Address++; 00142 Len--; 00143 } 00144 } 00145 00146 /* Release CMOS Lock */ 00147 HalpReleaseCmosSpinLock(); 00148 00149 /* Return length read */ 00150 return Length - Len; 00151 } 00152 00153 VOID 00154 NTAPI 00155 INIT_FUNCTION 00156 HalpInitializeCmos(VOID) 00157 { 00158 /* Set default century offset byte */ 00159 HalpCmosCenturyOffset = 50; 00160 00161 /* No support for EISA or MCA */ 00162 ASSERT(HalpBusType == MACHINE_TYPE_ISA); 00163 } 00164 00165 /* PUBLIC FUNCTIONS **********************************************************/ 00166 00167 /* 00168 * @implemented 00169 */ 00170 ARC_STATUS 00171 NTAPI 00172 HalGetEnvironmentVariable(IN PCH Name, 00173 IN USHORT ValueLength, 00174 IN PCH Value) 00175 { 00176 UCHAR Val; 00177 00178 /* Only variable supported on x86 */ 00179 if (_stricmp(Name, "LastKnownGood")) return ENOENT; 00180 00181 /* Acquire CMOS Lock */ 00182 HalpAcquireCmosSpinLock(); 00183 00184 /* Query the current value */ 00185 Val = HalpReadCmos(RTC_REGISTER_B) & 0x01; 00186 00187 /* Release CMOS lock */ 00188 HalpReleaseCmosSpinLock(); 00189 00190 /* Check the flag */ 00191 if (Val) 00192 { 00193 /* Return false */ 00194 strncpy(Value, "FALSE", ValueLength); 00195 } 00196 else 00197 { 00198 /* Return true */ 00199 strncpy(Value, "TRUE", ValueLength); 00200 } 00201 00202 /* Return success */ 00203 return ESUCCESS; 00204 } 00205 00206 /* 00207 * @implemented 00208 */ 00209 ARC_STATUS 00210 NTAPI 00211 HalSetEnvironmentVariable(IN PCH Name, 00212 IN PCH Value) 00213 { 00214 UCHAR Val; 00215 00216 /* Only variable supported on x86 */ 00217 if (_stricmp(Name, "LastKnownGood")) return ENOMEM; 00218 00219 /* Check if this is true or false */ 00220 if (!_stricmp(Value, "TRUE")) 00221 { 00222 /* It's true, acquire CMOS lock */ 00223 HalpAcquireCmosSpinLock(); 00224 00225 /* Read the current value and add the flag */ 00226 Val = HalpReadCmos(RTC_REGISTER_B) | 1; 00227 } 00228 else if (!_stricmp(Value, "FALSE")) 00229 { 00230 /* It's false, acquire CMOS lock */ 00231 HalpAcquireCmosSpinLock(); 00232 00233 /* Read the current value and mask out the flag */ 00234 Val = HalpReadCmos(RTC_REGISTER_B) & ~1; 00235 } 00236 else 00237 { 00238 /* Fail */ 00239 return ENOMEM; 00240 } 00241 00242 /* Write new value */ 00243 HalpWriteCmos(RTC_REGISTER_B, Val); 00244 00245 /* Release the lock and return success */ 00246 HalpReleaseCmosSpinLock(); 00247 return ESUCCESS; 00248 } 00249 00250 /* 00251 * @implemented 00252 */ 00253 BOOLEAN 00254 NTAPI 00255 HalQueryRealTimeClock(OUT PTIME_FIELDS Time) 00256 { 00257 /* Acquire CMOS Lock */ 00258 HalpAcquireCmosSpinLock(); 00259 00260 /* Loop while update is in progress */ 00261 while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP); 00262 00263 /* Set the time data */ 00264 Time->Second = BCD_INT(HalpReadCmos(0)); 00265 Time->Minute = BCD_INT(HalpReadCmos(2)); 00266 Time->Hour = BCD_INT(HalpReadCmos(4)); 00267 Time->Weekday = BCD_INT(HalpReadCmos(6)); 00268 Time->Day = BCD_INT(HalpReadCmos(7)); 00269 Time->Month = BCD_INT(HalpReadCmos(8)); 00270 Time->Year = BCD_INT(HalpReadCmos(9)); 00271 Time->Milliseconds = 0; 00272 00273 /* FIXME: Check century byte */ 00274 00275 /* Compensate for the century field */ 00276 Time->Year += (Time->Year > 80) ? 1900: 2000; 00277 00278 /* Release CMOS lock */ 00279 HalpReleaseCmosSpinLock(); 00280 00281 /* Always return TRUE */ 00282 return TRUE; 00283 } 00284 00285 /* 00286 * @implemented 00287 */ 00288 BOOLEAN 00289 NTAPI 00290 HalSetRealTimeClock(IN PTIME_FIELDS Time) 00291 { 00292 /* Acquire CMOS Lock */ 00293 HalpAcquireCmosSpinLock(); 00294 00295 /* Loop while update is in progress */ 00296 while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP); 00297 00298 /* Write time fields to CMOS RTC */ 00299 HalpWriteCmos(0, INT_BCD(Time->Second)); 00300 HalpWriteCmos(2, INT_BCD(Time->Minute)); 00301 HalpWriteCmos(4, INT_BCD(Time->Hour)); 00302 HalpWriteCmos(6, INT_BCD(Time->Weekday)); 00303 HalpWriteCmos(7, INT_BCD(Time->Day)); 00304 HalpWriteCmos(8, INT_BCD(Time->Month)); 00305 HalpWriteCmos(9, INT_BCD(Time->Year % 100)); 00306 00307 /* FIXME: Set the century byte */ 00308 00309 /* Release CMOS lock */ 00310 HalpReleaseCmosSpinLock(); 00311 00312 /* Always return TRUE */ 00313 return TRUE; 00314 } Generated on Sun May 27 2012 04:28:41 for ReactOS by
1.7.6.1
|