|
|
/*** misc.c - Miscellaneous functions
* * Copyright (c) 1996,1997 Microsoft Corporation * Author: Michael Tsang (MikeTs) * Created 11/18/96 * * MODIFICATION HISTORY */
#include "pch.h"
#ifdef LOCKABLE_PRAGMA
#pragma ACPI_LOCKABLE_DATA
#pragma ACPI_LOCKABLE_CODE
#endif
/***LP InitializeMutex - initialize mutex
* * ENTRY * pmut -> MUTEX * * EXIT * None */
VOID LOCAL InitializeMutex(PMUTEX pmut) { TRACENAME("INITIALIZEMUTEX")
ENTER(3, ("InitializeMutex(pmut=%x)\n", pmut));
KeInitializeSpinLock(&pmut->SpinLock); pmut->OldIrql = PASSIVE_LEVEL;
EXIT(3, ("InitializeMutex!\n")); } //InitializeMutex
/***LP AcquireMutex - acquire mutex
* * ENTRY * pmut -> MUTEX * * EXIT-SUCCESS * returns TRUE * EXIT-FAILURE * returns FALSE * * NOTE * AcquireMutex can be called at DISPATCH_LEVEL as long as the mutex * is unowned or owned by the same thread. If the mutex is owned by * some other thread, this thread cannot block if we are at * DISPATCH_LEVEL and therefore would fail to acquire the mutex. */
BOOLEAN LOCAL AcquireMutex(PMUTEX pmut) { TRACENAME("ACQUIREMUTEX") BOOLEAN rc = TRUE;
ENTER(3, ("AcquireMutex(pmut=%x)\n", pmut));
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); KeAcquireSpinLock(&pmut->SpinLock, &pmut->OldIrql);
EXIT(3, ("AcquireMutex=%x\n", rc)); return rc; } //AcquireMutex
/***LP ReleaseMutex - release mutex
* * ENTRY * pmut -> MUTEX * * EXIT-SUCCESS * returns TRUE * EXIT-FAILURE * returns FALSE */
BOOLEAN LOCAL ReleaseMutex(PMUTEX pmut) { TRACENAME("RELEASEMUTEX") BOOLEAN rc = TRUE;
ENTER(3, ("ReleaseMutex(pmut=%x)\n", pmut));
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); KeReleaseSpinLock(&pmut->SpinLock, pmut->OldIrql);
EXIT(3, ("ReleaseMutex!\n")); return rc; } //ReleaseMutex
/***LP FindOpcodeTerm - find the AMLTERM for the given opcode
* * ENTRY * dwOp - opcode * pOpTable -> opcode table * * EXIT-SUCCESS * returns pointer to the opcode's AMLTERM * EXIT-FAILURE * returns NULL */
PAMLTERM LOCAL FindOpcodeTerm(ULONG dwOp, POPCODEMAP pOpTable) { TRACENAME("FINDOPCODETERM") PAMLTERM pamlterm = NULL;
ENTER(3, ("FindOpcodeTerm(Op=%x,pOpTable=%x)\n", dwOp, pOpTable));
while (pOpTable->pamlterm != NULL) { if (dwOp == pOpTable->dwOpcode) { pamlterm = pOpTable->pamlterm; break; } else pOpTable++; }
EXIT(3, ("FindOpcodeTerm=%x\n", pamlterm)); return pamlterm; } //FindOpcodeTerm
/***LP GetHackFlags - Get the hack flags from the registry
* * ENTRY * pdsdt -> AML table * * EXIT-SUCCESS * returns the hack flags read * EXIT-FAILURE * returns zero */
ULONG LOCAL GetHackFlags(PDSDT pdsdt) { TRACENAME("GETHACKFLAGS") ULONG dwfHacks = 0, dwcb; static PSZ pszHackFlags = "AMLIHackFlags";
ENTER(3, ("GetHackFlags(pdsdt=%x)\n", pdsdt));
if (pdsdt == NULL) { dwcb = sizeof(dwfHacks); OSReadRegValue(pszHackFlags, (HANDLE)NULL, &dwfHacks, &dwcb); } else { ULONG dwLen, i; PSZ pszRegPath; HANDLE hRegKey; NTSTATUS status;
dwLen = STRLEN(ACPI_PARAMETERS_REGISTRY_KEY) + ACPI_MAX_TABLE_STRINGS + 8 + 5;
if ((pszRegPath = ExAllocatePoolWithTag(PagedPool, dwLen, PRIV_TAG)) != NULL) { STRCPY(pszRegPath, ACPI_PARAMETERS_REGISTRY_KEY); STRCAT(pszRegPath, "\\"); STRCATN(pszRegPath, (PSZ)&pdsdt->Header.Signature, ACPI_MAX_SIGNATURE); STRCAT(pszRegPath, "\\"); STRCATN(pszRegPath, (PSZ)pdsdt->Header.OEMID, ACPI_MAX_OEM_ID); STRCAT(pszRegPath, "\\"); STRCATN(pszRegPath, (PSZ)pdsdt->Header.OEMTableID, ACPI_MAX_TABLE_ID); STRCAT(pszRegPath, "\\"); ULTOA(pdsdt->Header.OEMRevision, &pszRegPath[STRLEN(pszRegPath)], 16); dwLen = STRLEN(pszRegPath); for (i = 0; i < dwLen; i++) { if (pszRegPath[i] == ' ') { pszRegPath[i] = '_'; } }
status = OSOpenHandle(pszRegPath, NULL, &hRegKey); if (NT_SUCCESS(status)) { dwcb = sizeof(dwfHacks); OSReadRegValue(pszHackFlags, hRegKey, &dwfHacks, &dwcb); } ExFreePool(pszRegPath); } }
EXIT(3, ("GetHackFlags=%x\n", dwfHacks)); return dwfHacks; } //GetHackFlags
/***LP GetBaseObject - If object type is OBJALIAS, follow the chain to the base
* * ENTRY * pnsObj -> object * * EXIT * returns the base object */
PNSOBJ LOCAL GetBaseObject(PNSOBJ pnsObj) { TRACENAME("GETBASEOBJECT")
ENTER(3, ("GetBaseObject(pnsObj=%s)\n", GetObjectPath(pnsObj)));
while (pnsObj->ObjData.dwDataType == OBJTYPE_OBJALIAS) { pnsObj = pnsObj->ObjData.pnsAlias; }
EXIT(3, ("GetBaseObject=%s\n", GetObjectPath(pnsObj))); return pnsObj; } //GetBaseObject
/***LP GetBaseData - If object type is DATAALIAS, follow the chain to the base
* * ENTRY * pdataObj -> object * * EXIT * returns the base object */
POBJDATA LOCAL GetBaseData(POBJDATA pdataObj) { TRACENAME("GETBASEDATA")
ENTER(3, ("GetBaseData(pdataObj=%x)\n", pdataObj));
ASSERT(pdataObj != NULL); for (;;) { if (pdataObj->dwDataType == OBJTYPE_OBJALIAS) { pdataObj = &pdataObj->pnsAlias->ObjData; } else if (pdataObj->dwDataType == OBJTYPE_DATAALIAS) { pdataObj = pdataObj->pdataAlias; } else { break; } }
EXIT(3, ("GetBaseData=%x\n", pdataObj)); return pdataObj; } //GetBaseData
/***LP NewObjOwner - create a new object owner
* * ENTRY * pheap -> HEAP * ppowner -> to hold new owner pointer * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL NewObjOwner(PHEAP pheap, POBJOWNER *ppowner) { TRACENAME("NEWOBJOWNER") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("NewObjOwner(pheap=%x,ppowner=%x)\n", pheap, ppowner));
if ((*ppowner = NEWOOOBJ(pheap, sizeof(OBJOWNER))) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("NewObjOwner: failed to allocate object owner")); } else {
MEMZERO(*ppowner, sizeof(OBJOWNER)); (*ppowner)->dwSig = SIG_OBJOWNER;
AcquireMutex(&gmutOwnerList); ListInsertTail(&(*ppowner)->list, &gplistObjOwners); ReleaseMutex(&gmutOwnerList);
}
EXIT(3, ("NewObjOwner=%x (powern=%x)\n", rc, *ppowner)); return rc; } //NewObjOwner
/***LP FreeObjOwner - free object owner
* * ENTRY * powner -> OBJOWNER * fUnload - if TRUE, the caller is unloading a DDB * * EXIT * None */
VOID LOCAL FreeObjOwner(POBJOWNER powner, BOOLEAN fUnload) { TRACENAME("FREEOBJOWNER") KIRQL oldIrql; PNSOBJ pns; PNSOBJ pnsNext = NULL; PNSOBJ pnsPrev = NULL; PNSOBJ pnsDeviceList = NULL; PNSOBJ pnsChild = NULL;
ENTER(3, ("FreeObjOwner(powner=%x,fUnload=%x)\n", powner,fUnload));
ASSERT(powner != NULL);
AcquireMutex(&gmutOwnerList); ListRemoveEntry(&powner->list, &gplistObjOwners); ReleaseMutex(&gmutOwnerList);
if (fUnload && (ghDestroyObj.pfnHandler != NULL)) {
//
// First we have to tell the driver that we are about to
// do walk the owner list so that we can seek and destroy
// the objects
//
((PFNDOBJ)ghDestroyObj.pfnHandler)(DESTROYOBJ_START, &oldIrql, 0);
//
// First pass, mark the objects defunc'd.
//
for (pns = powner->pnsObjList; pns != NULL; pns = pns->pnsOwnedNext) {
pns->ObjData.dwfData |= DATAF_NSOBJ_DEFUNC;
}
//
// Second pass, find the device in the list to be removed
//
for (pns = powner->pnsObjList; pns != NULL; pns = pnsNext) {
pnsNext = pns->pnsOwnedNext; if (pns->ObjData.dwDataType == OBJTYPE_DEVICE || pns->ObjData.dwDataType == OBJTYPE_POWERRES || pns->ObjData.dwDataType == OBJTYPE_THERMALZONE || pns->ObjData.dwDataType == OBJTYPE_PROCESSOR) {
if (pnsPrev) {
pnsPrev->pnsOwnedNext = pns->pnsOwnedNext;
} else {
powner->pnsObjList = pns->pnsOwnedNext;
} pns->pnsOwnedNext = pnsDeviceList; pnsDeviceList = pns;
//
// Detach the device from its parent
//
if (pns->pnsParent != NULL) {
ListRemoveEntry( &pns->list, (PPLIST)&pns->pnsParent->pnsFirstChild ); pns->pnsParent = NULL;
}
//
// Make sure that all of the device's children have been
// marked as being unloaded
//
if (pns->pnsFirstChild) {
pnsChild = pns->pnsFirstChild; do {
if (!(pnsChild->ObjData.dwfData & DATAF_NSOBJ_DEFUNC) ) {
((PFNDOBJ)ghDestroyObj.pfnHandler)( DESTROYOBJ_CHILD_NOT_FREED, pnsChild, 0 );
} pnsChild = (PNSOBJ) pnsChild->list.plistNext;
} while (pnsChild != pns->pnsFirstChild);
} //
// Not that if we don't put this continue in here, then
// it becomes possible for pnsPrev to point to a device,
// which would corrupt the list
continue;
} else if (pns->pnsParent == NULL || !(pns->pnsParent->ObjData.dwfData & DATAF_NSOBJ_DEFUNC)) {
((PFNDOBJ)ghDestroyObj.pfnHandler)( DESTROYOBJ_BOGUS_PARENT, pns, 0 );
} pnsPrev = pns;
}
//
// Chain the two lists back together
//
if (powner->pnsObjList == NULL) {
powner->pnsObjList = pnsDeviceList;
} else {
//
// Find a pointer to the last element in the list
//
pns = powner->pnsObjList;
while ( pns->pnsOwnedNext != NULL ) {
//
// Next element in the list
//
pns = pns->pnsOwnedNext;
}
pns->pnsOwnedNext = pnsDeviceList; }
// //
// Third pass pass, do callback for each device that is going away
//
for (pns = pnsDeviceList; pns != NULL; pns = pnsNext) {
//
// Remember what the next point is because we might nuke
// the current object in the callback (if there is no
// device extension associated with it
//
pnsNext = pns->pnsOwnedNext;
//
// Issue the callback. This might nuke the pnsObject
//
((PFNDOBJ)ghDestroyObj.pfnHandler)( DESTROYOBJ_REMOVE_OBJECT, pns, pns->ObjData.dwDataType );
}
//
// We end by tell the ACPI driver that we have finished looking
// at the list
//
((PFNDOBJ)ghDestroyObj.pfnHandler)(DESTROYOBJ_END, &oldIrql, 0 );
} else { for (pns = powner->pnsObjList; pns != NULL; pns = pnsNext) { pnsNext = pns->pnsOwnedNext; FreeNameSpaceObjects(pns); } } powner->pnsObjList = NULL; FREEOOOBJ(powner);
EXIT(3, ("FreeObjOwner!\n")); } //FreeObjOwner
/***LP InsertOwnerObjList - Insert the new object into the owner's object list
* * ENTRY * powner -> owner * pnsObj -> new object * * EXIT * None */
VOID LOCAL InsertOwnerObjList(POBJOWNER powner, PNSOBJ pnsObj) { TRACENAME("INSERTOWNEROBJLIST")
ENTER(3, ("InsertOwnerObjList(powner=%x,pnsObj=%x)\n", powner, pnsObj));
pnsObj->hOwner = (HANDLE)powner; if (powner != NULL) { pnsObj->pnsOwnedNext = powner->pnsObjList; powner->pnsObjList = pnsObj; }
EXIT(3, ("InsertOwnerObjList!\n")); } //InsertOwnerObjList
/***LP FreeDataBuffs - Free any buffers attached to OBJDATA array
* * ENTRY * adata -> OBJDATA array * icData - number of data object in array * * EXIT * None */
VOID LOCAL FreeDataBuffs(POBJDATA adata, int icData) { TRACENAME("FREEDATABUFFS") int i;
ENTER(3, ("FreeDataBuffs(adata=%x,icData=%d)\n", adata, icData));
for (i = 0; i < icData; ++i) { if (adata[i].pbDataBuff != NULL) { if (adata[i].dwfData & DATAF_BUFF_ALIAS) { //
// decrement the base object's reference count.
//
adata[i].pdataBase->dwRefCount--; } else { //
// We cannot free a base object buffer that has aliases on it.
//
ASSERT(adata[i].dwRefCount == 0); if (adata[i].dwDataType == OBJTYPE_PKGDATA) { PPACKAGEOBJ ppkg = (PPACKAGEOBJ)adata[i].pbDataBuff;
FreeDataBuffs(ppkg->adata, ppkg->dwcElements); } ENTER(4, ("FreeData(i=%d,Buff=%x,Flags=%x)\n", i, adata[i].pbDataBuff, adata[i].dwfData)); FREEOBJDATA(&adata[i]); EXIT(4, ("FreeData!\n")); } }
MEMZERO(&adata[i], sizeof(OBJDATA)); }
EXIT(3, ("FreeDataBuff!\n")); } //FreeDataBuffs
/***LP PutIntObjData - put integer data into data object
* * ENTRY * pctxt -> CTXT * pdataObj -> data object * dwData -> data to be written * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL PutIntObjData(PCTXT pctxt, POBJDATA pdataObj, ULONG dwData) { TRACENAME("PUTINTOBJDATA") NTSTATUS rc = STATUS_SUCCESS; OBJDATA data;
ENTER(3, ("PutIntObjData(pctxt=%x,pdataObj=%x,dwData=%x)\n", pctxt, pdataObj, dwData));
MEMZERO(&data, sizeof(OBJDATA)); data.dwDataType = OBJTYPE_INTDATA; data.uipDataValue = (ULONG_PTR)dwData;
rc = WriteObject(pctxt, pdataObj, &data);
EXIT(3, ("PutIntObjData=%x\n", rc)); return rc; } //PutIntObjData
/***LP GetFieldUnitRegionObj - Get the OperationRegion object of FieldUnit
* * ENTRY * pfu -> FIELDUNITOBJ * ppns -> to hold OperationRegion object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL GetFieldUnitRegionObj(PFIELDUNITOBJ pfu, PPNSOBJ ppns) { TRACENAME("GETFIELDUNITREGIONOBJ") NTSTATUS rc = STATUS_SUCCESS; PNSOBJ pns;
ENTER(3, ("GetFieldUnitRegionObj(pfu=%x,ppns=%x)\n", pfu, ppns));
pns = pfu->pnsFieldParent; switch (pns->ObjData.dwDataType) { case OBJTYPE_BANKFIELD: *ppns = ((PBANKFIELDOBJ)pns->ObjData.pbDataBuff)->pnsBase; break;
case OBJTYPE_FIELD: *ppns = ((PFIELDOBJ)pns->ObjData.pbDataBuff)->pnsBase; break;
case OBJTYPE_INDEXFIELD: pns = ((PINDEXFIELDOBJ)pns->ObjData.pbDataBuff)->pnsData; ASSERT(pns->ObjData.dwDataType == OBJTYPE_FIELDUNIT); rc = GetFieldUnitRegionObj((PFIELDUNITOBJ)pns->ObjData.pbDataBuff, ppns); break;
default: rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("GetFieldUnitRegionObj: unknown field unit parent object type - %x", (*ppns)->ObjData.dwDataType)); }
if ((*ppns != NULL) && ((*ppns)->ObjData.dwDataType != OBJTYPE_OPREGION)) { rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("GetFieldUnitRegionObj: base object of field unit is not OperationRegion (BaseObj=%s,Type=%x)", GetObjectPath(*ppns), (*ppns)->ObjData.dwDataType)); }
EXIT(3, ("GetFieldUnitRegionObj=%x (RegionObj=%x:%s)\n", rc, *ppns, GetObjectPath(*ppns))); return rc; } //GetFieldUnitRegionObj
/***LP CopyObjData - Copy object data
* * ENTRY * pdataDst -> target object * pdataSrc -> source object * * EXIT * None */
VOID LOCAL CopyObjData(POBJDATA pdataDst, POBJDATA pdataSrc) { TRACENAME("COPYOBJDATA")
ENTER(3, ("CopyObjData(Dest=%x,Src=%x)\n", pdataDst, pdataSrc));
ASSERT(pdataDst != NULL); ASSERT(pdataSrc != NULL); if (pdataDst != pdataSrc) { MEMCPY(pdataDst, pdataSrc, sizeof(OBJDATA)); if (pdataSrc->dwfData & DATAF_BUFF_ALIAS) { //
// Source is an alias, so we need to increment the base object
// reference count.
//
ASSERT(pdataSrc->pdataBase != NULL); pdataSrc->pdataBase->dwRefCount++; } else if (pdataSrc->pbDataBuff != NULL) { //
// Source is a base object with buffer, increment its reference
// count.
//
pdataSrc->dwRefCount++; pdataDst->dwfData |= DATAF_BUFF_ALIAS; pdataDst->pdataBase = pdataSrc; } }
EXIT(3, ("CopyObjData!\n")); } //CopyObjData
/***LP MoveObjData - Move object data
* * ENTRY * pdataDst -> target object * pdataSrc -> source object * * EXIT * None */
VOID LOCAL MoveObjData(POBJDATA pdataDst, POBJDATA pdataSrc) { TRACENAME("MOVEOBJDATA")
ENTER(3, ("MoveObjData(Dest=%x,Src=%x)\n", pdataDst, pdataSrc));
ASSERT(pdataDst != NULL); ASSERT(pdataSrc != NULL); if (pdataDst != pdataSrc) { //
// We can only move an alias object or a base object with zero
// reference count or a base object with no data buffer.
//
ASSERT((pdataSrc->dwfData & DATAF_BUFF_ALIAS) || (pdataSrc->pbDataBuff == NULL) || (pdataSrc->dwRefCount == 0));
MEMCPY(pdataDst, pdataSrc, sizeof(OBJDATA)); MEMZERO(pdataSrc, sizeof(OBJDATA)); }
EXIT(3, ("MoveObjData!\n")); } //MoveObjData
/***LP DupObjData - Duplicate object data
* * ENTRY * pheap -> HEAP * pdataDst -> target object * pdataSrc -> source object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL DupObjData(PHEAP pheap, POBJDATA pdataDst, POBJDATA pdataSrc) { TRACENAME("DUPOBJDATA") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("DupObjData(pheap=%x,Dest=%x,Src=%x)\n", pheap, pdataDst, pdataSrc));
ASSERT(pdataDst != NULL); ASSERT(pdataSrc != NULL); if (pdataDst != pdataSrc) { MEMCPY(pdataDst, pdataSrc, sizeof(OBJDATA)); if (pdataSrc->pbDataBuff != NULL) { if ((pdataDst->pbDataBuff = NEWOBJDATA(pheap, pdataSrc)) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("DupObjData: failed to allocate destination buffer")); } else if (pdataSrc->dwDataType == OBJTYPE_PKGDATA) { PPACKAGEOBJ ppkgSrc = (PPACKAGEOBJ)pdataSrc->pbDataBuff, ppkgDst = (PPACKAGEOBJ)pdataDst->pbDataBuff; int i;
ppkgDst->dwcElements = ppkgSrc->dwcElements; for (i = 0; i < (int)ppkgSrc->dwcElements; ++i) { if ((rc = DupObjData(pheap, &ppkgDst->adata[i], &ppkgSrc->adata[i])) != STATUS_SUCCESS) { break; } } } else { MEMCPY(pdataDst->pbDataBuff, pdataSrc->pbDataBuff, pdataSrc->dwDataLen); } pdataDst->dwfData &= ~DATAF_BUFF_ALIAS; pdataDst->dwRefCount = 0; } }
EXIT(3, ("DupObjData=%x\n", rc)); return rc; } //DupObjData
/***LP CopyObjBuffer - Copy object data to a buffer
* * ENTRY * pbBuff -> buffer * dwLen - buffer size * pdata -> object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL CopyObjBuffer(PUCHAR pbBuff, ULONG dwLen, POBJDATA pdata) { TRACENAME("COPYOBJBUFFER") NTSTATUS rc = STATUS_SUCCESS; PUCHAR pb = NULL; ULONG dwcb = 0;
ENTER(3, ("CopyObjBuffer(pbBuff=%x,Len=%d,pdata=%x)\n", pbBuff, dwLen, pdata));
switch (pdata->dwDataType) { case OBJTYPE_INTDATA: pb = (PUCHAR)&pdata->uipDataValue; dwcb = sizeof(ULONG); break;
case OBJTYPE_STRDATA: pb = pdata->pbDataBuff; dwcb = pdata->dwDataLen - 1; break;
case OBJTYPE_BUFFDATA: pb = pdata->pbDataBuff; dwcb = pdata->dwDataLen; break;
default: rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE, ("CopyObjBuffer: invalid source object type (type=%s)", GetObjectTypeName(pdata->dwDataType))); }
if ((rc == STATUS_SUCCESS) && (pbBuff != pb)) { MEMZERO(pbBuff, dwLen); dwcb = MIN(dwLen, dwcb); MEMCPY(pbBuff, pb, dwcb); }
EXIT(3, ("CopyObjBuffer=%x (CopyLen=%d)\n", rc, dwcb)); return rc; } //CopyObjBuffer
/***LP AcquireGL - acquire global lock
* * ENTRY * pctxt -> CTXT * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL AcquireGL(PCTXT pctxt) { TRACENAME("ACQUIREGL") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("AcquireGL(pctxt=%x)\n", pctxt));
if (ghGlobalLock.pfnHandler != NULL) { ASSERT(!(pctxt->dwfCtxt & CTXTF_READY)); rc = ((PFNGL)ghGlobalLock.pfnHandler)(EVTYPE_ACQREL_GLOBALLOCK, GLOBALLOCK_ACQUIRE, ghGlobalLock.uipParam, RestartCtxtCallback, &pctxt->CtxtData); if (rc == STATUS_PENDING) { rc = AMLISTA_PENDING; } else if (rc != STATUS_SUCCESS) { rc = AMLI_LOGERR(AMLIERR_ACQUIREGL_FAILED, ("AcquireGL: failed to acquire global lock")); } }
EXIT(3, ("AcquireGL=%x\n", rc)); return rc; } //AcquireGL
/***LP ReleaseGL - release global lock if acquired
* * ENTRY * pctxt -> CTXT * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL ReleaseGL(PCTXT pctxt) { TRACENAME("RELEASEGL") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("ReleaseGL(pctxt=%x)\n", pctxt));
if (ghGlobalLock.pfnHandler != NULL) { rc = ((PFNGL)ghGlobalLock.pfnHandler)(EVTYPE_ACQREL_GLOBALLOCK, GLOBALLOCK_RELEASE, ghGlobalLock.uipParam, NULL, &pctxt->CtxtData); }
EXIT(3, ("ReleaseGL=%x\n", rc)); return rc; } //ReleaseGL
/***LP MapUnmapPhysMem - Map/Unmap physical memory
* * ENTRY * pctxt -> CTXT (can be NULL if cannot handle STATUS_PENDING) * uipAddr - physical address * dwLen - length of memory range * puipMappedAddr -> to hold memory address mapped (NULL if unmap) * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL MapUnmapPhysMem(PCTXT pctxt, ULONG_PTR uipAddr, ULONG dwLen, PULONG_PTR puipMappedAddr) { TRACENAME("MAPUNMAPPHYSMEM") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("MapUnmapPhysMem(pctxt=%x,Addr=%x,Len=%d,pMappedAddr=%x)\n", pctxt, uipAddr, dwLen, puipMappedAddr));
if(dwLen) { if (KeGetCurrentIrql() == PASSIVE_LEVEL) { if (puipMappedAddr != NULL) { *puipMappedAddr = MapPhysMem(uipAddr, dwLen); } else { MmUnmapIoSpace((PVOID)uipAddr, dwLen); } } else if (pctxt != NULL) { PPASSIVEHOOK pph;
if ((pph = NEWPHOBJ(sizeof(PASSIVEHOOK))) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("MapUnmapPhysMem: failed to allocate passive hook")); } else { pph->pctxt = pctxt; pph->uipAddr = uipAddr; pph->dwLen = dwLen; pph->puipMappedAddr = puipMappedAddr; ExInitializeWorkItem(&pph->WorkItem, MapUnmapCallBack, pph); OSQueueWorkItem(&pph->WorkItem);
rc = AMLISTA_PENDING; } } else { rc = AMLI_LOGERR(AMLIERR_FATAL, ("MapUnmapPhysMem: IRQL is not at PASSIVE (IRQL=%x)", KeGetCurrentIrql())); } } else { rc = AMLI_LOGERR(AMLIERR_INVALID_DATA, ("MapUnmapPhysMem: Trying to create 0 length memory opregion"));
}
EXIT(3, ("MapUnmapPhysMem=%x (MappedAddr=%x)\n", rc, puipMappedAddr? *puipMappedAddr: 0)); return rc; } //MapUnmapPhysMem
/***LP MapPhysMem - Map physical memory
* * ENTRY * uipAddr - physical memory address * dwLen - length of memory block * * EXIT * returns mapped address */
ULONG_PTR LOCAL MapPhysMem(ULONG_PTR uipAddr, ULONG dwLen) { TRACENAME("MAPPHYSMEM") ULONG_PTR uipMappedAddr = 0; PHYSICAL_ADDRESS phyaddr = {0, 0}, XlatedAddr; ULONG dwAddrSpace;
ENTER(3, ("MapPhysMem(Addr=%x,Len=%d)\n", uipAddr, dwLen));
phyaddr.HighPart = 0; phyaddr.QuadPart = uipAddr; dwAddrSpace = 0; if (HalTranslateBusAddress(Internal, 0, phyaddr, &dwAddrSpace, &XlatedAddr)) { uipMappedAddr = (ULONG_PTR)MmMapIoSpace(XlatedAddr, dwLen, MmNonCached); }
EXIT(3, ("MapPhysMem=%x", uipMappedAddr)); return uipMappedAddr; } //MapPhysMem
/***LP MapUnmapCallBack - Map/Unmap physical memory callback
* * ENTRY * pph -> PASSIVEHOOK * * EXIT * None */
VOID MapUnmapCallBack(PPASSIVEHOOK pph) { TRACENAME("MAPUNMAPCALLBACK")
ENTER(3, ("MapUnmapCallBack(pph=%x,pctxt=%x,Addr=%x,Len=%d,pdwMappedAddr=%x)\n", pph, pph->pctxt, pph->uipAddr, pph->dwLen, pph->puipMappedAddr));
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
if (pph->puipMappedAddr != NULL) { *pph->puipMappedAddr = MapPhysMem(pph->uipAddr, pph->dwLen); } else { MmUnmapIoSpace((PVOID)pph->uipAddr, pph->dwLen); }
RestartContext(pph->pctxt, (BOOLEAN)((pph->pctxt->dwfCtxt & CTXTF_ASYNC_EVAL) == 0));
FREEPHOBJ(pph);
EXIT(3, ("MapUnmapCallBack!\n")); } //MapUnmapCallBack
/***LP MatchObjType - match object type
* * ENTRY * dwObjType - object type * dwExpected - expected type * * EXIT-SUCCESS * returns TRUE - type matched * EXIT-FAILURE * returns FALSE - type mismatch */
BOOLEAN LOCAL MatchObjType(ULONG dwObjType, ULONG dwExpectedType) { TRACENAME("MATCHOBJTYPE") BOOLEAN rc = FALSE;
ENTER(3, ("MatchObjType(ObjType=%s,Expected=%s)\n", GetObjectTypeName(dwObjType), GetObjectTypeName(dwExpectedType))); //
// OBJTYPE_BUFFFIELD is essentially OBJTYPE_INTDATA, so we'll let
// it pass the check.
//
if ((dwObjType == OBJTYPE_BUFFFIELD) && (dwExpectedType == OBJTYPE_INTDATA)) { rc = TRUE; } else if ((dwExpectedType == OBJTYPE_UNKNOWN) || (dwObjType == OBJTYPE_UNKNOWN) || (dwObjType == dwExpectedType)) { rc = TRUE; } else { if ((dwObjType == OBJTYPE_INTDATA) || (dwObjType == OBJTYPE_STRDATA) || (dwObjType == OBJTYPE_BUFFDATA) || (dwObjType == OBJTYPE_PKGDATA)) { dwObjType = OBJTYPE_DATA; } else if ((dwObjType == OBJTYPE_FIELDUNIT) || (dwObjType == OBJTYPE_BUFFFIELD)) { dwObjType = OBJTYPE_DATAFIELD; }
if ((dwObjType == dwExpectedType) || (dwExpectedType == OBJTYPE_DATAOBJ) && ((dwObjType == OBJTYPE_DATA) || (dwObjType == OBJTYPE_DATAFIELD))) { rc = TRUE; } }
EXIT(3, ("MatchObjType=%x\n", rc)); return rc; } //MatchObjType
/***LP ValidateTarget - Validate target object type
* * ENTRY * pdataTarget -> target object data * dwExpectedType - expected target object type * ppdata -> to hold base target object data pointer * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL ValidateTarget(POBJDATA pdataTarget, ULONG dwExpectedType, POBJDATA *ppdata) { TRACENAME("VALIDATETARGET") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("ValidateTarget(pdataTarget=%x,ExpectedType=%s,ppdata=%x)\n", pdataTarget, GetObjectTypeName(dwExpectedType), ppdata));
ASSERT(pdataTarget != NULL); if (pdataTarget->dwDataType == OBJTYPE_OBJALIAS) { *ppdata = &pdataTarget->pnsAlias->ObjData; } else if (pdataTarget->dwDataType == OBJTYPE_DATAALIAS) { *ppdata = pdataTarget->pdataAlias; } else if ((pdataTarget->dwDataType == OBJTYPE_UNKNOWN) || (pdataTarget->dwDataType == OBJTYPE_BUFFFIELD) || (pdataTarget->dwDataType == OBJTYPE_DEBUG)) { *ppdata = pdataTarget; } else { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_TARGETTYPE, ("ValidateTarget: target is not a supername (Type=%s)", GetObjectTypeName(pdataTarget->dwDataType))); }
if ((rc == STATUS_SUCCESS) && (pdataTarget->dwDataType == OBJTYPE_OBJALIAS) && !MatchObjType((*ppdata)->dwDataType, dwExpectedType)) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_TARGETTYPE, ("ValidateTarget: unexpected target type (Type=%s,Expected=%s)", GetObjectTypeName((*ppdata)->dwDataType), GetObjectTypeName(dwExpectedType))); }
if ((rc == STATUS_SUCCESS) && (pdataTarget->dwDataType != OBJTYPE_OBJALIAS) && MatchObjType((*ppdata)->dwDataType, OBJTYPE_DATA)) { FreeDataBuffs(*ppdata, 1); }
EXIT(3, ("ValidateTarget=%x (pdataTarget=%x)\n", rc, *ppdata)); return rc; } //ValidateTarget
/***LP ValidateArgTypes - Validate argument types
* * ENTRY * pArgs -> argument array * pszExpectedTypes -> expected argument types string * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL ValidateArgTypes(POBJDATA pArgs, PSZ pszExpectedTypes) { TRACENAME("VALIDATEARGTYPES") NTSTATUS rc = STATUS_SUCCESS; int icArgs, i;
ENTER(3, ("ValidateArgTypes(pArgs=%x,ExpectedTypes=%s)\n", pArgs, pszExpectedTypes));
ASSERT(pszExpectedTypes != NULL);
icArgs = STRLEN(pszExpectedTypes); for (i = 0; (rc == STATUS_SUCCESS) && (i < icArgs); ++i) { switch (pszExpectedTypes[i]) { case ARGOBJ_UNKNOWN: break;
case ARGOBJ_INTDATA: if (pArgs[i].dwDataType != OBJTYPE_INTDATA) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE, ("ValidateArgTypes: expected Arg%d to be type Integer (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_STRDATA: if (pArgs[i].dwDataType != OBJTYPE_STRDATA) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE, ("ValidateArgTypes: expected Arg%d to be type String (Type-%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_BUFFDATA: if (pArgs[i].dwDataType != OBJTYPE_BUFFDATA) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE, ("ValidateArgTypes: expected Arg%d to be type Buffer (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_PKGDATA: if (pArgs[i].dwDataType != OBJTYPE_PKGDATA) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE, ("ValidateArgTypes: expected Arg%d to be type Package (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_FIELDUNIT: if (pArgs[i].dwDataType != OBJTYPE_FIELDUNIT) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE, ("ValidateArgTypes: expected Arg%d to be type FieldUnit (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_OBJALIAS: if (pArgs[i].dwDataType != OBJTYPE_OBJALIAS) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE, ("ValidateArgTypes: expected Arg%d to be type ObjAlias (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_DATAALIAS: if (pArgs[i].dwDataType != OBJTYPE_DATAALIAS) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE, ("ValidateArgTypes: expected Arg%d to be type DataAlias (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_BASICDATA: if ((pArgs[i].dwDataType != OBJTYPE_INTDATA) && (pArgs[i].dwDataType != OBJTYPE_STRDATA) && (pArgs[i].dwDataType != OBJTYPE_BUFFDATA)) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE, ("ValidateArgTypes: expected Arg%d to be type int/str/buff (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_COMPLEXDATA: if ((pArgs[i].dwDataType != OBJTYPE_BUFFDATA) && (pArgs[i].dwDataType != OBJTYPE_PKGDATA)) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE, ("ValidateArgTypes: expected Arg%d to be type buff/pkg (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
case ARGOBJ_REFERENCE: if ((pArgs[i].dwDataType != OBJTYPE_OBJALIAS) && (pArgs[i].dwDataType != OBJTYPE_DATAALIAS) && (pArgs[i].dwDataType != OBJTYPE_BUFFFIELD)) { rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE, ("ValidateArgTypes: expected Arg%d to be type reference (Type=%s)", i, GetObjectTypeName(pArgs[i].dwDataType))); } break;
default: rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("ValidateArgTypes: internal error (invalid type - %c)", pszExpectedTypes[i])); } }
EXIT(3, ("ValidateArgTypes=%x\n", rc)); return rc; } //ValidateArgTypes
/***LP RegEventHandler - register event handler
* * ENTRY * peh -> EVHANDLE * pfnHandler -> handler entry point * uipParam - parameter pass to handler * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL RegEventHandler(PEVHANDLE peh, PFNHND pfnHandler, ULONG_PTR uipParam) { TRACENAME("REGEVENTHANDLER") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("RegEventHandler(peh=%x,pfnHandler=%x,Param=%x)\n", peh, pfnHandler, uipParam));
if ((peh->pfnHandler != NULL) && (pfnHandler != NULL)) { rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST, ("RegEventHandler: event handler already exist")); } else { peh->pfnHandler = pfnHandler; peh->uipParam = uipParam; }
EXIT(3, ("RegEventHandler=%x\n", rc)); return rc; } //RegEventHandler
/***LP RegOpcodeHandler - register an opcode callback handler
* * The callback handler will be called after the opcode finishes its * execution. If an opcode has a variable list, the opcode handler * will be called at the point of processing the closing brace. * * ENTRY * dwOpcode - opcode event to hook * pfnHandler -> handler entry point * uipParam - parameter pass to handler * dwfOpcode - opcode flags * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL RegOpcodeHandler(ULONG dwOpcode, PFNOH pfnHandler, ULONG_PTR uipParam, ULONG dwfOpcode) { TRACENAME("REGOPCODEHANDLER") NTSTATUS rc = STATUS_SUCCESS; PAMLTERM pamlterm;
ENTER(3, ("RegOpcodeHandler(Opcode=%x,pfnHandler=%x,Param=%x,dwfOpcode=%x)\n", dwOpcode, pfnHandler, uipParam, dwfOpcode));
if ((dwOpcode & 0xff) == OP_EXT_PREFIX) pamlterm = FindOpcodeTerm(dwOpcode >> 8, ExOpcodeTable); else pamlterm = OpcodeTable[dwOpcode];
if (pamlterm == NULL) { rc = AMLI_LOGERR(AMLIERR_REGHANDLER_FAILED, ("RegOpcodeHandler: either invalid opcode or " "opcode does not allow callback")); } else if ((pamlterm->pfnCallBack != NULL) && (pfnHandler != NULL)) { rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST, ("RegOpcodeHandler: opcode or opcode class already " "has a handler")); } else { pamlterm->pfnCallBack = pfnHandler; pamlterm->dwCBData = (ULONG)uipParam; pamlterm->dwfOpcode |= dwfOpcode; }
EXIT(3, ("RegOpcodeHandler=%x\n", rc)); return rc; } //RegOpcodeHandler
/***LP RegRSAccess - register region space cook/raw access handler
* * ENTRY * dwRegionSpace - specifying the region space to handle * pfnHandler -> handler entry point * uipParam - parameter pass to handler * fRaw - TRUE if registering raw access handler * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */
NTSTATUS LOCAL RegRSAccess(ULONG dwRegionSpace, PFNHND pfnHandler, ULONG_PTR uipParam, BOOLEAN fRaw) { TRACENAME("REGRSACCESS") NTSTATUS rc = STATUS_SUCCESS;
ENTER(3, ("RegRSAccess(RegionSpace=%x,pfnHandler=%x,Param=%x,fRaw=%x)\n", dwRegionSpace, pfnHandler, uipParam, fRaw));
if ((dwRegionSpace != REGSPACE_MEM) && (dwRegionSpace != REGSPACE_IO)) { PRSACCESS prsa;
if ((prsa = FindRSAccess(dwRegionSpace)) == NULL) { if ((prsa = NEWRSOBJ(sizeof(RSACCESS))) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("RegRSAccess: failed to allocate handler structure")); } else { MEMZERO(prsa, sizeof(RSACCESS)); prsa->dwRegionSpace = dwRegionSpace; prsa->prsaNext = gpRSAccessHead; gpRSAccessHead = prsa; } }
if (rc == STATUS_SUCCESS) { if (fRaw) { if ((prsa->pfnRawAccess != NULL) && (pfnHandler != NULL)) { rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST, ("RegRSAccess: RawAccess for RegionSpace %x " "already have a handler", dwRegionSpace)); } else { prsa->pfnRawAccess = (PFNRA)pfnHandler; prsa->uipRawParam = uipParam; } } else { if ((prsa->pfnCookAccess != NULL) && (pfnHandler != NULL)) { rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST, ("RegRSAccess: CookAccess for RegionSpace %x " "already have a handler", dwRegionSpace)); } else { prsa->pfnCookAccess = (PFNCA)pfnHandler; prsa->uipCookParam = uipParam; } } } } else { rc = AMLI_LOGERR(AMLIERR_INVALID_REGIONSPACE, ("RegRSAccess: illegal region space - %x", dwRegionSpace)); }
EXIT(3, ("RegRSAccess=%x\n", rc)); return rc; } //RegRSAccess
/***LP FindRSAccess - Find RSACCESS structure with a given RegionSpace
* * ENTRY * dwRegionSpace - region space * * EXIT-SUCCESS * returns the pointer to the structure found * EXIT-FAILURE * returns NULL */
PRSACCESS LOCAL FindRSAccess(ULONG dwRegionSpace) { TRACENAME("FINDRSACCESS") PRSACCESS prsa;
ENTER(3, ("FindRSAccess(RegionSpace=%x)\n", dwRegionSpace));
for (prsa = gpRSAccessHead; prsa != NULL; prsa = prsa->prsaNext) { if (prsa->dwRegionSpace == dwRegionSpace) break; }
EXIT(3, ("FindRSAccess=%x\n", prsa)); return prsa; } //FindRSAccess
/***LP FreeRSAccessList - free the RSACCESS structure list
* * ENTRY * prsa -> RSACCESS list * * EXIT * None */
VOID LOCAL FreeRSAccessList(PRSACCESS prsa) { TRACENAME("FREERSACCESSLIST") PRSACCESS prsaNext;
ENTER(3, ("FreeRSAccessList(prsa=%x)\n", prsa));
while (prsa != NULL) { prsaNext = prsa->prsaNext; FREERSOBJ(prsa); prsa = prsaNext; }
EXIT(3, ("FreeRSAccessList!\n")); } //FreeRSAccessList
/***LP GetObjectPath - get object namespace path
* * ENTRY * pns -> object * * EXIT * returns name space path */
PSZ LOCAL GetObjectPath(PNSOBJ pns) { TRACENAME("GETOBJECTPATH") static char szPath[MAX_NAME_LEN + 1] = {0}; int i;
ENTER(4, ("GetObjectPath(pns=%x)\n", pns));
if (pns != NULL) { if (pns->pnsParent == NULL) STRCPY(szPath, "\\"); else { GetObjectPath(pns->pnsParent); if (pns->pnsParent->pnsParent != NULL) STRCAT(szPath, "."); STRCATN(szPath, (PSZ)&pns->dwNameSeg, sizeof(NAMESEG)); }
for (i = STRLEN(szPath) - 1; i >= 0; --i) { if (szPath[i] == '_') szPath[i] = '\0'; else break; } } else { szPath[0] = '\0'; }
EXIT(4, ("GetObjectPath=%s\n", szPath)); return szPath; } //GetObjectPath
#ifdef DEBUGGER
/***LP NameSegString - convert a NameSeg to an ASCIIZ string
* * ENTRY * dwNameSeg - NameSeg * * EXIT * returns string */
PSZ LOCAL NameSegString(ULONG dwNameSeg) { TRACENAME("NAMESEGSTRING") static char szNameSeg[sizeof(NAMESEG) + 1] = {0};
ENTER(5, ("NameSegString(dwNameSeg=%x)\n", dwNameSeg));
STRCPYN(szNameSeg, (PSZ)&dwNameSeg, sizeof(NAMESEG));
EXIT(5, ("NameSegString=%s\n", szNameSeg)); return szNameSeg; } //NameSegString
/***LP GetObjectTypeName - get object type name
* * ENTRY * dwObjType - object type * * EXIT * return object type name */
PSZ LOCAL GetObjectTypeName(ULONG dwObjType) { TRACENAME("GETOBJECTTYPENAME") PSZ psz = NULL; int i; static struct { ULONG dwObjType; PSZ pszObjTypeName; } ObjTypeTable[] = { OBJTYPE_UNKNOWN, "Unknown", OBJTYPE_INTDATA, "Integer", OBJTYPE_STRDATA, "String", OBJTYPE_BUFFDATA, "Buffer", OBJTYPE_PKGDATA, "Package", OBJTYPE_FIELDUNIT, "FieldUnit", OBJTYPE_DEVICE, "Device", OBJTYPE_EVENT, "Event", OBJTYPE_METHOD, "Method", OBJTYPE_MUTEX, "Mutex", OBJTYPE_OPREGION, "OpRegion", OBJTYPE_POWERRES, "PowerResource", OBJTYPE_PROCESSOR, "Processor", OBJTYPE_THERMALZONE,"ThermalZone", OBJTYPE_BUFFFIELD, "BuffField", OBJTYPE_DDBHANDLE, "DDBHandle", OBJTYPE_DEBUG, "Debug", OBJTYPE_OBJALIAS, "ObjAlias", OBJTYPE_DATAALIAS, "DataAlias", OBJTYPE_BANKFIELD, "BankField", OBJTYPE_FIELD, "Field", OBJTYPE_INDEXFIELD, "IndexField", OBJTYPE_DATA, "Data", OBJTYPE_DATAFIELD, "DataField", OBJTYPE_DATAOBJ, "DataObject", 0, NULL };
ENTER(4, ("GetObjectTypeName(Type=%x)\n", dwObjType));
for (i = 0; ObjTypeTable[i].pszObjTypeName != NULL; ++i) { if (dwObjType == ObjTypeTable[i].dwObjType) { psz = ObjTypeTable[i].pszObjTypeName; break; } }
EXIT(4, ("GetObjectTypeName=%s\n", psz? psz: "NULL")); return psz; } //GetObjectTypeName
/***LP GetRegionSpaceName - get region space name
* * ENTRY * bRegionSpace - region space * * EXIT * return object type name */
PSZ LOCAL GetRegionSpaceName(UCHAR bRegionSpace) { TRACENAME("GETREGIONSPACENAME") PSZ psz = NULL; int i; static PSZ pszVendorDefined = "VendorDefined"; static struct { UCHAR bRegionSpace; PSZ pszRegionSpaceName; } RegionNameTable[] = { REGSPACE_MEM, "SystemMemory", REGSPACE_IO, "SystemIO", REGSPACE_PCICFG, "PCIConfigSpace", REGSPACE_EC, "EmbeddedController", REGSPACE_SMB, "SMBus", 0, NULL };
ENTER(4, ("GetRegionSpaceName(RegionSpace=%x)\n", bRegionSpace));
for (i = 0; RegionNameTable[i].pszRegionSpaceName != NULL; ++i) { if (bRegionSpace == RegionNameTable[i].bRegionSpace) { psz = RegionNameTable[i].pszRegionSpaceName; break; } }
if (psz == NULL) { psz = pszVendorDefined; }
EXIT(4, ("GetRegionSpaceName=%s\n", psz? psz: "NULL")); return psz; } //GetRegionSpaceName
#endif //ifdef DEBUGGER
/***LP ValidateTable - Validate the table creator and revision
* * ENTRY * pdsdt -> DSDT * * EXIT-SUCCESS * returns TRUE * EXIT-FAILURE * returns FALSE */
BOOLEAN LOCAL ValidateTable(PDSDT pdsdt) { TRACENAME("VALIDATETABLE") BOOLEAN rc = TRUE;
ENTER(3, ("ValidateTable(pdsdt=%x)\n", pdsdt));
if (!(gdwfAMLIInit & AMLIIF_NOCHK_TABLEVER) && (STRCMPN((PSZ)pdsdt->Header.CreatorID, CREATORID_MSFT, sizeof(pdsdt->Header.CreatorID)) == 0)) { if (pdsdt->Header.CreatorRev < MIN_CREATOR_REV) { rc = FALSE; } }
EXIT(3, ("ValidateTable=%x\n", rc)); return rc; } //ValidateTable
/***LP NewObjData - allocate new object data identical to a given old object
* * ENTRY * pheap -> HEAP * pdata -> old object * * EXIT-SUCCESS * returns pointer to the new data * EXIT-FAILURE * returns NULL */
PVOID LOCAL NewObjData(PHEAP pheap, POBJDATA pdata) { PVOID pv = NULL;
switch (pdata->dwDataType) { case OBJTYPE_STRDATA: pv = NEWSDOBJ(gpheapGlobal, pdata->dwDataLen); break;
case OBJTYPE_BUFFDATA: pv = NEWBDOBJ(gpheapGlobal, pdata->dwDataLen); break;
case OBJTYPE_PKGDATA: pv = NEWPKOBJ(gpheapGlobal, pdata->dwDataLen); break;
case OBJTYPE_FIELDUNIT: pv = NEWFUOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_EVENT: pv = NEWEVOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_METHOD: pv = NEWMEOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_MUTEX: pv = NEWMTOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_OPREGION: pv = NEWOROBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_POWERRES: pv = NEWPROBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_PROCESSOR: pv = NEWPCOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_BUFFFIELD: pv = NEWBFOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_BANKFIELD: pv = NEWKFOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_FIELD: pv = NEWFOBJ(pheap, pdata->dwDataLen); break;
case OBJTYPE_INDEXFIELD: pv = NEWIFOBJ(pheap, pdata->dwDataLen); break;
default: AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("NewObjData: invalid object type %s", GetObjectTypeName(pdata->dwDataType))); }
return pv; } //NewObjData
/***LP FreeObjData - Free object data
* * ENTRY * pdata -> object which its data is to be freed * * EXIT * None */
VOID LOCAL FreeObjData(POBJDATA pdata) { switch (pdata->dwDataType) { case OBJTYPE_STRDATA: FREESDOBJ(pdata->pbDataBuff); break;
case OBJTYPE_BUFFDATA: FREEBDOBJ(pdata->pbDataBuff); break;
case OBJTYPE_PKGDATA: FREEPKOBJ(pdata->pbDataBuff); break;
case OBJTYPE_FIELDUNIT: FREEFUOBJ(pdata->pbDataBuff); break;
case OBJTYPE_EVENT: FREEEVOBJ(pdata->pbDataBuff); break;
case OBJTYPE_METHOD: FREEMEOBJ(pdata->pbDataBuff); break;
case OBJTYPE_MUTEX: FREEMTOBJ(pdata->pbDataBuff); break;
case OBJTYPE_OPREGION: FREEOROBJ(pdata->pbDataBuff); break;
case OBJTYPE_POWERRES: FREEPROBJ(pdata->pbDataBuff); break;
case OBJTYPE_PROCESSOR: FREEPCOBJ(pdata->pbDataBuff); break;
case OBJTYPE_BUFFFIELD: FREEBFOBJ(pdata->pbDataBuff); break;
case OBJTYPE_BANKFIELD: FREEKFOBJ(pdata->pbDataBuff); break;
case OBJTYPE_FIELD: FREEFOBJ(pdata->pbDataBuff); break;
case OBJTYPE_INDEXFIELD: FREEIFOBJ(pdata->pbDataBuff); break;
default: AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("FreeObjData: invalid object type %s", GetObjectTypeName(pdata->dwDataType))); } } //FreeObjData
/*** LP InitializeRegOverrideFlags - Get override flags from
* the registry. * * ENTRY * None * * EXIT * None */ VOID LOCAL InitializeRegOverrideFlags(VOID) { TRACENAME("InitializeRegOverrideFlags") HANDLE hRegKey=NULL; NTSTATUS status; ULONG argSize;
ENTER(3, ("InitializeRegOverrideFlags\n")); status = OSOpenHandle(ACPI_PARAMETERS_REGISTRY_KEY, NULL, &hRegKey); if (NT_SUCCESS(status)) { argSize = sizeof(gOverrideFlags); OSReadRegValue(AMLI_ATTRIBUTES, hRegKey, &gOverrideFlags, &argSize); } else { gOverrideFlags = 0; } EXIT(3, ("InitializeRegOverrideFlags\n")); return; }
/*** LP ValidateMemoryOpregionRange - Validate the memory range that is
* required for the memory opregion. * * ENTRY * uipAddr - physical memory address * dwLen - length of memory block * * EXIT * returns TRUE iff the memory is in the legal range. */ BOOLEAN LOCAL ValidateMemoryOpregionRange(ULONG_PTR uipAddr, ULONG dwLen) { BOOLEAN Ret = FALSE; NTSTATUS status; PACPI_BIOS_MULTI_NODE e820Info; PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartialDesc; PCM_PARTIAL_RESOURCE_LIST cmPartialList; PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64 keyInfo; ULONGLONG i; ULONGLONG absMin; ULONGLONG absMax; //
// Read the key for the AcpiConfigurationData
//
status = OSReadAcpiConfigurationData( &keyInfo );
if (!NT_SUCCESS(status)) { PRINTF("ValidateMemoryOpregionRange: Cannot get E820 Information %08lx\n", status ); Ret = TRUE; } else { //
// Crack the structure to get the E820Table entry
//
cmPartialList = (PCM_PARTIAL_RESOURCE_LIST) (keyInfo->Data); cmPartialDesc = &(cmPartialList->PartialDescriptors[0]); e820Info = (PACPI_BIOS_MULTI_NODE) ( (PUCHAR) cmPartialDesc + sizeof(CM_PARTIAL_RESOURCE_LIST) );
//
// Calculate absmin and absmax for the incoming address
//
absMin = (ULONGLONG)uipAddr; absMax = absMin + dwLen; //
// walk the E820 list
//
for(i = 0; i < e820Info->Count; i++) { if (e820Info->E820Entry[i].Type == AcpiAddressRangeMemory) { if(absMax < (ULONGLONG)PAGE_SIZE) { Ret = TRUE; PRINTF("ValidateMemoryOpregionRange: Memory OpRegion (Base = 0x%I64x, Length = 0x%x) is in first physical page, skipping check.\n", absMin, dwLen ); } else { if((absMax < (ULONGLONG) e820Info->E820Entry[i].Base.QuadPart) ||(absMin >= (ULONGLONG) (e820Info->E820Entry[i].Base.QuadPart + e820Info->E820Entry[i].Length.QuadPart))) { Ret = TRUE; PRINTF("ValidateMemoryOpregionRange: Memory OpRegion (Base = 0x%I64x, Length = 0x%x) is not in AcpiAddressRangeMemory (Base = 0x%I64x, Length = 0x%I64x)\n", absMin, dwLen, e820Info->E820Entry[i].Base.QuadPart, e820Info->E820Entry[i].Length.QuadPart ); } else { //
// This opregion is mapping memory that belongs to the OS.
// Log a error in the event log.
//
PWCHAR illegalMemoryAddress[5]; WCHAR AMLIName[6]; WCHAR addressBuffer[64]; WCHAR addressLengthBuffer[64]; WCHAR OSaddressBufferRangeMin[64]; WCHAR OSaddressBufferRangeMax[64]; //
// Turn the address into a string
//
swprintf( AMLIName, L"AMLI"); swprintf( addressBuffer, L"0x%I64x", absMin ); swprintf( addressLengthBuffer, L"0x%lx", dwLen ); swprintf( OSaddressBufferRangeMin, L"0x%I64x", e820Info->E820Entry[i].Base.QuadPart ); swprintf( OSaddressBufferRangeMax, L"0x%I64x", e820Info->E820Entry[i].Base.QuadPart + e820Info->E820Entry[i].Length.QuadPart);
//
// Build the list of arguments to pass to the function that will write the
// error log to the registry
//
illegalMemoryAddress[0] = AMLIName; illegalMemoryAddress[1] = addressBuffer; illegalMemoryAddress[2] = addressLengthBuffer; illegalMemoryAddress[3] = OSaddressBufferRangeMin; illegalMemoryAddress[4] = OSaddressBufferRangeMax;
//
// Log error to event log
//
ACPIWriteEventLogEntry(ACPI_ERR_AMLI_ILLEGAL_MEMORY_OPREGION_FATAL, illegalMemoryAddress, 5, NULL, 0);
PRINTF("ValidateMemoryOpregionRange: Memory OpRegion (Base = 0x%I64x, Length = 0x%x) is in AcpiAddressRangeMemory (Base = 0x%I64x, Length = 0x%I64x)\n", absMin, dwLen, e820Info->E820Entry[i].Base.QuadPart, e820Info->E820Entry[i].Length.QuadPart ); Ret = FALSE; break; } } } } //
// Free the E820 info
//
ExFreePool( keyInfo ); } return Ret; }
#ifdef DEBUG
/*** LP FreeMem - Free memory object
* * ENTRY * pv -> memory object to be freed * pdwcObjs -> object counter to be decremented * * EXIT * None */
VOID LOCAL FreeMem(PVOID pv, PULONG pdwcObjs) { if (*pdwcObjs != 0) { ExFreePool(pv); (*pdwcObjs)--; } else { AMLI_ERROR(("FreeMem: Unbalanced MemFree")); } } //FreeMem
/*** LP CheckGlobalHeap - Make sure that the global heap has not become
* corrupted * * ENTRY * None * * Exit * None */ VOID LOCAL CheckGlobalHeap() { KIRQL oldIrql;
//
// We don't care about this is we are loading a DDB
//
if (gdwfAMLI & AMLIF_LOADING_DDB) {
return;
}
//
// Must have spinlock protection...
//
KeAcquireSpinLock( &gdwGHeapSpinLock, &oldIrql );
//
// We only care if they don't match...
//
if (gdwGlobalHeapSize == gdwGHeapSnapshot) {
goto CheckGlobalHeapExit;
}
//
// If the new heap size is smaller than the current size, then
// we shrunk the heap and that is good...
//
if (gdwGlobalHeapSize < gdwGHeapSnapshot) {
//
// Remember the new "snapshot size"
//
gdwGHeapSnapshot = gdwGlobalHeapSize; goto CheckGlobalHeapExit;
}
if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON) {
AMLI_WARN(("CheckGlobalHeap: " "potential memory leak " "detected (CurrentHeapSize=%d," "ReferenceSize=%d)", gdwGlobalHeapSize, gdwGHeapSnapshot));
} if (gdwGlobalHeapSize - gdwGHeapSnapshot > 8192) {
AMLI_WARN(("CheckGlobalHeap: detected memory leak")); KdBreakPoint();
}
CheckGlobalHeapExit:
//
// Release the lock and we are done
//
KeReleaseSpinLock( &gdwGHeapSpinLock, oldIrql ); } #endif //ifdef DEBUG
|