Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2234 lines
63 KiB

  1. /*** misc.c - Miscellaneous functions
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created 11/18/96
  6. *
  7. * MODIFICATION HISTORY
  8. */
  9. #include "pch.h"
  10. #ifdef LOCKABLE_PRAGMA
  11. #pragma ACPI_LOCKABLE_DATA
  12. #pragma ACPI_LOCKABLE_CODE
  13. #endif
  14. /***LP InitializeMutex - initialize mutex
  15. *
  16. * ENTRY
  17. * pmut -> MUTEX
  18. *
  19. * EXIT
  20. * None
  21. */
  22. VOID LOCAL InitializeMutex(PMUTEX pmut)
  23. {
  24. TRACENAME("INITIALIZEMUTEX")
  25. ENTER(3, ("InitializeMutex(pmut=%x)\n", pmut));
  26. KeInitializeSpinLock(&pmut->SpinLock);
  27. pmut->OldIrql = PASSIVE_LEVEL;
  28. EXIT(3, ("InitializeMutex!\n"));
  29. } //InitializeMutex
  30. /***LP AcquireMutex - acquire mutex
  31. *
  32. * ENTRY
  33. * pmut -> MUTEX
  34. *
  35. * EXIT-SUCCESS
  36. * returns TRUE
  37. * EXIT-FAILURE
  38. * returns FALSE
  39. *
  40. * NOTE
  41. * AcquireMutex can be called at DISPATCH_LEVEL as long as the mutex
  42. * is unowned or owned by the same thread. If the mutex is owned by
  43. * some other thread, this thread cannot block if we are at
  44. * DISPATCH_LEVEL and therefore would fail to acquire the mutex.
  45. */
  46. BOOLEAN LOCAL AcquireMutex(PMUTEX pmut)
  47. {
  48. TRACENAME("ACQUIREMUTEX")
  49. BOOLEAN rc = TRUE;
  50. ENTER(3, ("AcquireMutex(pmut=%x)\n", pmut));
  51. ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
  52. KeAcquireSpinLock(&pmut->SpinLock, &pmut->OldIrql);
  53. EXIT(3, ("AcquireMutex=%x\n", rc));
  54. return rc;
  55. } //AcquireMutex
  56. /***LP ReleaseMutex - release mutex
  57. *
  58. * ENTRY
  59. * pmut -> MUTEX
  60. *
  61. * EXIT-SUCCESS
  62. * returns TRUE
  63. * EXIT-FAILURE
  64. * returns FALSE
  65. */
  66. BOOLEAN LOCAL ReleaseMutex(PMUTEX pmut)
  67. {
  68. TRACENAME("RELEASEMUTEX")
  69. BOOLEAN rc = TRUE;
  70. ENTER(3, ("ReleaseMutex(pmut=%x)\n", pmut));
  71. ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
  72. KeReleaseSpinLock(&pmut->SpinLock, pmut->OldIrql);
  73. EXIT(3, ("ReleaseMutex!\n"));
  74. return rc;
  75. } //ReleaseMutex
  76. /***LP FindOpcodeTerm - find the AMLTERM for the given opcode
  77. *
  78. * ENTRY
  79. * dwOp - opcode
  80. * pOpTable -> opcode table
  81. *
  82. * EXIT-SUCCESS
  83. * returns pointer to the opcode's AMLTERM
  84. * EXIT-FAILURE
  85. * returns NULL
  86. */
  87. PAMLTERM LOCAL FindOpcodeTerm(ULONG dwOp, POPCODEMAP pOpTable)
  88. {
  89. TRACENAME("FINDOPCODETERM")
  90. PAMLTERM pamlterm = NULL;
  91. ENTER(3, ("FindOpcodeTerm(Op=%x,pOpTable=%x)\n", dwOp, pOpTable));
  92. while (pOpTable->pamlterm != NULL)
  93. {
  94. if (dwOp == pOpTable->dwOpcode)
  95. {
  96. pamlterm = pOpTable->pamlterm;
  97. break;
  98. }
  99. else
  100. pOpTable++;
  101. }
  102. EXIT(3, ("FindOpcodeTerm=%x\n", pamlterm));
  103. return pamlterm;
  104. } //FindOpcodeTerm
  105. /***LP GetHackFlags - Get the hack flags from the registry
  106. *
  107. * ENTRY
  108. * pdsdt -> AML table
  109. *
  110. * EXIT-SUCCESS
  111. * returns the hack flags read
  112. * EXIT-FAILURE
  113. * returns zero
  114. */
  115. ULONG LOCAL GetHackFlags(PDSDT pdsdt)
  116. {
  117. TRACENAME("GETHACKFLAGS")
  118. ULONG dwfHacks = 0, dwcb;
  119. static PSZ pszHackFlags = "AMLIHackFlags";
  120. ENTER(3, ("GetHackFlags(pdsdt=%x)\n", pdsdt));
  121. if (pdsdt == NULL)
  122. {
  123. dwcb = sizeof(dwfHacks);
  124. OSReadRegValue(pszHackFlags, (HANDLE)NULL, &dwfHacks, &dwcb);
  125. }
  126. else
  127. {
  128. ULONG dwLen, i;
  129. PSZ pszRegPath;
  130. HANDLE hRegKey;
  131. NTSTATUS status;
  132. dwLen = STRLEN(ACPI_PARAMETERS_REGISTRY_KEY) +
  133. ACPI_MAX_TABLE_STRINGS +
  134. 8 + 5;
  135. if ((pszRegPath = ExAllocatePoolWithTag(PagedPool, dwLen, PRIV_TAG)) != NULL)
  136. {
  137. STRCPY(pszRegPath, ACPI_PARAMETERS_REGISTRY_KEY);
  138. STRCAT(pszRegPath, "\\");
  139. STRCATN(pszRegPath, (PSZ)&pdsdt->Header.Signature,
  140. ACPI_MAX_SIGNATURE);
  141. STRCAT(pszRegPath, "\\");
  142. STRCATN(pszRegPath, (PSZ)pdsdt->Header.OEMID, ACPI_MAX_OEM_ID);
  143. STRCAT(pszRegPath, "\\");
  144. STRCATN(pszRegPath, (PSZ)pdsdt->Header.OEMTableID, ACPI_MAX_TABLE_ID);
  145. STRCAT(pszRegPath, "\\");
  146. ULTOA(pdsdt->Header.OEMRevision, &pszRegPath[STRLEN(pszRegPath)],
  147. 16);
  148. dwLen = STRLEN(pszRegPath);
  149. for (i = 0; i < dwLen; i++)
  150. {
  151. if (pszRegPath[i] == ' ')
  152. {
  153. pszRegPath[i] = '_';
  154. }
  155. }
  156. status = OSOpenHandle(pszRegPath, NULL, &hRegKey);
  157. if (NT_SUCCESS(status))
  158. {
  159. dwcb = sizeof(dwfHacks);
  160. OSReadRegValue(pszHackFlags, hRegKey, &dwfHacks, &dwcb);
  161. }
  162. ExFreePool(pszRegPath);
  163. }
  164. }
  165. EXIT(3, ("GetHackFlags=%x\n", dwfHacks));
  166. return dwfHacks;
  167. } //GetHackFlags
  168. /***LP GetBaseObject - If object type is OBJALIAS, follow the chain to the base
  169. *
  170. * ENTRY
  171. * pnsObj -> object
  172. *
  173. * EXIT
  174. * returns the base object
  175. */
  176. PNSOBJ LOCAL GetBaseObject(PNSOBJ pnsObj)
  177. {
  178. TRACENAME("GETBASEOBJECT")
  179. ENTER(3, ("GetBaseObject(pnsObj=%s)\n", GetObjectPath(pnsObj)));
  180. while (pnsObj->ObjData.dwDataType == OBJTYPE_OBJALIAS)
  181. {
  182. pnsObj = pnsObj->ObjData.pnsAlias;
  183. }
  184. EXIT(3, ("GetBaseObject=%s\n", GetObjectPath(pnsObj)));
  185. return pnsObj;
  186. } //GetBaseObject
  187. /***LP GetBaseData - If object type is DATAALIAS, follow the chain to the base
  188. *
  189. * ENTRY
  190. * pdataObj -> object
  191. *
  192. * EXIT
  193. * returns the base object
  194. */
  195. POBJDATA LOCAL GetBaseData(POBJDATA pdataObj)
  196. {
  197. TRACENAME("GETBASEDATA")
  198. ENTER(3, ("GetBaseData(pdataObj=%x)\n", pdataObj));
  199. ASSERT(pdataObj != NULL);
  200. for (;;)
  201. {
  202. if (pdataObj->dwDataType == OBJTYPE_OBJALIAS)
  203. {
  204. pdataObj = &pdataObj->pnsAlias->ObjData;
  205. }
  206. else if (pdataObj->dwDataType == OBJTYPE_DATAALIAS)
  207. {
  208. pdataObj = pdataObj->pdataAlias;
  209. }
  210. else
  211. {
  212. break;
  213. }
  214. }
  215. EXIT(3, ("GetBaseData=%x\n", pdataObj));
  216. return pdataObj;
  217. } //GetBaseData
  218. /***LP NewObjOwner - create a new object owner
  219. *
  220. * ENTRY
  221. * pheap -> HEAP
  222. * ppowner -> to hold new owner pointer
  223. *
  224. * EXIT-SUCCESS
  225. * returns STATUS_SUCCESS
  226. * EXIT-FAILURE
  227. * returns AMLIERR_ code
  228. */
  229. NTSTATUS LOCAL NewObjOwner(PHEAP pheap, POBJOWNER *ppowner)
  230. {
  231. TRACENAME("NEWOBJOWNER")
  232. NTSTATUS rc = STATUS_SUCCESS;
  233. ENTER(3, ("NewObjOwner(pheap=%x,ppowner=%x)\n", pheap, ppowner));
  234. if ((*ppowner = NEWOOOBJ(pheap, sizeof(OBJOWNER))) == NULL)
  235. {
  236. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  237. ("NewObjOwner: failed to allocate object owner"));
  238. }
  239. else
  240. {
  241. MEMZERO(*ppowner, sizeof(OBJOWNER));
  242. (*ppowner)->dwSig = SIG_OBJOWNER;
  243. AcquireMutex(&gmutOwnerList);
  244. ListInsertTail(&(*ppowner)->list, &gplistObjOwners);
  245. ReleaseMutex(&gmutOwnerList);
  246. }
  247. EXIT(3, ("NewObjOwner=%x (powern=%x)\n", rc, *ppowner));
  248. return rc;
  249. } //NewObjOwner
  250. /***LP FreeObjOwner - free object owner
  251. *
  252. * ENTRY
  253. * powner -> OBJOWNER
  254. * fUnload - if TRUE, the caller is unloading a DDB
  255. *
  256. * EXIT
  257. * None
  258. */
  259. VOID LOCAL FreeObjOwner(POBJOWNER powner, BOOLEAN fUnload)
  260. {
  261. TRACENAME("FREEOBJOWNER")
  262. KIRQL oldIrql;
  263. PNSOBJ pns;
  264. PNSOBJ pnsNext = NULL;
  265. PNSOBJ pnsPrev = NULL;
  266. PNSOBJ pnsDeviceList = NULL;
  267. PNSOBJ pnsChild = NULL;
  268. ENTER(3, ("FreeObjOwner(powner=%x,fUnload=%x)\n", powner,fUnload));
  269. ASSERT(powner != NULL);
  270. AcquireMutex(&gmutOwnerList);
  271. ListRemoveEntry(&powner->list, &gplistObjOwners);
  272. ReleaseMutex(&gmutOwnerList);
  273. if (fUnload && (ghDestroyObj.pfnHandler != NULL))
  274. {
  275. //
  276. // First we have to tell the driver that we are about to
  277. // do walk the owner list so that we can seek and destroy
  278. // the objects
  279. //
  280. ((PFNDOBJ)ghDestroyObj.pfnHandler)(DESTROYOBJ_START, &oldIrql, 0);
  281. //
  282. // First pass, mark the objects defunc'd.
  283. //
  284. for (pns = powner->pnsObjList; pns != NULL; pns = pns->pnsOwnedNext) {
  285. pns->ObjData.dwfData |= DATAF_NSOBJ_DEFUNC;
  286. }
  287. //
  288. // Second pass, find the device in the list to be removed
  289. //
  290. for (pns = powner->pnsObjList; pns != NULL; pns = pnsNext) {
  291. pnsNext = pns->pnsOwnedNext;
  292. if (pns->ObjData.dwDataType == OBJTYPE_DEVICE ||
  293. pns->ObjData.dwDataType == OBJTYPE_POWERRES ||
  294. pns->ObjData.dwDataType == OBJTYPE_THERMALZONE ||
  295. pns->ObjData.dwDataType == OBJTYPE_PROCESSOR) {
  296. if (pnsPrev) {
  297. pnsPrev->pnsOwnedNext = pns->pnsOwnedNext;
  298. } else {
  299. powner->pnsObjList = pns->pnsOwnedNext;
  300. }
  301. pns->pnsOwnedNext = pnsDeviceList;
  302. pnsDeviceList = pns;
  303. //
  304. // Detach the device from its parent
  305. //
  306. if (pns->pnsParent != NULL) {
  307. ListRemoveEntry(
  308. &pns->list,
  309. (PPLIST)&pns->pnsParent->pnsFirstChild
  310. );
  311. pns->pnsParent = NULL;
  312. }
  313. //
  314. // Make sure that all of the device's children have been
  315. // marked as being unloaded
  316. //
  317. if (pns->pnsFirstChild) {
  318. pnsChild = pns->pnsFirstChild;
  319. do {
  320. if (!(pnsChild->ObjData.dwfData & DATAF_NSOBJ_DEFUNC) ) {
  321. ((PFNDOBJ)ghDestroyObj.pfnHandler)(
  322. DESTROYOBJ_CHILD_NOT_FREED,
  323. pnsChild,
  324. 0
  325. );
  326. }
  327. pnsChild = (PNSOBJ) pnsChild->list.plistNext;
  328. } while (pnsChild != pns->pnsFirstChild);
  329. }
  330. //
  331. // Not that if we don't put this continue in here, then
  332. // it becomes possible for pnsPrev to point to a device,
  333. // which would corrupt the list
  334. continue;
  335. } else if (pns->pnsParent == NULL ||
  336. !(pns->pnsParent->ObjData.dwfData & DATAF_NSOBJ_DEFUNC)) {
  337. ((PFNDOBJ)ghDestroyObj.pfnHandler)(
  338. DESTROYOBJ_BOGUS_PARENT,
  339. pns,
  340. 0
  341. );
  342. }
  343. pnsPrev = pns;
  344. }
  345. //
  346. // Chain the two lists back together
  347. //
  348. if (powner->pnsObjList == NULL) {
  349. powner->pnsObjList = pnsDeviceList;
  350. } else {
  351. //
  352. // Find a pointer to the last element in the list
  353. //
  354. pns = powner->pnsObjList;
  355. while ( pns->pnsOwnedNext != NULL )
  356. {
  357. //
  358. // Next element in the list
  359. //
  360. pns = pns->pnsOwnedNext;
  361. }
  362. pns->pnsOwnedNext = pnsDeviceList;
  363. }
  364. // //
  365. // Third pass pass, do callback for each device that is going away
  366. //
  367. for (pns = pnsDeviceList; pns != NULL; pns = pnsNext) {
  368. //
  369. // Remember what the next point is because we might nuke
  370. // the current object in the callback (if there is no
  371. // device extension associated with it
  372. //
  373. pnsNext = pns->pnsOwnedNext;
  374. //
  375. // Issue the callback. This might nuke the pnsObject
  376. //
  377. ((PFNDOBJ)ghDestroyObj.pfnHandler)(
  378. DESTROYOBJ_REMOVE_OBJECT,
  379. pns,
  380. pns->ObjData.dwDataType
  381. );
  382. }
  383. //
  384. // We end by tell the ACPI driver that we have finished looking
  385. // at the list
  386. //
  387. ((PFNDOBJ)ghDestroyObj.pfnHandler)(DESTROYOBJ_END, &oldIrql, 0 );
  388. }
  389. else
  390. {
  391. for (pns = powner->pnsObjList; pns != NULL; pns = pnsNext)
  392. {
  393. pnsNext = pns->pnsOwnedNext;
  394. FreeNameSpaceObjects(pns);
  395. }
  396. }
  397. powner->pnsObjList = NULL;
  398. FREEOOOBJ(powner);
  399. EXIT(3, ("FreeObjOwner!\n"));
  400. } //FreeObjOwner
  401. /***LP InsertOwnerObjList - Insert the new object into the owner's object list
  402. *
  403. * ENTRY
  404. * powner -> owner
  405. * pnsObj -> new object
  406. *
  407. * EXIT
  408. * None
  409. */
  410. VOID LOCAL InsertOwnerObjList(POBJOWNER powner, PNSOBJ pnsObj)
  411. {
  412. TRACENAME("INSERTOWNEROBJLIST")
  413. ENTER(3, ("InsertOwnerObjList(powner=%x,pnsObj=%x)\n",
  414. powner, pnsObj));
  415. pnsObj->hOwner = (HANDLE)powner;
  416. if (powner != NULL)
  417. {
  418. pnsObj->pnsOwnedNext = powner->pnsObjList;
  419. powner->pnsObjList = pnsObj;
  420. }
  421. EXIT(3, ("InsertOwnerObjList!\n"));
  422. } //InsertOwnerObjList
  423. /***LP FreeDataBuffs - Free any buffers attached to OBJDATA array
  424. *
  425. * ENTRY
  426. * adata -> OBJDATA array
  427. * icData - number of data object in array
  428. *
  429. * EXIT
  430. * None
  431. */
  432. VOID LOCAL FreeDataBuffs(POBJDATA adata, int icData)
  433. {
  434. TRACENAME("FREEDATABUFFS")
  435. int i;
  436. ENTER(3, ("FreeDataBuffs(adata=%x,icData=%d)\n", adata, icData));
  437. for (i = 0; i < icData; ++i)
  438. {
  439. if (adata[i].pbDataBuff != NULL)
  440. {
  441. if (adata[i].dwfData & DATAF_BUFF_ALIAS)
  442. {
  443. //
  444. // decrement the base object's reference count.
  445. //
  446. adata[i].pdataBase->dwRefCount--;
  447. }
  448. else
  449. {
  450. //
  451. // We cannot free a base object buffer that has aliases on it.
  452. //
  453. ASSERT(adata[i].dwRefCount == 0);
  454. if (adata[i].dwDataType == OBJTYPE_PKGDATA)
  455. {
  456. PPACKAGEOBJ ppkg = (PPACKAGEOBJ)adata[i].pbDataBuff;
  457. FreeDataBuffs(ppkg->adata, ppkg->dwcElements);
  458. }
  459. ENTER(4, ("FreeData(i=%d,Buff=%x,Flags=%x)\n",
  460. i, adata[i].pbDataBuff, adata[i].dwfData));
  461. FREEOBJDATA(&adata[i]);
  462. EXIT(4, ("FreeData!\n"));
  463. }
  464. }
  465. MEMZERO(&adata[i], sizeof(OBJDATA));
  466. }
  467. EXIT(3, ("FreeDataBuff!\n"));
  468. } //FreeDataBuffs
  469. /***LP PutIntObjData - put integer data into data object
  470. *
  471. * ENTRY
  472. * pctxt -> CTXT
  473. * pdataObj -> data object
  474. * dwData -> data to be written
  475. *
  476. * EXIT-SUCCESS
  477. * returns STATUS_SUCCESS
  478. * EXIT-FAILURE
  479. * returns AMLIERR_ code
  480. */
  481. NTSTATUS LOCAL PutIntObjData(PCTXT pctxt, POBJDATA pdataObj, ULONG dwData)
  482. {
  483. TRACENAME("PUTINTOBJDATA")
  484. NTSTATUS rc = STATUS_SUCCESS;
  485. OBJDATA data;
  486. ENTER(3, ("PutIntObjData(pctxt=%x,pdataObj=%x,dwData=%x)\n",
  487. pctxt, pdataObj, dwData));
  488. MEMZERO(&data, sizeof(OBJDATA));
  489. data.dwDataType = OBJTYPE_INTDATA;
  490. data.uipDataValue = (ULONG_PTR)dwData;
  491. rc = WriteObject(pctxt, pdataObj, &data);
  492. EXIT(3, ("PutIntObjData=%x\n", rc));
  493. return rc;
  494. } //PutIntObjData
  495. /***LP GetFieldUnitRegionObj - Get the OperationRegion object of FieldUnit
  496. *
  497. * ENTRY
  498. * pfu -> FIELDUNITOBJ
  499. * ppns -> to hold OperationRegion object
  500. *
  501. * EXIT-SUCCESS
  502. * returns STATUS_SUCCESS
  503. * EXIT-FAILURE
  504. * returns AMLIERR_ code
  505. */
  506. NTSTATUS LOCAL GetFieldUnitRegionObj(PFIELDUNITOBJ pfu, PPNSOBJ ppns)
  507. {
  508. TRACENAME("GETFIELDUNITREGIONOBJ")
  509. NTSTATUS rc = STATUS_SUCCESS;
  510. PNSOBJ pns;
  511. ENTER(3, ("GetFieldUnitRegionObj(pfu=%x,ppns=%x)\n", pfu, ppns));
  512. pns = pfu->pnsFieldParent;
  513. switch (pns->ObjData.dwDataType)
  514. {
  515. case OBJTYPE_BANKFIELD:
  516. *ppns = ((PBANKFIELDOBJ)pns->ObjData.pbDataBuff)->pnsBase;
  517. break;
  518. case OBJTYPE_FIELD:
  519. *ppns = ((PFIELDOBJ)pns->ObjData.pbDataBuff)->pnsBase;
  520. break;
  521. case OBJTYPE_INDEXFIELD:
  522. pns = ((PINDEXFIELDOBJ)pns->ObjData.pbDataBuff)->pnsData;
  523. ASSERT(pns->ObjData.dwDataType == OBJTYPE_FIELDUNIT);
  524. rc = GetFieldUnitRegionObj((PFIELDUNITOBJ)pns->ObjData.pbDataBuff,
  525. ppns);
  526. break;
  527. default:
  528. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  529. ("GetFieldUnitRegionObj: unknown field unit parent object type - %x",
  530. (*ppns)->ObjData.dwDataType));
  531. }
  532. if ((*ppns != NULL) && ((*ppns)->ObjData.dwDataType != OBJTYPE_OPREGION))
  533. {
  534. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  535. ("GetFieldUnitRegionObj: base object of field unit is not OperationRegion (BaseObj=%s,Type=%x)",
  536. GetObjectPath(*ppns), (*ppns)->ObjData.dwDataType));
  537. }
  538. EXIT(3, ("GetFieldUnitRegionObj=%x (RegionObj=%x:%s)\n",
  539. rc, *ppns, GetObjectPath(*ppns)));
  540. return rc;
  541. } //GetFieldUnitRegionObj
  542. /***LP CopyObjData - Copy object data
  543. *
  544. * ENTRY
  545. * pdataDst -> target object
  546. * pdataSrc -> source object
  547. *
  548. * EXIT
  549. * None
  550. */
  551. VOID LOCAL CopyObjData(POBJDATA pdataDst, POBJDATA pdataSrc)
  552. {
  553. TRACENAME("COPYOBJDATA")
  554. ENTER(3, ("CopyObjData(Dest=%x,Src=%x)\n", pdataDst, pdataSrc));
  555. ASSERT(pdataDst != NULL);
  556. ASSERT(pdataSrc != NULL);
  557. if (pdataDst != pdataSrc)
  558. {
  559. MEMCPY(pdataDst, pdataSrc, sizeof(OBJDATA));
  560. if (pdataSrc->dwfData & DATAF_BUFF_ALIAS)
  561. {
  562. //
  563. // Source is an alias, so we need to increment the base object
  564. // reference count.
  565. //
  566. ASSERT(pdataSrc->pdataBase != NULL);
  567. pdataSrc->pdataBase->dwRefCount++;
  568. }
  569. else if (pdataSrc->pbDataBuff != NULL)
  570. {
  571. //
  572. // Source is a base object with buffer, increment its reference
  573. // count.
  574. //
  575. pdataSrc->dwRefCount++;
  576. pdataDst->dwfData |= DATAF_BUFF_ALIAS;
  577. pdataDst->pdataBase = pdataSrc;
  578. }
  579. }
  580. EXIT(3, ("CopyObjData!\n"));
  581. } //CopyObjData
  582. /***LP MoveObjData - Move object data
  583. *
  584. * ENTRY
  585. * pdataDst -> target object
  586. * pdataSrc -> source object
  587. *
  588. * EXIT
  589. * None
  590. */
  591. VOID LOCAL MoveObjData(POBJDATA pdataDst, POBJDATA pdataSrc)
  592. {
  593. TRACENAME("MOVEOBJDATA")
  594. ENTER(3, ("MoveObjData(Dest=%x,Src=%x)\n", pdataDst, pdataSrc));
  595. ASSERT(pdataDst != NULL);
  596. ASSERT(pdataSrc != NULL);
  597. if (pdataDst != pdataSrc)
  598. {
  599. //
  600. // We can only move an alias object or a base object with zero
  601. // reference count or a base object with no data buffer.
  602. //
  603. ASSERT((pdataSrc->dwfData & DATAF_BUFF_ALIAS) ||
  604. (pdataSrc->pbDataBuff == NULL) ||
  605. (pdataSrc->dwRefCount == 0));
  606. MEMCPY(pdataDst, pdataSrc, sizeof(OBJDATA));
  607. MEMZERO(pdataSrc, sizeof(OBJDATA));
  608. }
  609. EXIT(3, ("MoveObjData!\n"));
  610. } //MoveObjData
  611. /***LP DupObjData - Duplicate object data
  612. *
  613. * ENTRY
  614. * pheap -> HEAP
  615. * pdataDst -> target object
  616. * pdataSrc -> source object
  617. *
  618. * EXIT-SUCCESS
  619. * returns STATUS_SUCCESS
  620. * EXIT-FAILURE
  621. * returns AMLIERR_ code
  622. */
  623. NTSTATUS LOCAL DupObjData(PHEAP pheap, POBJDATA pdataDst, POBJDATA pdataSrc)
  624. {
  625. TRACENAME("DUPOBJDATA")
  626. NTSTATUS rc = STATUS_SUCCESS;
  627. ENTER(3, ("DupObjData(pheap=%x,Dest=%x,Src=%x)\n",
  628. pheap, pdataDst, pdataSrc));
  629. ASSERT(pdataDst != NULL);
  630. ASSERT(pdataSrc != NULL);
  631. if (pdataDst != pdataSrc)
  632. {
  633. MEMCPY(pdataDst, pdataSrc, sizeof(OBJDATA));
  634. if (pdataSrc->pbDataBuff != NULL)
  635. {
  636. if ((pdataDst->pbDataBuff = NEWOBJDATA(pheap, pdataSrc)) == NULL)
  637. {
  638. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  639. ("DupObjData: failed to allocate destination buffer"));
  640. }
  641. else if (pdataSrc->dwDataType == OBJTYPE_PKGDATA)
  642. {
  643. PPACKAGEOBJ ppkgSrc = (PPACKAGEOBJ)pdataSrc->pbDataBuff,
  644. ppkgDst = (PPACKAGEOBJ)pdataDst->pbDataBuff;
  645. int i;
  646. ppkgDst->dwcElements = ppkgSrc->dwcElements;
  647. for (i = 0; i < (int)ppkgSrc->dwcElements; ++i)
  648. {
  649. if ((rc = DupObjData(pheap, &ppkgDst->adata[i],
  650. &ppkgSrc->adata[i])) != STATUS_SUCCESS)
  651. {
  652. break;
  653. }
  654. }
  655. }
  656. else
  657. {
  658. MEMCPY(pdataDst->pbDataBuff, pdataSrc->pbDataBuff,
  659. pdataSrc->dwDataLen);
  660. }
  661. pdataDst->dwfData &= ~DATAF_BUFF_ALIAS;
  662. pdataDst->dwRefCount = 0;
  663. }
  664. }
  665. EXIT(3, ("DupObjData=%x\n", rc));
  666. return rc;
  667. } //DupObjData
  668. /***LP CopyObjBuffer - Copy object data to a buffer
  669. *
  670. * ENTRY
  671. * pbBuff -> buffer
  672. * dwLen - buffer size
  673. * pdata -> object
  674. *
  675. * EXIT-SUCCESS
  676. * returns STATUS_SUCCESS
  677. * EXIT-FAILURE
  678. * returns AMLIERR_ code
  679. */
  680. NTSTATUS LOCAL CopyObjBuffer(PUCHAR pbBuff, ULONG dwLen, POBJDATA pdata)
  681. {
  682. TRACENAME("COPYOBJBUFFER")
  683. NTSTATUS rc = STATUS_SUCCESS;
  684. PUCHAR pb = NULL;
  685. ULONG dwcb = 0;
  686. ENTER(3, ("CopyObjBuffer(pbBuff=%x,Len=%d,pdata=%x)\n",
  687. pbBuff, dwLen, pdata));
  688. switch (pdata->dwDataType)
  689. {
  690. case OBJTYPE_INTDATA:
  691. pb = (PUCHAR)&pdata->uipDataValue;
  692. dwcb = sizeof(ULONG);
  693. break;
  694. case OBJTYPE_STRDATA:
  695. pb = pdata->pbDataBuff;
  696. dwcb = pdata->dwDataLen - 1;
  697. break;
  698. case OBJTYPE_BUFFDATA:
  699. pb = pdata->pbDataBuff;
  700. dwcb = pdata->dwDataLen;
  701. break;
  702. default:
  703. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  704. ("CopyObjBuffer: invalid source object type (type=%s)",
  705. GetObjectTypeName(pdata->dwDataType)));
  706. }
  707. if ((rc == STATUS_SUCCESS) && (pbBuff != pb))
  708. {
  709. MEMZERO(pbBuff, dwLen);
  710. dwcb = MIN(dwLen, dwcb);
  711. MEMCPY(pbBuff, pb, dwcb);
  712. }
  713. EXIT(3, ("CopyObjBuffer=%x (CopyLen=%d)\n", rc, dwcb));
  714. return rc;
  715. } //CopyObjBuffer
  716. /***LP AcquireGL - acquire global lock
  717. *
  718. * ENTRY
  719. * pctxt -> CTXT
  720. *
  721. * EXIT-SUCCESS
  722. * returns STATUS_SUCCESS
  723. * EXIT-FAILURE
  724. * returns AMLIERR_ code
  725. */
  726. NTSTATUS LOCAL AcquireGL(PCTXT pctxt)
  727. {
  728. TRACENAME("ACQUIREGL")
  729. NTSTATUS rc = STATUS_SUCCESS;
  730. ENTER(3, ("AcquireGL(pctxt=%x)\n", pctxt));
  731. if (ghGlobalLock.pfnHandler != NULL)
  732. {
  733. ASSERT(!(pctxt->dwfCtxt & CTXTF_READY));
  734. rc = ((PFNGL)ghGlobalLock.pfnHandler)(EVTYPE_ACQREL_GLOBALLOCK,
  735. GLOBALLOCK_ACQUIRE,
  736. ghGlobalLock.uipParam,
  737. RestartCtxtCallback,
  738. &pctxt->CtxtData);
  739. if (rc == STATUS_PENDING)
  740. {
  741. rc = AMLISTA_PENDING;
  742. }
  743. else if (rc != STATUS_SUCCESS)
  744. {
  745. rc = AMLI_LOGERR(AMLIERR_ACQUIREGL_FAILED,
  746. ("AcquireGL: failed to acquire global lock"));
  747. }
  748. }
  749. EXIT(3, ("AcquireGL=%x\n", rc));
  750. return rc;
  751. } //AcquireGL
  752. /***LP ReleaseGL - release global lock if acquired
  753. *
  754. * ENTRY
  755. * pctxt -> CTXT
  756. *
  757. * EXIT-SUCCESS
  758. * returns STATUS_SUCCESS
  759. * EXIT-FAILURE
  760. * returns AMLIERR_ code
  761. */
  762. NTSTATUS LOCAL ReleaseGL(PCTXT pctxt)
  763. {
  764. TRACENAME("RELEASEGL")
  765. NTSTATUS rc = STATUS_SUCCESS;
  766. ENTER(3, ("ReleaseGL(pctxt=%x)\n", pctxt));
  767. if (ghGlobalLock.pfnHandler != NULL)
  768. {
  769. rc = ((PFNGL)ghGlobalLock.pfnHandler)(EVTYPE_ACQREL_GLOBALLOCK,
  770. GLOBALLOCK_RELEASE,
  771. ghGlobalLock.uipParam, NULL,
  772. &pctxt->CtxtData);
  773. }
  774. EXIT(3, ("ReleaseGL=%x\n", rc));
  775. return rc;
  776. } //ReleaseGL
  777. /***LP MapUnmapPhysMem - Map/Unmap physical memory
  778. *
  779. * ENTRY
  780. * pctxt -> CTXT (can be NULL if cannot handle STATUS_PENDING)
  781. * uipAddr - physical address
  782. * dwLen - length of memory range
  783. * puipMappedAddr -> to hold memory address mapped (NULL if unmap)
  784. *
  785. * EXIT-SUCCESS
  786. * returns STATUS_SUCCESS
  787. * EXIT-FAILURE
  788. * returns AMLIERR_ code
  789. */
  790. NTSTATUS LOCAL MapUnmapPhysMem(PCTXT pctxt, ULONG_PTR uipAddr, ULONG dwLen,
  791. PULONG_PTR puipMappedAddr)
  792. {
  793. TRACENAME("MAPUNMAPPHYSMEM")
  794. NTSTATUS rc = STATUS_SUCCESS;
  795. ENTER(3, ("MapUnmapPhysMem(pctxt=%x,Addr=%x,Len=%d,pMappedAddr=%x)\n",
  796. pctxt, uipAddr, dwLen, puipMappedAddr));
  797. if(dwLen)
  798. {
  799. if (KeGetCurrentIrql() == PASSIVE_LEVEL)
  800. {
  801. if (puipMappedAddr != NULL)
  802. {
  803. *puipMappedAddr = MapPhysMem(uipAddr, dwLen);
  804. }
  805. else
  806. {
  807. MmUnmapIoSpace((PVOID)uipAddr, dwLen);
  808. }
  809. }
  810. else if (pctxt != NULL)
  811. {
  812. PPASSIVEHOOK pph;
  813. if ((pph = NEWPHOBJ(sizeof(PASSIVEHOOK))) == NULL)
  814. {
  815. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  816. ("MapUnmapPhysMem: failed to allocate passive hook"));
  817. }
  818. else
  819. {
  820. pph->pctxt = pctxt;
  821. pph->uipAddr = uipAddr;
  822. pph->dwLen = dwLen;
  823. pph->puipMappedAddr = puipMappedAddr;
  824. ExInitializeWorkItem(&pph->WorkItem, MapUnmapCallBack, pph);
  825. OSQueueWorkItem(&pph->WorkItem);
  826. rc = AMLISTA_PENDING;
  827. }
  828. }
  829. else
  830. {
  831. rc = AMLI_LOGERR(AMLIERR_FATAL,
  832. ("MapUnmapPhysMem: IRQL is not at PASSIVE (IRQL=%x)",
  833. KeGetCurrentIrql()));
  834. }
  835. }
  836. else
  837. {
  838. rc = AMLI_LOGERR(AMLIERR_INVALID_DATA,
  839. ("MapUnmapPhysMem: Trying to create 0 length memory opregion"));
  840. }
  841. EXIT(3, ("MapUnmapPhysMem=%x (MappedAddr=%x)\n",
  842. rc, puipMappedAddr? *puipMappedAddr: 0));
  843. return rc;
  844. } //MapUnmapPhysMem
  845. /***LP MapPhysMem - Map physical memory
  846. *
  847. * ENTRY
  848. * uipAddr - physical memory address
  849. * dwLen - length of memory block
  850. *
  851. * EXIT
  852. * returns mapped address
  853. */
  854. ULONG_PTR LOCAL MapPhysMem(ULONG_PTR uipAddr, ULONG dwLen)
  855. {
  856. TRACENAME("MAPPHYSMEM")
  857. ULONG_PTR uipMappedAddr = 0;
  858. PHYSICAL_ADDRESS phyaddr = {0, 0}, XlatedAddr;
  859. ULONG dwAddrSpace;
  860. ENTER(3, ("MapPhysMem(Addr=%x,Len=%d)\n", uipAddr, dwLen));
  861. phyaddr.HighPart = 0;
  862. phyaddr.QuadPart = uipAddr;
  863. dwAddrSpace = 0;
  864. if (HalTranslateBusAddress(Internal, 0, phyaddr, &dwAddrSpace, &XlatedAddr))
  865. {
  866. uipMappedAddr = (ULONG_PTR)MmMapIoSpace(XlatedAddr, dwLen, MmNonCached);
  867. }
  868. EXIT(3, ("MapPhysMem=%x", uipMappedAddr));
  869. return uipMappedAddr;
  870. } //MapPhysMem
  871. /***LP MapUnmapCallBack - Map/Unmap physical memory callback
  872. *
  873. * ENTRY
  874. * pph -> PASSIVEHOOK
  875. *
  876. * EXIT
  877. * None
  878. */
  879. VOID MapUnmapCallBack(PPASSIVEHOOK pph)
  880. {
  881. TRACENAME("MAPUNMAPCALLBACK")
  882. ENTER(3, ("MapUnmapCallBack(pph=%x,pctxt=%x,Addr=%x,Len=%d,pdwMappedAddr=%x)\n",
  883. pph, pph->pctxt, pph->uipAddr, pph->dwLen, pph->puipMappedAddr));
  884. ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
  885. if (pph->puipMappedAddr != NULL)
  886. {
  887. *pph->puipMappedAddr = MapPhysMem(pph->uipAddr, pph->dwLen);
  888. }
  889. else
  890. {
  891. MmUnmapIoSpace((PVOID)pph->uipAddr, pph->dwLen);
  892. }
  893. RestartContext(pph->pctxt,
  894. (BOOLEAN)((pph->pctxt->dwfCtxt & CTXTF_ASYNC_EVAL) == 0));
  895. FREEPHOBJ(pph);
  896. EXIT(3, ("MapUnmapCallBack!\n"));
  897. } //MapUnmapCallBack
  898. /***LP MatchObjType - match object type
  899. *
  900. * ENTRY
  901. * dwObjType - object type
  902. * dwExpected - expected type
  903. *
  904. * EXIT-SUCCESS
  905. * returns TRUE - type matched
  906. * EXIT-FAILURE
  907. * returns FALSE - type mismatch
  908. */
  909. BOOLEAN LOCAL MatchObjType(ULONG dwObjType, ULONG dwExpectedType)
  910. {
  911. TRACENAME("MATCHOBJTYPE")
  912. BOOLEAN rc = FALSE;
  913. ENTER(3, ("MatchObjType(ObjType=%s,Expected=%s)\n",
  914. GetObjectTypeName(dwObjType), GetObjectTypeName(dwExpectedType)));
  915. //
  916. // OBJTYPE_BUFFFIELD is essentially OBJTYPE_INTDATA, so we'll let
  917. // it pass the check.
  918. //
  919. if ((dwObjType == OBJTYPE_BUFFFIELD) &&
  920. (dwExpectedType == OBJTYPE_INTDATA))
  921. {
  922. rc = TRUE;
  923. }
  924. else if ((dwExpectedType == OBJTYPE_UNKNOWN) ||
  925. (dwObjType == OBJTYPE_UNKNOWN) ||
  926. (dwObjType == dwExpectedType))
  927. {
  928. rc = TRUE;
  929. }
  930. else
  931. {
  932. if ((dwObjType == OBJTYPE_INTDATA) ||
  933. (dwObjType == OBJTYPE_STRDATA) ||
  934. (dwObjType == OBJTYPE_BUFFDATA) ||
  935. (dwObjType == OBJTYPE_PKGDATA))
  936. {
  937. dwObjType = OBJTYPE_DATA;
  938. }
  939. else if ((dwObjType == OBJTYPE_FIELDUNIT) ||
  940. (dwObjType == OBJTYPE_BUFFFIELD))
  941. {
  942. dwObjType = OBJTYPE_DATAFIELD;
  943. }
  944. if ((dwObjType == dwExpectedType) ||
  945. (dwExpectedType == OBJTYPE_DATAOBJ) &&
  946. ((dwObjType == OBJTYPE_DATA) || (dwObjType == OBJTYPE_DATAFIELD)))
  947. {
  948. rc = TRUE;
  949. }
  950. }
  951. EXIT(3, ("MatchObjType=%x\n", rc));
  952. return rc;
  953. } //MatchObjType
  954. /***LP ValidateTarget - Validate target object type
  955. *
  956. * ENTRY
  957. * pdataTarget -> target object data
  958. * dwExpectedType - expected target object type
  959. * ppdata -> to hold base target object data pointer
  960. *
  961. * EXIT-SUCCESS
  962. * returns STATUS_SUCCESS
  963. * EXIT-FAILURE
  964. * returns AMLIERR_ code
  965. */
  966. NTSTATUS LOCAL ValidateTarget(POBJDATA pdataTarget, ULONG dwExpectedType,
  967. POBJDATA *ppdata)
  968. {
  969. TRACENAME("VALIDATETARGET")
  970. NTSTATUS rc = STATUS_SUCCESS;
  971. ENTER(3, ("ValidateTarget(pdataTarget=%x,ExpectedType=%s,ppdata=%x)\n",
  972. pdataTarget, GetObjectTypeName(dwExpectedType), ppdata));
  973. ASSERT(pdataTarget != NULL);
  974. if (pdataTarget->dwDataType == OBJTYPE_OBJALIAS)
  975. {
  976. *ppdata = &pdataTarget->pnsAlias->ObjData;
  977. }
  978. else if (pdataTarget->dwDataType == OBJTYPE_DATAALIAS)
  979. {
  980. *ppdata = pdataTarget->pdataAlias;
  981. }
  982. else if ((pdataTarget->dwDataType == OBJTYPE_UNKNOWN) ||
  983. (pdataTarget->dwDataType == OBJTYPE_BUFFFIELD) ||
  984. (pdataTarget->dwDataType == OBJTYPE_DEBUG))
  985. {
  986. *ppdata = pdataTarget;
  987. }
  988. else
  989. {
  990. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_TARGETTYPE,
  991. ("ValidateTarget: target is not a supername (Type=%s)",
  992. GetObjectTypeName(pdataTarget->dwDataType)));
  993. }
  994. if ((rc == STATUS_SUCCESS) &&
  995. (pdataTarget->dwDataType == OBJTYPE_OBJALIAS) &&
  996. !MatchObjType((*ppdata)->dwDataType, dwExpectedType))
  997. {
  998. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_TARGETTYPE,
  999. ("ValidateTarget: unexpected target type (Type=%s,Expected=%s)",
  1000. GetObjectTypeName((*ppdata)->dwDataType),
  1001. GetObjectTypeName(dwExpectedType)));
  1002. }
  1003. if ((rc == STATUS_SUCCESS) &&
  1004. (pdataTarget->dwDataType != OBJTYPE_OBJALIAS) &&
  1005. MatchObjType((*ppdata)->dwDataType, OBJTYPE_DATA))
  1006. {
  1007. FreeDataBuffs(*ppdata, 1);
  1008. }
  1009. EXIT(3, ("ValidateTarget=%x (pdataTarget=%x)\n", rc, *ppdata));
  1010. return rc;
  1011. } //ValidateTarget
  1012. /***LP ValidateArgTypes - Validate argument types
  1013. *
  1014. * ENTRY
  1015. * pArgs -> argument array
  1016. * pszExpectedTypes -> expected argument types string
  1017. *
  1018. * EXIT-SUCCESS
  1019. * returns STATUS_SUCCESS
  1020. * EXIT-FAILURE
  1021. * returns AMLIERR_ code
  1022. */
  1023. NTSTATUS LOCAL ValidateArgTypes(POBJDATA pArgs, PSZ pszExpectedTypes)
  1024. {
  1025. TRACENAME("VALIDATEARGTYPES")
  1026. NTSTATUS rc = STATUS_SUCCESS;
  1027. int icArgs, i;
  1028. ENTER(3, ("ValidateArgTypes(pArgs=%x,ExpectedTypes=%s)\n",
  1029. pArgs, pszExpectedTypes));
  1030. ASSERT(pszExpectedTypes != NULL);
  1031. icArgs = STRLEN(pszExpectedTypes);
  1032. for (i = 0; (rc == STATUS_SUCCESS) && (i < icArgs); ++i)
  1033. {
  1034. switch (pszExpectedTypes[i])
  1035. {
  1036. case ARGOBJ_UNKNOWN:
  1037. break;
  1038. case ARGOBJ_INTDATA:
  1039. if (pArgs[i].dwDataType != OBJTYPE_INTDATA)
  1040. {
  1041. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE,
  1042. ("ValidateArgTypes: expected Arg%d to be type Integer (Type=%s)",
  1043. i,
  1044. GetObjectTypeName(pArgs[i].dwDataType)));
  1045. }
  1046. break;
  1047. case ARGOBJ_STRDATA:
  1048. if (pArgs[i].dwDataType != OBJTYPE_STRDATA)
  1049. {
  1050. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE,
  1051. ("ValidateArgTypes: expected Arg%d to be type String (Type-%s)",
  1052. i,
  1053. GetObjectTypeName(pArgs[i].dwDataType)));
  1054. }
  1055. break;
  1056. case ARGOBJ_BUFFDATA:
  1057. if (pArgs[i].dwDataType != OBJTYPE_BUFFDATA)
  1058. {
  1059. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE,
  1060. ("ValidateArgTypes: expected Arg%d to be type Buffer (Type=%s)",
  1061. i,
  1062. GetObjectTypeName(pArgs[i].dwDataType)));
  1063. }
  1064. break;
  1065. case ARGOBJ_PKGDATA:
  1066. if (pArgs[i].dwDataType != OBJTYPE_PKGDATA)
  1067. {
  1068. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE,
  1069. ("ValidateArgTypes: expected Arg%d to be type Package (Type=%s)",
  1070. i,
  1071. GetObjectTypeName(pArgs[i].dwDataType)));
  1072. }
  1073. break;
  1074. case ARGOBJ_FIELDUNIT:
  1075. if (pArgs[i].dwDataType != OBJTYPE_FIELDUNIT)
  1076. {
  1077. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE,
  1078. ("ValidateArgTypes: expected Arg%d to be type FieldUnit (Type=%s)",
  1079. i,
  1080. GetObjectTypeName(pArgs[i].dwDataType)));
  1081. }
  1082. break;
  1083. case ARGOBJ_OBJALIAS:
  1084. if (pArgs[i].dwDataType != OBJTYPE_OBJALIAS)
  1085. {
  1086. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  1087. ("ValidateArgTypes: expected Arg%d to be type ObjAlias (Type=%s)",
  1088. i,
  1089. GetObjectTypeName(pArgs[i].dwDataType)));
  1090. }
  1091. break;
  1092. case ARGOBJ_DATAALIAS:
  1093. if (pArgs[i].dwDataType != OBJTYPE_DATAALIAS)
  1094. {
  1095. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  1096. ("ValidateArgTypes: expected Arg%d to be type DataAlias (Type=%s)",
  1097. i,
  1098. GetObjectTypeName(pArgs[i].dwDataType)));
  1099. }
  1100. break;
  1101. case ARGOBJ_BASICDATA:
  1102. if ((pArgs[i].dwDataType != OBJTYPE_INTDATA) &&
  1103. (pArgs[i].dwDataType != OBJTYPE_STRDATA) &&
  1104. (pArgs[i].dwDataType != OBJTYPE_BUFFDATA))
  1105. {
  1106. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  1107. ("ValidateArgTypes: expected Arg%d to be type int/str/buff (Type=%s)",
  1108. i,
  1109. GetObjectTypeName(pArgs[i].dwDataType)));
  1110. }
  1111. break;
  1112. case ARGOBJ_COMPLEXDATA:
  1113. if ((pArgs[i].dwDataType != OBJTYPE_BUFFDATA) &&
  1114. (pArgs[i].dwDataType != OBJTYPE_PKGDATA))
  1115. {
  1116. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  1117. ("ValidateArgTypes: expected Arg%d to be type buff/pkg (Type=%s)",
  1118. i,
  1119. GetObjectTypeName(pArgs[i].dwDataType)));
  1120. }
  1121. break;
  1122. case ARGOBJ_REFERENCE:
  1123. if ((pArgs[i].dwDataType != OBJTYPE_OBJALIAS) &&
  1124. (pArgs[i].dwDataType != OBJTYPE_DATAALIAS) &&
  1125. (pArgs[i].dwDataType != OBJTYPE_BUFFFIELD))
  1126. {
  1127. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_ARGTYPE,
  1128. ("ValidateArgTypes: expected Arg%d to be type reference (Type=%s)",
  1129. i,
  1130. GetObjectTypeName(pArgs[i].dwDataType)));
  1131. }
  1132. break;
  1133. default:
  1134. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  1135. ("ValidateArgTypes: internal error (invalid type - %c)",
  1136. pszExpectedTypes[i]));
  1137. }
  1138. }
  1139. EXIT(3, ("ValidateArgTypes=%x\n", rc));
  1140. return rc;
  1141. } //ValidateArgTypes
  1142. /***LP RegEventHandler - register event handler
  1143. *
  1144. * ENTRY
  1145. * peh -> EVHANDLE
  1146. * pfnHandler -> handler entry point
  1147. * uipParam - parameter pass to handler
  1148. *
  1149. * EXIT-SUCCESS
  1150. * returns STATUS_SUCCESS
  1151. * EXIT-FAILURE
  1152. * returns AMLIERR_ code
  1153. */
  1154. NTSTATUS LOCAL RegEventHandler(PEVHANDLE peh, PFNHND pfnHandler,
  1155. ULONG_PTR uipParam)
  1156. {
  1157. TRACENAME("REGEVENTHANDLER")
  1158. NTSTATUS rc = STATUS_SUCCESS;
  1159. ENTER(3, ("RegEventHandler(peh=%x,pfnHandler=%x,Param=%x)\n",
  1160. peh, pfnHandler, uipParam));
  1161. if ((peh->pfnHandler != NULL) && (pfnHandler != NULL))
  1162. {
  1163. rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST,
  1164. ("RegEventHandler: event handler already exist"));
  1165. }
  1166. else
  1167. {
  1168. peh->pfnHandler = pfnHandler;
  1169. peh->uipParam = uipParam;
  1170. }
  1171. EXIT(3, ("RegEventHandler=%x\n", rc));
  1172. return rc;
  1173. } //RegEventHandler
  1174. /***LP RegOpcodeHandler - register an opcode callback handler
  1175. *
  1176. * The callback handler will be called after the opcode finishes its
  1177. * execution. If an opcode has a variable list, the opcode handler
  1178. * will be called at the point of processing the closing brace.
  1179. *
  1180. * ENTRY
  1181. * dwOpcode - opcode event to hook
  1182. * pfnHandler -> handler entry point
  1183. * uipParam - parameter pass to handler
  1184. * dwfOpcode - opcode flags
  1185. *
  1186. * EXIT-SUCCESS
  1187. * returns STATUS_SUCCESS
  1188. * EXIT-FAILURE
  1189. * returns AMLIERR_ code
  1190. */
  1191. NTSTATUS LOCAL RegOpcodeHandler(ULONG dwOpcode, PFNOH pfnHandler,
  1192. ULONG_PTR uipParam, ULONG dwfOpcode)
  1193. {
  1194. TRACENAME("REGOPCODEHANDLER")
  1195. NTSTATUS rc = STATUS_SUCCESS;
  1196. PAMLTERM pamlterm;
  1197. ENTER(3, ("RegOpcodeHandler(Opcode=%x,pfnHandler=%x,Param=%x,dwfOpcode=%x)\n",
  1198. dwOpcode, pfnHandler, uipParam, dwfOpcode));
  1199. if ((dwOpcode & 0xff) == OP_EXT_PREFIX)
  1200. pamlterm = FindOpcodeTerm(dwOpcode >> 8, ExOpcodeTable);
  1201. else
  1202. pamlterm = OpcodeTable[dwOpcode];
  1203. if (pamlterm == NULL)
  1204. {
  1205. rc = AMLI_LOGERR(AMLIERR_REGHANDLER_FAILED,
  1206. ("RegOpcodeHandler: either invalid opcode or "
  1207. "opcode does not allow callback"));
  1208. }
  1209. else if ((pamlterm->pfnCallBack != NULL) && (pfnHandler != NULL))
  1210. {
  1211. rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST,
  1212. ("RegOpcodeHandler: opcode or opcode class already "
  1213. "has a handler"));
  1214. }
  1215. else
  1216. {
  1217. pamlterm->pfnCallBack = pfnHandler;
  1218. pamlterm->dwCBData = (ULONG)uipParam;
  1219. pamlterm->dwfOpcode |= dwfOpcode;
  1220. }
  1221. EXIT(3, ("RegOpcodeHandler=%x\n", rc));
  1222. return rc;
  1223. } //RegOpcodeHandler
  1224. /***LP RegRSAccess - register region space cook/raw access handler
  1225. *
  1226. * ENTRY
  1227. * dwRegionSpace - specifying the region space to handle
  1228. * pfnHandler -> handler entry point
  1229. * uipParam - parameter pass to handler
  1230. * fRaw - TRUE if registering raw access handler
  1231. *
  1232. * EXIT-SUCCESS
  1233. * returns STATUS_SUCCESS
  1234. * EXIT-FAILURE
  1235. * returns AMLIERR_ code
  1236. */
  1237. NTSTATUS LOCAL RegRSAccess(ULONG dwRegionSpace, PFNHND pfnHandler,
  1238. ULONG_PTR uipParam, BOOLEAN fRaw)
  1239. {
  1240. TRACENAME("REGRSACCESS")
  1241. NTSTATUS rc = STATUS_SUCCESS;
  1242. ENTER(3, ("RegRSAccess(RegionSpace=%x,pfnHandler=%x,Param=%x,fRaw=%x)\n",
  1243. dwRegionSpace, pfnHandler, uipParam, fRaw));
  1244. if ((dwRegionSpace != REGSPACE_MEM) && (dwRegionSpace != REGSPACE_IO))
  1245. {
  1246. PRSACCESS prsa;
  1247. if ((prsa = FindRSAccess(dwRegionSpace)) == NULL)
  1248. {
  1249. if ((prsa = NEWRSOBJ(sizeof(RSACCESS))) == NULL)
  1250. {
  1251. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  1252. ("RegRSAccess: failed to allocate handler structure"));
  1253. }
  1254. else
  1255. {
  1256. MEMZERO(prsa, sizeof(RSACCESS));
  1257. prsa->dwRegionSpace = dwRegionSpace;
  1258. prsa->prsaNext = gpRSAccessHead;
  1259. gpRSAccessHead = prsa;
  1260. }
  1261. }
  1262. if (rc == STATUS_SUCCESS)
  1263. {
  1264. if (fRaw)
  1265. {
  1266. if ((prsa->pfnRawAccess != NULL) && (pfnHandler != NULL))
  1267. {
  1268. rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST,
  1269. ("RegRSAccess: RawAccess for RegionSpace %x "
  1270. "already have a handler", dwRegionSpace));
  1271. }
  1272. else
  1273. {
  1274. prsa->pfnRawAccess = (PFNRA)pfnHandler;
  1275. prsa->uipRawParam = uipParam;
  1276. }
  1277. }
  1278. else
  1279. {
  1280. if ((prsa->pfnCookAccess != NULL) && (pfnHandler != NULL))
  1281. {
  1282. rc = AMLI_LOGERR(AMLIERR_HANDLER_EXIST,
  1283. ("RegRSAccess: CookAccess for RegionSpace %x "
  1284. "already have a handler", dwRegionSpace));
  1285. }
  1286. else
  1287. {
  1288. prsa->pfnCookAccess = (PFNCA)pfnHandler;
  1289. prsa->uipCookParam = uipParam;
  1290. }
  1291. }
  1292. }
  1293. }
  1294. else
  1295. {
  1296. rc = AMLI_LOGERR(AMLIERR_INVALID_REGIONSPACE,
  1297. ("RegRSAccess: illegal region space - %x",
  1298. dwRegionSpace));
  1299. }
  1300. EXIT(3, ("RegRSAccess=%x\n", rc));
  1301. return rc;
  1302. } //RegRSAccess
  1303. /***LP FindRSAccess - Find RSACCESS structure with a given RegionSpace
  1304. *
  1305. * ENTRY
  1306. * dwRegionSpace - region space
  1307. *
  1308. * EXIT-SUCCESS
  1309. * returns the pointer to the structure found
  1310. * EXIT-FAILURE
  1311. * returns NULL
  1312. */
  1313. PRSACCESS LOCAL FindRSAccess(ULONG dwRegionSpace)
  1314. {
  1315. TRACENAME("FINDRSACCESS")
  1316. PRSACCESS prsa;
  1317. ENTER(3, ("FindRSAccess(RegionSpace=%x)\n", dwRegionSpace));
  1318. for (prsa = gpRSAccessHead; prsa != NULL; prsa = prsa->prsaNext)
  1319. {
  1320. if (prsa->dwRegionSpace == dwRegionSpace)
  1321. break;
  1322. }
  1323. EXIT(3, ("FindRSAccess=%x\n", prsa));
  1324. return prsa;
  1325. } //FindRSAccess
  1326. /***LP FreeRSAccessList - free the RSACCESS structure list
  1327. *
  1328. * ENTRY
  1329. * prsa -> RSACCESS list
  1330. *
  1331. * EXIT
  1332. * None
  1333. */
  1334. VOID LOCAL FreeRSAccessList(PRSACCESS prsa)
  1335. {
  1336. TRACENAME("FREERSACCESSLIST")
  1337. PRSACCESS prsaNext;
  1338. ENTER(3, ("FreeRSAccessList(prsa=%x)\n", prsa));
  1339. while (prsa != NULL)
  1340. {
  1341. prsaNext = prsa->prsaNext;
  1342. FREERSOBJ(prsa);
  1343. prsa = prsaNext;
  1344. }
  1345. EXIT(3, ("FreeRSAccessList!\n"));
  1346. } //FreeRSAccessList
  1347. /***LP GetObjectPath - get object namespace path
  1348. *
  1349. * ENTRY
  1350. * pns -> object
  1351. *
  1352. * EXIT
  1353. * returns name space path
  1354. */
  1355. PSZ LOCAL GetObjectPath(PNSOBJ pns)
  1356. {
  1357. TRACENAME("GETOBJECTPATH")
  1358. static char szPath[MAX_NAME_LEN + 1] = {0};
  1359. int i;
  1360. ENTER(4, ("GetObjectPath(pns=%x)\n", pns));
  1361. if (pns != NULL)
  1362. {
  1363. if (pns->pnsParent == NULL)
  1364. STRCPY(szPath, "\\");
  1365. else
  1366. {
  1367. GetObjectPath(pns->pnsParent);
  1368. if (pns->pnsParent->pnsParent != NULL)
  1369. STRCAT(szPath, ".");
  1370. STRCATN(szPath, (PSZ)&pns->dwNameSeg, sizeof(NAMESEG));
  1371. }
  1372. for (i = STRLEN(szPath) - 1; i >= 0; --i)
  1373. {
  1374. if (szPath[i] == '_')
  1375. szPath[i] = '\0';
  1376. else
  1377. break;
  1378. }
  1379. }
  1380. else
  1381. {
  1382. szPath[0] = '\0';
  1383. }
  1384. EXIT(4, ("GetObjectPath=%s\n", szPath));
  1385. return szPath;
  1386. } //GetObjectPath
  1387. #ifdef DEBUGGER
  1388. /***LP NameSegString - convert a NameSeg to an ASCIIZ string
  1389. *
  1390. * ENTRY
  1391. * dwNameSeg - NameSeg
  1392. *
  1393. * EXIT
  1394. * returns string
  1395. */
  1396. PSZ LOCAL NameSegString(ULONG dwNameSeg)
  1397. {
  1398. TRACENAME("NAMESEGSTRING")
  1399. static char szNameSeg[sizeof(NAMESEG) + 1] = {0};
  1400. ENTER(5, ("NameSegString(dwNameSeg=%x)\n", dwNameSeg));
  1401. STRCPYN(szNameSeg, (PSZ)&dwNameSeg, sizeof(NAMESEG));
  1402. EXIT(5, ("NameSegString=%s\n", szNameSeg));
  1403. return szNameSeg;
  1404. } //NameSegString
  1405. /***LP GetObjectTypeName - get object type name
  1406. *
  1407. * ENTRY
  1408. * dwObjType - object type
  1409. *
  1410. * EXIT
  1411. * return object type name
  1412. */
  1413. PSZ LOCAL GetObjectTypeName(ULONG dwObjType)
  1414. {
  1415. TRACENAME("GETOBJECTTYPENAME")
  1416. PSZ psz = NULL;
  1417. int i;
  1418. static struct
  1419. {
  1420. ULONG dwObjType;
  1421. PSZ pszObjTypeName;
  1422. } ObjTypeTable[] =
  1423. {
  1424. OBJTYPE_UNKNOWN, "Unknown",
  1425. OBJTYPE_INTDATA, "Integer",
  1426. OBJTYPE_STRDATA, "String",
  1427. OBJTYPE_BUFFDATA, "Buffer",
  1428. OBJTYPE_PKGDATA, "Package",
  1429. OBJTYPE_FIELDUNIT, "FieldUnit",
  1430. OBJTYPE_DEVICE, "Device",
  1431. OBJTYPE_EVENT, "Event",
  1432. OBJTYPE_METHOD, "Method",
  1433. OBJTYPE_MUTEX, "Mutex",
  1434. OBJTYPE_OPREGION, "OpRegion",
  1435. OBJTYPE_POWERRES, "PowerResource",
  1436. OBJTYPE_PROCESSOR, "Processor",
  1437. OBJTYPE_THERMALZONE,"ThermalZone",
  1438. OBJTYPE_BUFFFIELD, "BuffField",
  1439. OBJTYPE_DDBHANDLE, "DDBHandle",
  1440. OBJTYPE_DEBUG, "Debug",
  1441. OBJTYPE_OBJALIAS, "ObjAlias",
  1442. OBJTYPE_DATAALIAS, "DataAlias",
  1443. OBJTYPE_BANKFIELD, "BankField",
  1444. OBJTYPE_FIELD, "Field",
  1445. OBJTYPE_INDEXFIELD, "IndexField",
  1446. OBJTYPE_DATA, "Data",
  1447. OBJTYPE_DATAFIELD, "DataField",
  1448. OBJTYPE_DATAOBJ, "DataObject",
  1449. 0, NULL
  1450. };
  1451. ENTER(4, ("GetObjectTypeName(Type=%x)\n", dwObjType));
  1452. for (i = 0; ObjTypeTable[i].pszObjTypeName != NULL; ++i)
  1453. {
  1454. if (dwObjType == ObjTypeTable[i].dwObjType)
  1455. {
  1456. psz = ObjTypeTable[i].pszObjTypeName;
  1457. break;
  1458. }
  1459. }
  1460. EXIT(4, ("GetObjectTypeName=%s\n", psz? psz: "NULL"));
  1461. return psz;
  1462. } //GetObjectTypeName
  1463. /***LP GetRegionSpaceName - get region space name
  1464. *
  1465. * ENTRY
  1466. * bRegionSpace - region space
  1467. *
  1468. * EXIT
  1469. * return object type name
  1470. */
  1471. PSZ LOCAL GetRegionSpaceName(UCHAR bRegionSpace)
  1472. {
  1473. TRACENAME("GETREGIONSPACENAME")
  1474. PSZ psz = NULL;
  1475. int i;
  1476. static PSZ pszVendorDefined = "VendorDefined";
  1477. static struct
  1478. {
  1479. UCHAR bRegionSpace;
  1480. PSZ pszRegionSpaceName;
  1481. } RegionNameTable[] =
  1482. {
  1483. REGSPACE_MEM, "SystemMemory",
  1484. REGSPACE_IO, "SystemIO",
  1485. REGSPACE_PCICFG, "PCIConfigSpace",
  1486. REGSPACE_EC, "EmbeddedController",
  1487. REGSPACE_SMB, "SMBus",
  1488. 0, NULL
  1489. };
  1490. ENTER(4, ("GetRegionSpaceName(RegionSpace=%x)\n", bRegionSpace));
  1491. for (i = 0; RegionNameTable[i].pszRegionSpaceName != NULL; ++i)
  1492. {
  1493. if (bRegionSpace == RegionNameTable[i].bRegionSpace)
  1494. {
  1495. psz = RegionNameTable[i].pszRegionSpaceName;
  1496. break;
  1497. }
  1498. }
  1499. if (psz == NULL)
  1500. {
  1501. psz = pszVendorDefined;
  1502. }
  1503. EXIT(4, ("GetRegionSpaceName=%s\n", psz? psz: "NULL"));
  1504. return psz;
  1505. } //GetRegionSpaceName
  1506. #endif //ifdef DEBUGGER
  1507. /***LP ValidateTable - Validate the table creator and revision
  1508. *
  1509. * ENTRY
  1510. * pdsdt -> DSDT
  1511. *
  1512. * EXIT-SUCCESS
  1513. * returns TRUE
  1514. * EXIT-FAILURE
  1515. * returns FALSE
  1516. */
  1517. BOOLEAN LOCAL ValidateTable(PDSDT pdsdt)
  1518. {
  1519. TRACENAME("VALIDATETABLE")
  1520. BOOLEAN rc = TRUE;
  1521. ENTER(3, ("ValidateTable(pdsdt=%x)\n", pdsdt));
  1522. if (!(gdwfAMLIInit & AMLIIF_NOCHK_TABLEVER) &&
  1523. (STRCMPN((PSZ)pdsdt->Header.CreatorID, CREATORID_MSFT,
  1524. sizeof(pdsdt->Header.CreatorID)) == 0))
  1525. {
  1526. if (pdsdt->Header.CreatorRev < MIN_CREATOR_REV)
  1527. {
  1528. rc = FALSE;
  1529. }
  1530. }
  1531. EXIT(3, ("ValidateTable=%x\n", rc));
  1532. return rc;
  1533. } //ValidateTable
  1534. /***LP NewObjData - allocate new object data identical to a given old object
  1535. *
  1536. * ENTRY
  1537. * pheap -> HEAP
  1538. * pdata -> old object
  1539. *
  1540. * EXIT-SUCCESS
  1541. * returns pointer to the new data
  1542. * EXIT-FAILURE
  1543. * returns NULL
  1544. */
  1545. PVOID LOCAL NewObjData(PHEAP pheap, POBJDATA pdata)
  1546. {
  1547. PVOID pv = NULL;
  1548. switch (pdata->dwDataType)
  1549. {
  1550. case OBJTYPE_STRDATA:
  1551. pv = NEWSDOBJ(gpheapGlobal, pdata->dwDataLen);
  1552. break;
  1553. case OBJTYPE_BUFFDATA:
  1554. pv = NEWBDOBJ(gpheapGlobal, pdata->dwDataLen);
  1555. break;
  1556. case OBJTYPE_PKGDATA:
  1557. pv = NEWPKOBJ(gpheapGlobal, pdata->dwDataLen);
  1558. break;
  1559. case OBJTYPE_FIELDUNIT:
  1560. pv = NEWFUOBJ(pheap, pdata->dwDataLen);
  1561. break;
  1562. case OBJTYPE_EVENT:
  1563. pv = NEWEVOBJ(pheap, pdata->dwDataLen);
  1564. break;
  1565. case OBJTYPE_METHOD:
  1566. pv = NEWMEOBJ(pheap, pdata->dwDataLen);
  1567. break;
  1568. case OBJTYPE_MUTEX:
  1569. pv = NEWMTOBJ(pheap, pdata->dwDataLen);
  1570. break;
  1571. case OBJTYPE_OPREGION:
  1572. pv = NEWOROBJ(pheap, pdata->dwDataLen);
  1573. break;
  1574. case OBJTYPE_POWERRES:
  1575. pv = NEWPROBJ(pheap, pdata->dwDataLen);
  1576. break;
  1577. case OBJTYPE_PROCESSOR:
  1578. pv = NEWPCOBJ(pheap, pdata->dwDataLen);
  1579. break;
  1580. case OBJTYPE_BUFFFIELD:
  1581. pv = NEWBFOBJ(pheap, pdata->dwDataLen);
  1582. break;
  1583. case OBJTYPE_BANKFIELD:
  1584. pv = NEWKFOBJ(pheap, pdata->dwDataLen);
  1585. break;
  1586. case OBJTYPE_FIELD:
  1587. pv = NEWFOBJ(pheap, pdata->dwDataLen);
  1588. break;
  1589. case OBJTYPE_INDEXFIELD:
  1590. pv = NEWIFOBJ(pheap, pdata->dwDataLen);
  1591. break;
  1592. default:
  1593. AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  1594. ("NewObjData: invalid object type %s",
  1595. GetObjectTypeName(pdata->dwDataType)));
  1596. }
  1597. return pv;
  1598. } //NewObjData
  1599. /***LP FreeObjData - Free object data
  1600. *
  1601. * ENTRY
  1602. * pdata -> object which its data is to be freed
  1603. *
  1604. * EXIT
  1605. * None
  1606. */
  1607. VOID LOCAL FreeObjData(POBJDATA pdata)
  1608. {
  1609. switch (pdata->dwDataType)
  1610. {
  1611. case OBJTYPE_STRDATA:
  1612. FREESDOBJ(pdata->pbDataBuff);
  1613. break;
  1614. case OBJTYPE_BUFFDATA:
  1615. FREEBDOBJ(pdata->pbDataBuff);
  1616. break;
  1617. case OBJTYPE_PKGDATA:
  1618. FREEPKOBJ(pdata->pbDataBuff);
  1619. break;
  1620. case OBJTYPE_FIELDUNIT:
  1621. FREEFUOBJ(pdata->pbDataBuff);
  1622. break;
  1623. case OBJTYPE_EVENT:
  1624. FREEEVOBJ(pdata->pbDataBuff);
  1625. break;
  1626. case OBJTYPE_METHOD:
  1627. FREEMEOBJ(pdata->pbDataBuff);
  1628. break;
  1629. case OBJTYPE_MUTEX:
  1630. FREEMTOBJ(pdata->pbDataBuff);
  1631. break;
  1632. case OBJTYPE_OPREGION:
  1633. FREEOROBJ(pdata->pbDataBuff);
  1634. break;
  1635. case OBJTYPE_POWERRES:
  1636. FREEPROBJ(pdata->pbDataBuff);
  1637. break;
  1638. case OBJTYPE_PROCESSOR:
  1639. FREEPCOBJ(pdata->pbDataBuff);
  1640. break;
  1641. case OBJTYPE_BUFFFIELD:
  1642. FREEBFOBJ(pdata->pbDataBuff);
  1643. break;
  1644. case OBJTYPE_BANKFIELD:
  1645. FREEKFOBJ(pdata->pbDataBuff);
  1646. break;
  1647. case OBJTYPE_FIELD:
  1648. FREEFOBJ(pdata->pbDataBuff);
  1649. break;
  1650. case OBJTYPE_INDEXFIELD:
  1651. FREEIFOBJ(pdata->pbDataBuff);
  1652. break;
  1653. default:
  1654. AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  1655. ("FreeObjData: invalid object type %s",
  1656. GetObjectTypeName(pdata->dwDataType)));
  1657. }
  1658. } //FreeObjData
  1659. /*** LP InitializeRegOverrideFlags - Get override flags from
  1660. * the registry.
  1661. *
  1662. * ENTRY
  1663. * None
  1664. *
  1665. * EXIT
  1666. * None
  1667. */
  1668. VOID LOCAL InitializeRegOverrideFlags(VOID)
  1669. {
  1670. TRACENAME("InitializeRegOverrideFlags")
  1671. HANDLE hRegKey=NULL;
  1672. NTSTATUS status;
  1673. ULONG argSize;
  1674. ENTER(3, ("InitializeRegOverrideFlags\n"));
  1675. status = OSOpenHandle(ACPI_PARAMETERS_REGISTRY_KEY, NULL, &hRegKey);
  1676. if (NT_SUCCESS(status))
  1677. {
  1678. argSize = sizeof(gOverrideFlags);
  1679. OSReadRegValue(AMLI_ATTRIBUTES, hRegKey, &gOverrideFlags, &argSize);
  1680. }
  1681. else
  1682. {
  1683. gOverrideFlags = 0;
  1684. }
  1685. EXIT(3, ("InitializeRegOverrideFlags\n"));
  1686. return;
  1687. }
  1688. /*** LP ValidateMemoryOpregionRange - Validate the memory range that is
  1689. * required for the memory opregion.
  1690. *
  1691. * ENTRY
  1692. * uipAddr - physical memory address
  1693. * dwLen - length of memory block
  1694. *
  1695. * EXIT
  1696. * returns TRUE iff the memory is in the legal range.
  1697. */
  1698. BOOLEAN LOCAL ValidateMemoryOpregionRange(ULONG_PTR uipAddr, ULONG dwLen)
  1699. {
  1700. BOOLEAN Ret = FALSE;
  1701. NTSTATUS status;
  1702. PACPI_BIOS_MULTI_NODE e820Info;
  1703. PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartialDesc;
  1704. PCM_PARTIAL_RESOURCE_LIST cmPartialList;
  1705. PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64 keyInfo;
  1706. ULONGLONG i;
  1707. ULONGLONG absMin;
  1708. ULONGLONG absMax;
  1709. //
  1710. // Read the key for the AcpiConfigurationData
  1711. //
  1712. status = OSReadAcpiConfigurationData( &keyInfo );
  1713. if (!NT_SUCCESS(status))
  1714. {
  1715. PRINTF("ValidateMemoryOpregionRange: Cannot get E820 Information %08lx\n",
  1716. status
  1717. );
  1718. Ret = TRUE;
  1719. }
  1720. else
  1721. {
  1722. //
  1723. // Crack the structure to get the E820Table entry
  1724. //
  1725. cmPartialList = (PCM_PARTIAL_RESOURCE_LIST) (keyInfo->Data);
  1726. cmPartialDesc = &(cmPartialList->PartialDescriptors[0]);
  1727. e820Info = (PACPI_BIOS_MULTI_NODE) ( (PUCHAR) cmPartialDesc + sizeof(CM_PARTIAL_RESOURCE_LIST) );
  1728. //
  1729. // Calculate absmin and absmax for the incoming address
  1730. //
  1731. absMin = (ULONGLONG)uipAddr;
  1732. absMax = absMin + dwLen;
  1733. //
  1734. // walk the E820 list
  1735. //
  1736. for(i = 0; i < e820Info->Count; i++)
  1737. {
  1738. if (e820Info->E820Entry[i].Type == AcpiAddressRangeMemory)
  1739. {
  1740. if(absMax < (ULONGLONG)PAGE_SIZE)
  1741. {
  1742. Ret = TRUE;
  1743. PRINTF("ValidateMemoryOpregionRange: Memory OpRegion (Base = 0x%I64x, Length = 0x%x) is in first physical page, skipping check.\n",
  1744. absMin,
  1745. dwLen
  1746. );
  1747. }
  1748. else
  1749. {
  1750. if((absMax < (ULONGLONG) e820Info->E820Entry[i].Base.QuadPart)
  1751. ||(absMin >= (ULONGLONG) (e820Info->E820Entry[i].Base.QuadPart + e820Info->E820Entry[i].Length.QuadPart)))
  1752. {
  1753. Ret = TRUE;
  1754. PRINTF("ValidateMemoryOpregionRange: Memory OpRegion (Base = 0x%I64x, Length = 0x%x) is not in AcpiAddressRangeMemory (Base = 0x%I64x, Length = 0x%I64x)\n",
  1755. absMin,
  1756. dwLen,
  1757. e820Info->E820Entry[i].Base.QuadPart,
  1758. e820Info->E820Entry[i].Length.QuadPart
  1759. );
  1760. }
  1761. else
  1762. {
  1763. //
  1764. // This opregion is mapping memory that belongs to the OS.
  1765. // Log a error in the event log.
  1766. //
  1767. PWCHAR illegalMemoryAddress[5];
  1768. WCHAR AMLIName[6];
  1769. WCHAR addressBuffer[64];
  1770. WCHAR addressLengthBuffer[64];
  1771. WCHAR OSaddressBufferRangeMin[64];
  1772. WCHAR OSaddressBufferRangeMax[64];
  1773. //
  1774. // Turn the address into a string
  1775. //
  1776. swprintf( AMLIName, L"AMLI");
  1777. swprintf( addressBuffer, L"0x%I64x", absMin );
  1778. swprintf( addressLengthBuffer, L"0x%lx", dwLen );
  1779. swprintf( OSaddressBufferRangeMin, L"0x%I64x", e820Info->E820Entry[i].Base.QuadPart );
  1780. swprintf( OSaddressBufferRangeMax, L"0x%I64x", e820Info->E820Entry[i].Base.QuadPart + e820Info->E820Entry[i].Length.QuadPart);
  1781. //
  1782. // Build the list of arguments to pass to the function that will write the
  1783. // error log to the registry
  1784. //
  1785. illegalMemoryAddress[0] = AMLIName;
  1786. illegalMemoryAddress[1] = addressBuffer;
  1787. illegalMemoryAddress[2] = addressLengthBuffer;
  1788. illegalMemoryAddress[3] = OSaddressBufferRangeMin;
  1789. illegalMemoryAddress[4] = OSaddressBufferRangeMax;
  1790. //
  1791. // Log error to event log
  1792. //
  1793. ACPIWriteEventLogEntry(ACPI_ERR_AMLI_ILLEGAL_MEMORY_OPREGION_FATAL,
  1794. illegalMemoryAddress,
  1795. 5,
  1796. NULL,
  1797. 0);
  1798. PRINTF("ValidateMemoryOpregionRange: Memory OpRegion (Base = 0x%I64x, Length = 0x%x) is in AcpiAddressRangeMemory (Base = 0x%I64x, Length = 0x%I64x)\n",
  1799. absMin,
  1800. dwLen,
  1801. e820Info->E820Entry[i].Base.QuadPart,
  1802. e820Info->E820Entry[i].Length.QuadPart
  1803. );
  1804. Ret = FALSE;
  1805. break;
  1806. }
  1807. }
  1808. }
  1809. }
  1810. //
  1811. // Free the E820 info
  1812. //
  1813. ExFreePool( keyInfo );
  1814. }
  1815. return Ret;
  1816. }
  1817. #ifdef DEBUG
  1818. /*** LP FreeMem - Free memory object
  1819. *
  1820. * ENTRY
  1821. * pv -> memory object to be freed
  1822. * pdwcObjs -> object counter to be decremented
  1823. *
  1824. * EXIT
  1825. * None
  1826. */
  1827. VOID LOCAL FreeMem(PVOID pv, PULONG pdwcObjs)
  1828. {
  1829. if (*pdwcObjs != 0)
  1830. {
  1831. ExFreePool(pv);
  1832. (*pdwcObjs)--;
  1833. }
  1834. else
  1835. {
  1836. AMLI_ERROR(("FreeMem: Unbalanced MemFree"));
  1837. }
  1838. } //FreeMem
  1839. /*** LP CheckGlobalHeap - Make sure that the global heap has not become
  1840. * corrupted
  1841. *
  1842. * ENTRY
  1843. * None
  1844. *
  1845. * Exit
  1846. * None
  1847. */
  1848. VOID LOCAL CheckGlobalHeap()
  1849. {
  1850. KIRQL oldIrql;
  1851. //
  1852. // We don't care about this is we are loading a DDB
  1853. //
  1854. if (gdwfAMLI & AMLIF_LOADING_DDB) {
  1855. return;
  1856. }
  1857. //
  1858. // Must have spinlock protection...
  1859. //
  1860. KeAcquireSpinLock( &gdwGHeapSpinLock, &oldIrql );
  1861. //
  1862. // We only care if they don't match...
  1863. //
  1864. if (gdwGlobalHeapSize == gdwGHeapSnapshot) {
  1865. goto CheckGlobalHeapExit;
  1866. }
  1867. //
  1868. // If the new heap size is smaller than the current size, then
  1869. // we shrunk the heap and that is good...
  1870. //
  1871. if (gdwGlobalHeapSize < gdwGHeapSnapshot) {
  1872. //
  1873. // Remember the new "snapshot size"
  1874. //
  1875. gdwGHeapSnapshot = gdwGlobalHeapSize;
  1876. goto CheckGlobalHeapExit;
  1877. }
  1878. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON) {
  1879. AMLI_WARN(("CheckGlobalHeap: "
  1880. "potential memory leak "
  1881. "detected (CurrentHeapSize=%d,"
  1882. "ReferenceSize=%d)",
  1883. gdwGlobalHeapSize,
  1884. gdwGHeapSnapshot));
  1885. }
  1886. if (gdwGlobalHeapSize - gdwGHeapSnapshot > 8192) {
  1887. AMLI_WARN(("CheckGlobalHeap: detected memory leak"));
  1888. KdBreakPoint();
  1889. }
  1890. CheckGlobalHeapExit:
  1891. //
  1892. // Release the lock and we are done
  1893. //
  1894. KeReleaseSpinLock( &gdwGHeapSpinLock, oldIrql );
  1895. }
  1896. #endif //ifdef DEBUG