- Finish the work around for the Pentium cmpxchg8b lock errata: We detected the errat...
[reactos.git] / reactos / hal / halx86 / generic / reboot.c
index dbfef68..fe822ac 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * PROJECT:         ReactOS HAL
  * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            ntoskrnl/hal/x86/reboot.c
+ * FILE:            hal/halx86/generic/reboot.c
  * PURPOSE:         Reboot functions
  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
  *                  Eric Kohl (ekohl@abo.rhein-zeitung.de)
@@ -13,6 +13,8 @@
 #define NDEBUG
 #include <debug.h>
 
+#define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000)
+
 /* PRIVATE FUNCTIONS *********************************************************/
 
 VOID
@@ -28,15 +30,27 @@ NTAPI
 HalpReboot(VOID)
 {
     UCHAR Data;
-    extern PVOID HalpZeroPageMapping;
+    PVOID ZeroPageMapping;
+    PHARDWARE_PTE Pte;
 
-    /* Enable warm reboot */
-    ((PUSHORT)HalpZeroPageMapping)[0x472] = 0x1234;
+    /* Get a PTE in the HAL reserved region */
+    ZeroPageMapping = (PVOID)(0xFFC00000 + PAGE_SIZE);
+    Pte = GetPteAddress(ZeroPageMapping);
+
+    /* Make it valid and map it to the first physical page */
+    Pte->Valid = 1;
+    Pte->Write = 1;
+    Pte->Owner = 1;
+    Pte->PageFrameNumber = 0;
 
-    /* FIXME: Lock CMOS Access */
+    /* Flush the TLB by resetting CR3 */
+    __writecr3(__readcr3());
 
-    /* Disable interrupts */
-    _disable();
+    /* Enable warm reboot */
+    ((PUSHORT)ZeroPageMapping)[0x239] = 0x1234;
+
+    /* Lock CMOS Access (and disable interrupts) */
+    HalpAcquireSystemHardwareSpinLock();
 
     /* Setup control register B */
     WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0B);
@@ -44,7 +58,7 @@ HalpReboot(VOID)
 
     /* Read periodic register and clear the interrupt enable */
     Data = READ_PORT_UCHAR((PUCHAR)0x71);
-    WRITE_PORT_UCHAR((PUCHAR)0x71, Data & 0xBF);
+    WRITE_PORT_UCHAR((PUCHAR)0x71, Data & ~0x40);
     KeStallExecutionProcessor(1);
 
     /* Setup control register A */
@@ -53,7 +67,7 @@ HalpReboot(VOID)
 
     /* Read divider rate and reset it */
     Data = READ_PORT_UCHAR((PUCHAR)0x71);
-    WRITE_PORT_UCHAR((PUCHAR)0x71, (Data & 0xF0) | 0x06);
+    WRITE_PORT_UCHAR((PUCHAR)0x71, (Data & ~0x9) | 0x06);
     KeStallExecutionProcessor(1);
 
     /* Reset neutral CMOS address */
@@ -65,7 +79,7 @@ HalpReboot(VOID)
     HalpWriteResetCommand();
 
     /* Halt the CPU */
-    Ke386HaltProcessor();
+    __halt();
 }
 
 /* PUBLIC FUNCTIONS **********************************************************/
@@ -77,13 +91,16 @@ VOID
 NTAPI
 HalReturnToFirmware(IN FIRMWARE_REENTRY Action)
 {
-    /* Check the kind of action this is */
+    /* Check what kind of action this is */
     switch (Action)
     {
         /* All recognized actions */
         case HalHaltRoutine:
         case HalRebootRoutine:
 
+            /* Acquire the display */
+            InbvAcquireDisplayOwnership();
+
             /* Call the internal reboot function */
             HalpReboot();