2656 lines
60 KiB
C
2656 lines
60 KiB
C
/*++
|
||
|
||
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;
|
||
|
||
}
|