windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/kdext/table.c
2020-09-26 16:20:57 +08:00

2656 lines
60 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}