[HAL]
[reactos.git] / reactos / 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 /* PRIVATE FUNCTIONS **********************************************************/
20
21 #ifndef _MINIHAL_
22 NTSTATUS
23 NTAPI
24 HalpOpenRegistryKey(IN PHANDLE KeyHandle,
25 IN HANDLE RootKey,
26 IN PUNICODE_STRING KeyName,
27 IN ACCESS_MASK DesiredAccess,
28 IN BOOLEAN Create)
29 {
30 NTSTATUS Status;
31 ULONG Disposition;
32 OBJECT_ATTRIBUTES ObjectAttributes;
33
34 /* Setup the attributes we received */
35 InitializeObjectAttributes(&ObjectAttributes,
36 KeyName,
37 OBJ_CASE_INSENSITIVE,
38 RootKey,
39 NULL);
40
41 /* What to do? */
42 if ( Create )
43 {
44 /* Create the key */
45 Status = ZwCreateKey(KeyHandle,
46 DesiredAccess,
47 &ObjectAttributes,
48 0,
49 NULL,
50 REG_OPTION_VOLATILE,
51 &Disposition);
52 }
53 else
54 {
55 /* Open the key */
56 Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
57 }
58
59 /* We're done */
60 return Status;
61 }
62 #endif
63
64 VOID
65 NTAPI
66 HalpCheckPowerButton(VOID)
67 {
68 //
69 // Nothing to do on non-ACPI
70 //
71 return;
72 }
73
74 VOID
75 NTAPI
76 HalpFlushTLB(VOID)
77 {
78 ULONG Flags, Cr4;
79 INT CpuInfo[4];
80 ULONG_PTR PageDirectory;
81
82 //
83 // Disable interrupts
84 //
85 Flags = __readeflags();
86 _disable();
87
88 //
89 // Get page table directory base
90 //
91 PageDirectory = __readcr3();
92
93 //
94 // Check for CPUID support
95 //
96 if (KeGetCurrentPrcb()->CpuID)
97 {
98 //
99 // Check for global bit in CPU features
100 //
101 __cpuid(CpuInfo, 1);
102 if (CpuInfo[3] & 0x2000)
103 {
104 //
105 // Get current CR4 value
106 //
107 Cr4 = __readcr4();
108
109 //
110 // Disable global bit
111 //
112 __writecr4(Cr4 & ~CR4_PGE);
113
114 //
115 // Flush TLB and re-enable global bit
116 //
117 __writecr3(PageDirectory);
118 __writecr4(Cr4);
119
120 //
121 // Restore interrupts
122 //
123 __writeeflags(Flags);
124 return;
125 }
126 }
127
128 //
129 // Legacy: just flush TLB
130 //
131 __writecr3(PageDirectory);
132 __writeeflags(Flags);
133 }
134
135 /* FUNCTIONS *****************************************************************/
136
137 /*
138 * @implemented
139 */
140 VOID
141 NTAPI
142 HalHandleNMI(IN PVOID NmiInfo)
143 {
144 #ifndef _MINIHAL_
145 SYSTEM_CONTROL_PORT_B_REGISTER SystemControl;
146
147 //
148 // Don't recurse
149 //
150 if (HalpNMIInProgress++) while (TRUE);
151
152 //
153 // Read the system control register B
154 //
155 SystemControl.Bits = __inbyte(SYSTEM_CONTROL_PORT_B);
156
157 //
158 // Switch to boot vieo
159 //
160 if (InbvIsBootDriverInstalled())
161 {
162 //
163 // Acquire ownership
164 //
165 InbvAcquireDisplayOwnership();
166 InbvResetDisplay();
167
168 //
169 // Fill the screen
170 //
171 InbvSolidColorFill(0, 0, 639, 479, 1);
172 InbvSetScrollRegion(0, 0, 639, 479);
173
174 //
175 // Enable text
176 //
177 InbvSetTextColor(15);
178 InbvInstallDisplayStringFilter(NULL);
179 InbvEnableDisplayString(TRUE);
180 }
181
182 //
183 // Display NMI failure string
184 //
185 InbvDisplayString("\n*** Hardware Malfunction\n\n");
186 InbvDisplayString("Call your hardware vendor for support\n\n");
187
188 //
189 // Check for parity error
190 //
191 if (SystemControl.ParityCheck)
192 {
193 //
194 // Display message
195 //
196 InbvDisplayString("NMI: Parity Check / Memory Parity Error\n");
197 }
198
199 //
200 // Check for I/O failure
201 //
202 if (SystemControl.ChannelCheck)
203 {
204 //
205 // Display message
206 //
207 InbvDisplayString("NMI: Channel Check / IOCHK\n");
208 }
209
210 //
211 // Check for EISA systems
212 //
213 if (HalpBusType == MACHINE_TYPE_EISA)
214 {
215 //
216 // FIXME: Not supported
217 //
218 UNIMPLEMENTED;
219 }
220
221 //
222 // Halt the system
223 //
224 InbvDisplayString("\n*** The system has halted ***\n");
225 #endif
226
227 //
228 // Enter the debugger if possible
229 //
230 //if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
231
232 //
233 // Freeze the system
234 //
235 while (TRUE);
236 }
237
238 /*
239 * @implemented
240 */
241 UCHAR
242 FASTCALL
243 HalSystemVectorDispatchEntry(IN ULONG Vector,
244 OUT PKINTERRUPT_ROUTINE **FlatDispatch,
245 OUT PKINTERRUPT_ROUTINE *NoConnection)
246 {
247 //
248 // Not implemented on x86
249 //
250 return 0;
251 }
252
253 /*
254 * @implemented
255 */
256 VOID
257 NTAPI
258 KeFlushWriteBuffer(VOID)
259 {
260 //
261 // Not implemented on x86
262 //
263 return;
264 }
265
266 #ifdef _M_IX86
267 /* x86 fastcall wrappers */
268
269 #undef KeRaiseIrql
270 /*
271 * @implemented
272 */
273 VOID
274 NTAPI
275 KeRaiseIrql(KIRQL NewIrql,
276 PKIRQL OldIrql)
277 {
278 /* Call the fastcall function */
279 *OldIrql = KfRaiseIrql(NewIrql);
280 }
281
282 #undef KeLowerIrql
283 /*
284 * @implemented
285 */
286 VOID
287 NTAPI
288 KeLowerIrql(KIRQL NewIrql)
289 {
290 /* Call the fastcall function */
291 KfLowerIrql(NewIrql);
292 }
293
294 #undef KeAcquireSpinLock
295 /*
296 * @implemented
297 */
298 VOID
299 NTAPI
300 KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
301 PKIRQL OldIrql)
302 {
303 /* Call the fastcall function */
304 *OldIrql = KfAcquireSpinLock(SpinLock);
305 }
306
307 #undef KeReleaseSpinLock
308 /*
309 * @implemented
310 */
311 VOID
312 NTAPI
313 KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
314 KIRQL NewIrql)
315 {
316 /* Call the fastcall function */
317 KfReleaseSpinLock(SpinLock, NewIrql);
318 }
319
320 #endif
321