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