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 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 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 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 146 HalpCheckPowerButton(VOID) 147 { 148 // 149 // Nothing to do on non-ACPI 150 // 151 return; 152 } 153 154 VOID 155 NTAPI 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 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 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 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 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 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 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