ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cmos.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.