Note: Dump ACPI/FADT context

The program use Sysinfo driver, get from CrystalCPUID  project

// FindRSDP.cpp : Defines the entry point for the console application.
//

#include “stdafx.h"
#include “.SysInfoISysInfo.h"
#include “.SysInfoItemID.h"

typedef ISysInfo* (*_CreateSysInfo) (DWORD);
typedef void (*_DestroySysInfo) (ISysInfo*);
typedef ULONG    (*_MemReadBlock) (ULONG address, UCHAR* data, ULONG count, ULONG unitsize);

#pragma pack(push)
#pragma pack(1)
typedef struct
{
UCHAR Signature[8];
UCHAR Chksum;
UCHAR OEMID[6];
UCHAR Revision;
ULONG pRSDT;
ULONG Length;
ULONG64 pXSDT;
UCHAR XChksum;
UCHAR Reserved[3];
} RSDP;

typedef struct
{
UCHAR Signature[4];
ULONG Length;
UCHAR Revision;
UCHAR Chksum;
UCHAR OEMID[6];
UCHAR OEMTID[8];
ULONG OEMRev;
ULONG CreatorID;
ULONG CreatorRev;
} ACPI_TABLE_HEADER;

// Generic Address Structure, ref. Table 5-1 in ACPI spec.
typedef struct
{
UCHAR AddrSpace;
UCHAR RegBitWidth;
UCHAR RegBitOffset;
UCHAR AccessSize;
ULONG64 Addr;
} GAS;

typedef struct
{
ACPI_TABLE_HEADER TableHeader;
ULONG Firmware_Ctrl;
ULONG pDSDT;
UCHAR Revsered;
UCHAR PeferredPMProfile;
UINT16 SCI_INT;
ULONG  SMI_CMD;
UCHAR ACPI_ENABLE;
UCHAR ACPI_DISABLE;
UCHAR S4BIOS_REQ;
UCHAR PSTAT_CNT;
ULONG PM1a_EVT_BLK;
ULONG PM1b_EVT_BLK;
ULONG PM1a_CNT_BLK;
ULONG PM1b_CNT_BLK;
ULONG PM2_CNT_BLK;
ULONG PM_TMR_BLK;
ULONG GPE0_BLK;
ULONG GPE1_BLK;
UCHAR PM1_EVT_LEN;
UCHAR PM1_CNT_LEN;
UCHAR PM2_CNT_LEN;
UCHAR PM_TMR_LEN;
UCHAR GPE0_BLK_LEN;
UCHAR GPE1_BLK_LEN;
UCHAR GPE1_BASE;
UCHAR CST_CNT;
UINT16 P_LVL2_LAT;
UINT16 P_LVL3_LAT;
UINT16 FLUSH_SIZE;
UINT16 FLUSH_STRIDE;
UCHAR DUTY_OFFSET;
UCHAR DUTY_WIDTH;
UCHAR DAY_ALARM;
UCHAR MONTH_ALARM;
UCHAR CENTURY;
UINT16 IAPC_BOOT_ARCH;
UCHAR Reserved1;
ULONG Flags;
GAS      RESET_REG;
UCHAR RESET_VAL;
} FADT;

typedef struct
{
FADT fadt;
UCHAR Reserved2[3];
ULONG64 X_Firmware_CTRL;
ULONG64 X_DSDT;
GAS X_PM1a_EVT_BLK;
GAS X_PM1b_EVT_BLK;
GAS X_PM1a_CNT_BLK;
GAS X_PM1b_CNT_BLK;
GAS X_PM2_CNT_BLK;
GAS X_PM_TMR_BLK;
GAS X_GPE0_BLK;
GAS X_GPE1_BLK;
} XFADT;

#pragma pack(pop)

bool LoadSysInfo(HMODULE &hSysInfoLib, ISysInfo* pISysInfo)
{
hSysInfoLib = LoadLibrary(_T(“SysInfo.dll"));

if (NULL != hSysInfoLib)
{
_CreateSysInfo pCreateSysInfo = (_CreateSysInfo)GetProcAddress(hSysInfoLib, “CreateSysInfo");

if (NULL != pCreateSysInfo)
{
pISysInfo = pCreateSysInfo(MODE_PCI); // request access memory spaces, MODE_PCI
}
else
{
printf(“ERR: Failed in GetProcAddress(“CreateSysInfo")n");
exit(-1);
return false;
}
}
else
{
printf(“Can’t find Sysinfo.dlln");
exit(-1);
return false;
}
return true;
}

bool UnloadSysInfo(HMODULE hSysInfoLib, ISysInfo* pISysInfo)
{
_DestroySysInfo pDestroySysInfo = (_DestroySysInfo)GetProcAddress(hSysInfoLib, “DestroySysInfo");
if (pDestroySysInfo)
{
pDestroySysInfo(pISysInfo);
pISysInfo = NULL;
}
else
{
printf(“ERR: Failed in GetProcAddress(“DestroySysInfo")n");
exit(-1);
return false;
}
FreeLibrary(hSysInfoLib);
hSysInfoLib = NULL;
return true;
}

UCHAR* toString(const UCHAR* src, int len)
{
static UCHAR buff[256];
memcpy(buff, src, len);
buff[len] = 0;
return buff;
}

const char* strPMProfile(UCHAR val)
{
const char* strProfile[9] = {
“Unspecified",
“Desktop",
“Mobile",
“Workstation",
“Enterprise Server",
“SOHO Server",
“Appliance PC",
“Performance Server",
“Reserved",
};

if(val > 8) val = 8;

return strProfile[val];
}

const char* strAddrSpace(UCHAR val)
{
const char* strSpace[5] = {
“Memory",
“I/O",
“PCI Configuration",
“Function Fix Hardware",
“Reserved"
};

if (val == 3) val = 5;
if (val == 0x7F) val = 3;
if (val > 4) val = 4;

return strSpace[val];
}

void printRSDP(RSDP *pRSDP)
{
printf(“CheckSum: 0x%Xn", pRSDP->Chksum);
printf(“OEM ID: %sn", toString(pRSDP->OEMID,6));
printf(“Revision: 0x%Xn", pRSDP->Revision);
printf(“RSDT Address: 0x%Xn", pRSDP->pRSDT);
printf(“Length of the Table: %d(0x%X)n", pRSDP->Length, pRSDP->Length);
printf(“XSDT Address: 0x%Xn", pRSDP->pXSDT);
printf(“Extended Checksum 0x%Xn", pRSDP->XChksum);
}

void printACPITableHeader(ACPI_TABLE_HEADER &table,ULONG addr)
{
printf(“-==================================================-n");
printf(“Table: %s, at 0x%Xn", toString(table.Signature, 4), addr);
printf(“Length of the Table: %dn", table.Length);
printf(“Revision: 0x%Xn", table.Revision);
printf(“Checksum: 0x%Xn", table.Chksum);
printf(“OEMID: %sn", toString(table.OEMID, 6));
printf(“OEM Table ID: %sn", toString(table.OEMTID, 8));
printf(“OEM Revision: 0x%Xn",table.OEMRev);
printf(“Creator ID: %sn", toString((UCHAR*)&table.CreatorID, 4));
printf(“Creator Revision 0x%Xn", table.CreatorRev);
}

void printRSDT(ACPI_TABLE_HEADER &RSDT, ULONG addr)
{
printACPITableHeader(RSDT, addr);
printf(“Entry count : %dn", (RSDT.Length-sizeof(ACPI_TABLE_HEADER))/4);
}

void printFADT(FADT& fadt)
{
printf(“tFirmware Ctrl(FACS): 0x%Xn", fadt.Firmware_Ctrl);
printf(“tDSDT: 0x%Xn", fadt.pDSDT);
printf(“tPeferred_PM_Profile:%s(%d)n",
strPMProfile(fadt.PeferredPMProfile), fadt.PeferredPMProfile);
printf(“tSCI_INT: %d(0x%X)n", fadt.SCI_INT, fadt.SCI_INT);
printf(“tSMI_CMD: %d(0x%X)n", fadt.SMI_CMD, fadt.SMI_CMD);
printf(“tACPI_ENABLE: 0x%Xn", fadt.ACPI_ENABLE);
printf(“tACPI_DISABLE: 0x%Xn", fadt.ACPI_DISABLE);
printf(“tS4BIOS_REQ: 0x%Xn", fadt.S4BIOS_REQ);
printf(“tPSTAT_CNT: 0x%Xn", fadt.PSTAT_CNT);
printf(“tPM1a_EVT_BLK: 0x%Xn", fadt.PM1a_EVT_BLK);
printf(“tPM1b_EVT_BLK: 0x%Xn", fadt.PM1b_EVT_BLK);
printf(“tPM1a_CNT_BLK: 0x%Xn", fadt.PM1a_CNT_BLK);
printf(“tPM1b_CNT_BLK: 0x%Xn", fadt.PM1b_CNT_BLK);
printf(“tPM2_CNT_BLK: 0x%Xn", fadt.PM2_CNT_BLK);
printf(“tPM_TMR_BLK: 0x%Xn", fadt.PM_TMR_BLK);
printf(“tGPE0_BLK: 0x%Xn", fadt.GPE0_BLK);
printf(“tGPE1_BLK: 0x%Xn", fadt.GPE1_BLK);
printf(“tPM1_EVT_LEN: 0x%Xn", fadt.PM1_EVT_LEN);
printf(“tPM1_CNT_LEN: 0x%Xn", fadt.PM1_CNT_LEN);
printf(“tPM2_CNT_LEN: 0x%Xn", fadt.PM2_CNT_LEN);
printf(“tPM_TMR_LEN: 0x%Xn", fadt.PM_TMR_LEN);
printf(“tGPE0_BLK_LEN: 0x%Xn", fadt.GPE0_BLK_LEN);
printf(“tGPE1_BLK_LEN: 0x%Xn", fadt.GPE1_BLK_LEN);
printf(“tGPE1_BASE: 0x%Xn", fadt.GPE1_BASE);
printf(“tCST_CNT: 0x%Xn", fadt.CST_CNT);
printf(“tP_LVL2_LAT: 0x%Xn", fadt.P_LVL2_LAT);
printf(“tP_LVL3_LAT: 0x%Xn", fadt.P_LVL3_LAT);
printf(“tFLUSH_SIZE: 0x%Xn", fadt.FLUSH_SIZE);
printf(“tFLUSH_STRIDE: 0x%Xn", fadt.FLUSH_STRIDE);
printf(“tDuty Offset: 0x%Xn", fadt.DUTY_OFFSET);
printf(“tDuty Width: 0x%Xn", fadt.DUTY_WIDTH);
printf(“tDay Alarm: %dn", fadt.DAY_ALARM);
printf(“tMonth Alarm: %dn", fadt.MONTH_ALARM);
printf(“tCentury: 0x%Xn", fadt.CENTURY);
printf(“tIA Boot Architecture: 0x%Xn", fadt.IAPC_BOOT_ARCH);
printf(“tFlags: 0x%Xn", fadt.Flags);
printf(“tRESET Reg:nt  Address Space: %s(%d)n",
strAddrSpace(fadt.RESET_REG.AddrSpace), fadt.RESET_REG.AddrSpace);
printf(“t  BitWidth: 0x%X,n", fadt.RESET_REG.RegBitWidth);
printf(“t  BitOffset: 0x%X,n", fadt.RESET_REG.RegBitOffset);
printf(“t  AccessSize: 0x%X, n", fadt.RESET_REG.AccessSize);
printf(“t  Address:0x%Xn",    fadt.RESET_REG.Addr);
printf(“tReset Val: 0x%Xn", fadt.RESET_VAL);
}

int _tmain(int argc, _TCHAR* argv[])
{
ISysInfo* pISysInfo = NULL;
HMODULE hSysInfoLib = NULL;
const ULONG MEM_RANGE = 64*1024*2; // 0xE0000 ~ 0xFFFFF, segment 64K x 2
const ULONG MEM_START = 0xE0000;
UCHAR buff[MEM_RANGE];
if (false == LoadSysInfo(hSysInfoLib, pISysInfo))
return -1;

_MemReadBlock pfMemReadBlock = (_MemReadBlock) GetProcAddress(hSysInfoLib, “_MemReadBlock");
if (pfMemReadBlock)
{
pfMemReadBlock(MEM_START, buff, MEM_RANGE, sizeof(UCHAR));
}
else
{
printf(“ERR: failed in GetProcAddress(“_MemReadBlock")n");
}
if (pfMemReadBlock)
{
UCHAR *p = buff;
RSDP * pRSDP = NULL;
for (int i = 0; i < MEM_RANGE; i+=16)
{
if (0 == memcmp(p, “RSD PTR “, 8))
{
// Calc chksum,
// This includes only the first 20 bytes of this table,
// bytes 0 to 19, including the checksum field.
// These bytes must sum to zero.
UCHAR chksum = 0;
for(UCHAR *pc = p; pc < p+20; pc++)
{
chksum += *pc;
}

if (0 == chksum)
{
pRSDP = (RSDP*)p;
printf(“Find the Root System Description Table at 0x%Xn",MEM_START+i);
printRSDP(pRSDP);
}
// find out RSDP
if (pRSDP)
{
ACPI_TABLE_HEADER RSDT;
pfMemReadBlock(pRSDP->pRSDT, (UCHAR*)&RSDT, sizeof(RSDT), 1);
printRSDT(RSDT, pRSDP->pRSDT);

ULONG Entry[64];
int n = (RSDT.Length – sizeof(ACPI_TABLE_HEADER))/4;

if (n > 64) n = 64; // limit max. 63;

pfMemReadBlock(pRSDP->pRSDT + sizeof(ACPI_TABLE_HEADER),
(UCHAR*)&Entry[0], 4*n, 1);

ACPI_TABLE_HEADER ACPITab;
for (int i = 0; i < n; i++)
{
pfMemReadBlock(Entry[i], (UCHAR*)&ACPITab, sizeof(ACPI_TABLE_HEADER), 1);
if (memcmp(ACPITab.Signature, “FACP", 4) == 0)
{
XFADT xfadt;
memset(&xfadt, 0, sizeof(XFADT));
pfMemReadBlock(Entry[i], (UCHAR*)&xfadt, ACPITab.Length, 1);
printACPITableHeader(xfadt.fadt.TableHeader, Entry[i]);
printFADT(xfadt.fadt);
}
else
{
printACPITableHeader(ACPITab, Entry[i]);
}
}

}
break;
}
p+=16;
}

}

UnloadSysInfo(hSysInfoLib, pISysInfo);
return 0;
}

 

Result, Run the program

-==================================================-
Table: FACP, at 0xBF6D1B00
Length of the Table: 129
Revision: 0x2
Checksum: 0xF5
OEMID: LENOVO
OEM Table ID: TP-7B
OEM Revision: 0x2180
Creator ID: LNVO
Creator Revision 0x1
Firmware Ctrl(FACS): 0xBF6F4000
DSDT: 0xBF6D1D90
Peferred_PM_Profile:Mobile(2)
SCI_INT: 9(0x9)
SMI_CMD: 178(0xB2)
ACPI_ENABLE: 0xF0
ACPI_DISABLE: 0xF1
S4BIOS_REQ: 0x0
PSTAT_CNT: 0xF3
PM1a_EVT_BLK: 0x1000
PM1b_EVT_BLK: 0x0
PM1a_CNT_BLK: 0x1004
PM1b_CNT_BLK: 0x0
PM2_CNT_BLK: 0x1020
PM_TMR_BLK: 0x1008
GPE0_BLK: 0x1028
GPE1_BLK: 0x0
PM1_EVT_LEN: 0x4
PM1_CNT_LEN: 0x2
PM2_CNT_LEN: 0x1
PM_TMR_LEN: 0x4
GPE0_BLK_LEN: 0x8
GPE1_BLK_LEN: 0x0
GPE1_BASE: 0x0
CST_CNT: 0x85
P_LVL2_LAT: 0x1
P_LVL3_LAT: 0x23
FLUSH_SIZE: 0x0
FLUSH_STRIDE: 0x0
Duty Offset: 0x1
Duty Width: 0x3
Day Alarm: 13
Month Alarm: 0
Century: 0x32
IA Boot Architecture: 0x12
Flags: 0xC2AD
RESET Reg:
Address Space: I/O(1)
BitWidth: 0x8,
BitOffset: 0x0,
AccessSize: 0x0,
Address:0xCF9
Reset Val: 0x6

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: