[CMAKE]
[reactos.git] / hal / halx86 / generic / misc.c
index d8710c8..2ddd185 100644 (file)
 /*
- * PROJECT:         ReactOS HAL
- * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            hal/halx86/generic/misc.c
- * PURPOSE:         Miscellanous Routines
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
- *                  Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * PROJECT:         ReactOS Hardware Abstraction Layer (HAL)
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            halx86/generic/misc.c
+ * PURPOSE:         NMI, I/O Mapping and x86 Subs
+ * PROGRAMMERS:     ReactOS Portable Systems Group
  */
 
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <hal.h>
 #define NDEBUG
 #include <debug.h>
 
-/* PRIVATE FUNCTIONS *********************************************************/
+/* GLOBALS  *******************************************************************/
 
+BOOLEAN HalpNMIInProgress;
+
+UCHAR HalpSerialLen;
+CHAR HalpSerialNumber[31];
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+#ifndef _MINIHAL_
 VOID
 NTAPI
-HalpCheckPowerButton(VOID)
+INIT_FUNCTION
+HalpReportSerialNumber(VOID)
 {
-    /* Nothing to do on non-ACPI */
-    return;
+    NTSTATUS Status;
+    UNICODE_STRING KeyString;
+    HANDLE Handle;
+
+    /* Make sure there is a serial number */
+    if (!HalpSerialLen) return;
+
+    /* Open the system key */
+    RtlInitUnicodeString(&KeyString, L"\\Registry\\Machine\\Hardware\\Description\\System");
+    Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
+    if (NT_SUCCESS(Status))
+    {
+        /* Add the serial number */
+        RtlInitUnicodeString(&KeyString, L"Serial Number");
+        ZwSetValueKey(Handle,
+                      &KeyString,
+                      0,
+                      REG_BINARY,
+                      HalpSerialNumber,
+                      HalpSerialLen);
+                      
+        /* Close the handle */
+        ZwClose(Handle);
+    }
 }
 
-PVOID
+NTSTATUS
 NTAPI
-HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
-                        IN ULONG NumberPage)
+INIT_FUNCTION
+HalpMarkAcpiHal(VOID)
 {
-    /* Use kernel memory manager I/O map facilities */
-    return MmMapIoSpace(PhysicalAddress,
-                        NumberPage << PAGE_SHIFT,
-                        MmNonCached);
+    NTSTATUS Status;
+    UNICODE_STRING KeyString;
+    HANDLE KeyHandle;
+    HANDLE Handle;
+    
+    /* Open the control set key */
+    RtlInitUnicodeString(&KeyString,
+                         L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
+    Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
+    if (NT_SUCCESS(Status))
+    {
+        /* Open the PNP key */
+        RtlInitUnicodeString(&KeyString, L"Control\\Pnp");
+        Status = HalpOpenRegistryKey(&KeyHandle,
+                                     Handle,
+                                     &KeyString,
+                                     KEY_ALL_ACCESS,
+                                     TRUE);
+        /* Close root key */
+        ZwClose(Handle);
+        
+        /* Check if PNP BIOS key exists */
+        if (NT_SUCCESS(Status))
+        {
+            /* Set the disable value to false -- we need the mapper */
+            RtlInitUnicodeString(&KeyString, L"DisableFirmwareMapper");
+            Status = ZwSetValueKey(KeyHandle,
+                                   &KeyString,
+                                   0,
+                                   REG_DWORD,
+                                   &HalDisableFirmwareMapper,
+                                   sizeof(HalDisableFirmwareMapper));
+            
+            /* Close subkey */
+            ZwClose(KeyHandle);
+        }
+    }
+    
+    /* Return status */
+    return Status;
 }
 
+NTSTATUS 
+NTAPI
+HalpOpenRegistryKey(IN PHANDLE KeyHandle,
+                    IN HANDLE RootKey,
+                    IN PUNICODE_STRING KeyName,
+                    IN ACCESS_MASK DesiredAccess, 
+                    IN BOOLEAN Create)
+{
+    NTSTATUS Status;
+    ULONG Disposition;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    
+    /* Setup the attributes we received */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               RootKey,
+                               NULL);
+
+    /* What to do? */
+    if ( Create )
+    {
+        /* Create the key */
+        Status = ZwCreateKey(KeyHandle,
+                             DesiredAccess,
+                             &ObjectAttributes,
+                             0,
+                             NULL,
+                             REG_OPTION_VOLATILE,
+                             &Disposition);
+    }
+    else
+    {
+        /* Open the key */
+        Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
+    }
+        
+    /* We're done */
+    return Status;
+}
+#endif
+
 VOID
 NTAPI
-HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
-                        IN ULONG NumberPages)
+HalpCheckPowerButton(VOID)
 {
-    /* Use kernel memory manager I/O map facilities */
-    MmUnmapIoSpace(VirtualAddress, NumberPages << PAGE_SHIFT);
+    //
+    // Nothing to do on non-ACPI
+    //
+    return;
+}
+
+VOID
+NTAPI
+HalpFlushTLB(VOID)
+{
+    ULONG Flags, Cr4;
+    INT CpuInfo[4];
+    ULONG_PTR PageDirectory;
+
+    //
+    // Disable interrupts
+    //
+    Flags = __readeflags();
+    _disable();
+
+    //
+    // Get page table directory base
+    //
+    PageDirectory = __readcr3();
+
+    //
+    // Check for CPUID support
+    //
+    if (KeGetCurrentPrcb()->CpuID)
+    {
+        //
+        // Check for global bit in CPU features
+        //
+        __cpuid(CpuInfo, 1);
+        if (CpuInfo[3] & 0x2000)
+        {
+            //
+            // Get current CR4 value
+            //
+            Cr4 = __readcr4();
+
+            //
+            // Disable global bit
+            //
+            __writecr4(Cr4 & ~CR4_PGE);
+
+            //
+            // Flush TLB and re-enable global bit
+            //
+            __writecr3(PageDirectory);
+            __writecr4(Cr4);
+
+            //
+            // Restore interrupts
+            //
+            __writeeflags(Flags);
+            return;
+        }
+    }
+
+    //
+    // Legacy: just flush TLB
+    //
+    __writecr3(PageDirectory);
+    __writeeflags(Flags);
 }
 
 /* FUNCTIONS *****************************************************************/
@@ -52,32 +222,99 @@ VOID
 NTAPI
 HalHandleNMI(IN PVOID NmiInfo)
 {
-    UCHAR ucStatus;
+#ifndef _MINIHAL_
+    SYSTEM_CONTROL_PORT_B_REGISTER SystemControl;
+
+    //
+    // Don't recurse
+    //
+    if (HalpNMIInProgress++) while (TRUE);
+
+    //
+    // Read the system control register B
+    //
+    SystemControl.Bits = __inbyte(SYSTEM_CONTROL_PORT_B);
+
+    //
+    // Switch to boot vieo
+    //
+    if (InbvIsBootDriverInstalled())
+    {
+        //
+        // Acquire ownership
+        //
+        InbvAcquireDisplayOwnership();
+        InbvResetDisplay();
+
+        //
+        // Fill the screen
+        //
+        InbvSolidColorFill(0, 0, 639, 479, 1);       
+        InbvSetScrollRegion(0, 0, 639, 479);
 
-    /* Get the NMI Flag */
-    ucStatus = READ_PORT_UCHAR((PUCHAR)0x61);
+        //
+        // Enable text
+        //
+        InbvSetTextColor(15);
+        InbvInstallDisplayStringFilter(NULL);
+        InbvEnableDisplayString(TRUE);
+    }
+
+    //
+    // Display NMI failure string
+    //
+    InbvDisplayString("\n*** Hardware Malfunction\n\n");
+    InbvDisplayString("Call your hardware vendor for support\n\n");
 
-    /* Display NMI failure string */
-    HalDisplayString ("\n*** Hardware Malfunction\n\n");
-    HalDisplayString ("Call your hardware vendor for support\n\n");
+    //
+    // Check for parity error
+    //
+    if (SystemControl.ParityCheck)
+    {
+        //
+        // Display message
+        //
+        InbvDisplayString("NMI: Parity Check / Memory Parity Error\n");
+    }
 
-    /* Check for parity error */
-    if (ucStatus & 0x80)
+    //
+    // Check for I/O failure
+    //
+    if (SystemControl.ChannelCheck)
     {
-        /* Display message */
-        HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
+        //
+        // Display message
+        //
+        InbvDisplayString("NMI: Channel Check / IOCHK\n");
     }
 
-    /* Check for I/O failure */
-    if (ucStatus & 0x40)
+    //
+    // Check for EISA systems
+    //
+    if (HalpBusType == MACHINE_TYPE_EISA)
     {
-        /* Display message */
-        HalDisplayString ("NMI: Channel Check / IOCHK\n");
+        //
+        // FIXME: Not supported
+        //
+        UNIMPLEMENTED;
     }
 
-    /* Halt the system */
-    HalDisplayString("\n*** The system has halted ***\n");
-    //KeEnterKernelDebugger();
+    //
+    // Halt the system
+    //
+    InbvDisplayString("\n*** The system has halted ***\n");
+
+
+    //
+    // Enter the debugger if possible
+    //
+    KiBugCheckData[0] = (ULONG_PTR)KeServiceDescriptorTable; /* NMI Corruption? */
+    //if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
+#endif
+    //
+    // Freeze the system
+    //
+    while (TRUE);
 }
 
 /*
@@ -89,7 +326,9 @@ HalSystemVectorDispatchEntry(IN ULONG Vector,
                              OUT PKINTERRUPT_ROUTINE **FlatDispatch,
                              OUT PKINTERRUPT_ROUTINE *NoConnection)
 {
-    /* Not implemented on x86 */
+    //
+    // Not implemented on x86
+    //
     return 0;
 }
 
@@ -100,6 +339,65 @@ VOID
 NTAPI
 KeFlushWriteBuffer(VOID)
 {
-    /* Not implemented on x86 */
+    //
+    // Not implemented on x86
+    //
     return;
 }
+
+#ifdef _M_IX86
+/* x86 fastcall wrappers */
+
+#undef KeRaiseIrql
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeRaiseIrql(KIRQL NewIrql,
+            PKIRQL OldIrql)
+{
+    /* Call the fastcall function */
+    *OldIrql = KfRaiseIrql(NewIrql);
+}
+
+#undef KeLowerIrql
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeLowerIrql(KIRQL NewIrql)
+{
+    /* Call the fastcall function */
+    KfLowerIrql(NewIrql);
+}
+
+#undef KeAcquireSpinLock
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
+                  PKIRQL OldIrql)
+{
+    /* Call the fastcall function */
+    *OldIrql = KfAcquireSpinLock(SpinLock);
+}
+
+#undef KeReleaseSpinLock
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
+                  KIRQL NewIrql)
+{
+    /* Call the fastcall function */
+    KfReleaseSpinLock(SpinLock, NewIrql);
+}
+
+#endif
+