2 * PROJECT: ReactOS Hardware Abstraction Layer (HAL)
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: halx86/generic/misc.c
5 * PURPOSE: NMI, I/O Mapping and x86 Subs
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS *******************************************************************/
17 BOOLEAN HalpNMIInProgress
;
20 CHAR HalpSerialNumber
[31];
22 /* PRIVATE FUNCTIONS **********************************************************/
27 HalpReportSerialNumber(VOID
)
30 UNICODE_STRING KeyString
;
33 /* Make sure there is a serial number */
34 if (!HalpSerialLen
) return;
36 /* Open the system key */
37 RtlInitUnicodeString(&KeyString
, L
"\\Registry\\Machine\\Hardware\\Description\\System");
38 Status
= HalpOpenRegistryKey(&Handle
, 0, &KeyString
, KEY_ALL_ACCESS
, FALSE
);
39 if (NT_SUCCESS(Status
))
41 /* Add the serial number */
42 RtlInitUnicodeString(&KeyString
, L
"Serial Number");
50 /* Close the handle */
60 UNICODE_STRING KeyString
;
64 /* Open the control set key */
65 RtlInitUnicodeString(&KeyString
,
66 L
"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
67 Status
= HalpOpenRegistryKey(&Handle
, 0, &KeyString
, KEY_ALL_ACCESS
, FALSE
);
68 if (NT_SUCCESS(Status
))
70 /* Open the PNP key */
71 RtlInitUnicodeString(&KeyString
, L
"Control\\Pnp");
72 Status
= HalpOpenRegistryKey(&KeyHandle
,
80 /* Check if PNP BIOS key exists */
81 if (NT_SUCCESS(Status
))
83 /* Set the disable value to false -- we need the mapper */
84 RtlInitUnicodeString(&KeyString
, L
"DisableFirmwareMapper");
85 Status
= ZwSetValueKey(KeyHandle
,
89 &HalDisableFirmwareMapper
,
90 sizeof(HalDisableFirmwareMapper
));
103 HalpOpenRegistryKey(IN PHANDLE KeyHandle
,
105 IN PUNICODE_STRING KeyName
,
106 IN ACCESS_MASK DesiredAccess
,
111 OBJECT_ATTRIBUTES ObjectAttributes
;
113 /* Setup the attributes we received */
114 InitializeObjectAttributes(&ObjectAttributes
,
116 OBJ_CASE_INSENSITIVE
,
124 Status
= ZwCreateKey(KeyHandle
,
135 Status
= ZwOpenKey(KeyHandle
, DesiredAccess
, &ObjectAttributes
);
145 HalpCheckPowerButton(VOID
)
148 // Nothing to do on non-ACPI
159 ULONG_PTR PageDirectory
;
162 // Disable interrupts
164 Flags
= __readeflags();
168 // Get page table directory base
170 PageDirectory
= __readcr3();
173 // Check for CPUID support
175 if (KeGetCurrentPrcb()->CpuID
)
178 // Check for global bit in CPU features
181 if (CpuInfo
[3] & 0x2000)
184 // Get current CR4 value
189 // Disable global bit
191 __writecr4(Cr4
& ~CR4_PGE
);
194 // Flush TLB and re-enable global bit
196 __writecr3(PageDirectory
);
200 // Restore interrupts
202 __writeeflags(Flags
);
208 // Legacy: just flush TLB
210 __writecr3(PageDirectory
);
211 __writeeflags(Flags
);
214 /* FUNCTIONS *****************************************************************/
221 HalHandleNMI(IN PVOID NmiInfo
)
224 SYSTEM_CONTROL_PORT_B_REGISTER SystemControl
;
229 if (HalpNMIInProgress
++) while (TRUE
);
232 // Read the system control register B
234 SystemControl
.Bits
= __inbyte(SYSTEM_CONTROL_PORT_B
);
237 // Switch to boot vieo
239 if (InbvIsBootDriverInstalled())
244 InbvAcquireDisplayOwnership();
250 InbvSolidColorFill(0, 0, 639, 479, 1);
251 InbvSetScrollRegion(0, 0, 639, 479);
256 InbvSetTextColor(15);
257 InbvInstallDisplayStringFilter(NULL
);
258 InbvEnableDisplayString(TRUE
);
262 // Display NMI failure string
264 InbvDisplayString("\n*** Hardware Malfunction\n\n");
265 InbvDisplayString("Call your hardware vendor for support\n\n");
268 // Check for parity error
270 if (SystemControl
.ParityCheck
)
275 InbvDisplayString("NMI: Parity Check / Memory Parity Error\n");
279 // Check for I/O failure
281 if (SystemControl
.ChannelCheck
)
286 InbvDisplayString("NMI: Channel Check / IOCHK\n");
290 // Check for EISA systems
292 if (HalpBusType
== MACHINE_TYPE_EISA
)
295 // FIXME: Not supported
303 InbvDisplayString("\n*** The system has halted ***\n");
307 // Enter the debugger if possible
309 KiBugCheckData
[0] = (ULONG_PTR
)KeServiceDescriptorTable
; /* NMI Corruption? */
310 //if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
323 HalSystemVectorDispatchEntry(IN ULONG Vector
,
324 OUT PKINTERRUPT_ROUTINE
**FlatDispatch
,
325 OUT PKINTERRUPT_ROUTINE
*NoConnection
)
328 // Not implemented on x86
338 KeFlushWriteBuffer(VOID
)
341 // Not implemented on x86
347 /* x86 fastcall wrappers */
355 KeRaiseIrql(KIRQL NewIrql
,
358 /* Call the fastcall function */
359 *OldIrql
= KfRaiseIrql(NewIrql
);
368 KeLowerIrql(KIRQL NewIrql
)
370 /* Call the fastcall function */
371 KfLowerIrql(NewIrql
);
374 #undef KeAcquireSpinLock
380 KeAcquireSpinLock(PKSPIN_LOCK SpinLock
,
383 /* Call the fastcall function */
384 *OldIrql
= KfAcquireSpinLock(SpinLock
);
387 #undef KeReleaseSpinLock
393 KeReleaseSpinLock(PKSPIN_LOCK SpinLock
,
396 /* Call the fastcall function */
397 KfReleaseSpinLock(SpinLock
, NewIrql
);