You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2655 lines
63 KiB
2655 lines
63 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
acpi.c
|
|
|
|
Abstract:
|
|
|
|
WinDbg Extension Api for interpretting ACPI data structures
|
|
|
|
Author:
|
|
|
|
Stephane Plante (splante) 21-Mar-1997
|
|
|
|
Based on Code by:
|
|
Peter Wieland (peterwie) 16-Oct-1995
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
|
|
extern FILE *outputFile;
|
|
|
|
BOOL
|
|
ReadPhysicalOrVirtual(
|
|
IN ULONG_PTR Address,
|
|
IN PVOID Buffer,
|
|
IN ULONG Size,
|
|
IN OUT PULONG ReturnLength,
|
|
IN BOOL Virtual
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a way to abstract out the differences between ROM images
|
|
and mapped memory
|
|
|
|
Arguments:
|
|
|
|
Address - Where (either physical, or virtual) the buffer is located
|
|
Buffer - Address of where to copy the memory to
|
|
Size - How many bytes to copy (maximum)
|
|
ReturnLength - How many bytes where copied
|
|
Virtual - False if this is physical memory
|
|
|
|
--*/
|
|
{
|
|
BOOL status = TRUE;
|
|
PHYSICAL_ADDRESS physicalAddress = { 0L, 0L };
|
|
|
|
if (Virtual) {
|
|
|
|
status = ReadMemory(
|
|
Address,
|
|
Buffer,
|
|
Size,
|
|
ReturnLength
|
|
);
|
|
|
|
} else {
|
|
|
|
physicalAddress.QuadPart = Address;
|
|
ReadPhysical(
|
|
physicalAddress.QuadPart,
|
|
Buffer,
|
|
Size,
|
|
ReturnLength
|
|
);
|
|
|
|
}
|
|
|
|
if (ReturnLength && *ReturnLength != Size) {
|
|
|
|
//
|
|
// Didn't get enough memory
|
|
//
|
|
status = FALSE;
|
|
|
|
}
|
|
return status;
|
|
}
|
|
|
|
VOID
|
|
dumpAcpiGpeInformation(
|
|
VOID
|
|
)
|
|
{
|
|
ACPIInformation acpiInformation;
|
|
BOOL status;
|
|
UCHAR gpeEnable[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeCurEnable[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeWakeEnable[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeIsLevel[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeHandlerType[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeWakeHandler[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeSpecialHandler[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpePending[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeMap[MAX_GPE_BUFFER_SIZE * 8];
|
|
UCHAR gpeRunMethod[MAX_GPE_BUFFER_SIZE];
|
|
UCHAR gpeComplete[MAX_GPE_BUFFER_SIZE];
|
|
ULONG_PTR address;
|
|
ULONG acpiGpeRunning;
|
|
ULONG acpiGpeWorkDone;
|
|
ULONG returnLength;
|
|
ULONG size;
|
|
ULONG value = 0;
|
|
ULONG i;
|
|
|
|
//
|
|
// Get the ACPI Information Table
|
|
//
|
|
status = GetUlongPtr("ACPI!AcpiInformation", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!AcpiInformation\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
&acpiInformation,
|
|
sizeof(ACPIInformation),
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != sizeof(ACPIInformation)) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
sizeof(ACPIInformation),
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the current masks from the OS
|
|
//
|
|
status = GetUlongPtr("ACPI!GpeEnable", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeEnable\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeEnable,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeCurEnable", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeCurEnable\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeCurEnable,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeWakeEnable", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeWakeEnable\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeWakeEnable,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeIsLevel", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeIsLevel\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeIsLevel,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeHandlerType", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeHandlerType\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeHandlerType,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeWakeHandler", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeWakeHandler\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeWakeHandler,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeSpecialHandler", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeSpecialHandler\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeSpecialHandler,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpePending", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpePending\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpePending,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeRunMethod", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpePending\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeRunMethod,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeComplete", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpePending\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeComplete,
|
|
acpiInformation.GpeSize,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != acpiInformation.GpeSize) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
acpiInformation.GpeSize,
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr("ACPI!GpeMap", &address);
|
|
if (!status) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeMap\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory(
|
|
address,
|
|
gpeMap,
|
|
(acpiInformation.GpeSize * 8),
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != (ULONG) (acpiInformation.GpeSize * 8) ) {
|
|
|
|
dprintf(
|
|
"dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
|
|
(acpiInformation.GpeSize * 8),
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlong( "ACPI!AcpiGpeDpcRunning", &acpiGpeRunning );
|
|
if (status == FALSE) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!AcpiGpeDpcRunning\n");
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlong( "ACPI!AcpiGpeWorkDone", &acpiGpeWorkDone );
|
|
if (status == FALSE) {
|
|
|
|
dprintf("dumpAcpiGpeInformation: Could not read ACPI!AcpiGpeDpcRunning\n");
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf("ACPI General Purpose Events\n");
|
|
dprintf(" + AcpiGpeDpcRunning = %s\n", (acpiGpeRunning ? "TRUE" : "FALSE" ) );
|
|
dprintf(" + AcpiGpeWorkDone = %s\n", (acpiGpeRunning ? "TRUE" : "FALSE" ) );
|
|
dprintf(
|
|
" Register Size: %d bytes\n",
|
|
(acpiInformation.Gpe0Size + acpiInformation.Gpe1Size)
|
|
);
|
|
|
|
dprintf(" Status Register: ");
|
|
for (i = acpiInformation.Gpe1Size; i > 0; i--) {
|
|
|
|
size = 1;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP1_BLK + (i - 1), &value, &size );
|
|
if (!size) {
|
|
|
|
|
|
}
|
|
dprintf(" %02x", value );
|
|
|
|
}
|
|
for (i = acpiInformation.Gpe0Size; i > 0; i--) {
|
|
|
|
size = 1;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP0_BLK + (i - 1), &value, &size );
|
|
if (!size) {
|
|
|
|
value = 0;
|
|
|
|
}
|
|
dprintf(" %02x", value );
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf(" Enable Register: ");
|
|
for (i = acpiInformation.Gpe1Size; i > 0; i--) {
|
|
|
|
size = 1;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP1_ENABLE + (i - 1), &value, &size );
|
|
if (!size) {
|
|
|
|
value = 0;
|
|
|
|
}
|
|
dprintf(" %02x", value );
|
|
|
|
}
|
|
for (i = acpiInformation.Gpe0Size; i > 0; i--) {
|
|
|
|
size = 1;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP0_ENABLE + (i - 1), &value, &size );
|
|
if (!size) {
|
|
|
|
value = 0;
|
|
|
|
}
|
|
dprintf(" %02x", value );
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf(" OS Enable Mask: ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeEnable[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" OS Current Mask: ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeCurEnable[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" OS Wake Mask: ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeWakeEnable[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" GPE Level Type: ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeIsLevel[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" GPE Handler Type: ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeHandlerType[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" GPE Wake Handler: ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeWakeHandler[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" Special GPEs : ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeSpecialHandler[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" Pending GPEs : ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpePending[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" RunMethod GPEs : ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeRunMethod[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" Complete GPEs : ");
|
|
for (i = acpiInformation.GpeSize; i > 0; i--) {
|
|
|
|
dprintf(" %02x", gpeComplete[i-1] );
|
|
|
|
}
|
|
dprintf("\n");
|
|
dprintf(" GPE Map : ");
|
|
for (i = 0 ; i < (ULONG) (acpiInformation.GpeSize * 8); i++) {
|
|
|
|
dprintf(" %02x", gpeMap[i]);
|
|
if ( ((i+1) % 16) == 0) {
|
|
|
|
dprintf("\n ");
|
|
|
|
}
|
|
|
|
}
|
|
dprintf("\n");
|
|
}
|
|
|
|
VOID
|
|
dumpAcpiInformation(
|
|
VOID
|
|
)
|
|
{
|
|
BOOL status;
|
|
ACPIInformation acpiInformation;
|
|
ULONG_PTR address;
|
|
ULONG returnLength;
|
|
ULONG size;
|
|
ULONG value;
|
|
ULONG i;
|
|
|
|
status = GetUlongPtr( "ACPI!AcpiInformation", &address );
|
|
if (status == FALSE) {
|
|
|
|
dprintf("dumpAcpiInformation: Could not read ACPI!AcpiInformation\n");
|
|
return;
|
|
|
|
}
|
|
|
|
status = ReadMemory(
|
|
address,
|
|
&acpiInformation,
|
|
sizeof(ACPIInformation),
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != sizeof(ACPIInformation)) {
|
|
|
|
dprintf(
|
|
"dumpAcpiInformation: Could not read %x bytes at %x\n",
|
|
sizeof(ACPIInformation),
|
|
address
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf("ACPIInformation (%08lx)\n", address);
|
|
dprintf(
|
|
" RSDT - %x\n",
|
|
acpiInformation.RootSystemDescTable
|
|
);
|
|
dprintf(
|
|
" FADT - %x\n",
|
|
acpiInformation.FixedACPIDescTable
|
|
);
|
|
dprintf(
|
|
" FACS - %x\n",
|
|
acpiInformation.FirmwareACPIControlStructure
|
|
);
|
|
dprintf(
|
|
" DSDT - %x\n",
|
|
acpiInformation.DiffSystemDescTable
|
|
);
|
|
dprintf(
|
|
" GlobalLock - %x\n",
|
|
acpiInformation.GlobalLock
|
|
);
|
|
dprintf(
|
|
" GlobalLockQueue - F - %x B - %x\n",
|
|
acpiInformation.GlobalLockQueue.Flink,
|
|
acpiInformation.GlobalLockQueue.Blink
|
|
);
|
|
dprintf(
|
|
" GlobalLockQueueLock - %x\n",
|
|
acpiInformation.GlobalLockQueueLock
|
|
);
|
|
dprintf(
|
|
" GlobalLockOwnerContext - %x\n",
|
|
acpiInformation.GlobalLockOwnerContext
|
|
);
|
|
dprintf(
|
|
" GlobalLockOwnerDepth - %x\n",
|
|
acpiInformation.GlobalLockOwnerDepth
|
|
);
|
|
dprintf(
|
|
" ACPIOnly - %s\n",
|
|
(acpiInformation.ACPIOnly ? "TRUE" : "FALSE" )
|
|
);
|
|
dprintf(
|
|
" PM1a_BLK - %x",
|
|
acpiInformation.PM1a_BLK
|
|
);
|
|
if (acpiInformation.PM1a_BLK) {
|
|
|
|
size = 4;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.PM1a_BLK, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%04x) (%04x)\n", (value & 0xFFFF), (value >> 16) );
|
|
dumpPM1StatusRegister( value, 5 );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" PM1b_BLK - %x",
|
|
acpiInformation.PM1b_BLK
|
|
);
|
|
if (acpiInformation.PM1b_BLK) {
|
|
|
|
size = 4;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.PM1b_BLK, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%04x) (%04x)\n", (value & 0xFFFF), (value >> 16) );
|
|
dumpPM1StatusRegister( value, 5 );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
dprintf(
|
|
" PM1a_CTRL_BLK - %x",
|
|
acpiInformation.PM1a_CTRL_BLK
|
|
);
|
|
if (acpiInformation.PM1a_CTRL_BLK) {
|
|
|
|
size = 2;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.PM1a_CTRL_BLK, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%04x)\n", (value & 0xFFFF) );
|
|
dumpPM1ControlRegister( value, 5 );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
dprintf(
|
|
" PM1b_CTRL_BLK - %x",
|
|
acpiInformation.PM1b_CTRL_BLK
|
|
);
|
|
|
|
if (acpiInformation.PM1b_CTRL_BLK) {
|
|
|
|
size = 2;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.PM1b_CTRL_BLK, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%04x)\n", (value & 0xFFFF));
|
|
dumpPM1ControlRegister( value, 5 );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n" );
|
|
|
|
}
|
|
dprintf(
|
|
" PM2_CTRL_BLK - %x",
|
|
acpiInformation.PM2_CTRL_BLK
|
|
);
|
|
if (acpiInformation.PM2_CTRL_BLK) {
|
|
|
|
size = 1;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.PM2_CTRL_BLK, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%02x)\n", (value & 0xFF) );
|
|
if (value & 0x1) {
|
|
|
|
dprintf(" 0 - ARB_DIS\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" PM_TMR - %x",
|
|
acpiInformation.PM_TMR
|
|
);
|
|
if (acpiInformation.PM_TMR) {
|
|
|
|
size = 4;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.PM_TMR, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%08lx)\n", value );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" GP0_BLK - %x",
|
|
acpiInformation.GP0_BLK
|
|
);
|
|
if (acpiInformation.GP0_BLK) {
|
|
|
|
for(i = 0; i < acpiInformation.Gpe0Size; i++) {
|
|
|
|
size = 1;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP0_BLK + i, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%02x)", value );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)" );
|
|
|
|
}
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" GP0_ENABLE - %x",
|
|
acpiInformation.GP0_ENABLE
|
|
);
|
|
if (acpiInformation.GP0_ENABLE) {
|
|
|
|
for(i = 0; i < acpiInformation.Gpe0Size; i++) {
|
|
|
|
size = 1;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP0_ENABLE + i, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%02x)", value );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)" );
|
|
|
|
}
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" GP0_LEN - %x\n",
|
|
acpiInformation.GP0_LEN
|
|
);
|
|
dprintf(
|
|
" GP0_SIZE - %x\n",
|
|
acpiInformation.Gpe0Size
|
|
);
|
|
dprintf(
|
|
" GP1_BLK - %x",
|
|
acpiInformation.GP1_BLK
|
|
);
|
|
if (acpiInformation.GP1_BLK) {
|
|
|
|
for(i = 0; i < acpiInformation.Gpe0Size; i++) {
|
|
|
|
size = 1;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP1_BLK + i, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%02x)", value );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)" );
|
|
|
|
}
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" GP1_ENABLE - %x",
|
|
acpiInformation.GP1_ENABLE
|
|
);
|
|
if (acpiInformation.GP1_ENABLE) {
|
|
|
|
for(i = 0; i < acpiInformation.Gpe0Size; i++) {
|
|
|
|
size = 1;
|
|
value = 0;
|
|
ReadIoSpace( (ULONG) acpiInformation.GP1_ENABLE + i, &value, &size );
|
|
if (size) {
|
|
|
|
dprintf(" (%02x)", value );
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)" );
|
|
|
|
}
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
} else {
|
|
|
|
dprintf(" (N/A)\n");
|
|
|
|
}
|
|
dprintf(
|
|
" GP1_LEN - %x\n",
|
|
acpiInformation.GP1_LEN
|
|
);
|
|
dprintf(
|
|
" GP1_SIZE - %x\n",
|
|
acpiInformation.Gpe1Size
|
|
);
|
|
dprintf(
|
|
" GP1_BASE_INDEX - %x\n",
|
|
acpiInformation.GP1_Base_Index
|
|
);
|
|
dprintf(
|
|
" GPE_SIZE - %x\n",
|
|
acpiInformation.GpeSize
|
|
);
|
|
dprintf(
|
|
" PM1_EN_BITS - %04x\n",
|
|
acpiInformation.pm1_en_bits
|
|
);
|
|
dumpPM1StatusRegister( ( (ULONG) acpiInformation.pm1_en_bits << 16), 5 );
|
|
dprintf(
|
|
" PM1_WAKE_MASK - %04x\n",
|
|
acpiInformation.pm1_wake_mask
|
|
);
|
|
dumpPM1StatusRegister( ( (ULONG) acpiInformation.pm1_wake_mask << 16), 5 );
|
|
dprintf(
|
|
" C2_LATENCY - %x\n",
|
|
acpiInformation.c2_latency
|
|
);
|
|
dprintf(
|
|
" C3_LATENCY - %x\n",
|
|
acpiInformation.c3_latency
|
|
);
|
|
dprintf(
|
|
" ACPI_FLAGS - %x\n",
|
|
acpiInformation.ACPI_Flags
|
|
);
|
|
if (acpiInformation.ACPI_Flags & C2_SUPPORTED) {
|
|
|
|
dprintf(" %2d - C2_SUPPORTED\n", C2_SUPPORTED_BIT);
|
|
|
|
}
|
|
if (acpiInformation.ACPI_Flags & C3_SUPPORTED) {
|
|
|
|
dprintf(" %2d - C3_SUPPORTED\n", C3_SUPPORTED_BIT);
|
|
|
|
}
|
|
if (acpiInformation.ACPI_Flags & C3_PREFERRED) {
|
|
|
|
dprintf(" %2d - C3_PREFERRED\n", C3_PREFERRED_BIT);
|
|
|
|
}
|
|
dprintf(
|
|
" ACPI_CAPABILITIES - %x\n",
|
|
acpiInformation.ACPI_Capabilities
|
|
);
|
|
if (acpiInformation.ACPI_Capabilities & CSTATE_C1) {
|
|
|
|
dprintf(" %2d - CSTATE_C1\n", CSTATE_C1_BIT );
|
|
|
|
} if (acpiInformation.ACPI_Capabilities & CSTATE_C2) {
|
|
|
|
dprintf(" %2d - CSTATE_C2\n", CSTATE_C2_BIT );
|
|
|
|
} if (acpiInformation.ACPI_Capabilities & CSTATE_C3) {
|
|
|
|
dprintf(" %2d - CSTATE_C3\n", CSTATE_C3_BIT );
|
|
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
VOID
|
|
dumpDSDT(
|
|
IN ULONG_PTR Address,
|
|
IN PUCHAR Name
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This dumps the DSDT at the specified address
|
|
|
|
Arguments:
|
|
|
|
The address where the DSDT is located at
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
BOOL status;
|
|
BOOL virtualMemory;
|
|
DESCRIPTION_HEADER dsdtHeader;
|
|
NTSTATUS result;
|
|
PDSDT dsdt;
|
|
ULONG returnLength;
|
|
ULONG index;
|
|
|
|
//
|
|
// Determine if we have virtual or physical memory
|
|
//
|
|
for (index = 0; index < 2; index++) {
|
|
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
&dsdtHeader,
|
|
sizeof(DESCRIPTION_HEADER),
|
|
&returnLength,
|
|
(BOOL) index
|
|
);
|
|
if (!status) {
|
|
|
|
continue;
|
|
|
|
} else if (dsdtHeader.Signature != DSDT_SIGNATURE &&
|
|
dsdtHeader.Signature != SSDT_SIGNATURE &&
|
|
dsdtHeader.Signature != PSDT_SIGNATURE ) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// This will set the policy for the rest of the operation
|
|
//
|
|
switch (index) {
|
|
case 0:
|
|
virtualMemory = FALSE;
|
|
break;
|
|
case 1:
|
|
virtualMemory = TRUE;
|
|
break;
|
|
default:
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Could only read 0x%08lx of 0x%08lx bytes\n",
|
|
returnLength,
|
|
sizeof(DESCRIPTION_HEADER)
|
|
);
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Unknown Signature 0x%08lx\n",
|
|
dsdtHeader.Signature
|
|
);
|
|
dumpHeader( Address, &dsdtHeader, TRUE );
|
|
|
|
}
|
|
return;
|
|
} // switch
|
|
|
|
//
|
|
// Do we have a correctly sized data structure
|
|
//
|
|
dsdt = LocalAlloc( LPTR, dsdtHeader.Length );
|
|
if (dsdt == NULL) {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Could not allocate %#08lx bytes\n",
|
|
Address,
|
|
dsdtHeader.Length
|
|
);
|
|
dumpHeader( Address, &dsdtHeader, TRUE );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the data
|
|
//
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
dsdt,
|
|
dsdtHeader.Length,
|
|
&returnLength,
|
|
virtualMemory
|
|
);
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Read %#08lx of %#08lx bytes\n",
|
|
Address,
|
|
returnLength,
|
|
dsdtHeader.Length
|
|
);
|
|
dumpHeader( Address, &dsdtHeader, TRUE );
|
|
LocalFree( dsdt );
|
|
return;
|
|
|
|
} else if (dsdt->Header.Signature != DSDT_SIGNATURE &&
|
|
dsdt->Header.Signature != SSDT_SIGNATURE &&
|
|
dsdt->Header.Signature != PSDT_SIGNATURE) {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Unkown Signature (%#08lx)\n",
|
|
dsdt->Header.Signature
|
|
);
|
|
dumpHeader( Address, &dsdtHeader, TRUE );
|
|
LocalFree( dsdt );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Load the DSDT into the unassembler
|
|
//
|
|
if (!IsDSDTLoaded()) {
|
|
|
|
result = UnAsmLoadDSDT(
|
|
(PUCHAR) dsdt
|
|
);
|
|
if (!NT_SUCCESS(result)) {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Could not load DSDT %08lx because %08lx\n",
|
|
dsdt,
|
|
result
|
|
);
|
|
return;
|
|
|
|
}
|
|
result = UnAsmLoadXSDTEx();
|
|
if (!NT_SUCCESS(result)) {
|
|
|
|
dprintf(
|
|
"dumpDSDT: Could not load XSDTs because %08lx\n",
|
|
result
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Name == NULL) {
|
|
|
|
result = UnAsmDSDT(
|
|
(PUCHAR) dsdt,
|
|
DisplayPrint,
|
|
Address,
|
|
0
|
|
);
|
|
|
|
} else {
|
|
|
|
outputFile = fopen( Name, "w");
|
|
if (outputFile == NULL) {
|
|
|
|
dprintf("dumpDSDT: Could not open file \"%s\"\n", Name );
|
|
|
|
} else {
|
|
|
|
result = UnAsmDSDT(
|
|
(PUCHAR) dsdt,
|
|
FilePrint,
|
|
Address,
|
|
0
|
|
);
|
|
|
|
fflush( outputFile );
|
|
fclose( outputFile );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!NT_SUCCESS(result)) {
|
|
|
|
dprintf("dumpDSDT: Unasm Error 0x%08lx\n", result );
|
|
|
|
}
|
|
LocalFree( dsdt );
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
VOID
|
|
dumpFACS(
|
|
IN ULONG_PTR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This dumps the FADT at the specified address
|
|
|
|
Arguments:
|
|
|
|
The address where the FADT is located at
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
{
|
|
BOOL status;
|
|
FACS facs;
|
|
ULONG index;
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Read the data
|
|
//
|
|
dprintf("FACS - %#08lx\n", Address);
|
|
|
|
for (index = 0; index < 2; index++) {
|
|
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
&facs,
|
|
sizeof(FACS),
|
|
&returnLength,
|
|
(BOOL) index
|
|
);
|
|
if (!status || facs.Signature != FACS_SIGNATURE) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// This will set the policy for the rest of the operation
|
|
//
|
|
switch (index) {
|
|
default:
|
|
break;
|
|
case 2:
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpFACS: Could only read 0x%08lx of 0x%08lx bytes\n",
|
|
returnLength,
|
|
sizeof(FACS)
|
|
);
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
"dumpFACS: Invalid Signature 0x%08lx != FACS_SIGNATURE\n",
|
|
facs.Signature
|
|
);
|
|
|
|
}
|
|
return;
|
|
} // switch
|
|
|
|
//
|
|
// Dump the table
|
|
//
|
|
memset( Buffer, 0, 2048 );
|
|
memcpy( Buffer, &(facs.Signature), sizeof(ULONG) );
|
|
dprintf(
|
|
" Signature: %s\n"
|
|
" Length: %#08lx\n"
|
|
" Hardware Signature: %#08lx\n"
|
|
" Firmware Wake Vector: %#08lx\n"
|
|
" Global Lock : %#08lx\n",
|
|
Buffer,
|
|
facs.Length,
|
|
facs.HardwareSignature,
|
|
facs.pFirmwareWakingVector,
|
|
facs.GlobalLock
|
|
);
|
|
|
|
if ( (facs.GlobalLock & GL_PENDING) ) {
|
|
|
|
dprintf(" Request for Ownership Pending\n");
|
|
|
|
}
|
|
if ( (facs.GlobalLock & GL_OWNER) ) {
|
|
|
|
dprintf(" Global Lock is Owned\n");
|
|
|
|
}
|
|
dprintf(" Flags: %#08lx\n", facs.Flags );
|
|
if ( (facs.Flags & FACS_S4BIOS_SUPPORTED) ) {
|
|
|
|
dprintf(" S4BIOS_REQ Supported\n");
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
dumpFADT(
|
|
IN ULONG_PTR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This dumps the FADT at the specified address
|
|
|
|
Arguments:
|
|
|
|
The address where the FADT is located at
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
{
|
|
BOOL status;
|
|
BOOL virtualMemory;
|
|
DESCRIPTION_HEADER fadtHeader;
|
|
FADT fadt;
|
|
ULONG fadtLength;
|
|
ULONG returnLength;
|
|
ULONG index;
|
|
PCHAR addressSpace;
|
|
|
|
//
|
|
// First check to see if we find the correct things
|
|
//
|
|
dprintf("FADT - ");
|
|
|
|
for (index = 0; index < 2; index++) {
|
|
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
&fadtHeader,
|
|
sizeof(DESCRIPTION_HEADER),
|
|
&returnLength,
|
|
(BOOL) index
|
|
);
|
|
if (!status || fadtHeader.Signature != FADT_SIGNATURE) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// This will set the policy for the rest of the operation
|
|
//
|
|
switch (index) {
|
|
case 0:
|
|
virtualMemory = FALSE;
|
|
break;
|
|
case 1:
|
|
virtualMemory = TRUE;
|
|
break;
|
|
default:
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpFADT: Could only read 0x%08lx of 0x%08lx bytes\n",
|
|
returnLength,
|
|
sizeof(DESCRIPTION_HEADER)
|
|
);
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
"dumpFADT: Invalid Signature 0x%08lx != FADT_SIGNATURE\n",
|
|
fadtHeader.Signature
|
|
);
|
|
dumpHeader( Address, &fadtHeader, TRUE );
|
|
|
|
}
|
|
return;
|
|
} // switch
|
|
|
|
if (fadtHeader.Revision == 1) {
|
|
fadtLength = FADT_REV_1_SIZE; // 116
|
|
} else if (fadtHeader.Revision == 2) {
|
|
fadtLength = FADT_REV_2_SIZE; // 129
|
|
} else {
|
|
fadtLength = sizeof(FADT);
|
|
}
|
|
|
|
//
|
|
// Do we have a correctly sized data structure
|
|
//
|
|
if (fadtHeader.Length < fadtLength) {
|
|
|
|
dprintf(
|
|
"dumpFADT: Length (%#08lx) is not the size of the FADT (%#08lx)\n",
|
|
Address,
|
|
fadtHeader.Length,
|
|
fadtLength
|
|
);
|
|
dumpHeader( Address, &fadtHeader, TRUE );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the data
|
|
//
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
&fadt,
|
|
fadtLength,
|
|
&returnLength,
|
|
virtualMemory
|
|
);
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpFADT: Read %#08lx of %#08lx bytes\n",
|
|
Address,
|
|
returnLength,
|
|
sizeof(FADT)
|
|
);
|
|
dumpHeader( Address, &fadtHeader, TRUE );
|
|
return;
|
|
|
|
} else if (fadt.Header.Signature != FADT_SIGNATURE) {
|
|
|
|
dprintf(
|
|
"%#08lx: Signature (%#08lx) != fadt_SIGNATURE (%#08lx)\n",
|
|
Address,
|
|
fadt.Header.Signature,
|
|
FADT_SIGNATURE
|
|
);
|
|
dumpHeader( Address, &fadtHeader, TRUE );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Dump the table
|
|
//
|
|
dumpHeader( Address, &(fadt.Header), TRUE );
|
|
dprintf(
|
|
"FADT - BODY - %#08lx\n"
|
|
" FACS: 0x%08lx\n"
|
|
" DSDT: 0x%08lx\n"
|
|
" Int Model: %s\n"
|
|
" SCI Vector: 0x%03x\n"
|
|
" SMI Port: 0x%08lx\n"
|
|
" ACPI On Value: 0x%03x\n"
|
|
" ACPI Off Value: 0x%03x\n"
|
|
" SMI CMD For S4 State: 0x%03x\n"
|
|
" PM1A Event Block: 0x%08lx\n"
|
|
" PM1B Event Block: 0x%08lx\n"
|
|
" PM1 Event Length: 0x%03x\n"
|
|
" PM1A Control Block: 0x%08lx\n"
|
|
" PM1B Control Block: 0x%08lx\n"
|
|
" PM1 Control Length: 0x%03x\n"
|
|
" PM2 Control Block: 0x%08lx\n"
|
|
" PM2 Control Length: 0x%03x\n"
|
|
" PM Timer Block: 0x%08lx\n"
|
|
" PM Timer Length: 0x%03x\n"
|
|
" GP0 Block: 0x%08lx\n"
|
|
" GP0 Length: 0x%03x\n"
|
|
" GP1 Block: 0x%08lx\n"
|
|
" GP1 Length: 0x%08lx\n"
|
|
" GP1 Base: 0x%08lx\n"
|
|
" C2 Latency: 0x%05lx\n"
|
|
" C3 Latency: 0x%05lx\n"
|
|
" Memory Flush Size: 0x%05lx\n"
|
|
" Memory Flush Stride: 0x%05lx\n"
|
|
" Duty Cycle Index: 0x%03x\n"
|
|
" Duty Cycle Index Width: 0x%03x\n"
|
|
" Day Alarm Index: 0x%03x\n"
|
|
" Month Alarm Index: 0x%03x\n"
|
|
" Century byte (CMOS): 0x%03x\n"
|
|
" Boot Architecture: 0x%04x\n"
|
|
" Flags: 0x%08lx\n",
|
|
Address + sizeof(DESCRIPTION_HEADER),
|
|
fadt.facs,
|
|
fadt.dsdt,
|
|
(fadt.int_model == 0 ? "Dual PIC" : "Multiple APIC" ),
|
|
fadt.sci_int_vector,
|
|
fadt.smi_cmd_io_port,
|
|
fadt.acpi_on_value,
|
|
fadt.acpi_off_value,
|
|
fadt.s4bios_req,
|
|
fadt.pm1a_evt_blk_io_port,
|
|
fadt.pm1b_evt_blk_io_port,
|
|
fadt.pm1_evt_len,
|
|
fadt.pm1a_ctrl_blk_io_port,
|
|
fadt.pm1b_ctrl_blk_io_port,
|
|
fadt.pm1_ctrl_len,
|
|
fadt.pm2_ctrl_blk_io_port,
|
|
fadt.pm2_ctrl_len,
|
|
fadt.pm_tmr_blk_io_port,
|
|
fadt.pm_tmr_len,
|
|
fadt.gp0_blk_io_port,
|
|
fadt.gp0_blk_len,
|
|
fadt.gp1_blk_io_port,
|
|
fadt.gp1_blk_len,
|
|
fadt.gp1_base,
|
|
fadt.lvl2_latency,
|
|
fadt.lvl3_latency,
|
|
#ifndef _IA64_ // XXTF
|
|
fadt.flush_size,
|
|
fadt.flush_stride,
|
|
fadt.duty_offset,
|
|
fadt.duty_width,
|
|
#endif
|
|
fadt.day_alarm_index,
|
|
fadt.month_alarm_index,
|
|
fadt.century_alarm_index,
|
|
#ifndef _IA64_ // XXTF
|
|
fadt.boot_arch,
|
|
#endif
|
|
fadt.flags
|
|
);
|
|
if (fadt.flags & WRITEBACKINVALIDATE_WORKS) {
|
|
|
|
dprintf(" Write Back Invalidate is supported\n");
|
|
|
|
}
|
|
if (fadt.flags & WRITEBACKINVALIDATE_DOESNT_INVALIDATE) {
|
|
|
|
dprintf(" Write Back Invalidate doesn't invalidate the caches\n");
|
|
|
|
}
|
|
if (fadt.flags & SYSTEM_SUPPORTS_C1) {
|
|
|
|
dprintf(" System cupports C1 Power state on all processors\n");
|
|
|
|
}
|
|
if (fadt.flags & P_LVL2_UP_ONLY) {
|
|
|
|
dprintf(" System supports C2 in MP and UP configurations\n");
|
|
|
|
}
|
|
if (fadt.flags & PWR_BUTTON_GENERIC) {
|
|
|
|
dprintf(" Power Button is treated as a generic feature\n");
|
|
|
|
}
|
|
if (fadt.flags & SLEEP_BUTTON_GENERIC) {
|
|
|
|
dprintf(" Sleep Button is treated as a generic feature\n");
|
|
|
|
}
|
|
if (fadt.flags & RTC_WAKE_GENERIC) {
|
|
|
|
dprintf(" RTC Wake is not supported in fixed register space\n");
|
|
|
|
}
|
|
if (fadt.flags & RTC_WAKE_FROM_S4) {
|
|
|
|
dprintf(" RTC Wake can work from an S4 state\n");
|
|
|
|
}
|
|
if (fadt.flags & TMR_VAL_EXT) {
|
|
|
|
dprintf(" TMR_VAL implemented as 32-bit value\n");
|
|
|
|
}
|
|
#ifndef _IA64_ // XXTF
|
|
if (fadt.Header.Revision > 1) {
|
|
|
|
if (!(fadt.boot_arch & LEGACY_DEVICES)) {
|
|
|
|
dprintf(" The machine does not contain legacy ISA devices\n");
|
|
}
|
|
if (!(fadt.boot_arch & I8042)) {
|
|
|
|
dprintf(" The machine does not contain a legacy i8042\n");
|
|
}
|
|
if (fadt.flags & RESET_CAP) {
|
|
|
|
dprintf(" The reset register is supported\n");
|
|
dprintf(" Reset Val: %x\n", fadt.reset_val);
|
|
|
|
switch (fadt.reset_reg.AddressSpaceID) {
|
|
case 0:
|
|
addressSpace = "Memory";
|
|
break;
|
|
case 1:
|
|
addressSpace = "I/O";
|
|
break;
|
|
case 2:
|
|
addressSpace = "PCIConfig";
|
|
break;
|
|
default:
|
|
addressSpace = "undefined";
|
|
}
|
|
dprintf(" Reset register: %s - %08x'%08x\n",
|
|
addressSpace,
|
|
fadt.reset_reg.Address.HighPart,
|
|
fadt.reset_reg.Address.LowPart
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
dumpGBL(
|
|
ULONG Verbose
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads in all the system tables and prints out
|
|
what the ACPI Good Bios List Entry for this machine should
|
|
be
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
ACPIInformation inf;
|
|
BOOL status;
|
|
DESCRIPTION_HEADER hdr;
|
|
ULONG64 dateAddress;
|
|
PRSDTINFORMATION info;
|
|
PUCHAR tempPtr;
|
|
ULONG i;
|
|
ULONG numElements;
|
|
ULONG returnLength;
|
|
ULONG size;
|
|
ULONG_PTR address;
|
|
ULONG_PTR address2;
|
|
|
|
//
|
|
// Remember where the date address is stored
|
|
//
|
|
dateAddress = 0xFFFF5;
|
|
|
|
//
|
|
// Make sure that we can read the pointer
|
|
//
|
|
address2 = GetExpression( "ACPI!RsdtInformation" );
|
|
if (!address2) {
|
|
|
|
dprintf("dumpGBL: Could not find RsdtInformation\n");
|
|
return;
|
|
|
|
}
|
|
|
|
status = GetUlongPtr( "ACPI!RsdtInformation", &address );
|
|
if (status == FALSE || !address) {
|
|
|
|
dprintf("dumpGBL: No RsdtInformation present\n");
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the ACPInformation table, so that we know where the RSDT lives
|
|
//
|
|
status = GetUlongPtr( "ACPI!AcpiInformation", &address2 );
|
|
if (status == FALSE || !address2) {
|
|
|
|
dprintf("dumpGBL: Could not read AcpiInformation\n");
|
|
return;
|
|
|
|
}
|
|
status = ReadMemory( address2, &inf, sizeof(ACPIInformation), &returnLength );
|
|
if (!status || returnLength != sizeof(ACPIInformation)) {
|
|
|
|
dprintf("dumpGBL: Could not read AcpiInformation- %d %x\n", status, returnLength);
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read in the header for the RSDT
|
|
//
|
|
address2 = (ULONG_PTR) inf.RootSystemDescTable;
|
|
status = ReadMemory( address2, &hdr, sizeof(DESCRIPTION_HEADER), &returnLength );
|
|
if (!status || returnLength != sizeof(DESCRIPTION_HEADER)) {
|
|
|
|
dprintf("dumpGBL: Could not read RSDT @%x - %d %x\n", address2, status, returnLength );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// The number of elements in the table is the first entry
|
|
// in the structure
|
|
//
|
|
status = ReadMemory(address, &numElements, sizeof(ULONG), &returnLength);
|
|
if (status == FALSE || returnLength != sizeof(ULONG) ) {
|
|
|
|
dprintf("dumpGBL: Could not read RsdtInformation\n");
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// If there are no elements, then return
|
|
//
|
|
if (numElements == 0) {
|
|
|
|
dprintf("dumpGBL: No tables the RsdtInformation\n");
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Allocate the table, and read in all the pointers
|
|
//
|
|
size = sizeof(RSDTINFORMATION) + ( (numElements - 1) * sizeof(RSDTELEMENT) );
|
|
info = LocalAlloc( LPTR, size );
|
|
if (info == NULL) {
|
|
|
|
dprintf("dumpGBL: Could not allocate %x bytes for table\n", size);
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the entire table
|
|
//
|
|
status = ReadMemory(
|
|
address,
|
|
info,
|
|
size,
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != size) {
|
|
|
|
dprintf("dumpGBL: Could not read RsdtInformation Table\n");
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Dump a header so that people know what this is
|
|
//
|
|
memset( Buffer, 0, 2048 );
|
|
ReadPhysical( dateAddress, Buffer, 8, &returnLength );
|
|
dprintf("\nGood Bios List Entry --- Machine BIOS Date %s\n\n", Buffer);
|
|
|
|
memset( Buffer, 0, 2048 );
|
|
memcpy( Buffer, hdr.OEMID, 6);
|
|
tempPtr = Buffer;
|
|
while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
|
|
memcpy( tempPtr, hdr.OEMTableID, 8 );
|
|
while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
|
|
ReadPhysical( dateAddress, tempPtr, 8, &returnLength );
|
|
while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
|
|
|
|
//
|
|
// This is the entry name
|
|
//
|
|
dprintf("[%s]\n", Buffer );
|
|
|
|
//
|
|
// Dump the all the tables that are loaded in the RSDT table
|
|
//
|
|
for (i = 0; i < numElements; i++) {
|
|
|
|
if (!(info->Tables[i].Flags & RSDTELEMENT_MAPPED) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
dumpGBLEntry( (ULONG_PTR) info->Tables[i].Address, Verbose );
|
|
|
|
}
|
|
|
|
//
|
|
// Dump the entry for the RSDT
|
|
//
|
|
dumpGBLEntry( (ULONG_PTR) inf.RootSystemDescTable, Verbose );
|
|
|
|
//
|
|
// Add some whitespace
|
|
//
|
|
dprintf("\n");
|
|
|
|
//
|
|
// Free the RSDT information structure
|
|
//
|
|
LocalFree( info );
|
|
|
|
//
|
|
// Done
|
|
//
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
dumpGBLEntry(
|
|
IN ULONG_PTR Address,
|
|
IN ULONG Verbose
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine actually prints the rule for the table at the
|
|
specified address
|
|
|
|
Arguments:
|
|
|
|
Address - where the table is located
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
BOOL status;
|
|
DESCRIPTION_HEADER header;
|
|
ULONG returnLength;
|
|
UCHAR tableId[7];
|
|
UCHAR entryId[20];
|
|
|
|
|
|
//
|
|
// Read the header for the table
|
|
//
|
|
status = ReadMemory(
|
|
Address,
|
|
&header,
|
|
sizeof(DESCRIPTION_HEADER),
|
|
&returnLength
|
|
);
|
|
if (!status || returnLength != sizeof(DESCRIPTION_HEADER)) {
|
|
|
|
dprintf("dumpGBLEntry: %x - can't read header\n", Address );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Don't print out a table unless its the FACP or we are being verbose
|
|
//
|
|
if (!(Verbose & VERBOSE_2) && header.Signature != FADT_SIGNATURE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Initialize the table id field
|
|
//
|
|
memset( tableId, 0, 7 );
|
|
tableId[0] = '\"';
|
|
memcpy( &tableId[1], &(header.Signature), sizeof(ULONG) );
|
|
strcat( tableId, "\"" );
|
|
|
|
//
|
|
// Get the entry ready for the OEM Id
|
|
//
|
|
memset( entryId, 0, 20 );
|
|
entryId[0] = '\"';
|
|
memcpy( &entryId[1], header.OEMID, 6 );
|
|
strcat( entryId, "\"");
|
|
dprintf("AcpiOemId=%s,%s\n", tableId, entryId );
|
|
|
|
//
|
|
// Get the entry ready for the OEM Table Id
|
|
//
|
|
memset( entryId, 0, 20 );
|
|
entryId[0] = '\"';
|
|
memcpy( &entryId[1], header.OEMTableID, 8 );
|
|
strcat( entryId, "\"");
|
|
dprintf("AcpiOemTableId=%s,%s\n", tableId, entryId );
|
|
|
|
//
|
|
// Get the entry ready for the OEM Revision
|
|
//
|
|
dprintf("AcpiOemRevision=\">=\",%s,%x\n", tableId, header.OEMRevision );
|
|
|
|
//
|
|
// Get the entry ready for the ACPI revision
|
|
//
|
|
if (header.Revision != 1) {
|
|
|
|
dprintf("AcpiRevision=\">=\",%s,%x\n", tableId, header.Revision );
|
|
|
|
}
|
|
|
|
//
|
|
// Get the entry ready for the ACPI Creator Revision
|
|
//
|
|
dprintf("AcpiCreatorRevision=\">=\",%s,%x\n", tableId, header.CreatorRev );
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpHeader(
|
|
IN ULONG_PTR Address,
|
|
IN PDESCRIPTION_HEADER Header,
|
|
IN BOOLEAN Verbose
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function dumps out a table header
|
|
|
|
Arugments:
|
|
|
|
Address - Where the table is located
|
|
Header - The table header
|
|
Verbose - How much information to give
|
|
|
|
Return Value:
|
|
|
|
NULL
|
|
|
|
--*/
|
|
{
|
|
memset( Buffer, 0, 2048 );
|
|
memcpy( Buffer, &(Header->Signature), sizeof(ULONG) );
|
|
|
|
if (Verbose) {
|
|
|
|
dprintf(
|
|
"HEADER - %#08lx\n"
|
|
" Signature: %s\n"
|
|
" Length: 0x%08lx\n"
|
|
" Revision: 0x%02x\n"
|
|
" Checksum: 0x%02x\n",
|
|
Address,
|
|
Buffer,
|
|
Header->Length,
|
|
Header->Revision,
|
|
Header->Checksum
|
|
);
|
|
|
|
memset( Buffer, 0, 7 );
|
|
memcpy( Buffer, Header->OEMID, 6 );
|
|
dprintf(" OEMID: %s\n", Buffer );
|
|
memcpy( Buffer, Header->OEMTableID, 8 );
|
|
dprintf(" OEMTableID: %s\n", Buffer );
|
|
dprintf(" OEMRevision: 0x%08lx\n", Header->OEMRevision );
|
|
memset( Buffer, 0, 8 );
|
|
memcpy( Buffer, Header->CreatorID, 4 );
|
|
dprintf(" CreatorID: %s\n", Buffer );
|
|
dprintf(" CreatorRev: 0x%08lx\n", Header->CreatorRev );
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
" %s @(%#08lx) Rev: %#03x Len: %#08lx",
|
|
Buffer,
|
|
Address,
|
|
Header->Revision,
|
|
Header->Length
|
|
);
|
|
memset( Buffer, 0, sizeof(ULONG) );
|
|
memcpy( Buffer, Header->OEMTableID, 8 );
|
|
dprintf(" TableID: %s\n", Buffer );
|
|
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
dumpMAPIC(
|
|
IN ULONG_PTR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This dumps the multiple apic table
|
|
|
|
Arguments:
|
|
|
|
Address of the table
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
BOOL hasMPSFlags;
|
|
BOOL status;
|
|
BOOL virtualMemory;
|
|
DESCRIPTION_HEADER mapicHeader;
|
|
PIOAPIC ioApic;
|
|
PISA_VECTOR interruptSourceOverride;
|
|
PMAPIC mapic;
|
|
PIO_NMISOURCE nmiSource;
|
|
PLOCAL_NMISOURCE localNmiSource;
|
|
PPROCLOCALAPIC localApic;
|
|
PUCHAR buffer;
|
|
PUCHAR limit;
|
|
ULONG index;
|
|
ULONG returnLength;
|
|
ULONG flags;
|
|
|
|
//
|
|
// First check to see if we find the correct things
|
|
//
|
|
dprintf("MAPIC - ");
|
|
|
|
for (index = 0; index < 2; index++) {
|
|
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
&mapicHeader,
|
|
sizeof(DESCRIPTION_HEADER),
|
|
&returnLength,
|
|
(BOOL) index
|
|
);
|
|
if (!status || mapicHeader.Signature != APIC_SIGNATURE) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// This will set the policy for the rest of the operation
|
|
//
|
|
switch (index) {
|
|
case 0:
|
|
virtualMemory = FALSE;
|
|
break;
|
|
case 1:
|
|
virtualMemory = TRUE;
|
|
break;
|
|
default:
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpMAPIC: Could only read 0x%08lx of 0x%08lx bytes\n",
|
|
returnLength,
|
|
sizeof(DESCRIPTION_HEADER)
|
|
);
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
"dumpMAPIC: Invalid Signature 0x%08lx != ACPI_SIGNATURE\n",
|
|
mapicHeader.Signature
|
|
);
|
|
dumpHeader( Address, &mapicHeader, TRUE );
|
|
|
|
}
|
|
return;
|
|
} // switch
|
|
|
|
//
|
|
// Do we have a correctly sized data structure
|
|
//
|
|
mapic = LocalAlloc( LPTR, mapicHeader.Length );
|
|
if (mapic == NULL) {
|
|
|
|
dprintf(
|
|
"%#08lx: Could not allocate %#08lx bytes\n",
|
|
Address,
|
|
mapicHeader.Length
|
|
);
|
|
dumpHeader( Address, &mapicHeader, TRUE );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the data
|
|
//
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
mapic,
|
|
mapicHeader.Length,
|
|
&returnLength,
|
|
virtualMemory
|
|
);
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpMAPIC: Read %#08lx of %#08lx bytes\n",
|
|
Address,
|
|
returnLength,
|
|
mapicHeader.Length
|
|
);
|
|
dumpHeader( Address, &mapicHeader, TRUE );
|
|
LocalFree( mapic );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// At this point, we are confident that everything worked
|
|
//
|
|
dumpHeader( Address, &(mapic->Header), TRUE );
|
|
dprintf("MAPIC - BODY - %#08lx\n", Address + sizeof(DESCRIPTION_HEADER) );
|
|
dprintf(" Local APIC Address: %#08lx\n", mapic->LocalAPICAddress );
|
|
dprintf(" Flags: %#08lx\n", mapic->Flags );
|
|
if (mapic->Flags & PCAT_COMPAT) {
|
|
|
|
dprintf(" PC-AT dual 8259 compatible setup\n");
|
|
|
|
}
|
|
|
|
buffer = (PUCHAR) &(mapic->APICTables[0]);
|
|
limit = (PUCHAR) ( (ULONG_PTR)mapic + mapic->Header.Length );
|
|
while (buffer < limit) {
|
|
|
|
//
|
|
// Assume that no flags are set
|
|
//
|
|
hasMPSFlags = FALSE;
|
|
|
|
//
|
|
// Lets see what kind of table we have?
|
|
//
|
|
localApic = (PPROCLOCALAPIC) buffer;
|
|
ioApic = (PIOAPIC) buffer;
|
|
interruptSourceOverride = (PISA_VECTOR) buffer;
|
|
nmiSource = (PIO_NMISOURCE) buffer;
|
|
localNmiSource = (PLOCAL_NMISOURCE) buffer;
|
|
|
|
//
|
|
// Is it a localApic?
|
|
//
|
|
if (localApic->Type == PROCESSOR_LOCAL_APIC) {
|
|
|
|
buffer += localApic->Length;
|
|
dprintf(
|
|
" Processor Local Apic\n"
|
|
" ACPI Processor ID: 0x%02x\n"
|
|
" APIC ID: 0x%02x\n"
|
|
" Flags: 0x%08lx\n",
|
|
localApic->ACPIProcessorID,
|
|
localApic->APICID,
|
|
localApic->Flags
|
|
);
|
|
if (localApic->Flags & PLAF_ENABLED) {
|
|
|
|
dprintf(" Processor is Enabled\n");
|
|
|
|
}
|
|
if (localApic->Length != PROCESSOR_LOCAL_APIC_LENGTH) {
|
|
|
|
dprintf(
|
|
" Local Apic has length 0x%x instead of 0x%x\n",
|
|
localApic->Length,
|
|
PROCESSOR_LOCAL_APIC_LENGTH
|
|
);
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (ioApic->Type == IO_APIC) {
|
|
|
|
buffer += ioApic->Length;
|
|
dprintf(
|
|
" IO Apic\n"
|
|
" IO APIC ID: 0x%02x\n"
|
|
" IO APIC ADDRESS: 0x%08lx\n"
|
|
" System Vector Base: 0x%08lx\n",
|
|
ioApic->IOAPICID,
|
|
ioApic->IOAPICAddress,
|
|
ioApic->SystemVectorBase
|
|
);
|
|
if (ioApic->Length != IO_APIC_LENGTH) {
|
|
|
|
dprintf(
|
|
" IO Apic has length 0x%x instead of 0x%x\n",
|
|
ioApic->Length,
|
|
IO_APIC_LENGTH
|
|
);
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (interruptSourceOverride->Type == ISA_VECTOR_OVERRIDE) {
|
|
|
|
buffer += interruptSourceOverride->Length;
|
|
dprintf(
|
|
" Interrupt Source Override\n"
|
|
" Bus: 0x%02x\n"
|
|
" Source: 0x%02x\n"
|
|
" Global Interrupt: 0x%08lx\n"
|
|
" Flags: 0x%04x\n",
|
|
interruptSourceOverride->Bus,
|
|
interruptSourceOverride->Source,
|
|
interruptSourceOverride->GlobalSystemInterruptVector,
|
|
interruptSourceOverride->Flags
|
|
);
|
|
|
|
if (interruptSourceOverride->Length != ISA_VECTOR_OVERRIDE_LENGTH) {
|
|
|
|
dprintf(
|
|
" Interrupt Source Override has length 0x%x instead of 0x%x\n",
|
|
interruptSourceOverride->Length,
|
|
ISA_VECTOR_OVERRIDE_LENGTH
|
|
);
|
|
break;
|
|
|
|
}
|
|
|
|
hasMPSFlags = TRUE;
|
|
flags = interruptSourceOverride->Flags;
|
|
|
|
} else if (nmiSource->Type == IO_NMI_SOURCE) {
|
|
|
|
buffer += nmiSource->Length;
|
|
dprintf(
|
|
" Non Maskable Interrupt Source - on I/O APIC\n"
|
|
" Flags: 0x%02x\n"
|
|
" Global Interrupt: 0x%08lx\n",
|
|
nmiSource->Flags,
|
|
nmiSource->GlobalSystemInterruptVector
|
|
);
|
|
if (nmiSource->Length != IO_NMI_SOURCE_LENGTH) {
|
|
|
|
dprintf(
|
|
" Non Maskable Interrupt source has length 0x%x instead of 0x%x\n",
|
|
nmiSource->Length,
|
|
IO_NMI_SOURCE_LENGTH
|
|
);
|
|
break;
|
|
|
|
}
|
|
|
|
hasMPSFlags = TRUE;
|
|
flags = nmiSource->Flags;
|
|
|
|
|
|
} else if (localNmiSource->Type == LOCAL_NMI_SOURCE) {
|
|
|
|
buffer += localNmiSource->Length;
|
|
dprintf(
|
|
" Non Maskable Interrupt Source - local to processor\n"
|
|
" Flags: 0x%04x\n"
|
|
" Processor: 0x%02x %s\n"
|
|
" LINTIN: 0x%02x\n",
|
|
localNmiSource->Flags,
|
|
localNmiSource->ProcessorID,
|
|
localNmiSource->ProcessorID == 0xff ? "(all)" : "",
|
|
localNmiSource->LINTIN
|
|
);
|
|
if (localNmiSource->Length != LOCAL_NMI_SOURCE_LENGTH) {
|
|
|
|
dprintf(
|
|
" Non Maskable Interrupt source has length 0x%x instead of 0x%x\n",
|
|
localNmiSource->Length,
|
|
IO_NMI_SOURCE_LENGTH
|
|
);
|
|
break;
|
|
|
|
}
|
|
|
|
hasMPSFlags = TRUE;
|
|
flags = localNmiSource->Flags;
|
|
|
|
|
|
} else {
|
|
|
|
dprintf(" UNKOWN RECORD\n");
|
|
dprintf(" Length: 0x%8lx\n", ioApic->Length );
|
|
buffer += ioApic->Length;
|
|
|
|
}
|
|
|
|
//
|
|
// Do we have any flags to dump out?
|
|
//
|
|
if (hasMPSFlags) {
|
|
|
|
switch (flags & PO_BITS) {
|
|
case POLARITY_HIGH:
|
|
dprintf(" POLARITY_HIGH\n");
|
|
break;
|
|
case POLARITY_LOW:
|
|
dprintf(" POLARITY_LOW\n");
|
|
break;
|
|
case POLARITY_CONFORMS_WITH_BUS:
|
|
dprintf(" POLARITY_CONFORMS_WITH_BUS\n");
|
|
break;
|
|
default:
|
|
dprintf(" POLARITY_UNKNOWN\n");
|
|
break;
|
|
|
|
}
|
|
|
|
switch (flags & EL_BITS) {
|
|
case EL_EDGE_TRIGGERED:
|
|
dprintf(" EL_EDGE_TRIGGERED\n");
|
|
break;
|
|
case EL_LEVEL_TRIGGERED:
|
|
dprintf(" EL_LEVEL_TRIGGERED\n");
|
|
break;
|
|
case EL_CONFORMS_WITH_BUS:
|
|
dprintf(" EL_CONFORMS_WITH_BUS\n");
|
|
break;
|
|
default:
|
|
dprintf(" EL_UNKNOWN\n");
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LocalFree( mapic );
|
|
return;
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpRSDT(
|
|
IN ULONG_PTR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This search the dumps the RSDT table
|
|
|
|
Arguments:
|
|
|
|
Pointer to the table
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
{
|
|
BOOL status;
|
|
BOOL virtualMemory = FALSE;
|
|
DESCRIPTION_HEADER rsdtHeader;
|
|
PRSDT rsdt;
|
|
ULONG index;
|
|
ULONG numEntries;
|
|
ULONG returnLength;
|
|
|
|
dprintf("RSDT - ");
|
|
|
|
//
|
|
// Determine if we have virtual or physical memory
|
|
//
|
|
for (index = 0; index < 2; index++) {
|
|
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
&rsdtHeader,
|
|
sizeof(DESCRIPTION_HEADER),
|
|
&returnLength,
|
|
(BOOL) index
|
|
);
|
|
if (!status || rsdtHeader.Signature != RSDT_SIGNATURE) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// This will set the policy for the rest of the operation
|
|
//
|
|
switch (index) {
|
|
case 0:
|
|
virtualMemory = FALSE;
|
|
break;
|
|
case 1:
|
|
virtualMemory = TRUE;
|
|
break;
|
|
default:
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpRSDT: Could only read 0x%08lx of 0x%08lx bytes\n",
|
|
returnLength,
|
|
sizeof(DESCRIPTION_HEADER)
|
|
);
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
"dumpRSDT: Invalid Signature 0x%08lx != RSDT_SIGNATURE\n",
|
|
rsdtHeader.Signature
|
|
);
|
|
dumpHeader( Address, &rsdtHeader, TRUE );
|
|
|
|
}
|
|
return;
|
|
} // switch
|
|
|
|
//
|
|
// Do we have a correctly sized data structure
|
|
//
|
|
rsdt = LocalAlloc( LPTR, rsdtHeader.Length );
|
|
if (rsdt == NULL) {
|
|
|
|
dprintf(
|
|
"dumpRSDT: Could not allocate %#08lx bytes\n",
|
|
Address,
|
|
rsdtHeader.Length
|
|
);
|
|
dumpHeader( Address, &rsdtHeader, TRUE );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Read the data
|
|
//
|
|
status = ReadPhysicalOrVirtual(
|
|
Address,
|
|
rsdt,
|
|
rsdtHeader.Length,
|
|
&returnLength,
|
|
virtualMemory
|
|
);
|
|
if (!status) {
|
|
|
|
dprintf(
|
|
"dumpRSDT: Read %#08lx of %#08lx bytes\n",
|
|
Address,
|
|
returnLength,
|
|
rsdtHeader.Length
|
|
);
|
|
dumpHeader( Address, &rsdtHeader, TRUE );
|
|
LocalFree( rsdt );
|
|
return;
|
|
|
|
} else if (rsdt->Header.Signature != RSDT_SIGNATURE) {
|
|
|
|
dprintf(
|
|
"dumpRSDT: Signature (%#08lx) != RSDT_SIGNATURE (%#08lx)\n",
|
|
Address,
|
|
rsdt->Header.Signature,
|
|
RSDT_SIGNATURE
|
|
);
|
|
dumpHeader( Address, &rsdtHeader, TRUE );
|
|
LocalFree( rsdt );
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// At this point, we are confident that everything worked
|
|
//
|
|
dumpHeader( Address, &(rsdt->Header), TRUE );
|
|
dprintf("RSDT - BODY - %#08lx\n", Address + sizeof(DESCRIPTION_HEADER) );
|
|
numEntries = ( rsdt->Header.Length - sizeof(DESCRIPTION_HEADER) ) /
|
|
sizeof(rsdt->Tables[0]);
|
|
for (index = 0; index < numEntries; index++) {
|
|
|
|
//
|
|
// Note: unless things radically change, the pointers in the
|
|
// rsdt will always point to bios memory!
|
|
//
|
|
status = ReadPhysicalOrVirtual(
|
|
rsdt->Tables[index],
|
|
&rsdtHeader,
|
|
sizeof(DESCRIPTION_HEADER),
|
|
&returnLength,
|
|
FALSE
|
|
);
|
|
if (!status || returnLength != sizeof(DESCRIPTION_HEADER)) {
|
|
|
|
dprintf(
|
|
"dumpRSDT: [%d:0x%08lx] - Read %#08lx of %#08lx bytes\n",
|
|
index,
|
|
rsdt->Tables[index],
|
|
returnLength,
|
|
sizeof(DESCRIPTION_HEADER)
|
|
);
|
|
continue;
|
|
|
|
}
|
|
|
|
dumpHeader( rsdt->Tables[index], &rsdtHeader, FALSE );
|
|
|
|
}
|
|
|
|
LocalFree( rsdt );
|
|
return;
|
|
}
|
|
|
|
BOOLEAN
|
|
findRSDT(
|
|
IN PULONG_PTR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This searchs the memory on the target system for the RSDT pointer
|
|
|
|
Arguments:
|
|
|
|
Address - Where to store the result
|
|
|
|
Return Value:
|
|
|
|
TRUE - If we found the RSDT
|
|
|
|
--*/
|
|
{
|
|
PHYSICAL_ADDRESS address = { 0L, 0L };
|
|
RSDP rsdp;
|
|
RSDT rsdt;
|
|
UCHAR index;
|
|
UCHAR sum;
|
|
ULONG limit;
|
|
ULONG returnLength;
|
|
ULONG start;
|
|
|
|
//
|
|
// Calculate the start and end of the search range
|
|
//
|
|
start = (ULONG) RSDP_SEARCH_RANGE_BEGIN;
|
|
limit = (ULONG) start + RSDP_SEARCH_RANGE_LENGTH - RSDP_SEARCH_INTERVAL;
|
|
|
|
dprintf( "Searching for RSDP.");
|
|
|
|
//
|
|
// Loop for a while
|
|
//
|
|
for (; start <= limit; start += RSDP_SEARCH_INTERVAL) {
|
|
|
|
if (start % (RSDP_SEARCH_INTERVAL * 100 ) == 0) {
|
|
|
|
dprintf(".");
|
|
|
|
}
|
|
//
|
|
// Read the data from the target
|
|
//
|
|
address.LowPart = start;
|
|
ReadPhysical( address.QuadPart, &rsdp, sizeof(RSDP), &returnLength);
|
|
if (returnLength != sizeof(RSDP)) {
|
|
|
|
dprintf(
|
|
"%#08lx: Read %#08lx of %#08lx bytes\n",
|
|
start,
|
|
returnLength,
|
|
sizeof(RSDP)
|
|
);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
//
|
|
// Is this a match?
|
|
//
|
|
if (rsdp.Signature != RSDP_SIGNATURE) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//
|
|
// Check the checksum out
|
|
//
|
|
for (index = 0, sum = 0; index < sizeof(RSDP); index++) {
|
|
|
|
sum = (UCHAR) (sum + *( (UCHAR *) ( (ULONG_PTR) &rsdp + index ) ) );
|
|
|
|
}
|
|
if (sum != 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//
|
|
// Found RSDP
|
|
//
|
|
dprintf("\nRSDP - %#08lx\n", start );
|
|
memset( Buffer, 0, 2048 );
|
|
memcpy( Buffer, &(rsdp.Signature), sizeof(ULONGLONG) );
|
|
dprintf(" Signature: %s\n", Buffer );
|
|
dprintf(" Checksum: %#03x\n", rsdp.Checksum );
|
|
memset( Buffer, 0, sizeof(ULONGLONG) );
|
|
memcpy( Buffer, rsdp.OEMID, 6 );
|
|
dprintf(" OEMID: %s\n", Buffer );
|
|
dprintf(" Reserved: %#03x\n", rsdp.Reserved );
|
|
dprintf(" RsdtAddress: %#08lx\n", rsdp.RsdtAddress );
|
|
|
|
//
|
|
// Done
|
|
//
|
|
*Address = rsdp.RsdtAddress;
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|