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