mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 09:20:30 +00:00
[ACPI] Implement creating volatile registry keys for ACPI tables CORE-12942
svn path=/trunk/; revision=74559
This commit is contained in:
parent
8eede74d89
commit
44f1cf17c7
3 changed files with 286 additions and 0 deletions
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <precomp.h>
|
#include <precomp.h>
|
||||||
|
#include <ntstrsafe.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -369,4 +370,281 @@ end:
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
acpi_create_registry_table(HANDLE ParentKeyHandle, ACPI_TABLE_HEADER *OutTable, PCWSTR KeyName)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING HardwareKeyName, ValueName;
|
||||||
|
ANSI_STRING HardwareKeyNameA;
|
||||||
|
HANDLE KeyHandle = NULL, SubKeyHandle = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
char OemId[7] = { 0 }; /* exactly one byte more than ACPI_TABLE_HEADER->OemId */
|
||||||
|
char OemTableId[9] = { 0 }; /* exactly one byte more than ACPI_TABLE_HEADER->OemTableId */
|
||||||
|
WCHAR OemRevision[9] = { 0 }; /* enough to accept hex DWORD */
|
||||||
|
|
||||||
|
C_ASSERT(sizeof(OemId) == RTL_FIELD_SIZE(ACPI_TABLE_HEADER, OemId) + 1);
|
||||||
|
C_ASSERT(sizeof(OemTableId) == RTL_FIELD_SIZE(ACPI_TABLE_HEADER, OemTableId) + 1);
|
||||||
|
/* Copy OEM data from the table */
|
||||||
|
RtlCopyMemory(OemId, OutTable->OemId, sizeof(OutTable->OemId));
|
||||||
|
RtlCopyMemory(OemTableId, OutTable->OemTableId, sizeof(OutTable->OemTableId));
|
||||||
|
/* Create table subkey */
|
||||||
|
RtlInitUnicodeString(&HardwareKeyName, KeyName);
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&HardwareKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
ParentKeyHandle,
|
||||||
|
NULL);
|
||||||
|
Status = ZwCreateKey(&KeyHandle,
|
||||||
|
KEY_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwCreateKey() for %ws failed (Status 0x%08lx)\n", KeyName, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OutTable->OemRevision != 0)
|
||||||
|
{
|
||||||
|
/* We have OEM info in table, so create other OEM subkeys */
|
||||||
|
RtlInitAnsiString(&HardwareKeyNameA, OemId);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&HardwareKeyName, &HardwareKeyNameA, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("RtlAnsiStringToUnicodeString() for %s failed (Status 0x%08lx)\n", HardwareKeyNameA, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&HardwareKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
KeyHandle,
|
||||||
|
NULL);
|
||||||
|
Status = ZwCreateKey(&SubKeyHandle,
|
||||||
|
KEY_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
RtlFreeUnicodeString(&HardwareKeyName);
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwCreateKey() for %s failed (Status 0x%08lx)\n", HardwareKeyNameA, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
KeyHandle = SubKeyHandle;
|
||||||
|
|
||||||
|
RtlInitAnsiString(&HardwareKeyNameA, OemTableId);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&HardwareKeyName, &HardwareKeyNameA, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("RtlAnsiStringToUnicodeString() for %s failed (Status 0x%08lx)\n", HardwareKeyNameA, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&HardwareKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
KeyHandle,
|
||||||
|
NULL);
|
||||||
|
Status = ZwCreateKey(&SubKeyHandle,
|
||||||
|
KEY_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
RtlFreeUnicodeString(&HardwareKeyName);
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwCreateKey() for %s failed (Status 0x%08lx)\n", HardwareKeyNameA, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
KeyHandle = SubKeyHandle;
|
||||||
|
|
||||||
|
Status = RtlStringCbPrintfW(OemRevision,
|
||||||
|
sizeof(OemRevision),
|
||||||
|
L"%08X",
|
||||||
|
OutTable->OemRevision);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("RtlStringCbPrintfW() for 0x%08lx failed (Status 0x%08lx)\n", OutTable->OemRevision, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
RtlInitUnicodeString(&HardwareKeyName, OemRevision);
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&HardwareKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
KeyHandle,
|
||||||
|
NULL);
|
||||||
|
Status = ZwCreateKey(&SubKeyHandle,
|
||||||
|
KEY_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwCreateKey() for %ws failed (Status 0x%08lx)\n", KeyName, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
KeyHandle = SubKeyHandle;
|
||||||
|
}
|
||||||
|
/* Table reg value name is always '00000000' */
|
||||||
|
RtlInitUnicodeString(&ValueName,
|
||||||
|
L"00000000");
|
||||||
|
Status = ZwSetValueKey(KeyHandle,
|
||||||
|
&ValueName,
|
||||||
|
0,
|
||||||
|
REG_BINARY,
|
||||||
|
OutTable,
|
||||||
|
OutTable->Length);
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwSetValueKey() failed (Status 0x%08lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
acpi_create_volatile_registry_tables()
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING HardwareKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\ACPI");
|
||||||
|
HANDLE KeyHandle = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ACPI_STATUS AcpiStatus;
|
||||||
|
ACPI_TABLE_HEADER *OutTable;
|
||||||
|
ACPI_PHYSICAL_ADDRESS RsdpAddress;
|
||||||
|
ACPI_TABLE_RSDP *Rsdp;
|
||||||
|
ACPI_PHYSICAL_ADDRESS Address;
|
||||||
|
UINT32 TableEntrySize;
|
||||||
|
|
||||||
|
/* Create Main Hardware ACPI key*/
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&HardwareKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = ZwCreateKey(&KeyHandle,
|
||||||
|
KEY_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwCreateKey() for ACPI failed (Status 0x%08lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/* Read DSDT table */
|
||||||
|
AcpiStatus = AcpiGetTable(ACPI_SIG_DSDT, 0, &OutTable);
|
||||||
|
if (ACPI_FAILURE(AcpiStatus))
|
||||||
|
{
|
||||||
|
DPRINT1("AcpiGetTable() for DSDT failed (Status 0x%08lx)\n", AcpiStatus);
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Dump DSDT table */
|
||||||
|
Status = acpi_create_registry_table(KeyHandle, OutTable, L"DSDT");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("acpi_dump_table_to_registry() for DSDT failed (Status 0x%08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Read FACS table */
|
||||||
|
AcpiStatus = AcpiGetTable(ACPI_SIG_FACS, 0, &OutTable);
|
||||||
|
if (ACPI_FAILURE(AcpiStatus))
|
||||||
|
{
|
||||||
|
DPRINT1("AcpiGetTable() for FACS failed (Status 0x%08lx)\n", AcpiStatus);
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Dump FACS table */
|
||||||
|
Status = acpi_create_registry_table(KeyHandle, OutTable, L"FACS");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("acpi_dump_table_to_registry() for FACS failed (Status 0x%08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Read FACS table */
|
||||||
|
AcpiStatus = AcpiGetTable(ACPI_SIG_FADT, 0, &OutTable);
|
||||||
|
if (ACPI_FAILURE(AcpiStatus))
|
||||||
|
{
|
||||||
|
DPRINT1("AcpiGetTable() for FADT failed (Status 0x%08lx)\n", AcpiStatus);
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Dump FADT table */
|
||||||
|
Status = acpi_create_registry_table(KeyHandle, OutTable, L"FADT");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("acpi_dump_table_to_registry() for FADT failed (Status 0x%08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* This is a rough copy from ACPICA reading of RSDT/XSDT and added to avoid patching acpica */
|
||||||
|
RsdpAddress = AcpiOsGetRootPointer();
|
||||||
|
/* Map the entire RSDP and extract the address of the RSDT or XSDT */
|
||||||
|
Rsdp = AcpiOsMapMemory(RsdpAddress, sizeof(ACPI_TABLE_RSDP));
|
||||||
|
if (!Rsdp)
|
||||||
|
{
|
||||||
|
DPRINT1("AcpiOsMapMemory() failed\n");
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Use XSDT if present and not overridden. Otherwise, use RSDT */
|
||||||
|
if ((Rsdp->Revision > 1) &&
|
||||||
|
Rsdp->XsdtPhysicalAddress &&
|
||||||
|
!AcpiGbl_DoNotUseXsdt)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* RSDP contains an XSDT (64-bit physical addresses). We must use
|
||||||
|
* the XSDT if the revision is > 1 and the XSDT pointer is present,
|
||||||
|
* as per the ACPI specification.
|
||||||
|
*/
|
||||||
|
Address = (ACPI_PHYSICAL_ADDRESS)Rsdp->XsdtPhysicalAddress;
|
||||||
|
TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Root table is an RSDT (32-bit physical addresses) */
|
||||||
|
Address = (ACPI_PHYSICAL_ADDRESS)Rsdp->RsdtPhysicalAddress;
|
||||||
|
TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* It is not possible to map more than one entry in some environments,
|
||||||
|
* so unmap the RSDP here before mapping other tables
|
||||||
|
*/
|
||||||
|
AcpiOsUnmapMemory(Rsdp, sizeof(ACPI_TABLE_RSDP));
|
||||||
|
OutTable = AcpiOsMapMemory(Address, TableEntrySize);
|
||||||
|
if (!OutTable)
|
||||||
|
{
|
||||||
|
DPRINT1("AcpiOsMapMemory() failed\n");
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Dump RSDT table */
|
||||||
|
Status = acpi_create_registry_table(KeyHandle, OutTable, L"RSDT");
|
||||||
|
AcpiOsUnmapMemory(OutTable, TableEntrySize);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("acpi_dump_table_to_registry() for RSDT failed (Status 0x%08lx)\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ acpi_evaluate_reference (
|
||||||
ACPI_STRING pathname,
|
ACPI_STRING pathname,
|
||||||
struct acpi_object_list *arguments,
|
struct acpi_object_list *arguments,
|
||||||
struct acpi_handle_list *list);
|
struct acpi_handle_list *list);
|
||||||
|
NTSTATUS
|
||||||
|
acpi_create_volatile_registry_tables(void);
|
||||||
|
|
||||||
enum acpi_bus_removal_type {
|
enum acpi_bus_removal_type {
|
||||||
ACPI_BUS_REMOVAL_NORMAL = 0,
|
ACPI_BUS_REMOVAL_NORMAL = 0,
|
||||||
|
|
|
@ -299,6 +299,12 @@ Bus_StartFdo (
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = acpi_create_volatile_registry_tables();
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DPRINT1("Unable to create ACPI tables in registry\n");
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("Acpi subsystem init\n");
|
DPRINT("Acpi subsystem init\n");
|
||||||
/* Initialize ACPI bus manager */
|
/* Initialize ACPI bus manager */
|
||||||
AcpiStatus = acpi_init();
|
AcpiStatus = acpi_init();
|
||||||
|
|
Loading…
Reference in a new issue