From bf59a888877b7ba0b126ccc67526072050f5696d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 15 Aug 2011 06:27:23 +0000 Subject: [PATCH] [USETUP] - Autodetect ACPI like we autodetect a multiprocessor configuration - This will make the ACPI HAL the default on ACPI-compliant machines while the standard HAL will continue to be the default on older machines - Please file bugs for any issues encountered when running in ACPI mode and assign them to me (I think it's very important to have working ACPI for 0.4.0 so I'd really like to get everything fixed now) [TXTSETUP.SIF] - Add a MP configuration for ACPI HAL - Slightly modify the names of each HAL configuration svn path=/trunk/; revision=53257 --- reactos/base/setup/usetup/settings.c | 167 +++++++++++++++++++++++++-- reactos/boot/bootdata/txtsetup.sif | 16 ++- 2 files changed, 171 insertions(+), 12 deletions(-) diff --git a/reactos/base/setup/usetup/settings.c b/reactos/base/setup/usetup/settings.c index 90fd2634585..4b4d000387c 100644 --- a/reactos/base/setup/usetup/settings.c +++ b/reactos/base/setup/usetup/settings.c @@ -33,6 +33,143 @@ /* FUNCTIONS ****************************************************************/ +static BOOLEAN +IsAcpiComputer(VOID) +{ + UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); + UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); + UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS"); + OBJECT_ATTRIBUTES ObjectAttributes; + PKEY_BASIC_INFORMATION pDeviceInformation = NULL; + ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR); + PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL; + ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); + ULONG RequiredSize; + ULONG IndexDevice = 0; + UNICODE_STRING DeviceName, ValueName; + HANDLE hDevicesKey = NULL; + HANDLE hDeviceKey = NULL; + NTSTATUS Status; + BOOLEAN ret = FALSE; + + InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = NtOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("RtlAllocateHeap() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); + if (!pDeviceInformation) + { + DPRINT("RtlAllocateHeap() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + while (TRUE) + { + Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + if (Status == STATUS_NO_MORE_ENTRIES) + break; + else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); + DeviceInfoLength = RequiredSize; + pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("RtlAllocateHeap() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + IndexDevice++; + + /* Open device key */ + DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; + DeviceName.Buffer = pDeviceInformation->Name; + InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, hDevicesKey, NULL); + Status = NtOpenKey( + &hDeviceKey, + KEY_QUERY_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* Read identifier */ + Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("RtlAllocateHeap() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + else if (pValueInformation->Type != REG_SZ) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); + goto nextdevice; + } + + ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; + ValueName.Buffer = (PWCHAR)pValueInformation->Data; + if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + ValueName.Length -= sizeof(WCHAR); + if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0) + { + DPRINT("Found ACPI BIOS\n"); + ret = TRUE; + goto cleanup; + } + +nextdevice: + NtClose(hDeviceKey); + hDeviceKey = NULL; + } + +cleanup: + if (pDeviceInformation) + RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); + if (pValueInformation) + RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); + if (hDevicesKey) + NtClose(hDevicesKey); + if (hDeviceKey) + NtClose(hDeviceKey); + return ret; +} + + static BOOLEAN GetComputerIdentifier(PWSTR Identifier, ULONG IdentifierLength) @@ -98,15 +235,31 @@ GetComputerIdentifier(PWSTR Identifier, return FALSE; } - if (pFullInfo->SubKeys == 1) + if (IsAcpiComputer()) { - /* Computer is mono-CPU */ - ComputerIdentifier = L"PC UP"; + if (pFullInfo->SubKeys == 1) + { + /* Computer is mono-CPU */ + ComputerIdentifier = L"ACPI UP"; + } + else + { + /* Computer is multi-CPUs */ + ComputerIdentifier = L"ACPI MP"; + } } else { - /* Computer is multi-CPUs */ - ComputerIdentifier = L"PC MP"; + if (pFullInfo->SubKeys == 1) + { + /* Computer is mono-CPU */ + ComputerIdentifier = L"PC UP"; + } + else + { + /* Computer is multi-CPUs */ + ComputerIdentifier = L"PC MP"; + } } RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); @@ -140,7 +293,7 @@ CreateComputerTypeList(HINF InfFile) ComputerIdentifier[0] = 0; } - DPRINT("Computer identifier: '%S'\n", ComputerIdentifier); + DPRINT1("Computer identifier: '%S'\n", ComputerIdentifier); /* Search for matching device identifier */ if (!SetupFindFirstLineW(InfFile, L"Map.Computer", NULL, &Context)) @@ -158,7 +311,7 @@ CreateComputerTypeList(HINF InfFile) return NULL; } - DPRINT("KeyValue: %S\n", KeyValue); + DPRINT1("KeyValue: %S\n", KeyValue); if (wcsstr(ComputerIdentifier, KeyValue)) { if (!INF_GetDataField(&Context, 0, &KeyName)) diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index 4671fe1ec33..140d4ebce3c 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -91,15 +91,17 @@ DefaultLayout = 00000409 DefaultLanguage = 00000409 [Computer] -pci_up = "Standard-PC" -pci_mp = "Standard-PC Multiprocessor" -acpi = "ACPI PC" +pci_up = "Standard PC Uniprocessor" +pci_mp = "Standard PC Multiprocessor" +acpi_up = "ACPI PC Uniprocessor" +acpi_mp = "ACPI PC Multiprocessor" [Map.Computer] ; = pci_up = "PC UP" pci_mp = "PC MP" -acpi = "ACPI" +acpi_up = "ACPI UP" +acpi_mp = "ACPI MP" [Files.pci_up] ntoskrnl.exe=,,,,,,,,,,,,2 @@ -109,10 +111,14 @@ hal.dll=,,,,,,,,,,,,2 ntkrnlmp.exe=,,,,,,,,,,ntoskrnl.exe,,2 halmps.dll=,,,,,,,,,,hal.dll,,2 -[Files.acpi] +[Files.acpi_up] ntoskrnl.exe=,,,,,,,,,,,,2 halacpi.dll=,,,,,,,,,,hal.dll,,2 +[Files.acpi_mp] +ntkrnlmp.exe=,,,,,,,,,,ntoskrnl.exe,,2 +halacpi.dll=,,,,,,,,,,hal.dll,,2 + [Display] ; = ,,,,, vga = "VGA Display (640x480x4)",,Vga,640,480,4