windows-nt/Source/XPSP1/NT/base/busdrv/acpi/asl/tables.c

1150 lines
30 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*** tables.c - Dump various ACPI tables
*
* This module provides the functions to dump various ACPI tables.
*
* Copyright (c) 1999 Microsoft Corporation
* Author: Michael Tsang (MikeTs)
* Created 04/08/99
*
* MODIFICATION HISTORY
*/
#ifdef __UNASM
#pragma warning (disable: 4201 4214 4514)
typedef unsigned __int64 ULONGLONG;
#define LOCAL __cdecl
#define EXPORT __cdecl
#include <stdarg.h>
//#define _X86_
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#define ULONG_PTR ULONG
#define EXCL_BASEDEF
#include "pch.h"
#include "fmtdata.h"
#define BYTEOF(d,i) (((BYTE *)&(d))[i])
/***LP IsWinNT - check if OS is NT
*
* ENTRY
* None
*
* EXIT-SUCCESS
* returns TRUE - OS is NT
* EXIT-FAILURE
* returns FALSE - OS is not NT
*/
BOOL LOCAL IsWinNT(VOID)
{
BOOL rc = FALSE;
OSVERSIONINFO osinfo;
ENTER((2, "IsWinNT()\n"));
osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osinfo) && (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT))
{
rc = TRUE;
}
EXIT((2, "IsWinNT=%x\n", rc));
return rc;
} //IsWinNT
#ifndef WINNT
/***LP OpenVxD - Open ACPITAB.VXD
*
* ENTRY
* None
*
* EXIT-SUCCESS
* returns VxD handle
* EXIT-FAILURE
* returns NULL
*/
HANDLE LOCAL OpenVxD(VOID)
{
HANDLE hVxD;
DWORD dwVersion;
ENTER((2, "OpenVxD()\n"));
if ((hVxD = CreateFile(ACPITAB_VXD_NAME, 0, 0, NULL, 0,
FILE_FLAG_DELETE_ON_CLOSE, NULL)) ==
INVALID_HANDLE_VALUE)
{
ERROR(("OpenVxD: failed to open VxD %s (rc=%x)",
ACPITAB_VXD_NAME, GetLastError()));
hVxD = NULL;
}
else if (!DeviceIoControl(hVxD, ACPITAB_DIOC_GETVERSION, NULL, 0,
&dwVersion, sizeof(dwVersion), NULL, NULL))
{
ERROR(("OpenVxD: failed to get VxD version. (rc=%x)", GetLastError()));
CloseVxD(hVxD);
hVxD = NULL;
}
else if (dwVersion != ((ACPITAB_MAJOR_VER << 8) | ACPITAB_MINOR_VER))
{
ERROR(("OpenVxD: version error (Ver=%x)", dwVersion));
CloseVxD(hVxD);
hVxD = NULL;
}
EXIT((2, "OpenVxD=%x\n", hVxD));
return hVxD;
} //OpenVxD
/***LP CloseVxD - Close the VxD
*
* ENTRY
* hVxD - VxD handle
*
* EXIT
* None
*/
VOID LOCAL CloseVxD(HANDLE hVxD)
{
ENTER((2, "CloseVxD(hVxD=%x)\n", hVxD));
CloseHandle(hVxD);
EXIT((2, "CloseVxD!\n"));
} //CloseVxD
/***LP VxDGetTableBySig - Get table by its signature
*
* ENTRY
* dwTabSig - table signature
* pdwTableAddr -> to hold physical address of table (can be NULL)
*
* EXIT-SUCCESS
* returns pointer to table
* EXIT-FAILURE
* returns NULL
*/
PBYTE LOCAL VxDGetTableBySig(DWORD dwTabSig, PDWORD pdwTableAddr)
{
PBYTE pb = NULL;
TABINFO TabInfo;
ENTER((2, "VxDGetTableBySig(TabSig=%x,pdwAddr=%p)\n",
dwTabSig, pdwTableAddr));
TabInfo.dwTabSig = dwTabSig;
if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABINFO, NULL, 0, &TabInfo,
sizeof(TabInfo), NULL, NULL))
{
if (dwTabSig == SIG_RSDP)
{
//
// We are getting RSD PTR
//
if ((pb = MEMALLOC(sizeof(RSDP))) != NULL)
{
memcpy(pb, &TabInfo.rsdp, sizeof(RSDP));
if (pdwTableAddr != NULL)
{
*pdwTableAddr = TabInfo.dwPhyAddr;
}
}
else
{
ERROR(("VxDGetTableBySig: failed to allocate RSDP buffer"));
}
}
else if (dwTabSig == FACS_SIGNATURE)
{
if ((pb = MEMALLOC(sizeof(FACS))) != NULL)
{
memcpy(pb, &TabInfo.facs, sizeof(FACS));
if (pdwTableAddr != NULL)
{
*pdwTableAddr = TabInfo.dwPhyAddr;
}
}
else
{
ERROR(("VxDGetTableBySig: failed to allocate FACS buffer"));
}
}
else if ((pb = MEMALLOC(TabInfo.dh.Length)) != NULL)
{
if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE,
(PVOID)TabInfo.dwPhyAddr, 0, pb,
TabInfo.dh.Length, NULL, NULL) == 0)
{
ERROR(("VxDGetTableBySig: failed to get table %s. (rc=%x)",
GetTableSigStr(dwTabSig), GetLastError()));
MEMFREE(pb);
pb = NULL;
}
else
{
if (pdwTableAddr != NULL)
{
*pdwTableAddr = TabInfo.dwPhyAddr;
}
ValidateTable(pb, TabInfo.dh.Length);
}
}
else
{
ERROR(("VxDGetTableBySig: failed to allocate table buffer (len=%d)",
TabInfo.dh.Length));
}
}
else
{
ERROR(("VxDGetTableBySig: failed to get table info %s. (rc=%x)",
GetTableSigStr(dwTabSig), GetLastError()));
}
EXIT((2, "VxDGetTableBySig=%x\n", pb));
return pb;
} //VxDGetTableBySig
/***LP VxDGetTableByAddr - Get table by its physical address
*
* ENTRY
* dwTableAddr - physical address of table
* pdwTableSig -> to hold signature of table (can be NULL)
*
* EXIT-SUCCESS
* returns pointer to table
* EXIT-FAILURE
* returns NULL
*/
PBYTE LOCAL VxDGetTableByAddr(DWORD dwTableAddr, PDWORD pdwTableSig)
{
PBYTE pb = NULL;
DESCRIPTION_HEADER dh;
ENTER((2, "VxDGetTableByAddr(TabAddr=%x,pdwSig=%p)\n",
dwTableAddr, pdwTableSig));
if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE, (PVOID)dwTableAddr, 0,
&dh, sizeof(dh), NULL, NULL))
{
DWORD dwLen = (dh.Signature == SIG_LOW_RSDP)? sizeof(RSDP): dh.Length;
if ((pb = MEMALLOC(dwLen)) != NULL)
{
if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE,
(PVOID)dwTableAddr, 0, pb, dwLen, NULL, NULL)
== 0)
{
ERROR(("VxDGetTableByAddr: failed to get table %s at %x. (rc=%x)",
GetTableSigStr(dh.Signature), dwTableAddr,
GetLastError()));
MEMFREE(pb);
pb = NULL;
}
else if (pdwTableSig != NULL)
{
if (pdwTableSig != NULL)
{
*pdwTableSig = (dh.Signature == SIG_LOW_RSDP)?
SIG_RSDP: dh.Signature;
}
ValidateTable(pb, dwLen);
}
}
else
{
ERROR(("VxDGetTableByAddr: failed to allocate table buffer (len=%d)",
dh.Length));
}
}
else
{
ERROR(("VxDGetTableByAddr: failed to get table %s header (rc=%x)",
GetTableSigStr(dh.Signature), GetLastError()));
}
EXIT((2, "VxDGetTableByAddr=%x\n", pb));
return pb;
} //VxDGetTableByAddr
#endif //ifndef WINNT
/***LP EnumSubKey - enumerate subkey
*
* ENTRY
* hkey - key to enumerate
* dwIndex - subkey index
*
* EXIT-SUCCESS
* returns subkey
* EXIT-FAILURE
* returns NULL
*/
HKEY LOCAL EnumSubKey(HKEY hkey, DWORD dwIndex)
{
HKEY hkeySub = NULL;
char szSubKey[32];
DWORD dwSubKeySize = sizeof(szSubKey);
ENTER((2, "EnumSubKey(hkey=%x,Index=%d)\n", hkey, dwIndex));
if ((RegEnumKeyEx(hkey, dwIndex, szSubKey, &dwSubKeySize, NULL, NULL, NULL,
NULL) == ERROR_SUCCESS) &&
(RegOpenKeyEx(hkey, szSubKey, 0, KEY_READ, &hkeySub) != ERROR_SUCCESS))
{
hkeySub = NULL;
}
EXIT((2, "EnumSubKey=%x\n", hkeySub));
return hkeySub;
} //EnumSubKey
/***LP OpenNTTable - Open ACPI table in NT registry
*
* ENTRY
* dwTabSig - table signature
*
* EXIT-SUCCESS
* returns table registry handle
* EXIT-FAILURE
* returns NULL
*/
HKEY LOCAL OpenNTTable(DWORD dwTabSig)
{
HKEY hkeyTab = NULL, hkey1 = NULL, hkey2 = NULL;
static char szTabKey[] = "Hardware\\ACPI\\xxxx";
ENTER((2, "OpenNTTable(TabSig=%s)\n", GetTableSigStr(dwTabSig)));
if (dwTabSig == FADT_SIGNATURE)
{
memcpy(&szTabKey[strlen(szTabKey) - 4], "FADT", sizeof(ULONG));
}
else
{
memcpy(&szTabKey[strlen(szTabKey) - 4], &dwTabSig, sizeof(ULONG));
}
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTabKey, 0, KEY_READ, &hkey1) ==
ERROR_SUCCESS)
{
//
// hkey1 is now "Hardware\ACPI\<TabSig>"
//
if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL)
{
//
// hkey2 is now "Hardware\ACPI\<TabSig>\<OEMID>"
//
RegCloseKey(hkey1);
if ((hkey1 = EnumSubKey(hkey2, 0)) != NULL)
{
//
// hkey1 is now "Hardware\ACPI\<TabSig>\<OEMID>\<OEMTabID>"
//
RegCloseKey(hkey2);
if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL)
{
//
// hkey2 is now
// "Hardware\ACPI\<TabSig>\<OEMID>\<OEMTabID>\<OEMRev>"
//
hkeyTab = hkey2;
}
}
}
}
if (hkey1 != NULL)
{
RegCloseKey(hkey1);
}
if ((hkey2 != NULL) && (hkeyTab != hkey2))
{
RegCloseKey(hkey2);
}
EXIT((2, "OpenNTTable=%x\n", hkeyTab));
return hkeyTab;
} //OpenNTTable
/***LP GetNTTable - Get ACPI table from NT registry
*
* ENTRY
* dwTabSig - table signature
*
* EXIT-SUCCESS
* returns pointer to table
* EXIT-FAILURE
* returns NULL
*/
PBYTE LOCAL GetNTTable(DWORD dwTabSig)
{
PBYTE pb = NULL;
HKEY hkeyTab;
ENTER((2, "GetNTTable(TabSig=%s)\n", GetTableSigStr(dwTabSig)));
if ((hkeyTab = OpenNTTable(dwTabSig)) != NULL)
{
DWORD dwLen = 0;
PSZ pszTabKey = "00000000";
if (RegQueryValueEx(hkeyTab, pszTabKey, NULL, NULL, NULL, &dwLen) ==
ERROR_SUCCESS)
{
if ((pb = MEMALLOC(dwLen)) != NULL)
{
if (RegQueryValueEx(hkeyTab, pszTabKey, NULL, NULL, pb, &dwLen)
!= ERROR_SUCCESS)
{
ERROR(("GetNTTable: failed to read table"));
}
}
else
{
ERROR(("GetNTTable: failed to allocate table buffer"));
}
}
else
{
ERROR(("GetNTTable: failed to read table key"));
}
RegCloseKey(hkeyTab);
}
else
{
ERROR(("GetNTTable: failed to get table %s", GetTableSigStr(dwTabSig)));
}
EXIT((2, "GetNTTable=%x\n", pb));
return pb;
} //GetNTTable
/***LP GetTableBySig - Get table by its signature
*
* ENTRY
* dwTabSig - table signature
* pdwTableAddr -> to hold physical address of table (can be NULL)
*
* EXIT-SUCCESS
* returns pointer to table
* EXIT-FAILURE
* returns NULL
*/
PBYTE LOCAL GetTableBySig(DWORD dwTabSig, PDWORD pdwTableAddr)
{
PBYTE pb = NULL;
ENTER((2, "GetTableBySig(TabSig=%x,pdwAddr=%p)\n", dwTabSig, pdwTableAddr));
if (gdwfASL & ASLF_NT)
{
if (((pb = GetNTTable(dwTabSig)) != NULL) && (pdwTableAddr != NULL))
{
*pdwTableAddr = 0;
}
}
#ifndef WINNT
else
{
pb = VxDGetTableBySig(dwTabSig, pdwTableAddr);
}
#endif
EXIT((2, "GetTableBySig=%x\n", pb));
return pb;
} //GetTableBySig
/***LP GetTableByAddr - Get table by its physical address
*
* ENTRY
* dwTableAddr - physical address of table
* pdwTableSig -> to hold signature of table (can be NULL)
*
* EXIT-SUCCESS
* returns pointer to table
* EXIT-FAILURE
* returns NULL
*/
PBYTE LOCAL GetTableByAddr(DWORD dwTableAddr, PDWORD pdwTableSig)
{
PBYTE pb = NULL;
ENTER((2, "GetTableByAddr(TabAddr=%x,pdwSig=%p)\n",
dwTableAddr, pdwTableSig));
if (gdwfASL & ASLF_NT)
{
ERROR(("GetTableByAddr: not supported by NT"));
}
#ifndef WINNT
else
{
pb = VxDGetTableByAddr(dwTableAddr, pdwTableSig);
}
#endif
EXIT((2, "GetTableByAddr=%x\n", pb));
return pb;
} //GetTableByAddr
/***LP DumpAllTables - Dump all ACPI tables
*
* ENTRY
* pfileOut -> output file
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpAllTables(FILE *pfileOut)
{
int rc = ASLERR_NONE;
PBYTE pb;
DWORD dwAddr;
ENTER((1, "DumpAllTables(pfileOut=%p)\n", pfileOut));
if (gdwfASL & ASLF_NT)
{
DumpTableBySig(pfileOut, RSDT_SIGNATURE);
DumpTableBySig(pfileOut, FADT_SIGNATURE);
DumpTableBySig(pfileOut, FACS_SIGNATURE);
DumpTableBySig(pfileOut, SBST_SIGNATURE);
DumpTableBySig(pfileOut, APIC_SIGNATURE);
DumpTableBySig(pfileOut, SIG_BOOT);
DumpTableBySig(pfileOut, SIG_DBGP);
DumpTableBySig(pfileOut, DSDT_SIGNATURE);
DumpTableBySig(pfileOut, SSDT_SIGNATURE);
DumpTableBySig(pfileOut, PSDT_SIGNATURE);
}
else if ((pb = GetTableBySig(SIG_RSDP, &dwAddr)) != NULL)
{
if ((rc = DumpRSDP(pfileOut, pb, dwAddr)) == ASLERR_NONE)
{
DWORD dwRSDTAddr = ((PRSDP)pb)->RsdtAddress;
DWORD dwTableSig;
MEMFREE(pb);
if ((pb = GetTableByAddr(dwRSDTAddr, &dwTableSig)) != NULL)
{
if ((rc = DumpTable(pfileOut, pb, dwRSDTAddr, dwTableSig)) ==
ASLERR_NONE)
{
PRSDT pRSDT = (PRSDT)pb;
DWORD i, dwcEntries;
dwcEntries = (pRSDT->Header.Length -
sizeof(DESCRIPTION_HEADER))/sizeof(ULONG);
for (i = 0; i < dwcEntries; ++i)
{
if ((rc = DumpTableByAddr(pfileOut, pRSDT->Tables[i]))
!= ASLERR_NONE)
{
break;
}
}
}
if ((rc == ASLERR_NONE) &&
((rc = DumpTableBySig(pfileOut, FACS_SIGNATURE)) ==
ASLERR_NONE))
{
rc = DumpTableBySig(pfileOut, DSDT_SIGNATURE);
}
}
else
{
rc = ASLERR_GET_TABLE;
}
}
if (pb != NULL)
{
MEMFREE(pb);
}
}
else
{
rc = ASLERR_GET_TABLE;
}
EXIT((1, "DumpAllTables=%d\n", rc));
return rc;
} //DumpAllTables
/***LP DumpTableBySig - Dump an ACPI table by its Table Signature
*
* ENTRY
* pfileOut -> output file
* dwTableSig - table signature
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpTableBySig(FILE *pfileOut, DWORD dwTableSig)
{
int rc = ASLERR_NONE;
PBYTE pb;
DWORD dwTableAddr;
ENTER((1, "DumpTableBySig(pfileOut=%p,TableSig=%s)\n",
pfileOut, GetTableSigStr(dwTableSig)));
if (((PSZ)&dwTableSig)[0] == '*')
{
rc = DumpAllTables(pfileOut);
}
else if ((pb = GetTableBySig(dwTableSig, &dwTableAddr)) != NULL)
{
rc = DumpTable(pfileOut, pb, dwTableAddr, dwTableSig);
MEMFREE(pb);
}
else
{
rc = ASLERR_GET_TABLE;
}
EXIT((1, "DumpTableBySig=%d\n", rc));
return rc;
} //DumpTableBySig
/***LP DumpTableByAddr - Dump an ACPI table by its address
*
* ENTRY
* pfileOut -> output file
* dwTableAddr - physical address of the table
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpTableByAddr(FILE *pfileOut, DWORD dwTableAddr)
{
int rc = ASLERR_NONE;
PBYTE pb;
DWORD dwTableSig;
ENTER((1, "DumpTableByAddr(pfileOut=%p,TableAddr=%x)\n",
pfileOut, dwTableAddr));
if ((pb = GetTableByAddr(dwTableAddr, &dwTableSig)) != NULL)
{
rc = DumpTable(pfileOut, pb, dwTableAddr, dwTableSig);
MEMFREE(pb);
}
else
{
rc = ASLERR_GET_TABLE;
}
EXIT((1, "DumpTableByAddr=%d\n", rc));
return rc;
} //DumpTableByAddr
/***LP DumpRSDP - Dump the RSD PTR table
*
* ENTRY
* pfileOut -> output file
* pb -> RSDP structure
* dwAddr - physical address of RSDP
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpRSDP(FILE *pfileOut, PBYTE pb, DWORD dwAddr)
{
int rc = ASLERR_NONE;
ENTER((1, "DumpRSDP(pfileOut=%p,Addr=%x,pRSDP=%p)\n",
pfileOut, dwAddr, pb));
if (pfileOut != NULL)
{
DWORD dwOffset = 0;
fprintf(pfileOut, szSectFmt, dwAddr, "RSD PTR");
if (BinFPrintf(pfileOut, NULL, afmtRSDPTR, pb, &dwOffset, szOffsetFmt)
!= FERR_NONE)
{
ERROR(("DumpRSDP: failed to dump RSD PTR structure"));
rc = ASLERR_INTERNAL_ERROR;
}
}
else
{
rc = DumpTableBin(SIG_RSDP, dwAddr, pb, sizeof(RSDP));
}
EXIT((1, "DumpRSDP=%d\n", rc));
return rc;
} //DumpRSDP
/***LP DumpTable - Dump an ACPI table
*
* ENTRY
* pfileOut -> output file
* pb -> ACPI table
* dwTableAddr - physical address of table
* dwTableSig - signature of table
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpTable(FILE *pfileOut, PBYTE pb, DWORD dwTableAddr,
DWORD dwTableSig)
{
int rc = ASLERR_NONE;
ENTER((1, "DumpTable(pfileOut=%p,pb=%p,TableAddr=%x,TableSig=%s)\n",
pfileOut, pb, dwTableAddr, GetTableSigStr(dwTableSig)));
if (dwTableSig == SIG_RSDP)
{
rc = DumpRSDP(pfileOut, pb, dwTableAddr);
}
else if (pfileOut != NULL)
{
rc = DumpTableTxt(pfileOut, pb, dwTableAddr, dwTableSig);
}
else
{
rc = DumpTableBin(dwTableSig, dwTableAddr, pb,
(dwTableSig == FACS_SIGNATURE)?
sizeof(FACS):
((PDESCRIPTION_HEADER)pb)->Length);
}
EXIT((1, "DumpTable=%d\n", rc));
return rc;
} //DumpTable
/***LP DumpTableTxt - Dump an ACPI table to a text file
*
* ENTRY
* pfileOut -> output file
* pb -> ACPI table
* dwTableAddr - physical address of table
* dwTableSig - signature of table
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpTableTxt(FILE *pfileOut, PBYTE pb, DWORD dwTableAddr,
DWORD dwTableSig)
{
int rc = ASLERR_NONE;
PFMT pfmt;
DWORD dwFlags;
ENTER((1, "DumpTableTxt(pfileOut=%p,pb=%p,TableAddr=%x,TableSig=%s)\n",
pfileOut, pb, dwTableAddr, GetTableSigStr(dwTableSig)));
if ((rc = FindTableFmt(dwTableSig, &pfmt, &dwFlags)) ==
ASLERR_SIG_NOT_FOUND)
{
rc = ASLERR_NONE;
}
if (rc == ASLERR_NONE)
{
DWORD dwOffset = 0;
fprintf(pfileOut, szSectFmt, dwTableAddr, GetTableSigStr(dwTableSig));
if (!(dwFlags & TF_NOHDR) &&
(BinFPrintf(pfileOut, NULL, afmtTableHdr, pb, &dwOffset,
szOffsetFmt) != FERR_NONE))
{
ERROR(("DumpTableTxt: failed to dump %s structure header",
GetTableSigStr(dwTableSig)));
rc = ASLERR_INTERNAL_ERROR;
}
else if (pfmt != NULL)
{
if (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset, szOffsetFmt) !=
FERR_NONE)
{
ERROR(("DumpTableTxt: failed to dump %s structure",
GetTableSigStr(dwTableSig)));
rc = ASLERR_INTERNAL_ERROR;
}
else if ((dwTableSig == FADT_SIGNATURE) &&
(((PDESCRIPTION_HEADER)pb)->Revision > 1))
{
/*
pfmt = (((PGRAS)pb)->id == REGSPACE_PCICFG)? afmtGRASPCICS:
afmtGRASRegAddr;*/
fprintf(pfileOut, "; Reset Register\n");
if ((BinFPrintf(pfileOut, NULL, afmtGRASCommon, pb, &dwOffset,
szOffsetFmt) != FERR_NONE) ||
(BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset,
szOffsetFmt) != FERR_NONE) ||
(BinFPrintf(pfileOut, NULL, afmtFACP2, pb, &dwOffset,
szOffsetFmt) != FERR_NONE))
{
ERROR(("DumpTableTxt: failed to dump extended %s structure",
GetTableSigStr(dwTableSig)));
rc = ASLERR_INTERNAL_ERROR;
}
}
else if (dwTableSig == SIG_DBGP)
{
/*
pfmt = (((PGRAS)pb)->id == REGSPACE_PCICFG)? afmtGRASPCICS:
afmtGRASRegAddr;*/
fprintf(pfileOut, "; Debug Port Base Address\n");
if ((BinFPrintf(pfileOut, NULL, afmtGRASCommon, pb, &dwOffset,
szOffsetFmt) != FERR_NONE) ||
(BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset,
szOffsetFmt) != FERR_NONE))
{
ERROR(("DumpTableTxt: failed to dump extended %s structure",
GetTableSigStr(dwTableSig)));
rc = ASLERR_INTERNAL_ERROR;
}
}
}
else
{
#define NUM_COLS 16
PRSDT pRSDT;
DWORD i, dwcEntries;
PBYTE pbEnd;
char szAMLName[_MAX_FNAME];
char szBytes[NUM_COLS + 1];
switch (dwTableSig)
{
case RSDT_SIGNATURE:
pRSDT = (PRSDT)pb;
dwcEntries = (pRSDT->Header.Length -
sizeof(DESCRIPTION_HEADER))/sizeof(ULONG);
for (i = 0; i < dwcEntries; ++i)
{
fprintf(pfileOut, szOffsetFmt, dwOffset);
fprintf(pfileOut, "[%02d] %08lx\n",
i, pRSDT->Tables[i]);
dwOffset += sizeof(ULONG);
}
break;
case DSDT_SIGNATURE:
case SSDT_SIGNATURE:
case PSDT_SIGNATURE:
strncpy(szAMLName, (PSZ)&dwTableSig, sizeof(DWORD));
strcpy(&szAMLName[sizeof(DWORD)], ".AML");
rc = UnAsmAML(szAMLName, dwTableAddr, pb,
(PFNPRINT)fprintf, pfileOut);
break;
default:
//
// Don't return error because we want to continue.
//
WARN(("DumpTableTxt: unexpected table signature %s",
GetTableSigStr(dwTableSig)));
pbEnd = pb + ((PDESCRIPTION_HEADER)pb)->Length;
pb += sizeof(DESCRIPTION_HEADER);
i = 0;
while (pb < pbEnd)
{
szBytes[i] = (char)(isprint(*pb)? *pb: '.');
if (i == 0)
{
fprintf(pfileOut, szOffsetFmt, dwOffset);
fprintf(pfileOut, "%02x", *pb);
}
else if (i == NUM_COLS/2)
{
fprintf(pfileOut, "-%02x", *pb);
}
else
{
fprintf(pfileOut, ",%02x", *pb);
}
i++;
if (i == NUM_COLS)
{
szBytes[i] = '\0';
fprintf(pfileOut, " ;%s\n", szBytes);
i = 0;
}
dwOffset += sizeof(BYTE);
pb += sizeof(BYTE);
}
if (i < NUM_COLS)
{
szBytes[i] = '\0';
while (i < NUM_COLS)
{
fprintf(pfileOut, " ");
i++;
}
fprintf(pfileOut, " ;%s\n", szBytes);
}
}
}
}
EXIT((1, "DumpTableTxt=%d\n", rc));
return rc;
} //DumpTableTxt
/***LP DumpTableBin - Dump an ACPI table to a binary file
*
* ENTRY
* dwTableSig - table signature
* dwAddr - physical address of table
* pb -> ACPI table
* dwLen - length of table
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL DumpTableBin(DWORD dwTableSig, DWORD dwAddr, PBYTE pb, DWORD dwLen)
{
int rc = ASLERR_NONE;
char szBinFile[_MAX_FNAME];
FILE *pfile;
ENTER((1, "DumpTableBin(TableSig=%s,Addr=%x,pb=%p,Len=%d)\n",
GetTableSigStr(dwTableSig), dwAddr, pb, dwLen));
strncpy(szBinFile, (PSZ)&dwTableSig, sizeof(DWORD));
sprintf(&szBinFile[sizeof(DWORD)], "%04x", (WORD)dwAddr);
strcpy(&szBinFile[sizeof(DWORD) + 4], ".BIN");
if ((pfile = fopen(szBinFile, "wb")) == NULL)
{
ERROR(("DumpTableBin: failed to create file %s", szBinFile));
rc = ASLERR_CREATE_FILE;
}
else
{
if (fwrite(pb, dwLen, 1, pfile) != 1)
{
ERROR(("DumpTableBin: failed to write to file %s", szBinFile));
rc = ASLERR_WRITE_FILE;
}
fclose(pfile);
}
EXIT((1, "DumpTableBin=%d\n", rc));
return rc;
} //DumpTableBin
/***LP FindTableFmt - Find the appropriate table format structure
*
* ENTRY
* dwTableSig - table signature
* ppfmt -> to hold pfmt found
* pdwFlags -> to hold table flags
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL FindTableFmt(DWORD dwTableSig, PFMT *ppfmt, PDWORD pdwFlags)
{
int rc = ASLERR_NONE;
int i;
ENTER((1, "FindTableFmt(TableSig=%s,ppfmt=%p,pdwFlags=%p)\n",
GetTableSigStr(dwTableSig), ppfmt, pdwFlags));
for (i = 0; FmtTable[i].dwTableSig != 0; ++i)
{
if (dwTableSig == FmtTable[i].dwTableSig)
{
*ppfmt = FmtTable[i].pfmt;
*pdwFlags = FmtTable[i].dwFlags;
break;
}
}
if (FmtTable[i].dwTableSig == 0)
{
*ppfmt = NULL;
*pdwFlags = 0;
rc = ASLERR_SIG_NOT_FOUND;
}
EXIT((1, "FindTableFmt=%d (pfmt=%p,Flags=%x)\n", rc, *ppfmt, *pdwFlags));
return rc;
} //FindTableFmt
/***LP GetTableSigStr - Get table signature string
*
* ENTRY
* dwTableSig - table signature
*
* EXIT
* returns the table signature string
*/
PSZ LOCAL GetTableSigStr(DWORD dwTableSig)
{
static char szTableSig[5] = {0};
ENTER((2, "GetTableSigStr(TableSig=%08x)\n", dwTableSig));
strncpy(szTableSig, (PSZ)&dwTableSig, sizeof(DWORD));
EXIT((2, "GetTableSigStr=%s\n", szTableSig));
return szTableSig;
} //GetTableSigStr
/***LP ValidateTable - Validate the given table
*
* ENTRY
* pbTable -> Table
* dwLen - Table length
*
* EXIT-SUCCESS
* returns TRUE
* EXIT-FAILURE
* returns FALSE
*/
BOOL LOCAL ValidateTable(PBYTE pbTable, DWORD dwLen)
{
BOOL rc = TRUE;
DWORD dwTableSig, dwTableLen = 0;
BOOL fNeedChkSum = FALSE;
ENTER((2, "ValidateTable(pbTable=%x,Len=%d)\n", pbTable, dwLen));
dwTableSig = ((PDESCRIPTION_HEADER)pbTable)->Signature;
switch (dwTableSig)
{
case SIG_LOW_RSDP:
dwTableLen = sizeof(RSDP);
fNeedChkSum = TRUE;
break;
case RSDT_SIGNATURE:
case FADT_SIGNATURE:
case DSDT_SIGNATURE:
case SSDT_SIGNATURE:
case PSDT_SIGNATURE:
case APIC_SIGNATURE:
case SBST_SIGNATURE:
case SIG_BOOT:
case SIG_DBGP:
dwTableLen = ((PDESCRIPTION_HEADER)pbTable)->Length;
fNeedChkSum = TRUE;
break;
case FACS_SIGNATURE:
dwTableLen = ((PFACS)pbTable)->Length;
break;
default:
if (IsALikelySig(dwTableSig) &&
(((PDESCRIPTION_HEADER)pbTable)->Length < 256))
{
dwTableLen = ((PDESCRIPTION_HEADER)pbTable)->Length;
fNeedChkSum = TRUE;
}
else
{
WARN(("ValidateTable: invalid table signature %s",
GetTableSigStr(dwTableSig)));
rc = FALSE;
}
}
if (dwTableLen > dwLen)
{
WARN(("ValidateTable: invalid length %d in table %s",
dwTableLen, GetTableSigStr(dwTableSig)));
rc = FALSE;
}
if ((rc == TRUE) && fNeedChkSum &&
(ComputeDataChkSum(pbTable, dwTableLen) != 0))
{
WARN(("ValidateTable: invalid checksum in table %s",
GetTableSigStr(dwTableSig)));
rc = FALSE;
}
EXIT((2, "ValidateTable=%x\n", rc));
return rc;
} //ValidateTable
/***LP IsALikelySig - Check if a table signature is possibly valid
*
* ENTRY
* dwTableSig - table signature
*
* EXIT-SUCCESS
* returns TRUE
* EXIT-FAILURE
* returns FALSE
*/
BOOL LOCAL IsALikelySig(DWORD dwTableSig)
{
BOOL rc = TRUE;
int i, ch;
ENTER((2, "IsALikelySig(dwTableSig=%x)\n", dwTableSig));
for (i = 0; i < sizeof(DWORD); ++i)
{
ch = BYTEOF(dwTableSig, i);
if ((ch < 'A') || (ch > 'Z'))
{
rc = FALSE;
break;
}
}
EXIT((2, "IsALikelySig=%x\n", rc));
return rc;
} //IsALikelySig
#endif //ifdef __UNASM