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