[CMAKE]
[reactos.git] / hal / halx86 / generic / misc.c
1 /*
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
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS *******************************************************************/
16
17 BOOLEAN HalpNMIInProgress;
18
19 UCHAR HalpSerialLen;
20 CHAR HalpSerialNumber[31];
21
22 /* PRIVATE FUNCTIONS **********************************************************/
23
24 #ifndef _MINIHAL_
25 VOID
26 NTAPI
27 HalpReportSerialNumber(VOID)
28 {
29 NTSTATUS Status;
30 UNICODE_STRING KeyString;
31 HANDLE Handle;
32
33 /* Make sure there is a serial number */
34 if (!HalpSerialLen) return;
35
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))
40 {
41 /* Add the serial number */
42 RtlInitUnicodeString(&KeyString, L"Serial Number");
43 ZwSetValueKey(Handle,
44 &KeyString,
45 0,
46 REG_BINARY,
47 HalpSerialNumber,
48 HalpSerialLen);
49
50 /* Close the handle */
51 ZwClose(Handle);
52 }
53 }
54
55 NTSTATUS
56 NTAPI
57 HalpMarkAcpiHal(VOID)
58 {
59 NTSTATUS Status;
60 UNICODE_STRING KeyString;
61 HANDLE KeyHandle;
62 HANDLE Handle;
63
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))
69 {
70 /* Open the PNP key */
71 RtlInitUnicodeString(&KeyString, L"Control\\Pnp");
72 Status = HalpOpenRegistryKey(&KeyHandle,
73 Handle,
74 &KeyString,
75 KEY_ALL_ACCESS,
76 TRUE);
77 /* Close root key */
78 ZwClose(Handle);
79
80 /* Check if PNP BIOS key exists */
81 if (NT_SUCCESS(Status))
82 {
83 /* Set the disable value to false -- we need the mapper */
84 RtlInitUnicodeString(&KeyString, L"DisableFirmwareMapper");
85 Status = ZwSetValueKey(KeyHandle,
86 &KeyString,
87 0,
88 REG_DWORD,
89 &HalDisableFirmwareMapper,
90 sizeof(HalDisableFirmwareMapper));
91
92 /* Close subkey */
93 ZwClose(KeyHandle);
94 }
95 }
96
97 /* Return status */
98 return Status;
99 }
100
101 NTSTATUS
102 NTAPI
103 HalpOpenRegistryKey(IN PHANDLE KeyHandle,
104 IN HANDLE RootKey,
105 IN PUNICODE_STRING KeyName,
106 IN ACCESS_MASK DesiredAccess,
107 IN BOOLEAN Create)
108 {
109 NTSTATUS Status;
110 ULONG Disposition;
111 OBJECT_ATTRIBUTES ObjectAttributes;
112
113 /* Setup the attributes we received */
114 InitializeObjectAttributes(&ObjectAttributes,
115 KeyName,
116 OBJ_CASE_INSENSITIVE,
117 RootKey,
118 NULL);
119
120 /* What to do? */
121 if ( Create )
122 {
123 /* Create the key */
124 Status = ZwCreateKey(KeyHandle,
125 DesiredAccess,
126 &ObjectAttributes,
127 0,
128 NULL,
129 REG_OPTION_VOLATILE,
130 &Disposition);
131 }
132 else
133 {
134 /* Open the key */
135 Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
136 }
137
138 /* We're done */
139 return Status;
140 }
141 #endif
142
143 VOID
144 NTAPI
145 HalpCheckPowerButton(VOID)
146 {
147 //
148 // Nothing to do on non-ACPI
149 //
150 return;
151 }
152
153 VOID
154 NTAPI
155 HalpFlushTLB(VOID)
156 {
157 ULONG Flags, Cr4;
158 INT CpuInfo[4];
159 ULONG_PTR PageDirectory;
160
161 //
162 // Disable interrupts
163 //
164 Flags = __readeflags();
165 _disable();
166
167 //
168 // Get page table directory base
169 //
170 PageDirectory = __readcr3();
171
172 //
173 // Check for CPUID support
174 //
175 if (KeGetCurrentPrcb()->CpuID)
176 {
177 //
178 // Check for global bit in CPU features
179 //
180 __cpuid(CpuInfo, 1);
181 if (CpuInfo[3] & 0x2000)
182 {
183 //
184 // Get current CR4 value
185 //
186 Cr4 = __readcr4();
187
188 //
189 // Disable global bit
190 //
191 __writecr4(Cr4 & ~CR4_PGE);
192
193 //
194 // Flush TLB and re-enable global bit
195 //
196 __writecr3(PageDirectory);
197 __writecr4(Cr4);
198
199 //
200 // Restore interrupts
201 //
202 __writeeflags(Flags);
203 return;
204 }
205 }
206
207 //
208 // Legacy: just flush TLB
209 //
210 __writecr3(PageDirectory);
211 __writeeflags(Flags);
212 }
213
214 /* FUNCTIONS *****************************************************************/
215
216 /*
217 * @implemented
218 */
219 VOID
220 NTAPI
221 HalHandleNMI(IN PVOID NmiInfo)
222 {
223 #ifndef _MINIHAL_
224 SYSTEM_CONTROL_PORT_B_REGISTER SystemControl;
225
226 //
227 // Don't recurse
228 //
229 if (HalpNMIInProgress++) while (TRUE);
230
231 //
232 // Read the system control register B
233 //
234 SystemControl.Bits = __inbyte(SYSTEM_CONTROL_PORT_B);
235
236 //
237 // Switch to boot vieo
238 //
239 if (InbvIsBootDriverInstalled())
240 {
241 //
242 // Acquire ownership
243 //
244 InbvAcquireDisplayOwnership();
245 InbvResetDisplay();
246
247 //
248 // Fill the screen
249 //
250 InbvSolidColorFill(0, 0, 639, 479, 1);
251 InbvSetScrollRegion(0, 0, 639, 479);
252
253 //
254 // Enable text
255 //
256 InbvSetTextColor(15);
257 InbvInstallDisplayStringFilter(NULL);
258 InbvEnableDisplayString(TRUE);
259 }
260
261 //
262 // Display NMI failure string
263 //
264 InbvDisplayString("\n*** Hardware Malfunction\n\n");
265 InbvDisplayString("Call your hardware vendor for support\n\n");
266
267 //
268 // Check for parity error
269 //
270 if (SystemControl.ParityCheck)
271 {
272 //
273 // Display message
274 //
275 InbvDisplayString("NMI: Parity Check / Memory Parity Error\n");
276 }
277
278 //
279 // Check for I/O failure
280 //
281 if (SystemControl.ChannelCheck)
282 {
283 //
284 // Display message
285 //
286 InbvDisplayString("NMI: Channel Check / IOCHK\n");
287 }
288
289 //
290 // Check for EISA systems
291 //
292 if (HalpBusType == MACHINE_TYPE_EISA)
293 {
294 //
295 // FIXME: Not supported
296 //
297 UNIMPLEMENTED;
298 }
299
300 //
301 // Halt the system
302 //
303 InbvDisplayString("\n*** The system has halted ***\n");
304
305
306 //
307 // Enter the debugger if possible
308 //
309 KiBugCheckData[0] = (ULONG_PTR)KeServiceDescriptorTable; /* NMI Corruption? */
310 //if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
311 #endif
312 //
313 // Freeze the system
314 //
315 while (TRUE);
316 }
317
318 /*
319 * @implemented
320 */
321 UCHAR
322 FASTCALL
323 HalSystemVectorDispatchEntry(IN ULONG Vector,
324 OUT PKINTERRUPT_ROUTINE **FlatDispatch,
325 OUT PKINTERRUPT_ROUTINE *NoConnection)
326 {
327 //
328 // Not implemented on x86
329 //
330 return 0;
331 }
332
333 /*
334 * @implemented
335 */
336 VOID
337 NTAPI
338 KeFlushWriteBuffer(VOID)
339 {
340 //
341 // Not implemented on x86
342 //
343 return;
344 }
345
346 #ifdef _M_IX86
347 /* x86 fastcall wrappers */
348
349 #undef KeRaiseIrql
350 /*
351 * @implemented
352 */
353 VOID
354 NTAPI
355 KeRaiseIrql(KIRQL NewIrql,
356 PKIRQL OldIrql)
357 {
358 /* Call the fastcall function */
359 *OldIrql = KfRaiseIrql(NewIrql);
360 }
361
362 #undef KeLowerIrql
363 /*
364 * @implemented
365 */
366 VOID
367 NTAPI
368 KeLowerIrql(KIRQL NewIrql)
369 {
370 /* Call the fastcall function */
371 KfLowerIrql(NewIrql);
372 }
373
374 #undef KeAcquireSpinLock
375 /*
376 * @implemented
377 */
378 VOID
379 NTAPI
380 KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
381 PKIRQL OldIrql)
382 {
383 /* Call the fastcall function */
384 *OldIrql = KfAcquireSpinLock(SpinLock);
385 }
386
387 #undef KeReleaseSpinLock
388 /*
389 * @implemented
390 */
391 VOID
392 NTAPI
393 KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
394 KIRQL NewIrql)
395 {
396 /* Call the fastcall function */
397 KfReleaseSpinLock(SpinLock, NewIrql);
398 }
399
400 #endif
401