dsopcode.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /******************************************************************************
  2. *
  3. * Module Name: dsopcode - Dispatcher support for regions and fields
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2015, Intel Corp.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include "acpi.h"
  43. #include "accommon.h"
  44. #include "acparser.h"
  45. #include "amlcode.h"
  46. #include "acdispat.h"
  47. #include "acinterp.h"
  48. #include "acnamesp.h"
  49. #include "acevents.h"
  50. #include "actables.h"
  51. #define _COMPONENT ACPI_DISPATCHER
  52. ACPI_MODULE_NAME ("dsopcode")
  53. /* Local prototypes */
  54. static ACPI_STATUS
  55. AcpiDsInitBufferField (
  56. UINT16 AmlOpcode,
  57. ACPI_OPERAND_OBJECT *ObjDesc,
  58. ACPI_OPERAND_OBJECT *BufferDesc,
  59. ACPI_OPERAND_OBJECT *OffsetDesc,
  60. ACPI_OPERAND_OBJECT *LengthDesc,
  61. ACPI_OPERAND_OBJECT *ResultDesc);
  62. /*******************************************************************************
  63. *
  64. * FUNCTION: AcpiDsInitializeRegion
  65. *
  66. * PARAMETERS: ObjHandle - Region namespace node
  67. *
  68. * RETURN: Status
  69. *
  70. * DESCRIPTION: Front end to EvInitializeRegion
  71. *
  72. ******************************************************************************/
  73. ACPI_STATUS
  74. AcpiDsInitializeRegion (
  75. ACPI_HANDLE ObjHandle)
  76. {
  77. ACPI_OPERAND_OBJECT *ObjDesc;
  78. ACPI_STATUS Status;
  79. ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
  80. /* Namespace is NOT locked */
  81. Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
  82. return (Status);
  83. }
  84. /*******************************************************************************
  85. *
  86. * FUNCTION: AcpiDsInitBufferField
  87. *
  88. * PARAMETERS: AmlOpcode - CreateXxxField
  89. * ObjDesc - BufferField object
  90. * BufferDesc - Host Buffer
  91. * OffsetDesc - Offset into buffer
  92. * LengthDesc - Length of field (CREATE_FIELD_OP only)
  93. * ResultDesc - Where to store the result
  94. *
  95. * RETURN: Status
  96. *
  97. * DESCRIPTION: Perform actual initialization of a buffer field
  98. *
  99. ******************************************************************************/
  100. static ACPI_STATUS
  101. AcpiDsInitBufferField (
  102. UINT16 AmlOpcode,
  103. ACPI_OPERAND_OBJECT *ObjDesc,
  104. ACPI_OPERAND_OBJECT *BufferDesc,
  105. ACPI_OPERAND_OBJECT *OffsetDesc,
  106. ACPI_OPERAND_OBJECT *LengthDesc,
  107. ACPI_OPERAND_OBJECT *ResultDesc)
  108. {
  109. UINT32 Offset;
  110. UINT32 BitOffset;
  111. UINT32 BitCount;
  112. UINT8 FieldFlags;
  113. ACPI_STATUS Status;
  114. ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
  115. /* Host object must be a Buffer */
  116. if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
  117. {
  118. ACPI_ERROR ((AE_INFO,
  119. "Target of Create Field is not a Buffer object - %s",
  120. AcpiUtGetObjectTypeName (BufferDesc)));
  121. Status = AE_AML_OPERAND_TYPE;
  122. goto Cleanup;
  123. }
  124. /*
  125. * The last parameter to all of these opcodes (ResultDesc) started
  126. * out as a NameString, and should therefore now be a NS node
  127. * after resolution in AcpiExResolveOperands().
  128. */
  129. if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
  130. {
  131. ACPI_ERROR ((AE_INFO,
  132. "(%s) destination not a NS Node [%s]",
  133. AcpiPsGetOpcodeName (AmlOpcode),
  134. AcpiUtGetDescriptorName (ResultDesc)));
  135. Status = AE_AML_OPERAND_TYPE;
  136. goto Cleanup;
  137. }
  138. Offset = (UINT32) OffsetDesc->Integer.Value;
  139. /*
  140. * Setup the Bit offsets and counts, according to the opcode
  141. */
  142. switch (AmlOpcode)
  143. {
  144. case AML_CREATE_FIELD_OP:
  145. /* Offset is in bits, count is in bits */
  146. FieldFlags = AML_FIELD_ACCESS_BYTE;
  147. BitOffset = Offset;
  148. BitCount = (UINT32) LengthDesc->Integer.Value;
  149. /* Must have a valid (>0) bit count */
  150. if (BitCount == 0)
  151. {
  152. ACPI_ERROR ((AE_INFO,
  153. "Attempt to CreateField of length zero"));
  154. Status = AE_AML_OPERAND_VALUE;
  155. goto Cleanup;
  156. }
  157. break;
  158. case AML_CREATE_BIT_FIELD_OP:
  159. /* Offset is in bits, Field is one bit */
  160. BitOffset = Offset;
  161. BitCount = 1;
  162. FieldFlags = AML_FIELD_ACCESS_BYTE;
  163. break;
  164. case AML_CREATE_BYTE_FIELD_OP:
  165. /* Offset is in bytes, field is one byte */
  166. BitOffset = 8 * Offset;
  167. BitCount = 8;
  168. FieldFlags = AML_FIELD_ACCESS_BYTE;
  169. break;
  170. case AML_CREATE_WORD_FIELD_OP:
  171. /* Offset is in bytes, field is one word */
  172. BitOffset = 8 * Offset;
  173. BitCount = 16;
  174. FieldFlags = AML_FIELD_ACCESS_WORD;
  175. break;
  176. case AML_CREATE_DWORD_FIELD_OP:
  177. /* Offset is in bytes, field is one dword */
  178. BitOffset = 8 * Offset;
  179. BitCount = 32;
  180. FieldFlags = AML_FIELD_ACCESS_DWORD;
  181. break;
  182. case AML_CREATE_QWORD_FIELD_OP:
  183. /* Offset is in bytes, field is one qword */
  184. BitOffset = 8 * Offset;
  185. BitCount = 64;
  186. FieldFlags = AML_FIELD_ACCESS_QWORD;
  187. break;
  188. default:
  189. ACPI_ERROR ((AE_INFO,
  190. "Unknown field creation opcode 0x%02X",
  191. AmlOpcode));
  192. Status = AE_AML_BAD_OPCODE;
  193. goto Cleanup;
  194. }
  195. /* Entire field must fit within the current length of the buffer */
  196. if ((BitOffset + BitCount) >
  197. (8 * (UINT32) BufferDesc->Buffer.Length))
  198. {
  199. ACPI_ERROR ((AE_INFO,
  200. "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
  201. AcpiUtGetNodeName (ResultDesc),
  202. BitOffset + BitCount,
  203. AcpiUtGetNodeName (BufferDesc->Buffer.Node),
  204. 8 * (UINT32) BufferDesc->Buffer.Length));
  205. Status = AE_AML_BUFFER_LIMIT;
  206. goto Cleanup;
  207. }
  208. /*
  209. * Initialize areas of the field object that are common to all fields
  210. * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
  211. * UPDATE_RULE = 0 (UPDATE_PRESERVE)
  212. */
  213. Status = AcpiExPrepCommonFieldObject (
  214. ObjDesc, FieldFlags, 0, BitOffset, BitCount);
  215. if (ACPI_FAILURE (Status))
  216. {
  217. goto Cleanup;
  218. }
  219. ObjDesc->BufferField.BufferObj = BufferDesc;
  220. /* Reference count for BufferDesc inherits ObjDesc count */
  221. BufferDesc->Common.ReferenceCount = (UINT16)
  222. (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
  223. Cleanup:
  224. /* Always delete the operands */
  225. AcpiUtRemoveReference (OffsetDesc);
  226. AcpiUtRemoveReference (BufferDesc);
  227. if (AmlOpcode == AML_CREATE_FIELD_OP)
  228. {
  229. AcpiUtRemoveReference (LengthDesc);
  230. }
  231. /* On failure, delete the result descriptor */
  232. if (ACPI_FAILURE (Status))
  233. {
  234. AcpiUtRemoveReference (ResultDesc); /* Result descriptor */
  235. }
  236. else
  237. {
  238. /* Now the address and length are valid for this BufferField */
  239. ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
  240. }
  241. return_ACPI_STATUS (Status);
  242. }
  243. /*******************************************************************************
  244. *
  245. * FUNCTION: AcpiDsEvalBufferFieldOperands
  246. *
  247. * PARAMETERS: WalkState - Current walk
  248. * Op - A valid BufferField Op object
  249. *
  250. * RETURN: Status
  251. *
  252. * DESCRIPTION: Get BufferField Buffer and Index
  253. * Called from AcpiDsExecEndOp during BufferField parse tree walk
  254. *
  255. ******************************************************************************/
  256. ACPI_STATUS
  257. AcpiDsEvalBufferFieldOperands (
  258. ACPI_WALK_STATE *WalkState,
  259. ACPI_PARSE_OBJECT *Op)
  260. {
  261. ACPI_STATUS Status;
  262. ACPI_OPERAND_OBJECT *ObjDesc;
  263. ACPI_NAMESPACE_NODE *Node;
  264. ACPI_PARSE_OBJECT *NextOp;
  265. ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
  266. /*
  267. * This is where we evaluate the address and length fields of the
  268. * CreateXxxField declaration
  269. */
  270. Node = Op->Common.Node;
  271. /* NextOp points to the op that holds the Buffer */
  272. NextOp = Op->Common.Value.Arg;
  273. /* Evaluate/create the address and length operands */
  274. Status = AcpiDsCreateOperands (WalkState, NextOp);
  275. if (ACPI_FAILURE (Status))
  276. {
  277. return_ACPI_STATUS (Status);
  278. }
  279. ObjDesc = AcpiNsGetAttachedObject (Node);
  280. if (!ObjDesc)
  281. {
  282. return_ACPI_STATUS (AE_NOT_EXIST);
  283. }
  284. /* Resolve the operands */
  285. Status = AcpiExResolveOperands (
  286. Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
  287. if (ACPI_FAILURE (Status))
  288. {
  289. ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
  290. AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
  291. return_ACPI_STATUS (Status);
  292. }
  293. /* Initialize the Buffer Field */
  294. if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
  295. {
  296. /* NOTE: Slightly different operands for this opcode */
  297. Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
  298. WalkState->Operands[0], WalkState->Operands[1],
  299. WalkState->Operands[2], WalkState->Operands[3]);
  300. }
  301. else
  302. {
  303. /* All other, CreateXxxField opcodes */
  304. Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
  305. WalkState->Operands[0], WalkState->Operands[1],
  306. NULL, WalkState->Operands[2]);
  307. }
  308. return_ACPI_STATUS (Status);
  309. }
  310. /*******************************************************************************
  311. *
  312. * FUNCTION: AcpiDsEvalRegionOperands
  313. *
  314. * PARAMETERS: WalkState - Current walk
  315. * Op - A valid region Op object
  316. *
  317. * RETURN: Status
  318. *
  319. * DESCRIPTION: Get region address and length
  320. * Called from AcpiDsExecEndOp during OpRegion parse tree walk
  321. *
  322. ******************************************************************************/
  323. ACPI_STATUS
  324. AcpiDsEvalRegionOperands (
  325. ACPI_WALK_STATE *WalkState,
  326. ACPI_PARSE_OBJECT *Op)
  327. {
  328. ACPI_STATUS Status;
  329. ACPI_OPERAND_OBJECT *ObjDesc;
  330. ACPI_OPERAND_OBJECT *OperandDesc;
  331. ACPI_NAMESPACE_NODE *Node;
  332. ACPI_PARSE_OBJECT *NextOp;
  333. ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
  334. /*
  335. * This is where we evaluate the address and length fields of the
  336. * OpRegion declaration
  337. */
  338. Node = Op->Common.Node;
  339. /* NextOp points to the op that holds the SpaceID */
  340. NextOp = Op->Common.Value.Arg;
  341. /* NextOp points to address op */
  342. NextOp = NextOp->Common.Next;
  343. /* Evaluate/create the address and length operands */
  344. Status = AcpiDsCreateOperands (WalkState, NextOp);
  345. if (ACPI_FAILURE (Status))
  346. {
  347. return_ACPI_STATUS (Status);
  348. }
  349. /* Resolve the length and address operands to numbers */
  350. Status = AcpiExResolveOperands (
  351. Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
  352. if (ACPI_FAILURE (Status))
  353. {
  354. return_ACPI_STATUS (Status);
  355. }
  356. ObjDesc = AcpiNsGetAttachedObject (Node);
  357. if (!ObjDesc)
  358. {
  359. return_ACPI_STATUS (AE_NOT_EXIST);
  360. }
  361. /*
  362. * Get the length operand and save it
  363. * (at Top of stack)
  364. */
  365. OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
  366. ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
  367. AcpiUtRemoveReference (OperandDesc);
  368. /*
  369. * Get the address and save it
  370. * (at top of stack - 1)
  371. */
  372. OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
  373. ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
  374. OperandDesc->Integer.Value;
  375. AcpiUtRemoveReference (OperandDesc);
  376. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
  377. ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
  378. ObjDesc->Region.Length));
  379. /* Now the address and length are valid for this opregion */
  380. ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
  381. return_ACPI_STATUS (Status);
  382. }
  383. /*******************************************************************************
  384. *
  385. * FUNCTION: AcpiDsEvalTableRegionOperands
  386. *
  387. * PARAMETERS: WalkState - Current walk
  388. * Op - A valid region Op object
  389. *
  390. * RETURN: Status
  391. *
  392. * DESCRIPTION: Get region address and length.
  393. * Called from AcpiDsExecEndOp during DataTableRegion parse
  394. * tree walk.
  395. *
  396. ******************************************************************************/
  397. ACPI_STATUS
  398. AcpiDsEvalTableRegionOperands (
  399. ACPI_WALK_STATE *WalkState,
  400. ACPI_PARSE_OBJECT *Op)
  401. {
  402. ACPI_STATUS Status;
  403. ACPI_OPERAND_OBJECT *ObjDesc;
  404. ACPI_OPERAND_OBJECT **Operand;
  405. ACPI_NAMESPACE_NODE *Node;
  406. ACPI_PARSE_OBJECT *NextOp;
  407. ACPI_TABLE_HEADER *Table;
  408. UINT32 TableIndex;
  409. ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
  410. /*
  411. * This is where we evaluate the Signature string, OemId string,
  412. * and OemTableId string of the Data Table Region declaration
  413. */
  414. Node = Op->Common.Node;
  415. /* NextOp points to Signature string op */
  416. NextOp = Op->Common.Value.Arg;
  417. /*
  418. * Evaluate/create the Signature string, OemId string,
  419. * and OemTableId string operands
  420. */
  421. Status = AcpiDsCreateOperands (WalkState, NextOp);
  422. if (ACPI_FAILURE (Status))
  423. {
  424. return_ACPI_STATUS (Status);
  425. }
  426. Operand = &WalkState->Operands[0];
  427. /*
  428. * Resolve the Signature string, OemId string,
  429. * and OemTableId string operands
  430. */
  431. Status = AcpiExResolveOperands (
  432. Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
  433. if (ACPI_FAILURE (Status))
  434. {
  435. goto Cleanup;
  436. }
  437. /* Find the ACPI table */
  438. Status = AcpiTbFindTable (
  439. Operand[0]->String.Pointer,
  440. Operand[1]->String.Pointer,
  441. Operand[2]->String.Pointer, &TableIndex);
  442. if (ACPI_FAILURE (Status))
  443. {
  444. if (Status == AE_NOT_FOUND)
  445. {
  446. ACPI_ERROR ((AE_INFO,
  447. "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
  448. Operand[0]->String.Pointer,
  449. Operand[1]->String.Pointer,
  450. Operand[2]->String.Pointer));
  451. }
  452. goto Cleanup;
  453. }
  454. Status = AcpiGetTableByIndex (TableIndex, &Table);
  455. if (ACPI_FAILURE (Status))
  456. {
  457. goto Cleanup;
  458. }
  459. ObjDesc = AcpiNsGetAttachedObject (Node);
  460. if (!ObjDesc)
  461. {
  462. Status = AE_NOT_EXIST;
  463. goto Cleanup;
  464. }
  465. ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
  466. ObjDesc->Region.Length = Table->Length;
  467. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
  468. ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
  469. ObjDesc->Region.Length));
  470. /* Now the address and length are valid for this opregion */
  471. ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
  472. Cleanup:
  473. AcpiUtRemoveReference (Operand[0]);
  474. AcpiUtRemoveReference (Operand[1]);
  475. AcpiUtRemoveReference (Operand[2]);
  476. return_ACPI_STATUS (Status);
  477. }
  478. /*******************************************************************************
  479. *
  480. * FUNCTION: AcpiDsEvalDataObjectOperands
  481. *
  482. * PARAMETERS: WalkState - Current walk
  483. * Op - A valid DataObject Op object
  484. * ObjDesc - DataObject
  485. *
  486. * RETURN: Status
  487. *
  488. * DESCRIPTION: Get the operands and complete the following data object types:
  489. * Buffer, Package.
  490. *
  491. ******************************************************************************/
  492. ACPI_STATUS
  493. AcpiDsEvalDataObjectOperands (
  494. ACPI_WALK_STATE *WalkState,
  495. ACPI_PARSE_OBJECT *Op,
  496. ACPI_OPERAND_OBJECT *ObjDesc)
  497. {
  498. ACPI_STATUS Status;
  499. ACPI_OPERAND_OBJECT *ArgDesc;
  500. UINT32 Length;
  501. ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
  502. /* The first operand (for all of these data objects) is the length */
  503. /*
  504. * Set proper index into operand stack for AcpiDsObjStackPush
  505. * invoked inside AcpiDsCreateOperand.
  506. */
  507. WalkState->OperandIndex = WalkState->NumOperands;
  508. Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
  509. if (ACPI_FAILURE (Status))
  510. {
  511. return_ACPI_STATUS (Status);
  512. }
  513. Status = AcpiExResolveOperands (WalkState->Opcode,
  514. &(WalkState->Operands [WalkState->NumOperands -1]),
  515. WalkState);
  516. if (ACPI_FAILURE (Status))
  517. {
  518. return_ACPI_STATUS (Status);
  519. }
  520. /* Extract length operand */
  521. ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
  522. Length = (UINT32) ArgDesc->Integer.Value;
  523. /* Cleanup for length operand */
  524. Status = AcpiDsObjStackPop (1, WalkState);
  525. if (ACPI_FAILURE (Status))
  526. {
  527. return_ACPI_STATUS (Status);
  528. }
  529. AcpiUtRemoveReference (ArgDesc);
  530. /*
  531. * Create the actual data object
  532. */
  533. switch (Op->Common.AmlOpcode)
  534. {
  535. case AML_BUFFER_OP:
  536. Status = AcpiDsBuildInternalBufferObj (
  537. WalkState, Op, Length, &ObjDesc);
  538. break;
  539. case AML_PACKAGE_OP:
  540. case AML_VAR_PACKAGE_OP:
  541. Status = AcpiDsBuildInternalPackageObj (
  542. WalkState, Op, Length, &ObjDesc);
  543. break;
  544. default:
  545. return_ACPI_STATUS (AE_AML_BAD_OPCODE);
  546. }
  547. if (ACPI_SUCCESS (Status))
  548. {
  549. /*
  550. * Return the object in the WalkState, unless the parent is a package -
  551. * in this case, the return object will be stored in the parse tree
  552. * for the package.
  553. */
  554. if ((!Op->Common.Parent) ||
  555. ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
  556. (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
  557. (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
  558. {
  559. WalkState->ResultObj = ObjDesc;
  560. }
  561. }
  562. return_ACPI_STATUS (Status);
  563. }
  564. /*******************************************************************************
  565. *
  566. * FUNCTION: AcpiDsEvalBankFieldOperands
  567. *
  568. * PARAMETERS: WalkState - Current walk
  569. * Op - A valid BankField Op object
  570. *
  571. * RETURN: Status
  572. *
  573. * DESCRIPTION: Get BankField BankValue
  574. * Called from AcpiDsExecEndOp during BankField parse tree walk
  575. *
  576. ******************************************************************************/
  577. ACPI_STATUS
  578. AcpiDsEvalBankFieldOperands (
  579. ACPI_WALK_STATE *WalkState,
  580. ACPI_PARSE_OBJECT *Op)
  581. {
  582. ACPI_STATUS Status;
  583. ACPI_OPERAND_OBJECT *ObjDesc;
  584. ACPI_OPERAND_OBJECT *OperandDesc;
  585. ACPI_NAMESPACE_NODE *Node;
  586. ACPI_PARSE_OBJECT *NextOp;
  587. ACPI_PARSE_OBJECT *Arg;
  588. ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
  589. /*
  590. * This is where we evaluate the BankValue field of the
  591. * BankField declaration
  592. */
  593. /* NextOp points to the op that holds the Region */
  594. NextOp = Op->Common.Value.Arg;
  595. /* NextOp points to the op that holds the Bank Register */
  596. NextOp = NextOp->Common.Next;
  597. /* NextOp points to the op that holds the Bank Value */
  598. NextOp = NextOp->Common.Next;
  599. /*
  600. * Set proper index into operand stack for AcpiDsObjStackPush
  601. * invoked inside AcpiDsCreateOperand.
  602. *
  603. * We use WalkState->Operands[0] to store the evaluated BankValue
  604. */
  605. WalkState->OperandIndex = 0;
  606. Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
  607. if (ACPI_FAILURE (Status))
  608. {
  609. return_ACPI_STATUS (Status);
  610. }
  611. Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
  612. if (ACPI_FAILURE (Status))
  613. {
  614. return_ACPI_STATUS (Status);
  615. }
  616. ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
  617. AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
  618. /*
  619. * Get the BankValue operand and save it
  620. * (at Top of stack)
  621. */
  622. OperandDesc = WalkState->Operands[0];
  623. /* Arg points to the start Bank Field */
  624. Arg = AcpiPsGetArg (Op, 4);
  625. while (Arg)
  626. {
  627. /* Ignore OFFSET and ACCESSAS terms here */
  628. if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
  629. {
  630. Node = Arg->Common.Node;
  631. ObjDesc = AcpiNsGetAttachedObject (Node);
  632. if (!ObjDesc)
  633. {
  634. return_ACPI_STATUS (AE_NOT_EXIST);
  635. }
  636. ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
  637. }
  638. /* Move to next field in the list */
  639. Arg = Arg->Common.Next;
  640. }
  641. AcpiUtRemoveReference (OperandDesc);
  642. return_ACPI_STATUS (Status);
  643. }