|
|
/*** acpi.c - ACPI VXD to provide table access IOCTLs
* * Author: Michael Tsang (MikeTs) * Created 10/08/97 * * MODIFICATION HISTORY * 10/06/98 YanL Modified to be used in WUBIOS.VXD */
#include "wubiosp.h"
/*** Function prototypes
*/
PRSDT CM_LOCAL FindRSDT(DWORD* pdwRSDTAddr); BYTE CM_LOCAL CheckSum(PBYTE pb, DWORD dwLen); #ifdef TRACING
PSZ CM_LOCAL SigStr(DWORD dwSig); #endif
#pragma CM_PAGEABLE_DATA
#pragma CM_PAGEABLE_CODE
/***LP FindRSDT - Find the RSDT
* * ENTRY * None * * EXIT-SUCCESS * returns the RSDT pointer * EXIT-FAILURE * returns NULL */
PRSDT CM_LOCAL FindRSDT(DWORD* pdwRSDTAddr) { TRACENAME("FINDRSDT") PRSDT pRSDT = NULL; PBYTE pbROM;
ENTER(2, ("FindRSDT()\n"));
if ((pbROM = (PBYTE)_MapPhysToLinear(RSDP_SEARCH_RANGE_BEGIN, RSDP_SEARCH_RANGE_LENGTH, 0)) != (PBYTE)0xffffffff) { PBYTE pbROMEnd; DWORD dwRSDTAddr = 0;
pbROMEnd = pbROM + RSDP_SEARCH_RANGE_LENGTH - RSDP_SEARCH_INTERVAL; while (pbROM != NULL) { if ((((PRSDP)pbROM)->Signature == RSDP_SIGNATURE) && (CheckSum(pbROM, sizeof(RSDP)) == 0)) { dwRSDTAddr = ((PRSDP)pbROM)->RsdtAddress; if (((pbROM = (PBYTE)_MapPhysToLinear(dwRSDTAddr, sizeof(DESCRIPTION_HEADER), 0)) == (PBYTE)0xffffffff) || (((PDESCRIPTION_HEADER)pbROM)->Signature != RSDT_SIGNATURE)) { pbROM = NULL; } break; } else { pbROM += RSDP_SEARCH_INTERVAL; if (pbROM > pbROMEnd) { pbROM = NULL; } } }
if (pbROM != NULL) { DWORD dwLen = ((PDESCRIPTION_HEADER)pbROM)->Length;
pRSDT = (PRSDT)_MapPhysToLinear(dwRSDTAddr, dwLen, 0); if ((pRSDT == (PRSDT)0xffffffff) || (CheckSum((PBYTE)pRSDT, dwLen) != 0)) { pRSDT = NULL; } *pdwRSDTAddr = dwRSDTAddr; } }
EXIT(2, ("FindRSDT=%x\n", pRSDT)); return pRSDT; } //FindRSDT
/***LP AcpiFindTable - Find an ACPI Table
* * ENTRY * dwSig - signature of the table * pdwLen -> to hold length of table (can be NULL) * * EXIT-SUCCESS * returns physical address of table * EXIT-FAILURE * returns 0 */
DWORD CM_INTERNAL AcpiFindTable(DWORD dwSig, PDWORD pdwLen) { TRACENAME("AcpiFindTable") DWORD dwPhyAddr = 0; static PRSDT pRSDT = (PRSDT)0xffffffff; static DWORD dwRSDTAddr;
ENTER(2, ("AcpiFindTable(Sig=%s,pdwLen=%x)\n", SigStr(dwSig), pdwLen));
if (pRSDT == (PRSDT)0xffffffff) { pRSDT = FindRSDT(&dwRSDTAddr); }
if (pRSDT != NULL) { PDESCRIPTION_HEADER pdh = NULL;
if (dwSig == RSDT_SIGNATURE) { *pdwLen = ((PDESCRIPTION_HEADER)pRSDT)->Length; dwPhyAddr = dwRSDTAddr; } else if (dwSig == DSDT_SIGNATURE) { DWORD dwLen; PFADT pFADT;
if (((dwPhyAddr = AcpiFindTable(FADT_SIGNATURE, &dwLen)) != 0) && ((pFADT = (PFADT)_MapPhysToLinear(dwPhyAddr, dwLen, 0)) != (PFADT)0xffffffff)) { dwPhyAddr = pFADT->dsdt; if ((pdh = (PDESCRIPTION_HEADER)_MapPhysToLinear( dwPhyAddr, sizeof(DESCRIPTION_HEADER), 0)) == (PDESCRIPTION_HEADER)0xffffffff) { dwPhyAddr = 0; } } else { dwPhyAddr = 0; } } else { int i, iNumTables = NumTableEntriesFromRSDTPointer(pRSDT);
for (i = 0; i < iNumTables; ++i) { dwPhyAddr = pRSDT->Tables[i]; if (((pdh = (PDESCRIPTION_HEADER)_MapPhysToLinear( dwPhyAddr, sizeof(DESCRIPTION_HEADER), 0)) != (PDESCRIPTION_HEADER)0xffffffff)) { if (pdh->Signature == dwSig && (CheckSum((PBYTE)pdh, pdh->Length) == 0) ) { break; } } }
if (i >= iNumTables) { dwPhyAddr = 0; } }
if ((dwPhyAddr != 0) && (pdwLen != NULL)) { *pdwLen = pdh->Length; } }
EXIT(2, ("AcpiFindTable=%x (Len=%x)\n", dwPhyAddr, pdwLen? *pdwLen: 0)); return dwPhyAddr; } //AcpiFindTable
/***LP AcpiCopyROM - Copy ROM memory to buffer
* * ENTRY * dwPhyAddr - physical address of ROM location * pbBuff -> buffer * dwLen - buffer length * * EXIT * None */
VOID CM_INTERNAL AcpiCopyROM(DWORD dwPhyAddr, PBYTE pbBuff, DWORD dwLen) { TRACENAME("AcpiCopyROM") PBYTE pbROM;
ENTER(2, ("AcpiCopyROM(PhyAddr=%x,pbBuff=%x,Len=%x)\n", dwPhyAddr, pbBuff, dwLen));
if ((pbROM = (PBYTE)_MapPhysToLinear(dwPhyAddr, dwLen, 0)) != (PBYTE)0xffffffff) { memcpy(pbBuff, pbROM, dwLen); }
EXIT(2, ("AcpiCopyROM!\n")); } //AcpiCopyROM
#ifdef TRACING
/***LP SigStr - return string of DWORD signature
* * ENTRY * dwSig - signature * * EXIT * returns signature string */
PSZ CM_LOCAL SigStr(DWORD dwSig) { static char szSig[sizeof(DWORD) + 1] = {0};
memcpy(szSig, &dwSig, sizeof(DWORD));
return (PSZ)szSig; } //SigStr
#endif
|