[HAL]
[reactos.git] / reactos / hal / halx86 / generic / cmos.c
index 14cd589..71c4e67 100644 (file)
-/*\r
- * PROJECT:         ReactOS HAL\r
- * LICENSE:         GPL - See COPYING in the top level directory\r
- * FILE:            hal/halx86/generic/cmos.c\r
- * PURPOSE:         CMOS Access Routines (Real Time Clock and LastKnownGood)\r
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
- *                  Eric Kohl (ekohl@abo.rhein-zeitung.de)\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <hal.h>\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* GLOBALS *******************************************************************/\r
-\r
-KSPIN_LOCK HalpSystemHardwareLock;\r
-\r
-/* PRIVATE FUNCTIONS *********************************************************/\r
-\r
-UCHAR\r
-FORCEINLINE\r
-HalpReadCmos(IN UCHAR Reg)\r
-{\r
-    /* Select the register */\r
-    WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);\r
-\r
-    /* Query the value */\r
-    return READ_PORT_UCHAR(CMOS_DATA_PORT);\r
-}\r
-\r
-VOID\r
-FORCEINLINE\r
-HalpWriteCmos(IN UCHAR Reg,\r
-              IN UCHAR Value)\r
-{\r
-    /* Select the register */\r
-    WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);\r
-\r
-    /* Write the value */\r
-    WRITE_PORT_UCHAR(CMOS_DATA_PORT, Value);\r
-}\r
-\r
-ULONG\r
-NTAPI\r
-HalpGetCmosData(IN ULONG BusNumber,\r
-                IN ULONG SlotNumber,\r
-                IN PVOID Buffer,\r
-                IN ULONG Length)\r
-{\r
-    PUCHAR Ptr = (PUCHAR)Buffer;\r
-    ULONG Address = SlotNumber;\r
-    ULONG Len = Length;\r
-\r
-    /* FIXME: Acquire CMOS Lock */\r
-\r
-    /* Do nothing if we don't have a length */\r
-    if (!Length) return 0;\r
-\r
-    /* Check if this is simple CMOS */\r
-    if (!BusNumber)\r
-    {\r
-        /* Loop the buffer up to 0xFF */\r
-        while ((Len > 0) && (Address < 0x100))\r
-        {\r
-            /* Read the data */\r
-            *Ptr = HalpReadCmos((UCHAR)Address);\r
-\r
-            /* Update position and length */\r
-            Ptr++;\r
-            Address++;\r
-            Len--;\r
-        }\r
-    }\r
-    else if (BusNumber == 1)\r
-    {\r
-        /* Loop the buffer up to 0xFFFF */\r
-        while ((Len > 0) && (Address < 0x10000))\r
-        {\r
-            /* Write the data */\r
-            *Ptr = HalpReadCmos((UCHAR)Address);\r
-\r
-            /* Update position and length */\r
-            Ptr++;\r
-            Address++;\r
-            Len--;\r
-        }\r
-    }\r
-\r
-    /* FIXME: Release the CMOS Lock */\r
-\r
-    /* Return length read */\r
-    return Length - Len;\r
-}\r
-\r
-ULONG\r
-NTAPI\r
-HalpSetCmosData(IN ULONG BusNumber,\r
-                IN ULONG SlotNumber,\r
-                IN PVOID Buffer,\r
-                IN ULONG Length)\r
-{\r
-    PUCHAR Ptr = (PUCHAR)Buffer;\r
-    ULONG Address = SlotNumber;\r
-    ULONG Len = Length;\r
-\r
-    /* FIXME: Acquire CMOS Lock */\r
-\r
-    /* Do nothing if we don't have a length */\r
-    if (!Length) return 0;\r
-\r
-    /* Check if this is simple CMOS */\r
-    if (!BusNumber)\r
-    {\r
-        /* Loop the buffer up to 0xFF */\r
-        while ((Len > 0) && (Address < 0x100))\r
-        {\r
-            /* Write the data */\r
-            HalpWriteCmos((UCHAR)Address, *Ptr);\r
-\r
-            /* Update position and length */\r
-            Ptr++;\r
-            Address++;\r
-            Len--;\r
-        }\r
-    }\r
-    else if (BusNumber == 1)\r
-    {\r
-        /* Loop the buffer up to 0xFFFF */\r
-        while ((Len > 0) && (Address < 0x10000))\r
-        {\r
-            /* Write the data */\r
-            HalpWriteCmos((UCHAR)Address, *Ptr);\r
-\r
-            /* Update position and length */\r
-            Ptr++;\r
-            Address++;\r
-            Len--;\r
-        }\r
-    }\r
-\r
-    /* FIXME: Release the CMOS Lock */\r
-\r
-    /* Return length read */\r
-    return Length - Len;\r
-}\r
-\r
-/* PUBLIC FUNCTIONS **********************************************************/\r
-\r
-/*\r
- * @implemented\r
- */\r
-ARC_STATUS\r
-NTAPI\r
-HalGetEnvironmentVariable(IN PCH Name,\r
-                          IN USHORT ValueLength,\r
-                          IN PCH Value)\r
-{\r
-    UCHAR Val;\r
-\r
-    /* Only variable supported on x86 */\r
-    if (_stricmp(Name, "LastKnownGood")) return ENOENT;\r
-\r
-    /* FIXME: Acquire CMOS Lock */\r
-\r
-    /* Query the current value */\r
-    Val = HalpReadCmos(RTC_REGISTER_B) & 0x01;\r
-\r
-    /* FIXME: Release CMOS lock */\r
-\r
-    /* Check the flag */\r
-    if (Val)\r
-    {\r
-        /* Return false */\r
-        strncpy(Value, "FALSE", ValueLength);\r
-    }\r
-    else\r
-    {\r
-        /* Return true */\r
-        strncpy(Value, "TRUE", ValueLength);\r
-    }\r
-\r
-    /* Return success */\r
-    return ESUCCESS;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ARC_STATUS\r
-NTAPI\r
-HalSetEnvironmentVariable(IN PCH Name,\r
-                          IN PCH Value)\r
-{\r
-    UCHAR Val;\r
-\r
-    /* Only variable supported on x86 */\r
-    if (_stricmp(Name, "LastKnownGood")) return ENOMEM;\r
-\r
-    /* Check if this is true or false */\r
-    if (!_stricmp(Value, "TRUE"))\r
-    {\r
-        /* It's true, acquire CMOS lock (FIXME) */\r
-\r
-        /* Read the current value and add the flag */\r
-        Val = HalpReadCmos(RTC_REGISTER_B) | 1;\r
-    }\r
-    else if (!_stricmp(Value, "FALSE"))\r
-    {\r
-        /* It's false, acquire CMOS lock (FIXME) */\r
-\r
-        /* Read the current value and mask out  the flag */\r
-        Val = HalpReadCmos(RTC_REGISTER_B) & ~1;\r
-    }\r
-    else\r
-    {\r
-        /* Fail */\r
-        return ENOMEM;\r
-    }\r
-\r
-    /* Write new value */\r
-    HalpWriteCmos(RTC_REGISTER_B, Val);\r
-\r
-    /* Release the lock and return success */\r
-    return ESUCCESS;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOLEAN\r
-NTAPI\r
-HalQueryRealTimeClock(OUT PTIME_FIELDS Time)\r
-{\r
-    /* FIXME: Acquire CMOS Lock */\r
-\r
-    /* Loop while update is in progress */\r
-    while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);\r
-\r
-    /* Set the time data */\r
-    Time->Second = BCD_INT(HalpReadCmos(0));\r
-    Time->Minute = BCD_INT(HalpReadCmos(2));\r
-    Time->Hour = BCD_INT(HalpReadCmos(4));\r
-    Time->Weekday = BCD_INT(HalpReadCmos(6));\r
-    Time->Day = BCD_INT(HalpReadCmos(7));\r
-    Time->Month = BCD_INT(HalpReadCmos(8));\r
-    Time->Year = BCD_INT(HalpReadCmos(9));\r
-    Time->Milliseconds = 0;\r
-\r
-    /* FIXME: Check century byte */\r
-\r
-    /* Compensate for the century field */\r
-    Time->Year += (Time->Year > 80) ? 1900: 2000;\r
-\r
-    /* FIXME: Release CMOS Lock */\r
-\r
-    /* Always return TRUE */\r
-    return TRUE;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOLEAN\r
-NTAPI\r
-HalSetRealTimeClock(IN PTIME_FIELDS Time)\r
-{\r
-    /* FIXME: Acquire CMOS Lock */\r
-\r
-    /* Loop while update is in progress */\r
-    while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);\r
-\r
-    /* Write time fields to CMOS RTC */\r
-    HalpWriteCmos(0, INT_BCD(Time->Second));\r
-    HalpWriteCmos(2, INT_BCD(Time->Minute));\r
-    HalpWriteCmos(4, INT_BCD(Time->Hour));\r
-    HalpWriteCmos(6, INT_BCD(Time->Weekday));\r
-    HalpWriteCmos(7, INT_BCD(Time->Day));\r
-    HalpWriteCmos(8, INT_BCD(Time->Month));\r
-    HalpWriteCmos(9, INT_BCD(Time->Year % 100));\r
-\r
-    /* FIXME: Set the century byte */\r
-\r
-    /* FIXME: Release the CMOS Lock */\r
-\r
-    /* Always return TRUE */\r
-    return TRUE;\r
-}\r
-\r
-/* EOF */\r
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            hal/halx86/generic/cmos.c
+ * PURPOSE:         CMOS Access Routines (Real Time Clock and LastKnownGood)
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ *                  Eric Kohl
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+UCHAR HalpCmosCenturyOffset;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+UCHAR
+NTAPI
+HalpReadCmos(IN UCHAR Reg)
+{
+    /* Select the register */
+    WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
+
+    /* Query the value */
+    return READ_PORT_UCHAR(CMOS_DATA_PORT);
+}
+
+VOID
+NTAPI
+HalpWriteCmos(IN UCHAR Reg,
+              IN UCHAR Value)
+{
+    /* Select the register */
+    WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
+
+    /* Write the value */
+    WRITE_PORT_UCHAR(CMOS_DATA_PORT, Value);
+}
+
+ULONG
+NTAPI
+HalpGetCmosData(IN ULONG BusNumber,
+                IN ULONG SlotNumber,
+                IN PVOID Buffer,
+                IN ULONG Length)
+{
+    PUCHAR Ptr = (PUCHAR)Buffer;
+    ULONG Address = SlotNumber;
+    ULONG Len = Length;
+
+    /* Do nothing if we don't have a length */
+    if (!Length) return 0;
+
+    /* Acquire CMOS Lock */
+    HalpAcquireSystemHardwareSpinLock();
+
+    /* Check if this is simple CMOS */
+    if (BusNumber == 0)
+    {
+        /* Loop the buffer up to 0xFF */
+        while ((Len > 0) && (Address < 0x100))
+        {
+            /* Read the data */
+            *Ptr = HalpReadCmos((UCHAR)Address);
+
+            /* Update position and length */
+            Ptr++;
+            Address++;
+            Len--;
+        }
+    }
+    else if (BusNumber == 1)
+    {
+        /* Loop the buffer up to 0xFFFF */
+        while ((Len > 0) && (Address < 0x10000))
+        {
+            /* Write the data */
+            *Ptr = HalpReadCmos((UCHAR)Address);
+
+            /* Update position and length */
+            Ptr++;
+            Address++;
+            Len--;
+        }
+    }
+
+    /* Release CMOS Lock */
+    HalpReleaseCmosSpinLock();
+
+    /* Return length read */
+    return Length - Len;
+}
+
+ULONG
+NTAPI
+HalpSetCmosData(IN ULONG BusNumber,
+                IN ULONG SlotNumber,
+                IN PVOID Buffer,
+                IN ULONG Length)
+{
+    PUCHAR Ptr = (PUCHAR)Buffer;
+    ULONG Address = SlotNumber;
+    ULONG Len = Length;
+
+    /* Do nothing if we don't have a length */
+    if (!Length) return 0;
+
+    /* Acquire CMOS Lock */
+    HalpAcquireSystemHardwareSpinLock();
+
+    /* Check if this is simple CMOS */
+    if (BusNumber == 0)
+    {
+        /* Loop the buffer up to 0xFF */
+        while ((Len > 0) && (Address < 0x100))
+        {
+            /* Write the data */
+            HalpWriteCmos((UCHAR)Address, *Ptr);
+
+            /* Update position and length */
+            Ptr++;
+            Address++;
+            Len--;
+        }
+    }
+    else if (BusNumber == 1)
+    {
+        /* Loop the buffer up to 0xFFFF */
+        while ((Len > 0) && (Address < 0x10000))
+        {
+            /* Write the data */
+            HalpWriteCmos((UCHAR)Address, *Ptr);
+
+            /* Update position and length */
+            Ptr++;
+            Address++;
+            Len--;
+        }
+    }
+
+    /* Release CMOS Lock */
+    HalpReleaseCmosSpinLock();
+
+    /* Return length read */
+    return Length - Len;
+}
+
+VOID
+NTAPI
+HalpInitializeCmos(VOID)
+{
+    /* Set default century offset byte */
+    HalpCmosCenturyOffset = 50;
+
+    /* No support for EISA or MCA */
+    ASSERT(HalpBusType == MACHINE_TYPE_ISA);
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+ARC_STATUS
+NTAPI
+HalGetEnvironmentVariable(IN PCH Name,
+                          IN USHORT ValueLength,
+                          IN PCH Value)
+{
+    UCHAR Val;
+
+    /* Only variable supported on x86 */
+    if (_stricmp(Name, "LastKnownGood")) return ENOENT;
+
+    /* Acquire CMOS Lock */
+    HalpAcquireSystemHardwareSpinLock();
+
+    /* Query the current value */
+    Val = HalpReadCmos(RTC_REGISTER_B) & 0x01;
+
+    /* Release CMOS lock */
+    HalpReleaseCmosSpinLock();
+
+    /* Check the flag */
+    if (Val)
+    {
+        /* Return false */
+        strncpy(Value, "FALSE", ValueLength);
+    }
+    else
+    {
+        /* Return true */
+        strncpy(Value, "TRUE", ValueLength);
+    }
+
+    /* Return success */
+    return ESUCCESS;
+}
+
+/*
+ * @implemented
+ */
+ARC_STATUS
+NTAPI
+HalSetEnvironmentVariable(IN PCH Name,
+                          IN PCH Value)
+{
+    UCHAR Val;
+
+    /* Only variable supported on x86 */
+    if (_stricmp(Name, "LastKnownGood")) return ENOMEM;
+
+    /* Check if this is true or false */
+    if (!_stricmp(Value, "TRUE"))
+    {
+        /* It's true, acquire CMOS lock */
+        HalpAcquireSystemHardwareSpinLock();
+
+        /* Read the current value and add the flag */
+        Val = HalpReadCmos(RTC_REGISTER_B) | 1;
+    }
+    else if (!_stricmp(Value, "FALSE"))
+    {
+        /* It's false, acquire CMOS lock */
+        HalpAcquireSystemHardwareSpinLock();
+
+        /* Read the current value and mask out  the flag */
+        Val = HalpReadCmos(RTC_REGISTER_B) & ~1;
+    }
+    else
+    {
+        /* Fail */
+        return ENOMEM;
+    }
+
+    /* Write new value */
+    HalpWriteCmos(RTC_REGISTER_B, Val);
+
+    /* Release the lock and return success */
+    HalpReleaseCmosSpinLock();
+    return ESUCCESS;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalQueryRealTimeClock(OUT PTIME_FIELDS Time)
+{
+    /* Acquire CMOS Lock */
+    HalpAcquireSystemHardwareSpinLock();
+
+    /* Loop while update is in progress */
+    while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
+
+    /* Set the time data */
+    Time->Second = BCD_INT(HalpReadCmos(0));
+    Time->Minute = BCD_INT(HalpReadCmos(2));
+    Time->Hour = BCD_INT(HalpReadCmos(4));
+    Time->Weekday = BCD_INT(HalpReadCmos(6));
+    Time->Day = BCD_INT(HalpReadCmos(7));
+    Time->Month = BCD_INT(HalpReadCmos(8));
+    Time->Year = BCD_INT(HalpReadCmos(9));
+    Time->Milliseconds = 0;
+
+    /* FIXME: Check century byte */
+
+    /* Compensate for the century field */
+    Time->Year += (Time->Year > 80) ? 1900: 2000;
+
+    /* Release CMOS lock */
+    HalpReleaseCmosSpinLock();
+
+    /* Always return TRUE */
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalSetRealTimeClock(IN PTIME_FIELDS Time)
+{
+    /* Acquire CMOS Lock */
+    HalpAcquireSystemHardwareSpinLock();
+
+    /* Loop while update is in progress */
+    while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
+
+    /* Write time fields to CMOS RTC */
+    HalpWriteCmos(0, INT_BCD(Time->Second));
+    HalpWriteCmos(2, INT_BCD(Time->Minute));
+    HalpWriteCmos(4, INT_BCD(Time->Hour));
+    HalpWriteCmos(6, INT_BCD(Time->Weekday));
+    HalpWriteCmos(7, INT_BCD(Time->Day));
+    HalpWriteCmos(8, INT_BCD(Time->Month));
+    HalpWriteCmos(9, INT_BCD(Time->Year % 100));
+
+    /* FIXME: Set the century byte */
+
+    /* Release CMOS lock */
+    HalpReleaseCmosSpinLock();
+
+    /* Always return TRUE */
+    return TRUE;
+}