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.

1903 lines
54 KiB

  1. /*** parser.c - AML Parser
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created 06/13/97
  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 ParseScope - Parse a scope
  15. *
  16. * ENTRY
  17. * pctxt -> CTXT
  18. * pscope -> SCOPE
  19. * rc - status code
  20. *
  21. * EXIT-SUCCESS
  22. * returns STATUS_SUCCESS
  23. * EXIT-FAILURE
  24. * returns AMLIERR_ code
  25. */
  26. NTSTATUS LOCAL ParseScope(PCTXT pctxt, PSCOPE pscope, NTSTATUS rc)
  27. {
  28. TRACENAME("PARSESCOPE")
  29. ULONG dwStage = ((rc == STATUS_SUCCESS) || (rc == AMLISTA_BREAK))?
  30. (pscope->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2;
  31. ENTER(2, ("ParseScope(Stage=%d,pctxt=%p,pbOp=%p,pscope=%p,rc=%x)\n",
  32. dwStage, pctxt, pctxt->pbOp, pscope, rc));
  33. ASSERT(pscope->FrameHdr.dwSig == SIG_SCOPE);
  34. switch (dwStage)
  35. {
  36. case 0:
  37. //
  38. // Stage 0: Do debug print if necessary.
  39. //
  40. #ifdef DEBUGGER
  41. if (gDebugger.dwfDebugger &
  42. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  43. {
  44. PrintIndent(pctxt);
  45. PRINTF("{");
  46. gDebugger.iPrintLevel++;
  47. pscope->FrameHdr.dwfFrame |= SCOPEF_FIRST_TERM;
  48. }
  49. #endif
  50. //
  51. // There is nothing blockable, so continue to next stage.
  52. //
  53. pscope->FrameHdr.dwfFrame++;
  54. case 1:
  55. Stage1:
  56. //
  57. // Stage 1: Parse next opcode.
  58. //
  59. if (rc == AMLISTA_BREAK)
  60. {
  61. pctxt->pbOp = pscope->pbOpEnd;
  62. rc = STATUS_SUCCESS;
  63. }
  64. else
  65. {
  66. while (pctxt->pbOp < pscope->pbOpEnd)
  67. {
  68. #ifdef DEBUGGER
  69. gDebugger.pbUnAsm = pctxt->pbOp;
  70. if (gDebugger.dwfDebugger &
  71. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  72. {
  73. if (pscope->FrameHdr.dwfFrame & SCOPEF_FIRST_TERM)
  74. {
  75. pscope->FrameHdr.dwfFrame &= ~SCOPEF_FIRST_TERM;
  76. }
  77. else if (gDebugger.dwfDebugger & DBGF_STEP_OVER)
  78. {
  79. gDebugger.dwfDebugger &= ~DBGF_STEP_OVER;
  80. AMLIDebugger(FALSE);
  81. }
  82. }
  83. if ((gDebugger.dwfDebugger &
  84. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) &&
  85. (*pctxt->pbOp != OP_PACKAGE))
  86. {
  87. PrintIndent(pctxt);
  88. }
  89. #endif
  90. //
  91. // Discard result of previous term if any.
  92. //
  93. FreeDataBuffs(pscope->pdataResult, 1);
  94. if (((rc = ParseOpcode(pctxt, pscope->pbOpEnd,
  95. pscope->pdataResult)) !=
  96. STATUS_SUCCESS) ||
  97. (&pscope->FrameHdr !=
  98. (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  99. {
  100. break;
  101. }
  102. }
  103. if (rc == AMLISTA_BREAK)
  104. {
  105. pctxt->pbOp = pscope->pbOpEnd;
  106. rc = STATUS_SUCCESS;
  107. }
  108. else if ((rc == AMLISTA_PENDING) ||
  109. (&pscope->FrameHdr !=
  110. (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  111. {
  112. break;
  113. }
  114. else if ((rc == STATUS_SUCCESS) &&
  115. (pctxt->pbOp < pscope->pbOpEnd))
  116. {
  117. goto Stage1;
  118. }
  119. }
  120. //
  121. // If we come here, there was no more opcode in this scope, so
  122. // continue to next stage.
  123. //
  124. pscope->FrameHdr.dwfFrame++;
  125. case 2:
  126. //
  127. // Stage 2: clean up.
  128. //
  129. #ifdef DEBUGGER
  130. if (gDebugger.dwfDebugger &
  131. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  132. {
  133. gDebugger.iPrintLevel--;
  134. PrintIndent(pctxt);
  135. PRINTF("}");
  136. }
  137. #endif
  138. pctxt->pnsScope = pscope->pnsPrevScope;
  139. pctxt->powner = pscope->pownerPrev;
  140. pctxt->pheapCurrent = pscope->pheapPrev;
  141. if (pscope->pbOpRet != NULL)
  142. {
  143. pctxt->pbOp = pscope->pbOpRet;
  144. }
  145. PopFrame(pctxt);
  146. }
  147. EXIT(2, ("ParseScope=%x\n", rc));
  148. return rc;
  149. } //ParseScope
  150. /***LP ParseNestedContext - Parse and evaluate a nested context
  151. *
  152. * ENTRY
  153. * pctxt -> CTXT
  154. * pcall -> CALL
  155. * rc - status code
  156. *
  157. * EXIT-SUCCESS
  158. * returns STATUS_SUCCESS
  159. * EXIT-FAILURE
  160. * returns AMLIERR_ code
  161. */
  162. NTSTATUS LOCAL ParseNestedContext(PCTXT pctxt, PNESTEDCTXT pnctxt, NTSTATUS rc)
  163. {
  164. TRACENAME("PARSENESTEDCONTEXT")
  165. ENTER(2, ("ParseNestedContext(pctxt=%x,pnctxt=%x,rc=%x)\n",
  166. pctxt, pnctxt, rc));
  167. ASSERT(pctxt->dwfCtxt & CTXTF_NEST_EVAL);
  168. if ((rc == STATUS_SUCCESS) && (pnctxt->pdataCallBack != NULL))
  169. {
  170. rc = DupObjData(gpheapGlobal, pnctxt->pdataCallBack, &pnctxt->Result);
  171. }
  172. AsyncCallBack(pctxt, rc);
  173. FreeDataBuffs(&pnctxt->Result, 1);
  174. pctxt->dwfCtxt &= ~CTXTF_ASYNC_EVAL;
  175. pctxt->dwfCtxt |= pnctxt->dwfPrevCtxt & CTXTF_ASYNC_EVAL;
  176. pctxt->pnctxt = pnctxt->pnctxtPrev;
  177. PopFrame(pctxt);
  178. EXIT(2, ("ParseNestedContext=%x (rcEval=%x)\n", AMLISTA_DONE, rc));
  179. return AMLISTA_DONE;
  180. } //ParseNestedContext
  181. /***LP ParseCall - Parse and evaluate a method call
  182. *
  183. * ENTRY
  184. * pctxt -> CTXT
  185. * pcall -> CALL
  186. * rc - status code
  187. *
  188. * EXIT-SUCCESS
  189. * returns STATUS_SUCCESS
  190. * EXIT-FAILURE
  191. * returns AMLIERR_ code
  192. */
  193. NTSTATUS LOCAL ParseCall(PCTXT pctxt, PCALL pcall, NTSTATUS rc)
  194. {
  195. TRACENAME("PARSECALL")
  196. ULONG dwStage = (rc == STATUS_SUCCESS)?
  197. (pcall->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 4;
  198. PMETHODOBJ pm;
  199. POBJOWNER powner;
  200. ENTER(2, ("ParseCall(Stage=%d,pctxt=%x,pbOp=%x,pcall=%x,rc=%x)\n",
  201. dwStage, pctxt, pctxt->pbOp, pcall, rc));
  202. ASSERT(pcall->FrameHdr.dwSig == SIG_CALL);
  203. pm = (pcall->pnsMethod != NULL)?
  204. (PMETHODOBJ)pcall->pnsMethod->ObjData.pbDataBuff: NULL;
  205. switch (dwStage)
  206. {
  207. case 0:
  208. //
  209. // Stage 0: Print debug stuff if necessary.
  210. //
  211. pcall->FrameHdr.dwfFrame++;
  212. #ifdef DEBUGGER
  213. if (gDebugger.dwfDebugger &
  214. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  215. {
  216. PRINTF("(");
  217. }
  218. #endif
  219. case 1:
  220. Stage1:
  221. //
  222. // Stage 1: Parse arguments.
  223. //
  224. while (pcall->iArg < pcall->icArgs)
  225. {
  226. //
  227. // There are still arguments, parse it.
  228. //
  229. #ifdef DEBUGGER
  230. if (gDebugger.dwfDebugger &
  231. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  232. {
  233. if (pcall->iArg > 0)
  234. {
  235. PRINTF(",");
  236. }
  237. }
  238. #endif
  239. rc = ParseArg(pctxt, 'C', &pcall->pdataArgs[pcall->iArg++]);
  240. if ((rc != STATUS_SUCCESS) ||
  241. (&pcall->FrameHdr !=
  242. (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  243. {
  244. break;
  245. }
  246. }
  247. if ((rc != STATUS_SUCCESS) ||
  248. (&pcall->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  249. {
  250. break;
  251. }
  252. else if (pcall->iArg < pcall->icArgs)
  253. {
  254. goto Stage1;
  255. }
  256. //
  257. // If we come here, there is no more argument, so we can fall
  258. // through to the next stage.
  259. //
  260. #ifdef DEBUGGER
  261. if (gDebugger.dwfDebugger &
  262. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  263. {
  264. PRINTF(")");
  265. }
  266. #endif
  267. pcall->FrameHdr.dwfFrame++;
  268. case 2:
  269. //
  270. // Stage 2: Acquire mutex if necessary
  271. //
  272. pcall->FrameHdr.dwfFrame++;
  273. if(pm)
  274. {
  275. if (pm->bMethodFlags & METHOD_SERIALIZED)
  276. {
  277. PACQUIRE pacq;
  278. if ((rc = PushFrame(pctxt, SIG_ACQUIRE, sizeof(ACQUIRE),
  279. ParseAcquire, &pacq)) == STATUS_SUCCESS)
  280. {
  281. pacq->pmutex = &pm->Mutex;
  282. pacq->wTimeout = 0xffff;
  283. pacq->pdataResult = pcall->pdataResult;
  284. }
  285. break;
  286. }
  287. }
  288. else
  289. {
  290. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("ParseCall: pcall->pnsMethod == NULL"));
  291. break;
  292. }
  293. case 3:
  294. //
  295. // Stage 3: Invoke the method.
  296. //
  297. pcall->FrameHdr.dwfFrame++;
  298. //
  299. // If we come here, we must have acquired the serialization mutex.
  300. //
  301. if (pcall->FrameHdr.dwfFrame & CALLF_NEED_MUTEX)
  302. {
  303. pcall->FrameHdr.dwfFrame |= CALLF_ACQ_MUTEX;
  304. }
  305. if ((rc = NewObjOwner(pctxt->pheapCurrent, &powner)) ==
  306. STATUS_SUCCESS)
  307. {
  308. pcall->pownerPrev = pctxt->powner;
  309. pctxt->powner = powner;
  310. pcall->pcallPrev = pctxt->pcall;
  311. pctxt->pcall = pcall;
  312. pcall->FrameHdr.dwfFrame |= CALLF_INVOKE_CALL;
  313. rc = PushScope(pctxt, pm->abCodeBuff,
  314. pcall->pnsMethod->ObjData.pbDataBuff +
  315. pcall->pnsMethod->ObjData.dwDataLen,
  316. pctxt->pbOp,
  317. pcall->pnsMethod,
  318. powner,
  319. pctxt->pheapCurrent,
  320. pcall->pdataResult);
  321. break;
  322. }
  323. case 4:
  324. //
  325. // Stage 4: Clean up.
  326. //
  327. pcall->FrameHdr.dwfFrame++;
  328. if (rc == AMLISTA_RETURN)
  329. {
  330. rc = STATUS_SUCCESS;
  331. }
  332. if (pcall->pdataResult->dwfData & DATAF_BUFF_ALIAS)
  333. {
  334. OBJDATA data;
  335. //
  336. // The result object is an alias. It could be an alias of
  337. // ArgX or LocalX. We better dup it because we are going
  338. // to blow ArgX and LocalX away.
  339. //
  340. DupObjData(pctxt->pheapCurrent, &data, pcall->pdataResult);
  341. FreeDataBuffs(pcall->pdataResult, 1);
  342. MoveObjData(pcall->pdataResult, &data);
  343. }
  344. FreeDataBuffs(pcall->Locals, MAX_NUM_LOCALS);
  345. if (pcall->FrameHdr.dwfFrame & CALLF_INVOKE_CALL)
  346. {
  347. FreeObjOwner(pctxt->powner, FALSE);
  348. pctxt->powner = pcall->pownerPrev;
  349. pctxt->pcall = pcall->pcallPrev;
  350. }
  351. else if (pcall->pnsMethod == NULL)
  352. {
  353. //
  354. // This is the dummy call frame for LoadDDB. All NameSpace
  355. // objects created by LoadDDB are persistent (i.e. don't
  356. // destroy them).
  357. //
  358. pctxt->powner = pcall->pownerPrev;
  359. pctxt->pcall = pcall->pcallPrev;
  360. }
  361. if (pcall->pdataArgs != NULL)
  362. {
  363. FreeDataBuffs(pcall->pdataArgs, pcall->icArgs);
  364. FREEODOBJ(pcall->pdataArgs);
  365. }
  366. if (pcall->FrameHdr.dwfFrame & CALLF_ACQ_MUTEX)
  367. {
  368. ReleaseASLMutex(pctxt, &pm->Mutex);
  369. }
  370. case 5:
  371. //
  372. // Stage 5: This stage is for the dummy call frame to exit.
  373. //
  374. PopFrame(pctxt);
  375. }
  376. EXIT(2, ("ParseCall=%x\n", rc));
  377. return rc;
  378. } //ParseCall
  379. /***LP ParseTerm - Parse and evaluate an ASL term
  380. *
  381. * ENTRY
  382. * pctxt -> CTXT
  383. * pterm -> TERM
  384. * rc - status code
  385. *
  386. * EXIT-SUCCESS
  387. * returns STATUS_SUCCESS
  388. * EXIT-FAILURE
  389. * returns AMLIERR_ code
  390. */
  391. NTSTATUS LOCAL ParseTerm(PCTXT pctxt, PTERM pterm, NTSTATUS rc)
  392. {
  393. TRACENAME("PARSETERM")
  394. ULONG dwStage = (rc == STATUS_SUCCESS)?
  395. (pterm->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 4;
  396. int i;
  397. ENTER(2, ("ParseTerm(Term=%s,Stage=%d,pctxt=%x,pbOp=%x,pterm=%x,rc=%x)\n",
  398. pterm->pamlterm->pszTermName, dwStage, pctxt, pctxt->pbOp, pterm,
  399. rc));
  400. ASSERT(pterm->FrameHdr.dwSig == SIG_TERM);
  401. switch (dwStage)
  402. {
  403. case 0:
  404. //
  405. // Stage 0: Parse package length if any.
  406. //
  407. pterm->FrameHdr.dwfFrame++;
  408. #ifdef DEBUGGER
  409. if (gDebugger.dwfDebugger &
  410. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  411. {
  412. if (pterm->pamlterm->dwOpcode == OP_PACKAGE)
  413. {
  414. gDebugger.iPrintLevel++;
  415. PrintIndent(pctxt);
  416. }
  417. PRINTF("%s", pterm->pamlterm->pszTermName);
  418. if (pterm->icArgs > 0)
  419. {
  420. PRINTF("(");
  421. }
  422. }
  423. #endif
  424. if (pterm->pamlterm->dwfOpcode & OF_VARIABLE_LIST)
  425. {
  426. ParsePackageLen(&pctxt->pbOp, &pterm->pbOpEnd);
  427. }
  428. case 1:
  429. Stage1:
  430. //
  431. // Stage 1: Parse arguments.
  432. //
  433. while (pterm->iArg < pterm->icArgs)
  434. {
  435. i = pterm->iArg++;
  436. #ifdef DEBUGGER
  437. if (gDebugger.dwfDebugger &
  438. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  439. {
  440. if (i > 0)
  441. {
  442. PRINTF(",");
  443. }
  444. }
  445. #endif
  446. rc = ParseArg(pctxt, pterm->pamlterm->pszArgTypes[i],
  447. &pterm->pdataArgs[i]);
  448. if ((rc != STATUS_SUCCESS) ||
  449. (&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  450. {
  451. break;
  452. }
  453. }
  454. if ((rc != STATUS_SUCCESS) ||
  455. (&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  456. {
  457. break;
  458. }
  459. else if (pterm->iArg < pterm->icArgs)
  460. {
  461. goto Stage1;
  462. }
  463. //
  464. // If we come here, there is no more argument, so we can fall
  465. // through to the next stage.
  466. //
  467. pterm->FrameHdr.dwfFrame++;
  468. case 2:
  469. //
  470. // Stage 2: Execute the term and prepare to go to the next stage.
  471. //
  472. pterm->FrameHdr.dwfFrame++;
  473. #ifdef DEBUGGER
  474. if (gDebugger.dwfDebugger &
  475. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  476. {
  477. if (pterm->icArgs > 0)
  478. {
  479. PRINTF(")");
  480. }
  481. }
  482. #endif
  483. if ((pterm->pamlterm->dwfOpcode & OF_CALLBACK_EX) &&
  484. (pterm->pamlterm->pfnCallBack != NULL))
  485. {
  486. ((PFNOPEX)pterm->pamlterm->pfnCallBack)(
  487. EVTYPE_OPCODE_EX,
  488. OPEXF_NOTIFY_PRE,
  489. pterm->pamlterm->dwOpcode,
  490. pterm->pnsObj,
  491. pterm->pamlterm->dwCBData);
  492. }
  493. if (pterm->pamlterm->pfnOpcode != NULL)
  494. {
  495. if (((rc = pterm->pamlterm->pfnOpcode(pctxt, pterm)) !=
  496. STATUS_SUCCESS) ||
  497. (&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  498. {
  499. break;
  500. }
  501. }
  502. case 3:
  503. //
  504. // Stage 3: Do Opcode Callback if any
  505. //
  506. pterm->FrameHdr.dwfFrame++;
  507. #ifdef DEBUGGER
  508. if (gDebugger.dwfDebugger &
  509. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  510. {
  511. if ((pterm->pamlterm->dwOpcode != OP_BUFFER) &&
  512. (pterm->pamlterm->dwOpcode != OP_PACKAGE))
  513. {
  514. if (pterm->pamlterm->dwTermClass == TC_OPCODE_TYPE2)
  515. {
  516. PRINTF("=");
  517. PrintObject(pterm->pdataResult);
  518. }
  519. }
  520. }
  521. if (gDebugger.dwfDebugger & DBGF_SINGLE_STEP)
  522. {
  523. gDebugger.dwfDebugger &= ~DBGF_SINGLE_STEP;
  524. AMLIDebugger(FALSE);
  525. }
  526. else
  527. {
  528. #endif
  529. if (pterm->pamlterm->pfnCallBack != NULL)
  530. {
  531. if (pterm->pamlterm->dwfOpcode & OF_CALLBACK_EX)
  532. {
  533. ((PFNOPEX)pterm->pamlterm->pfnCallBack)(
  534. EVTYPE_OPCODE_EX,
  535. OPEXF_NOTIFY_POST,
  536. pterm->pamlterm->dwOpcode,
  537. pterm->pnsObj,
  538. pterm->pamlterm->dwCBData);
  539. }
  540. else
  541. {
  542. pterm->pamlterm->pfnCallBack(
  543. EVTYPE_OPCODE,
  544. pterm->pamlterm->dwOpcode,
  545. pterm->pnsObj,
  546. pterm->pamlterm->dwCBData
  547. );
  548. }
  549. }
  550. #ifdef DEBUGGER
  551. }
  552. #endif
  553. case 4:
  554. //
  555. // Stage 4: Clean up.
  556. //
  557. #ifdef DEBUGGER
  558. if (gDebugger.dwfDebugger &
  559. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  560. {
  561. if (pterm->pamlterm->dwOpcode == OP_PACKAGE)
  562. {
  563. gDebugger.iPrintLevel--;
  564. }
  565. }
  566. #endif
  567. if (pterm->pdataArgs != NULL)
  568. {
  569. FreeDataBuffs(pterm->pdataArgs, pterm->icArgs);
  570. FREEODOBJ(pterm->pdataArgs);
  571. }
  572. PopFrame(pctxt);
  573. }
  574. EXIT(2, ("ParseTerm=%x\n", rc));
  575. return rc;
  576. } //ParseTerm
  577. /***LP ParseAcquire - Parse and evaluate an Acquire term
  578. *
  579. * ENTRY
  580. * pctxt -> CTXT
  581. * pacq - ACQUIRE
  582. * rc - status code
  583. *
  584. * EXIT-SUCCESS
  585. * returns STATUS_SUCCESS
  586. * EXIT-FAILURE
  587. * returns AMLIERR_ code
  588. */
  589. NTSTATUS LOCAL ParseAcquire(PCTXT pctxt, PACQUIRE pacq, NTSTATUS rc)
  590. {
  591. TRACENAME("PARSEACQUIRE")
  592. ULONG dwStage = (rc == STATUS_SUCCESS)?
  593. (pacq->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2;
  594. ENTER(2, ("ParseAcquire(Stage=%d,pctxt=%x,pbOp=%x,pacq=%x,rc=%x)\n",
  595. dwStage, pctxt, pctxt->pbOp, pacq, rc));
  596. ASSERT(pacq->FrameHdr.dwSig == SIG_ACQUIRE);
  597. switch (dwStage)
  598. {
  599. case 0:
  600. //
  601. // Stage 0: Acquire GlobalLock if necessary.
  602. //
  603. pacq->FrameHdr.dwfFrame++;
  604. if (pacq->FrameHdr.dwfFrame & ACQF_NEED_GLOBALLOCK)
  605. {
  606. if ((rc = AcquireGL(pctxt)) != STATUS_SUCCESS)
  607. {
  608. break;
  609. }
  610. }
  611. case 1:
  612. //
  613. // Stage 1: Acquire the mutex.
  614. //
  615. if (pacq->FrameHdr.dwfFrame & ACQF_NEED_GLOBALLOCK)
  616. {
  617. //
  618. // If we come here, we must have acquired the global lock.
  619. //
  620. pacq->FrameHdr.dwfFrame |= ACQF_HAVE_GLOBALLOCK;
  621. }
  622. rc = AcquireASLMutex(pctxt, pacq->pmutex, pacq->wTimeout);
  623. if (rc == AMLISTA_PENDING)
  624. {
  625. //
  626. // If it is pending, we must release the global lock and
  627. // retry the whole operation.
  628. //
  629. if (pacq->FrameHdr.dwfFrame & ACQF_HAVE_GLOBALLOCK)
  630. {
  631. pacq->FrameHdr.dwfFrame &= ~ACQF_HAVE_GLOBALLOCK;
  632. if ((rc = ReleaseGL(pctxt)) == STATUS_SUCCESS)
  633. {
  634. pacq->FrameHdr.dwfFrame--;
  635. }
  636. else
  637. {
  638. pacq->FrameHdr.dwfFrame++;
  639. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  640. ("ParseAcquire: failed to release global lock (rc=%x)",
  641. rc));
  642. }
  643. }
  644. break;
  645. }
  646. else
  647. {
  648. if (pacq->FrameHdr.dwfFrame & ACQF_SET_RESULT)
  649. {
  650. pacq->pdataResult->dwDataType = OBJTYPE_INTDATA;
  651. if (rc == AMLISTA_TIMEOUT)
  652. {
  653. pacq->pdataResult->uipDataValue = DATAVALUE_ONES;
  654. rc = STATUS_SUCCESS;
  655. }
  656. else
  657. {
  658. pacq->pdataResult->uipDataValue = DATAVALUE_ZERO;
  659. }
  660. }
  661. }
  662. pacq->FrameHdr.dwfFrame++;
  663. case 2:
  664. //
  665. // Stage 2: Clean up.
  666. //
  667. PopFrame(pctxt);
  668. }
  669. EXIT(2, ("ParseAcquire=%x\n", rc));
  670. return rc;
  671. } //ParseAcquire
  672. /***LP ParseOpcode - Parse AML opcode
  673. *
  674. * ENTRY
  675. * pctxt -> CTXT
  676. * pbScopeEnd -> end of current scope
  677. * pdataResult -> result object
  678. *
  679. * EXIT-SUCCESS
  680. * returns STATUS_SUCCESS
  681. * EXIT-FAILURE
  682. * returns AMLIERR_ code
  683. */
  684. NTSTATUS LOCAL ParseOpcode(PCTXT pctxt, PUCHAR pbScopeEnd, POBJDATA pdataResult)
  685. {
  686. TRACENAME("PARSEOPCODE")
  687. NTSTATUS rc = STATUS_SUCCESS;
  688. PUCHAR pbOpTerm;
  689. PAMLTERM pamlterm;
  690. #ifdef DEBUGGER
  691. int iBrkPt;
  692. #endif
  693. ENTER(2, ("ParseOpcode(pctxt=%x,pbOp=%x,pbScopeEnd=%x,pdataResult=%x)\n",
  694. pctxt, pctxt->pbOp, pbScopeEnd, pdataResult));
  695. ASSERT(pdataResult != NULL);
  696. #ifdef DEBUGGER
  697. if ((iBrkPt = CheckBP(pctxt->pbOp)) != -1)
  698. {
  699. PRINTF("\nHit Breakpoint %d.\n", iBrkPt);
  700. AMLIDebugger(FALSE);
  701. }
  702. #endif
  703. pbOpTerm = pctxt->pbOp;
  704. if (*pctxt->pbOp == OP_EXT_PREFIX)
  705. {
  706. pctxt->pbOp++;
  707. pamlterm = FindOpcodeTerm(*pctxt->pbOp, ExOpcodeTable);
  708. }
  709. else
  710. {
  711. pamlterm = OpcodeTable[*pctxt->pbOp];
  712. }
  713. if (pamlterm == NULL)
  714. {
  715. rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
  716. ("ParseOpcode: invalid opcode 0x%02x at 0x%08x",
  717. *pctxt->pbOp, pctxt->pbOp));
  718. }
  719. else if (pamlterm->dwfOpcode & OF_DATA_OBJECT)
  720. {
  721. rc = ParseIntObj(&pctxt->pbOp, pdataResult, FALSE);
  722. }
  723. else if (pamlterm->dwfOpcode & OF_STRING_OBJECT)
  724. {
  725. rc = ParseString(&pctxt->pbOp, pdataResult, FALSE);
  726. }
  727. else if (pamlterm->dwfOpcode & OF_ARG_OBJECT)
  728. {
  729. rc = ParseArgObj(pctxt, pdataResult);
  730. }
  731. else if (pamlterm->dwfOpcode & OF_LOCAL_OBJECT)
  732. {
  733. rc = ParseLocalObj(pctxt, pdataResult);
  734. }
  735. else if (pamlterm->dwfOpcode & OF_NAME_OBJECT)
  736. {
  737. rc = ParseNameObj(pctxt, pdataResult);
  738. }
  739. else if (pamlterm->dwfOpcode & OF_DEBUG_OBJECT)
  740. {
  741. rc = AMLI_LOGERR(AMLIERR_FATAL,
  742. ("ParseOpcode: debug object cannot be evaluated"));
  743. }
  744. else
  745. {
  746. //
  747. // Must be an ASL Term.
  748. //
  749. pctxt->pbOp++;
  750. rc = PushTerm(pctxt, pbOpTerm, pbScopeEnd, pamlterm, pdataResult);
  751. }
  752. EXIT(2, ("ParseOpcode=%x (pbOp=%x,pamlterm=%x)\n",
  753. rc, pctxt->pbOp, pamlterm));
  754. return rc;
  755. } //ParseOpcode
  756. /***LP ParseArgObj - Parse and execute the ArgX instruction
  757. *
  758. * ENTRY
  759. * pctxt -> CTXT
  760. * pdataResult -> result object
  761. *
  762. * EXIT-SUCCESS
  763. * returns STATUS_SUCCESS
  764. * EXIT-FAILURE
  765. * returns AMLIERR_ code
  766. */
  767. NTSTATUS LOCAL ParseArgObj(PCTXT pctxt, POBJDATA pdataResult)
  768. {
  769. TRACENAME("PARSEARGOBJ")
  770. NTSTATUS rc = STATUS_SUCCESS;
  771. int i;
  772. ENTER(2, ("ParseArgObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n",
  773. pctxt, pctxt->pbOp, pdataResult));
  774. ASSERT(pdataResult != NULL);
  775. i = *pctxt->pbOp - OP_ARG0;
  776. if (i >= pctxt->pcall->icArgs)
  777. {
  778. rc = AMLI_LOGERR(AMLIERR_ARG_NOT_EXIST,
  779. ("ParseArgObj: Arg%d does not exist", i));
  780. }
  781. else
  782. {
  783. CopyObjData(pdataResult, &pctxt->pcall->pdataArgs[i]);
  784. pctxt->pbOp++;
  785. #ifdef DEBUGGER
  786. if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  787. {
  788. PRINTF("Arg%d=", i);
  789. PrintObject(pdataResult);
  790. }
  791. #endif
  792. }
  793. EXIT(2, ("ParseArgObj=%x (pbOp=%x)\n", rc, pctxt->pbOp));
  794. return rc;
  795. } //ParseArgObj
  796. /***LP ParseLocalObj - Parse and execute the LocalX instruction
  797. *
  798. * ENTRY
  799. * pctxt -> CTXT
  800. * pdataResult -> Result object
  801. *
  802. * EXIT-SUCCESS
  803. * returns STATUS_SUCCESS
  804. * EXIT-FAILURE
  805. * returns AMLIERR_ code
  806. */
  807. NTSTATUS LOCAL ParseLocalObj(PCTXT pctxt, POBJDATA pdataResult)
  808. {
  809. TRACENAME("PARSELOCALOBJ")
  810. NTSTATUS rc = STATUS_SUCCESS;
  811. int i;
  812. ENTER(2, ("ParseLocalObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n",
  813. pctxt, pctxt->pbOp, pdataResult));
  814. ASSERT(pdataResult != NULL);
  815. i = *pctxt->pbOp - OP_LOCAL0;
  816. CopyObjData(pdataResult, &pctxt->pcall->Locals[i]);
  817. #ifdef DEBUGGER
  818. if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  819. {
  820. PRINTF("Local%d=", i);
  821. PrintObject(pdataResult);
  822. }
  823. #endif
  824. pctxt->pbOp++;
  825. EXIT(2, ("ParseLocalObj=%x (pbOp=%x)\n", rc, pctxt->pbOp));
  826. return rc;
  827. } //ParseLocalObj
  828. /***LP ParseNameObj - Parse and evaluate an AML name object
  829. *
  830. * ENTRY
  831. * pctxt -> CTXT
  832. * pdataResult -> result object
  833. *
  834. * EXIT-SUCCESS
  835. * returns STATUS_SUCCESS
  836. * EXIT-FAILURE
  837. * returns AMLIERR_ code
  838. */
  839. NTSTATUS LOCAL ParseNameObj(PCTXT pctxt, POBJDATA pdataResult)
  840. {
  841. TRACENAME("PARSENAMEOBJ")
  842. NTSTATUS rc = STATUS_SUCCESS;
  843. PNSOBJ pns = NULL;
  844. ENTER(2, ("ParseNameObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n",
  845. pctxt, pctxt->pbOp, pdataResult));
  846. ASSERT(pdataResult != NULL);
  847. rc = ParseAndGetNameSpaceObject(&pctxt->pbOp, pctxt->pnsScope, &pns, FALSE);
  848. if (rc == STATUS_SUCCESS)
  849. {
  850. pns = GetBaseObject(pns);
  851. if (pns->ObjData.dwDataType == OBJTYPE_METHOD)
  852. {
  853. rc = PushCall(pctxt, pns, pdataResult);
  854. }
  855. else
  856. {
  857. rc = ReadObject(pctxt, &pns->ObjData, pdataResult);
  858. }
  859. }
  860. EXIT(2, ("ParseNameObj=%x\n", rc));
  861. return rc;
  862. } //ParseNameObj
  863. /***LP ParseAndGetNameSpaceObject - Parse NameSpace path and get the object
  864. *
  865. * ENTRY
  866. * ppbOp -> opcode pointer
  867. * pnsScope - current scope
  868. * ppns -> to hold the object found
  869. * fAbsentOK - if TRUE, do not print error message when object is not
  870. * found
  871. *
  872. * EXIT-SUCCESS
  873. * returns STATUS_SUCCESS
  874. * EXIT-FAILURE
  875. * returns AMLIERR_ code
  876. */
  877. NTSTATUS LOCAL ParseAndGetNameSpaceObject(PUCHAR *ppbOp, PNSOBJ pnsScope,
  878. PPNSOBJ ppns, BOOLEAN fAbsentOK)
  879. {
  880. TRACENAME("PARSEANDGETNAMESPACEOBJECT")
  881. NTSTATUS rc;
  882. char szNameBuff[MAX_NAME_LEN + 1];
  883. ENTER(2, ("ParseAndGetNameSpaceObject(pbOp=%x,Scope=%s,ppns=%x,fAbsentOK=%x)\n",
  884. *ppbOp, GetObjectPath(pnsScope), ppns, fAbsentOK));
  885. if ((rc = ParseName(ppbOp, szNameBuff, sizeof(szNameBuff))) ==
  886. STATUS_SUCCESS)
  887. {
  888. rc = GetNameSpaceObject(szNameBuff, pnsScope, ppns, 0);
  889. if (rc == AMLIERR_OBJ_NOT_FOUND)
  890. {
  891. if (fAbsentOK)
  892. {
  893. rc = STATUS_SUCCESS;
  894. *ppns = NULL;
  895. }
  896. else
  897. {
  898. rc = AMLI_LOGERR(rc,
  899. ("ParseAndGetNameSpaceObject: object %s not found",
  900. szNameBuff));
  901. }
  902. }
  903. }
  904. EXIT(2, ("ParseAndGetNameSpaceObject=%x (Name=%s)\n", rc, szNameBuff));
  905. return rc;
  906. } //ParseAndGetNameSpaceObject
  907. /***LP ParseArg - Parse and evaluate an argument
  908. *
  909. * ENTRY
  910. * pctxt -> CTXT
  911. * chArgType - expected argument type
  912. * pdataArg -> argument object
  913. *
  914. * EXIT-SUCCESS
  915. * returns STATUS_SUCCESS
  916. * EXIT-FAILURE
  917. * returns AMLIERR_ code
  918. */
  919. NTSTATUS LOCAL ParseArg(PCTXT pctxt, char chArgType, POBJDATA pdataArg)
  920. {
  921. TRACENAME("PARSEARG")
  922. NTSTATUS rc = STATUS_SUCCESS;
  923. ENTER(2, ("ParseArg(pctxt=%x,pbOp=%x,ArgType=%c,pdataArg=%x)\n",
  924. pctxt, pctxt->pbOp, chArgType, pdataArg));
  925. ASSERT(pdataArg != NULL);
  926. switch (chArgType)
  927. {
  928. case ARGTYPE_NAME:
  929. rc = ParseObjName(&pctxt->pbOp, pdataArg, FALSE);
  930. break;
  931. case ARGTYPE_DATAOBJ:
  932. if (((rc = ParseIntObj(&pctxt->pbOp, pdataArg, TRUE)) ==
  933. AMLIERR_INVALID_OPCODE) &&
  934. ((rc = ParseString(&pctxt->pbOp, pdataArg, TRUE)) ==
  935. AMLIERR_INVALID_OPCODE) &&
  936. ((*pctxt->pbOp == OP_BUFFER) || (*pctxt->pbOp == OP_PACKAGE)))
  937. {
  938. rc = PushTerm(pctxt, pctxt->pbOp, NULL,
  939. OpcodeTable[*pctxt->pbOp], pdataArg);
  940. pctxt->pbOp++;
  941. }
  942. break;
  943. case ARGTYPE_BYTE:
  944. rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(UCHAR));
  945. break;
  946. case ARGTYPE_WORD:
  947. rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(USHORT));
  948. break;
  949. case ARGTYPE_DWORD:
  950. rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(ULONG));
  951. break;
  952. case ARGTYPE_SNAME:
  953. rc = ParseSuperName(pctxt, pdataArg, FALSE);
  954. break;
  955. case ARGTYPE_SNAME2:
  956. rc = ParseSuperName(pctxt, pdataArg, TRUE);
  957. break;
  958. case ARGTYPE_OPCODE:
  959. rc = ParseOpcode(pctxt, NULL, pdataArg);
  960. break;
  961. default:
  962. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  963. ("ParseArg: unexpected arguemnt type (%c)",
  964. chArgType));
  965. }
  966. EXIT(2, ("ParseArg=%x\n", rc));
  967. return rc;
  968. } //ParseArg
  969. /***LP ParseSuperName - Parse AML SuperName
  970. *
  971. * ENTRY
  972. * pctxt -> CTXT
  973. * pdata -> object data
  974. * fAbsentOK - If TRUE, it is not an error for the object to be absent
  975. *
  976. * EXIT-SUCCESS
  977. * returns STATUS_SUCCESS
  978. * EXIT-FAILURE
  979. * returns AMLIERR_ code
  980. */
  981. NTSTATUS LOCAL ParseSuperName(PCTXT pctxt, POBJDATA pdata, BOOLEAN fAbsentOK)
  982. {
  983. TRACENAME("PARSESUPERNAME")
  984. NTSTATUS rc = STATUS_SUCCESS;
  985. PAMLTERM pamlterm;
  986. PNSOBJ pns = NULL;
  987. int i;
  988. ENTER(2, ("ParseSuperName(pctxt=%x,pbOp=%x,pdata=%x,fAbsentOK=%x)\n",
  989. pctxt, pctxt->pbOp, pdata, fAbsentOK));
  990. ASSERT(pdata != NULL);
  991. if (*pctxt->pbOp == 0)
  992. {
  993. ASSERT(pdata->dwDataType == OBJTYPE_UNKNOWN);
  994. pctxt->pbOp++;
  995. }
  996. else if ((*pctxt->pbOp == OP_EXT_PREFIX) &&
  997. (*(pctxt->pbOp + 1) == EXOP_DEBUG))
  998. {
  999. pctxt->pbOp += 2;
  1000. pdata->dwDataType = OBJTYPE_DEBUG;
  1001. #ifdef DEBUGGER
  1002. if (gDebugger.dwfDebugger &
  1003. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1004. {
  1005. PRINTF("Debug");
  1006. }
  1007. #endif
  1008. }
  1009. else if ((pamlterm = OpcodeTable[*pctxt->pbOp]) == NULL)
  1010. {
  1011. rc = AMLI_LOGERR(AMLIERR_INVALID_SUPERNAME,
  1012. ("ParseSuperName: invalid SuperName - 0x%02x at 0x%08x",
  1013. *pctxt->pbOp, pctxt->pbOp));
  1014. }
  1015. else if (pamlterm->dwfOpcode & OF_NAME_OBJECT)
  1016. {
  1017. rc = ParseAndGetNameSpaceObject(&pctxt->pbOp, pctxt->pnsScope, &pns,
  1018. fAbsentOK);
  1019. if (rc == STATUS_SUCCESS)
  1020. {
  1021. if (pns != NULL)
  1022. {
  1023. pdata->dwDataType = OBJTYPE_OBJALIAS;
  1024. pdata->pnsAlias = GetBaseObject(pns);
  1025. }
  1026. else
  1027. {
  1028. ASSERT(pdata->dwDataType == OBJTYPE_UNKNOWN);
  1029. }
  1030. }
  1031. }
  1032. else if (pamlterm->dwfOpcode & OF_ARG_OBJECT)
  1033. {
  1034. i = *pctxt->pbOp - OP_ARG0;
  1035. pctxt->pbOp++;
  1036. if (i < pctxt->pcall->icArgs)
  1037. {
  1038. #ifdef DEBUGGER
  1039. if (gDebugger.dwfDebugger &
  1040. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1041. {
  1042. PRINTF("Arg%d", i);
  1043. }
  1044. #endif
  1045. pdata->dwDataType = OBJTYPE_DATAALIAS;
  1046. pdata->pdataAlias = GetBaseData(&pctxt->pcall->pdataArgs[i]);
  1047. }
  1048. else
  1049. {
  1050. rc = AMLI_LOGERR(AMLIERR_ARG_NOT_EXIST,
  1051. ("ParseSuperName: Arg%d does not exist", i));
  1052. }
  1053. }
  1054. else if (pamlterm->dwfOpcode & OF_LOCAL_OBJECT)
  1055. {
  1056. i = *pctxt->pbOp - OP_LOCAL0;
  1057. pctxt->pbOp++;
  1058. #ifdef DEBUGGER
  1059. if (gDebugger.dwfDebugger &
  1060. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1061. {
  1062. PRINTF("Local%d", i);
  1063. }
  1064. #endif
  1065. pdata->dwDataType = OBJTYPE_DATAALIAS;
  1066. pdata->pdataAlias = &pctxt->pcall->Locals[i];
  1067. }
  1068. else if (pamlterm->dwfOpcode & OF_REF_OBJECT)
  1069. {
  1070. rc = PushTerm(pctxt, pctxt->pbOp, NULL, pamlterm, pdata);
  1071. pctxt->pbOp++;
  1072. }
  1073. else
  1074. {
  1075. rc = AMLI_LOGERR(AMLIERR_INVALID_SUPERNAME,
  1076. ("ParseSuperName: invalid SuperName %x at %x",
  1077. *pctxt->pbOp, pctxt->pbOp));
  1078. }
  1079. EXIT(2, ("ParseSuperName=%x\n", rc));
  1080. return rc;
  1081. } //ParseSuperName
  1082. /***LP ParseIntObj - Parse AML integer object
  1083. *
  1084. * ENTRY
  1085. * ppbOp -> opcode pointer
  1086. * pdataResult -> result object
  1087. * fErrOK - TRUE if error is OK
  1088. *
  1089. * EXIT-SUCCESS
  1090. * returns STATUS_SUCCESS
  1091. * EXIT-FAILURE
  1092. * returns AMLIERR_ code
  1093. */
  1094. NTSTATUS LOCAL ParseIntObj(PUCHAR *ppbOp, POBJDATA pdataResult, BOOLEAN fErrOK)
  1095. {
  1096. TRACENAME("PARSEINTOBJ")
  1097. NTSTATUS rc = STATUS_SUCCESS;
  1098. UCHAR bOp;
  1099. ENTER(2, ("ParseIntObj(pbOp=%x,pdataResult=%x,fErrOK=%x)\n",
  1100. *ppbOp, pdataResult, fErrOK));
  1101. ASSERT(pdataResult != NULL);
  1102. bOp = **ppbOp;
  1103. (*ppbOp)++;
  1104. pdataResult->dwDataType = OBJTYPE_INTDATA;
  1105. pdataResult->uipDataValue = 0;
  1106. switch (bOp)
  1107. {
  1108. case OP_ZERO:
  1109. pdataResult->uipDataValue = DATAVALUE_ZERO;
  1110. #ifdef DEBUGGER
  1111. if (gDebugger.dwfDebugger &
  1112. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1113. {
  1114. PRINTF("Zero");
  1115. }
  1116. #endif
  1117. break;
  1118. case OP_ONE:
  1119. pdataResult->uipDataValue = DATAVALUE_ONE;
  1120. #ifdef DEBUGGER
  1121. if (gDebugger.dwfDebugger &
  1122. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1123. {
  1124. PRINTF("One");
  1125. }
  1126. #endif
  1127. break;
  1128. case OP_ONES:
  1129. pdataResult->uipDataValue = DATAVALUE_ONES;
  1130. #ifdef DEBUGGER
  1131. if (gDebugger.dwfDebugger &
  1132. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1133. {
  1134. PRINTF("Ones");
  1135. }
  1136. #endif
  1137. break;
  1138. case OP_REVISION:
  1139. pdataResult->uipDataValue = AMLI_REVISION;
  1140. #ifdef DEBUGGER
  1141. if (gDebugger.dwfDebugger &
  1142. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1143. {
  1144. PRINTF("Revision");
  1145. }
  1146. #endif
  1147. break;
  1148. case OP_BYTE:
  1149. MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(UCHAR));
  1150. (*ppbOp) += sizeof(UCHAR);
  1151. #ifdef DEBUGGER
  1152. if (gDebugger.dwfDebugger &
  1153. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1154. {
  1155. PRINTF("0x%x", pdataResult->uipDataValue);
  1156. }
  1157. #endif
  1158. break;
  1159. case OP_WORD:
  1160. MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(USHORT));
  1161. (*ppbOp) += sizeof(USHORT);
  1162. #ifdef DEBUGGER
  1163. if (gDebugger.dwfDebugger &
  1164. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1165. {
  1166. PRINTF("0x%x", pdataResult->uipDataValue);
  1167. }
  1168. #endif
  1169. break;
  1170. case OP_DWORD:
  1171. MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(ULONG));
  1172. (*ppbOp) += sizeof(ULONG);
  1173. #ifdef DEBUGGER
  1174. if (gDebugger.dwfDebugger &
  1175. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1176. {
  1177. PRINTF("0x%x", pdataResult->uipDataValue);
  1178. }
  1179. #endif
  1180. break;
  1181. default:
  1182. (*ppbOp)--;
  1183. if (fErrOK)
  1184. {
  1185. rc = AMLIERR_INVALID_OPCODE;
  1186. }
  1187. else
  1188. {
  1189. rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
  1190. ("ParseIntObj: invalid opcode 0x%02x at 0x%08x",
  1191. **ppbOp, *ppbOp));
  1192. }
  1193. }
  1194. EXIT(2, ("ParseIntObj=%x (pbOp=%x,Value=%x)\n",
  1195. rc, *ppbOp, pdataResult->uipDataValue));
  1196. return rc;
  1197. } //ParseIntObj
  1198. /***LP ParseString - Parse AML string object
  1199. *
  1200. * ENTRY
  1201. * ppbOp -> opcode pointer
  1202. * pdataResult -> result object
  1203. * fErrOK - TRUE if error is OK
  1204. *
  1205. * EXIT-SUCCESS
  1206. * returns STATUS_SUCCESS
  1207. * EXIT-FAILURE
  1208. * returns AMLIERR_ code
  1209. */
  1210. NTSTATUS LOCAL ParseString(PUCHAR *ppbOp, POBJDATA pdataResult, BOOLEAN fErrOK)
  1211. {
  1212. TRACENAME("PARSESTRING")
  1213. NTSTATUS rc = STATUS_SUCCESS;
  1214. ENTER(2, ("ParseString(pbOp=%x,pdataResult=%x,fErrOK=%x)\n",
  1215. *ppbOp, pdataResult, fErrOK));
  1216. ASSERT(pdataResult != NULL);
  1217. if (**ppbOp == OP_STRING)
  1218. {
  1219. (*ppbOp)++;
  1220. pdataResult->dwDataType = OBJTYPE_STRDATA;
  1221. pdataResult->dwDataLen = STRLEN((PSZ)*ppbOp) + 1;
  1222. #ifdef DEBUGGER
  1223. if (gDebugger.dwfDebugger &
  1224. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1225. {
  1226. PRINTF("\"%s\"", *ppbOp);
  1227. }
  1228. #endif
  1229. if ((pdataResult->pbDataBuff = NEWSDOBJ(gpheapGlobal,
  1230. pdataResult->dwDataLen)) ==
  1231. NULL)
  1232. {
  1233. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  1234. ("ParseString: failed to allocate string buffer"));
  1235. }
  1236. else
  1237. {
  1238. MEMCPY(pdataResult->pbDataBuff, *ppbOp, pdataResult->dwDataLen);
  1239. }
  1240. (*ppbOp) += pdataResult->dwDataLen;
  1241. }
  1242. else if (fErrOK)
  1243. {
  1244. rc = AMLIERR_INVALID_OPCODE;
  1245. }
  1246. else
  1247. {
  1248. rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
  1249. ("ParseStrObj: invalid opcode 0x%02x at 0x%08x",
  1250. **ppbOp, *ppbOp));
  1251. }
  1252. EXIT(2, ("ParseString=%x (Value=%s)\n",
  1253. rc, pdataResult->pbDataBuff? (PSZ)pdataResult->pbDataBuff:
  1254. "<null>"));
  1255. return rc;
  1256. } //ParseString
  1257. /***LP ParseObjName - Parse AML object name
  1258. *
  1259. * ENTRY
  1260. * ppbOp -> opcode pointer
  1261. * pdata -> to hold name data
  1262. * fErrOK - TRUE if error is OK
  1263. *
  1264. * EXIT-SUCCESS
  1265. * returns STATUS_SUCCESS
  1266. * EXIT-FAILURE
  1267. * returns AMLIERR_ code
  1268. */
  1269. NTSTATUS LOCAL ParseObjName(PUCHAR *ppbOp, POBJDATA pdata, BOOLEAN fErrOK)
  1270. {
  1271. TRACENAME("PARSEOBJNAME")
  1272. NTSTATUS rc = STATUS_SUCCESS;
  1273. PAMLTERM pamlterm = OpcodeTable[**ppbOp];
  1274. char szNameBuff[MAX_NAME_LEN+1];
  1275. ENTER(2, ("ParseObjName(pbOp=%x,pdata=%x,fErrOK=%x)\n",
  1276. *ppbOp, pdata, fErrOK));
  1277. ASSERT(pdata != NULL);
  1278. if ((pamlterm == NULL) || !(pamlterm->dwfOpcode & OF_NAME_OBJECT))
  1279. {
  1280. if (fErrOK)
  1281. {
  1282. rc = AMLIERR_INVALID_OPCODE;
  1283. }
  1284. else
  1285. {
  1286. rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
  1287. ("ParseObjName: invalid opcode 0x%02x at 0x%08x",
  1288. **ppbOp, *ppbOp));
  1289. }
  1290. }
  1291. else if ((rc = ParseName(ppbOp, szNameBuff, sizeof(szNameBuff))) ==
  1292. STATUS_SUCCESS)
  1293. {
  1294. pdata->dwDataType = OBJTYPE_STRDATA;
  1295. pdata->dwDataLen = STRLEN(szNameBuff) + 1;
  1296. if ((pdata->pbDataBuff = (PUCHAR)NEWSDOBJ(gpheapGlobal,
  1297. pdata->dwDataLen)) == NULL)
  1298. {
  1299. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  1300. ("ParseObjName: failed to allocate name buffer - %s",
  1301. szNameBuff));
  1302. }
  1303. else
  1304. {
  1305. MEMCPY(pdata->pbDataBuff, szNameBuff, pdata->dwDataLen);
  1306. }
  1307. }
  1308. EXIT(2, ("ParseObjName=%x (Name=%s)\n", rc, szNameBuff));
  1309. return rc;
  1310. } //ParseObjName
  1311. /***LP ParseName - Parse AML name
  1312. *
  1313. * ENTRY
  1314. * ppbOp -> opcode pointer
  1315. * pszBuff -> to hold parsed name
  1316. * dwLen - buffer length
  1317. *
  1318. * EXIT-SUCCESS
  1319. * returns STATUS_SUCCESS
  1320. * EXIT-FAILURE
  1321. * returns AMLIERR_ code
  1322. */
  1323. NTSTATUS LOCAL ParseName(PUCHAR *ppbOp, PSZ pszBuff, ULONG dwLen)
  1324. {
  1325. TRACENAME("PARSENAME")
  1326. NTSTATUS rc = STATUS_SUCCESS;
  1327. ENTER(2, ("ParseName(pbOp=%x,pszBuff=%x,Len=%d)\n",
  1328. *ppbOp, pszBuff, dwLen));
  1329. if (**ppbOp == OP_ROOT_PREFIX)
  1330. {
  1331. if (dwLen > 1)
  1332. {
  1333. STRCPY(pszBuff, "\\");
  1334. (*ppbOp)++;
  1335. rc = ParseNameTail(ppbOp, pszBuff, dwLen);
  1336. }
  1337. else
  1338. {
  1339. rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
  1340. ("ParseName: name too long - \"%s\"", pszBuff));
  1341. }
  1342. }
  1343. else if (**ppbOp == OP_PARENT_PREFIX)
  1344. {
  1345. if (dwLen > 1)
  1346. {
  1347. int i;
  1348. STRCPY(pszBuff, "^");
  1349. for ((*ppbOp)++, i = 1;
  1350. (i < (int)dwLen) && (**ppbOp == OP_PARENT_PREFIX);
  1351. (*ppbOp)++, i++)
  1352. {
  1353. pszBuff[i] = '^';
  1354. }
  1355. pszBuff[i] = '\0';
  1356. if (**ppbOp == OP_PARENT_PREFIX)
  1357. {
  1358. rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
  1359. ("ParseName: name too long - \"%s\"",
  1360. pszBuff));
  1361. }
  1362. else
  1363. {
  1364. rc = ParseNameTail(ppbOp, pszBuff, dwLen);
  1365. }
  1366. }
  1367. else
  1368. {
  1369. rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
  1370. ("ParseName: name too long - \"%s\"", pszBuff));
  1371. }
  1372. }
  1373. else if (dwLen > 0)
  1374. {
  1375. pszBuff[0] = '\0';
  1376. rc = ParseNameTail(ppbOp, pszBuff, dwLen);
  1377. }
  1378. else
  1379. {
  1380. rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
  1381. ("ParseName: name too long - \"%s\"", pszBuff));
  1382. }
  1383. #ifdef DEBUGGER
  1384. if ((rc == STATUS_SUCCESS) &&
  1385. (gDebugger.dwfDebugger &
  1386. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)))
  1387. {
  1388. PRINTF("%s", pszBuff);
  1389. }
  1390. #endif
  1391. EXIT(2, ("ParseName=%x (Name=%s)\n", rc, pszBuff));
  1392. return rc;
  1393. } //ParseName
  1394. /***LP ParseNameTail - Parse AML name tail
  1395. *
  1396. * ENTRY
  1397. * ppbOp -> opcode pointer
  1398. * pszBuff -> to hold parsed name
  1399. * dwLen - buffer length
  1400. *
  1401. * EXIT-SUCCESS
  1402. * returns STATUS_SUCCESS
  1403. * EXIT-FAILURE
  1404. * returns AMLIERR_ code
  1405. */
  1406. NTSTATUS LOCAL ParseNameTail(PUCHAR *ppbOp, PSZ pszBuff, ULONG dwLen)
  1407. {
  1408. TRACENAME("PARSENAMETAIL")
  1409. NTSTATUS rc = STATUS_SUCCESS;
  1410. int iLen;
  1411. int icNameSegs = 0;
  1412. ENTER(2, ("ParseNameTail(pbOp=%x,Name=%s,Len=%d)\n",
  1413. *ppbOp, pszBuff, dwLen));
  1414. //
  1415. // We do not check for invalid NameSeg characters here and assume that
  1416. // the compiler does its job not generating it.
  1417. //
  1418. iLen = STRLEN(pszBuff);
  1419. if (**ppbOp == '\0')
  1420. {
  1421. //
  1422. // There is no NameTail (i.e. either NULL name or name with just
  1423. // prefixes.
  1424. //
  1425. (*ppbOp)++;
  1426. }
  1427. else if (**ppbOp == OP_MULTI_NAME_PREFIX)
  1428. {
  1429. (*ppbOp)++;
  1430. icNameSegs = (int)**ppbOp;
  1431. (*ppbOp)++;
  1432. }
  1433. else if (**ppbOp == OP_DUAL_NAME_PREFIX)
  1434. {
  1435. (*ppbOp)++;
  1436. icNameSegs = 2;
  1437. }
  1438. else
  1439. icNameSegs = 1;
  1440. while ((icNameSegs > 0) && (iLen + sizeof(NAMESEG) < dwLen))
  1441. {
  1442. STRCPYN(&pszBuff[iLen], (PSZ)(*ppbOp), sizeof(NAMESEG));
  1443. iLen += sizeof(NAMESEG);
  1444. (*ppbOp) += sizeof(NAMESEG);
  1445. icNameSegs--;
  1446. if ((icNameSegs > 0) && (iLen + 1 < (int)dwLen))
  1447. {
  1448. STRCPY(&pszBuff[iLen], ".");
  1449. iLen++;
  1450. }
  1451. }
  1452. if (icNameSegs > 0)
  1453. {
  1454. rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
  1455. ("ParseNameTail: name too long - %s", pszBuff));
  1456. }
  1457. EXIT(2, ("ParseNameTail=%x (Name=%s)\n", rc, pszBuff));
  1458. return rc;
  1459. } //ParseNameTail
  1460. /***LP ParseInteger - Parse AML integer object
  1461. *
  1462. * ENTRY
  1463. * ppbOp -> opcode pointer
  1464. * pdata -> to hold data
  1465. * dwDataLen - data length in bytes
  1466. *
  1467. * EXIT-SUCCESS
  1468. * returns STATUS_SUCCESS
  1469. * EXIT-FAILURE
  1470. * returns AMLIERR_ code
  1471. */
  1472. NTSTATUS LOCAL ParseInteger(PUCHAR *ppbOp, POBJDATA pdata, ULONG dwDataLen)
  1473. {
  1474. TRACENAME("PARSEINTEGER")
  1475. NTSTATUS rc = STATUS_SUCCESS;
  1476. ENTER(2, ("ParseInteger(pbOp=%x,pdata=%x,DataLen=%d)\n",
  1477. *ppbOp, pdata, dwDataLen));
  1478. ASSERT(pdata != NULL);
  1479. pdata->dwDataType = OBJTYPE_INTDATA;
  1480. pdata->uipDataValue = 0;
  1481. MEMCPY(&pdata->uipDataValue, *ppbOp, dwDataLen);
  1482. (*ppbOp) += dwDataLen;
  1483. #ifdef DEBUGGER
  1484. if ((rc == STATUS_SUCCESS) &&
  1485. (gDebugger.dwfDebugger &
  1486. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)))
  1487. {
  1488. PRINTF("0x%x", pdata->uipDataValue);
  1489. }
  1490. #endif
  1491. EXIT(2, ("ParseInteger=%x (Value=%x,pbOp=%x)\n",
  1492. rc, pdata->uipDataValue, *ppbOp));
  1493. return rc;
  1494. } //ParseInteger
  1495. /***LP ParseField - Parse AML field data
  1496. *
  1497. * ENTRY
  1498. * pctxt -> CTXT
  1499. * pnsParent -> parent
  1500. * pdwFieldFlags -> field flags
  1501. * pdwBitPos -> to hold the bit position parsed
  1502. *
  1503. * EXIT-SUCCESS
  1504. * returns STATUS_SUCCESS
  1505. * EXIT-FAILURE
  1506. * returns AMLIERR_ code
  1507. */
  1508. NTSTATUS LOCAL ParseField(PCTXT pctxt, PNSOBJ pnsParent, PULONG pdwFieldFlags,
  1509. PULONG pdwBitPos)
  1510. {
  1511. TRACENAME("PARSEFIELD")
  1512. NTSTATUS rc = STATUS_SUCCESS;
  1513. char szName[sizeof(NAMESEG) + 1];
  1514. ENTER(2, ("ParseField(pctxt=%x,pbOp=%x,pnsParent=%x,FieldFlags=%x,BitPos=%x)\n",
  1515. pctxt, pctxt->pbOp, pnsParent, *pdwFieldFlags, *pdwBitPos));
  1516. if (*pctxt->pbOp == 0x01)
  1517. {
  1518. pctxt->pbOp++;
  1519. *pdwFieldFlags &= ~ACCTYPE_MASK;
  1520. *pdwFieldFlags |= *pctxt->pbOp & ACCTYPE_MASK;
  1521. pctxt->pbOp++;
  1522. *pdwFieldFlags &= ~ACCATTRIB_MASK;
  1523. *pdwFieldFlags |= (ULONG)*pctxt->pbOp << 8;
  1524. pctxt->pbOp++;
  1525. #ifdef DEBUGGER
  1526. if (gDebugger.dwfDebugger &
  1527. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1528. {
  1529. PrintIndent(pctxt);
  1530. PRINTF("AccessAs(0x%x,0x%x)",
  1531. *pdwFieldFlags & 0xff, (*pdwFieldFlags >> 8) & 0xff);
  1532. }
  1533. #endif
  1534. }
  1535. else
  1536. {
  1537. ULONG dwcbBits, dwAccSize = ACCSIZE(*pdwFieldFlags);
  1538. PNSOBJ pns;
  1539. if (*pctxt->pbOp == 0)
  1540. {
  1541. szName[0] = '\0';
  1542. pctxt->pbOp++;
  1543. }
  1544. else
  1545. {
  1546. STRCPYN(szName, (PSZ)pctxt->pbOp, sizeof(NAMESEG));
  1547. pctxt->pbOp += sizeof(NAMESEG);
  1548. }
  1549. dwcbBits = ParsePackageLen(&pctxt->pbOp, NULL);
  1550. #ifdef DEBUGGER
  1551. if (gDebugger.dwfDebugger &
  1552. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1553. {
  1554. PrintIndent(pctxt);
  1555. if (szName[0] == '\0')
  1556. {
  1557. if ((dwcbBits > 32) && (((*pdwBitPos + dwcbBits) % 8) == 0))
  1558. {
  1559. PRINTF("Offset(0x%x)", (*pdwBitPos + dwcbBits)/8);
  1560. }
  1561. else
  1562. {
  1563. PRINTF(",%d", dwcbBits);
  1564. }
  1565. }
  1566. else
  1567. {
  1568. PRINTF("%s,%d", szName, dwcbBits);
  1569. }
  1570. }
  1571. #endif
  1572. if ((rc = CreateNameSpaceObject(pctxt->pheapCurrent, szName,
  1573. pctxt->pnsScope, pctxt->powner, &pns,
  1574. 0)) == STATUS_SUCCESS)
  1575. {
  1576. pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
  1577. pns->ObjData.dwDataLen = sizeof(FIELDUNITOBJ);
  1578. if ((pns->ObjData.pbDataBuff = NEWFUOBJ(pctxt->pheapCurrent,
  1579. pns->ObjData.dwDataLen)) ==
  1580. NULL)
  1581. {
  1582. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  1583. ("ParseField: failed to allocate FieldUnit object"));
  1584. }
  1585. else
  1586. {
  1587. PFIELDUNITOBJ pfu;
  1588. MEMZERO(pns->ObjData.pbDataBuff, pns->ObjData.dwDataLen);
  1589. pfu = (PFIELDUNITOBJ)pns->ObjData.pbDataBuff;
  1590. pfu->pnsFieldParent = pnsParent;
  1591. pfu->FieldDesc.dwFieldFlags = *pdwFieldFlags;
  1592. pfu->FieldDesc.dwByteOffset = (*pdwBitPos / (dwAccSize*8))*
  1593. dwAccSize;
  1594. pfu->FieldDesc.dwStartBitPos = *pdwBitPos -
  1595. pfu->FieldDesc.dwByteOffset*8;
  1596. pfu->FieldDesc.dwNumBits = dwcbBits;
  1597. (*pdwBitPos) += dwcbBits;
  1598. }
  1599. }
  1600. }
  1601. EXIT(2, ("ParseField=%x (Field=%s,BitPos=%x)\n", rc, szName, *pdwBitPos));
  1602. return rc;
  1603. } //ParseField
  1604. /***LP ParseFieldList - Parse the FieldUnit list
  1605. *
  1606. * ENTRY
  1607. * pctxt -> CTXT
  1608. * pbOpEnd -> end of field list
  1609. * pnsParent -> parent
  1610. * dwFieldFlags - field flags
  1611. * dwRegionLen - length of operation region (0xffffffff if no length limit)
  1612. *
  1613. * EXIT-SUCCESS
  1614. * returns STATUS_SUCCESS
  1615. * EXIT-FAILURE
  1616. * returns AMLIERR_ code
  1617. */
  1618. NTSTATUS LOCAL ParseFieldList(PCTXT pctxt, PUCHAR pbOpEnd, PNSOBJ pnsParent,
  1619. ULONG dwFieldFlags, ULONG dwRegionLen)
  1620. {
  1621. TRACENAME("PARSESFIELDLIST")
  1622. NTSTATUS rc = STATUS_SUCCESS;
  1623. ULONG dwBitPos = 0;
  1624. ENTER(2, ("ParseFieldList(pctxt=%x,pbOp=%x,pnsParent=%x,FieldFlags=%x,RegionLen=%x)\n",
  1625. pctxt, pctxt->pbOp, pnsParent, dwFieldFlags, dwRegionLen));
  1626. #ifdef DEBUGGER
  1627. if (gDebugger.dwfDebugger &
  1628. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1629. {
  1630. PrintIndent(pctxt);
  1631. PRINTF("{");
  1632. gDebugger.iPrintLevel++;
  1633. }
  1634. #endif
  1635. while ((rc == STATUS_SUCCESS) && (pctxt->pbOp < pbOpEnd))
  1636. {
  1637. if ((rc = ParseField(pctxt, pnsParent, &dwFieldFlags, &dwBitPos)) ==
  1638. STATUS_SUCCESS)
  1639. {
  1640. #ifdef DEBUGGER
  1641. if ((gDebugger.dwfDebugger &
  1642. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) &&
  1643. (rc == STATUS_SUCCESS) &&
  1644. (pctxt->pbOp < pbOpEnd))
  1645. {
  1646. PRINTF(",");
  1647. }
  1648. #endif
  1649. if ((dwRegionLen != 0xffffffff) && ((dwBitPos + 7)/8 > dwRegionLen))
  1650. {
  1651. rc = AMLI_LOGERR(AMLIERR_INDEX_TOO_BIG,
  1652. ("ParseFieldList: offset exceeds OpRegion range (Offset=0x%x, RegionLen=0x%x)",
  1653. (dwBitPos + 7)/8, dwRegionLen));
  1654. }
  1655. }
  1656. }
  1657. #ifdef DEBUGGER
  1658. if (gDebugger.dwfDebugger &
  1659. (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  1660. {
  1661. gDebugger.iPrintLevel--;
  1662. PrintIndent(pctxt);
  1663. PRINTF("}");
  1664. }
  1665. #endif
  1666. EXIT(2, ("ParseFieldList=%x\n", rc));
  1667. return rc;
  1668. } //ParseFieldList
  1669. /***LP ParsePackageLen - parse package length
  1670. *
  1671. * ENTRY
  1672. * ppbOp -> instruction pointer
  1673. * ppbOpNext -> to hold pointer to next instruction (can be NULL)
  1674. *
  1675. * EXIT
  1676. * returns package length
  1677. */
  1678. ULONG LOCAL ParsePackageLen(PUCHAR *ppbOp, PUCHAR *ppbOpNext)
  1679. {
  1680. TRACENAME("PARSEPACKAGELEN")
  1681. ULONG dwLen;
  1682. UCHAR bFollowCnt, i;
  1683. ENTER(2, ("ParsePackageLen(pbOp=%x,ppbOpNext=%x)\n", *ppbOp, ppbOpNext));
  1684. if (ppbOpNext != NULL)
  1685. *ppbOpNext = *ppbOp;
  1686. dwLen = (ULONG)(**ppbOp);
  1687. (*ppbOp)++;
  1688. bFollowCnt = (UCHAR)((dwLen & 0xc0) >> 6);
  1689. if (bFollowCnt != 0)
  1690. {
  1691. dwLen &= 0x0000000f;
  1692. for (i = 0; i < bFollowCnt; ++i)
  1693. {
  1694. dwLen |= (ULONG)(**ppbOp) << (i*8 + 4);
  1695. (*ppbOp)++;
  1696. }
  1697. }
  1698. if (ppbOpNext != NULL)
  1699. *ppbOpNext += dwLen;
  1700. EXIT(2, ("ParsePackageLen=%x (pbOp=%x,pbOpNext=%x)\n",
  1701. dwLen, *ppbOp, ppbOpNext? *ppbOpNext: 0));
  1702. return dwLen;
  1703. } //ParsePackageLen