1 /*
2 * PROJECT: ReactOS Hardware Abstraction Layer (HAL)
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * PURPOSE: I/O Mapping and x86 Subs
5 * PROGRAMMERS: ReactOS Portable Systems Group
6 */
7
8 /* INCLUDES *******************************************************************/
9
10 #include <hal.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS *******************************************************************/
16
17 UCHAR HalpSerialLen;
18 CHAR HalpSerialNumber[31];
19
20 /* PRIVATE FUNCTIONS **********************************************************/
21
22 #ifndef _MINIHAL_
23 CODE_SEG("INIT")
24 VOID
25 NTAPI
HalpReportSerialNumber(VOID)26 HalpReportSerialNumber(VOID)
27 {
28 NTSTATUS Status;
29 UNICODE_STRING KeyString;
30 HANDLE Handle;
31
32 /* Make sure there is a serial number */
33 if (!HalpSerialLen) return;
34
35 /* Open the system key */
36 RtlInitUnicodeString(&KeyString, L"\\Registry\\Machine\\Hardware\\Description\\System");
37 Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
38 if (NT_SUCCESS(Status))
39 {
40 /* Add the serial number */
41 RtlInitUnicodeString(&KeyString, L"Serial Number");
42 ZwSetValueKey(Handle,
43 &KeyString,
44 0,
45 REG_BINARY,
46 HalpSerialNumber,
47 HalpSerialLen);
48
49 /* Close the handle */
50 ZwClose(Handle);
51 }
52 }
53
54 CODE_SEG("INIT")
55 NTSTATUS
56 NTAPI
HalpMarkAcpiHal(VOID)57 HalpMarkAcpiHal(VOID)
58 {
59 NTSTATUS Status;
60 UNICODE_STRING KeyString;
61 HANDLE KeyHandle;
62 HANDLE Handle;
63 ULONG Value = HalDisableFirmwareMapper ? 1 : 0;
64
65 /* Open the control set key */
66 RtlInitUnicodeString(&KeyString,
67 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
68 Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
69 if (NT_SUCCESS(Status))
70 {
71 /* Open the PNP key */
72 RtlInitUnicodeString(&KeyString, L"Control\\Pnp");
73 Status = HalpOpenRegistryKey(&KeyHandle,
74 Handle,
75 &KeyString,
76 KEY_ALL_ACCESS,
77 TRUE);
78 /* Close root key */
79 ZwClose(Handle);
80
81 /* Check if PNP BIOS key exists */
82 if (NT_SUCCESS(Status))
83 {
84 /* Set the disable value to false -- we need the mapper */
85 RtlInitUnicodeString(&KeyString, L"DisableFirmwareMapper");
86 Status = ZwSetValueKey(KeyHandle,
87 &KeyString,
88 0,
89 REG_DWORD,
90 &Value,
91 sizeof(Value));
92
93 /* Close subkey */
94 ZwClose(KeyHandle);
95 }
96 }
97
98 /* Return status */
99 return Status;
100 }
101
102 NTSTATUS
103 NTAPI
HalpOpenRegistryKey(IN PHANDLE KeyHandle,IN HANDLE RootKey,IN PUNICODE_STRING KeyName,IN ACCESS_MASK DesiredAccess,IN BOOLEAN Create)104 HalpOpenRegistryKey(IN PHANDLE KeyHandle,
105 IN HANDLE RootKey,
106 IN PUNICODE_STRING KeyName,
107 IN ACCESS_MASK DesiredAccess,
108 IN BOOLEAN Create)
109 {
110 NTSTATUS Status;
111 ULONG Disposition;
112 OBJECT_ATTRIBUTES ObjectAttributes;
113
114 /* Setup the attributes we received */
115 InitializeObjectAttributes(&ObjectAttributes,
116 KeyName,
117 OBJ_CASE_INSENSITIVE,
118 RootKey,
119 NULL);
120
121 /* What to do? */
122 if ( Create )
123 {
124 /* Create the key */
125 Status = ZwCreateKey(KeyHandle,
126 DesiredAccess,
127 &ObjectAttributes,
128 0,
129 NULL,
130 REG_OPTION_VOLATILE,
131 &Disposition);
132 }
133 else
134 {
135 /* Open the key */
136 Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
137 }
138
139 /* We're done */
140 return Status;
141 }
142 #endif /* !_MINIHAL_ */
143
144 VOID
145 NTAPI
HalpCheckPowerButton(VOID)146 HalpCheckPowerButton(VOID)
147 {
148 //
149 // Nothing to do on non-ACPI
150 //
151 return;
152 }
153
154 VOID
155 NTAPI
HalpFlushTLB(VOID)156 HalpFlushTLB(VOID)
157 {
158 ULONG_PTR Flags, Cr4;
159 INT CpuInfo[4];
160 ULONG_PTR PageDirectory;
161
162 //
163 // Disable interrupts
164 //
165 Flags = __readeflags();
166 _disable();
167
168 //
169 // Get page table directory base
170 //
171 PageDirectory = __readcr3();
172
173 //
174 // Check for CPUID support
175 //
176 if (KeGetCurrentPrcb()->CpuID)
177 {
178 //
179 // Check for global bit in CPU features
180 //
181 __cpuid(CpuInfo, 1);
182 if (CpuInfo[3] & 0x2000)
183 {
184 //
185 // Get current CR4 value
186 //
187 Cr4 = __readcr4();
188
189 //
190 // Disable global bit
191 //
192 __writecr4(Cr4 & ~CR4_PGE);
193
194 //
195 // Flush TLB and re-enable global bit
196 //
197 __writecr3(PageDirectory);
198 __writecr4(Cr4);
199
200 //
201 // Restore interrupts
202 //
203 __writeeflags(Flags);
204 return;
205 }
206 }
207
208 //
209 // Legacy: just flush TLB
210 //
211 __writecr3(PageDirectory);
212 __writeeflags(Flags);
213 }
214
215 /* FUNCTIONS *****************************************************************/
216
217 /*
218 * @implemented
219 */
220 UCHAR
221 FASTCALL
HalSystemVectorDispatchEntry(IN ULONG Vector,OUT PKINTERRUPT_ROUTINE ** FlatDispatch,OUT PKINTERRUPT_ROUTINE * NoConnection)222 HalSystemVectorDispatchEntry(IN ULONG Vector,
223 OUT PKINTERRUPT_ROUTINE **FlatDispatch,
224 OUT PKINTERRUPT_ROUTINE *NoConnection)
225 {
226 //
227 // Not implemented on x86
228 //
229 return 0;
230 }
231
232 /*
233 * @implemented
234 */
235 VOID
236 NTAPI
KeFlushWriteBuffer(VOID)237 KeFlushWriteBuffer(VOID)
238 {
239 //
240 // Not implemented on x86
241 //
242 return;
243 }
244
245 #ifdef _M_IX86
246 /* x86 fastcall wrappers */
247
248 #undef KeRaiseIrql
249 /*
250 * @implemented
251 */
252 VOID
253 NTAPI
KeRaiseIrql(KIRQL NewIrql,PKIRQL OldIrql)254 KeRaiseIrql(KIRQL NewIrql,
255 PKIRQL OldIrql)
256 {
257 /* Call the fastcall function */
258 *OldIrql = KfRaiseIrql(NewIrql);
259 }
260
261 #undef KeLowerIrql
262 /*
263 * @implemented
264 */
265 VOID
266 NTAPI
KeLowerIrql(KIRQL NewIrql)267 KeLowerIrql(KIRQL NewIrql)
268 {
269 /* Call the fastcall function */
270 KfLowerIrql(NewIrql);
271 }
272
273 #undef KeAcquireSpinLock
274 /*
275 * @implemented
276 */
277 VOID
278 NTAPI
KeAcquireSpinLock(PKSPIN_LOCK SpinLock,PKIRQL OldIrql)279 KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
280 PKIRQL OldIrql)
281 {
282 /* Call the fastcall function */
283 *OldIrql = KfAcquireSpinLock(SpinLock);
284 }
285
286 #undef KeReleaseSpinLock
287 /*
288 * @implemented
289 */
290 VOID
291 NTAPI
KeReleaseSpinLock(PKSPIN_LOCK SpinLock,KIRQL NewIrql)292 KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
293 KIRQL NewIrql)
294 {
295 /* Call the fastcall function */
296 KfReleaseSpinLock(SpinLock, NewIrql);
297 }
298
299 #endif /* _M_IX86 */
300