Sync with trunk r62754.
[reactos.git] / drivers / bus / acpi / acpica / dispatcher / dsopcode.c
1 /******************************************************************************
2 *
3 * Module Name: dsopcode - Dispatcher support for regions and fields
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116 #define __DSOPCODE_C__
117
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "acparser.h"
121 #include "amlcode.h"
122 #include "acdispat.h"
123 #include "acinterp.h"
124 #include "acnamesp.h"
125 #include "acevents.h"
126 #include "actables.h"
127
128 #define _COMPONENT ACPI_DISPATCHER
129 ACPI_MODULE_NAME ("dsopcode")
130
131 /* Local prototypes */
132
133 static ACPI_STATUS
134 AcpiDsInitBufferField (
135 UINT16 AmlOpcode,
136 ACPI_OPERAND_OBJECT *ObjDesc,
137 ACPI_OPERAND_OBJECT *BufferDesc,
138 ACPI_OPERAND_OBJECT *OffsetDesc,
139 ACPI_OPERAND_OBJECT *LengthDesc,
140 ACPI_OPERAND_OBJECT *ResultDesc);
141
142
143 /*******************************************************************************
144 *
145 * FUNCTION: AcpiDsInitializeRegion
146 *
147 * PARAMETERS: ObjHandle - Region namespace node
148 *
149 * RETURN: Status
150 *
151 * DESCRIPTION: Front end to EvInitializeRegion
152 *
153 ******************************************************************************/
154
155 ACPI_STATUS
156 AcpiDsInitializeRegion (
157 ACPI_HANDLE ObjHandle)
158 {
159 ACPI_OPERAND_OBJECT *ObjDesc;
160 ACPI_STATUS Status;
161
162
163 ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
164
165 /* Namespace is NOT locked */
166
167 Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
168 return (Status);
169 }
170
171
172 /*******************************************************************************
173 *
174 * FUNCTION: AcpiDsInitBufferField
175 *
176 * PARAMETERS: AmlOpcode - CreateXxxField
177 * ObjDesc - BufferField object
178 * BufferDesc - Host Buffer
179 * OffsetDesc - Offset into buffer
180 * LengthDesc - Length of field (CREATE_FIELD_OP only)
181 * ResultDesc - Where to store the result
182 *
183 * RETURN: Status
184 *
185 * DESCRIPTION: Perform actual initialization of a buffer field
186 *
187 ******************************************************************************/
188
189 static ACPI_STATUS
190 AcpiDsInitBufferField (
191 UINT16 AmlOpcode,
192 ACPI_OPERAND_OBJECT *ObjDesc,
193 ACPI_OPERAND_OBJECT *BufferDesc,
194 ACPI_OPERAND_OBJECT *OffsetDesc,
195 ACPI_OPERAND_OBJECT *LengthDesc,
196 ACPI_OPERAND_OBJECT *ResultDesc)
197 {
198 UINT32 Offset;
199 UINT32 BitOffset;
200 UINT32 BitCount;
201 UINT8 FieldFlags;
202 ACPI_STATUS Status;
203
204
205 ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
206
207
208 /* Host object must be a Buffer */
209
210 if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
211 {
212 ACPI_ERROR ((AE_INFO,
213 "Target of Create Field is not a Buffer object - %s",
214 AcpiUtGetObjectTypeName (BufferDesc)));
215
216 Status = AE_AML_OPERAND_TYPE;
217 goto Cleanup;
218 }
219
220 /*
221 * The last parameter to all of these opcodes (ResultDesc) started
222 * out as a NameString, and should therefore now be a NS node
223 * after resolution in AcpiExResolveOperands().
224 */
225 if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
226 {
227 ACPI_ERROR ((AE_INFO,
228 "(%s) destination not a NS Node [%s]",
229 AcpiPsGetOpcodeName (AmlOpcode),
230 AcpiUtGetDescriptorName (ResultDesc)));
231
232 Status = AE_AML_OPERAND_TYPE;
233 goto Cleanup;
234 }
235
236 Offset = (UINT32) OffsetDesc->Integer.Value;
237
238 /*
239 * Setup the Bit offsets and counts, according to the opcode
240 */
241 switch (AmlOpcode)
242 {
243 case AML_CREATE_FIELD_OP:
244
245 /* Offset is in bits, count is in bits */
246
247 FieldFlags = AML_FIELD_ACCESS_BYTE;
248 BitOffset = Offset;
249 BitCount = (UINT32) LengthDesc->Integer.Value;
250
251 /* Must have a valid (>0) bit count */
252
253 if (BitCount == 0)
254 {
255 ACPI_ERROR ((AE_INFO,
256 "Attempt to CreateField of length zero"));
257 Status = AE_AML_OPERAND_VALUE;
258 goto Cleanup;
259 }
260 break;
261
262 case AML_CREATE_BIT_FIELD_OP:
263
264 /* Offset is in bits, Field is one bit */
265
266 BitOffset = Offset;
267 BitCount = 1;
268 FieldFlags = AML_FIELD_ACCESS_BYTE;
269 break;
270
271 case AML_CREATE_BYTE_FIELD_OP:
272
273 /* Offset is in bytes, field is one byte */
274
275 BitOffset = 8 * Offset;
276 BitCount = 8;
277 FieldFlags = AML_FIELD_ACCESS_BYTE;
278 break;
279
280 case AML_CREATE_WORD_FIELD_OP:
281
282 /* Offset is in bytes, field is one word */
283
284 BitOffset = 8 * Offset;
285 BitCount = 16;
286 FieldFlags = AML_FIELD_ACCESS_WORD;
287 break;
288
289 case AML_CREATE_DWORD_FIELD_OP:
290
291 /* Offset is in bytes, field is one dword */
292
293 BitOffset = 8 * Offset;
294 BitCount = 32;
295 FieldFlags = AML_FIELD_ACCESS_DWORD;
296 break;
297
298 case AML_CREATE_QWORD_FIELD_OP:
299
300 /* Offset is in bytes, field is one qword */
301
302 BitOffset = 8 * Offset;
303 BitCount = 64;
304 FieldFlags = AML_FIELD_ACCESS_QWORD;
305 break;
306
307 default:
308
309 ACPI_ERROR ((AE_INFO,
310 "Unknown field creation opcode 0x%02X",
311 AmlOpcode));
312 Status = AE_AML_BAD_OPCODE;
313 goto Cleanup;
314 }
315
316 /* Entire field must fit within the current length of the buffer */
317
318 if ((BitOffset + BitCount) >
319 (8 * (UINT32) BufferDesc->Buffer.Length))
320 {
321 ACPI_ERROR ((AE_INFO,
322 "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
323 AcpiUtGetNodeName (ResultDesc),
324 BitOffset + BitCount,
325 AcpiUtGetNodeName (BufferDesc->Buffer.Node),
326 8 * (UINT32) BufferDesc->Buffer.Length));
327 Status = AE_AML_BUFFER_LIMIT;
328 goto Cleanup;
329 }
330
331 /*
332 * Initialize areas of the field object that are common to all fields
333 * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
334 * UPDATE_RULE = 0 (UPDATE_PRESERVE)
335 */
336 Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
337 BitOffset, BitCount);
338 if (ACPI_FAILURE (Status))
339 {
340 goto Cleanup;
341 }
342
343 ObjDesc->BufferField.BufferObj = BufferDesc;
344
345 /* Reference count for BufferDesc inherits ObjDesc count */
346
347 BufferDesc->Common.ReferenceCount = (UINT16)
348 (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
349
350
351 Cleanup:
352
353 /* Always delete the operands */
354
355 AcpiUtRemoveReference (OffsetDesc);
356 AcpiUtRemoveReference (BufferDesc);
357
358 if (AmlOpcode == AML_CREATE_FIELD_OP)
359 {
360 AcpiUtRemoveReference (LengthDesc);
361 }
362
363 /* On failure, delete the result descriptor */
364
365 if (ACPI_FAILURE (Status))
366 {
367 AcpiUtRemoveReference (ResultDesc); /* Result descriptor */
368 }
369 else
370 {
371 /* Now the address and length are valid for this BufferField */
372
373 ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
374 }
375
376 return_ACPI_STATUS (Status);
377 }
378
379
380 /*******************************************************************************
381 *
382 * FUNCTION: AcpiDsEvalBufferFieldOperands
383 *
384 * PARAMETERS: WalkState - Current walk
385 * Op - A valid BufferField Op object
386 *
387 * RETURN: Status
388 *
389 * DESCRIPTION: Get BufferField Buffer and Index
390 * Called from AcpiDsExecEndOp during BufferField parse tree walk
391 *
392 ******************************************************************************/
393
394 ACPI_STATUS
395 AcpiDsEvalBufferFieldOperands (
396 ACPI_WALK_STATE *WalkState,
397 ACPI_PARSE_OBJECT *Op)
398 {
399 ACPI_STATUS Status;
400 ACPI_OPERAND_OBJECT *ObjDesc;
401 ACPI_NAMESPACE_NODE *Node;
402 ACPI_PARSE_OBJECT *NextOp;
403
404
405 ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
406
407
408 /*
409 * This is where we evaluate the address and length fields of the
410 * CreateXxxField declaration
411 */
412 Node = Op->Common.Node;
413
414 /* NextOp points to the op that holds the Buffer */
415
416 NextOp = Op->Common.Value.Arg;
417
418 /* Evaluate/create the address and length operands */
419
420 Status = AcpiDsCreateOperands (WalkState, NextOp);
421 if (ACPI_FAILURE (Status))
422 {
423 return_ACPI_STATUS (Status);
424 }
425
426 ObjDesc = AcpiNsGetAttachedObject (Node);
427 if (!ObjDesc)
428 {
429 return_ACPI_STATUS (AE_NOT_EXIST);
430 }
431
432 /* Resolve the operands */
433
434 Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
435 ACPI_WALK_OPERANDS, WalkState);
436 if (ACPI_FAILURE (Status))
437 {
438 ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
439 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
440
441 return_ACPI_STATUS (Status);
442 }
443
444 /* Initialize the Buffer Field */
445
446 if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
447 {
448 /* NOTE: Slightly different operands for this opcode */
449
450 Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
451 WalkState->Operands[0], WalkState->Operands[1],
452 WalkState->Operands[2], WalkState->Operands[3]);
453 }
454 else
455 {
456 /* All other, CreateXxxField opcodes */
457
458 Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
459 WalkState->Operands[0], WalkState->Operands[1],
460 NULL, WalkState->Operands[2]);
461 }
462
463 return_ACPI_STATUS (Status);
464 }
465
466
467 /*******************************************************************************
468 *
469 * FUNCTION: AcpiDsEvalRegionOperands
470 *
471 * PARAMETERS: WalkState - Current walk
472 * Op - A valid region Op object
473 *
474 * RETURN: Status
475 *
476 * DESCRIPTION: Get region address and length
477 * Called from AcpiDsExecEndOp during OpRegion parse tree walk
478 *
479 ******************************************************************************/
480
481 ACPI_STATUS
482 AcpiDsEvalRegionOperands (
483 ACPI_WALK_STATE *WalkState,
484 ACPI_PARSE_OBJECT *Op)
485 {
486 ACPI_STATUS Status;
487 ACPI_OPERAND_OBJECT *ObjDesc;
488 ACPI_OPERAND_OBJECT *OperandDesc;
489 ACPI_NAMESPACE_NODE *Node;
490 ACPI_PARSE_OBJECT *NextOp;
491
492
493 ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
494
495
496 /*
497 * This is where we evaluate the address and length fields of the
498 * OpRegion declaration
499 */
500 Node = Op->Common.Node;
501
502 /* NextOp points to the op that holds the SpaceID */
503
504 NextOp = Op->Common.Value.Arg;
505
506 /* NextOp points to address op */
507
508 NextOp = NextOp->Common.Next;
509
510 /* Evaluate/create the address and length operands */
511
512 Status = AcpiDsCreateOperands (WalkState, NextOp);
513 if (ACPI_FAILURE (Status))
514 {
515 return_ACPI_STATUS (Status);
516 }
517
518 /* Resolve the length and address operands to numbers */
519
520 Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
521 ACPI_WALK_OPERANDS, WalkState);
522 if (ACPI_FAILURE (Status))
523 {
524 return_ACPI_STATUS (Status);
525 }
526
527 ObjDesc = AcpiNsGetAttachedObject (Node);
528 if (!ObjDesc)
529 {
530 return_ACPI_STATUS (AE_NOT_EXIST);
531 }
532
533 /*
534 * Get the length operand and save it
535 * (at Top of stack)
536 */
537 OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
538
539 ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
540 AcpiUtRemoveReference (OperandDesc);
541
542 /*
543 * Get the address and save it
544 * (at top of stack - 1)
545 */
546 OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
547
548 ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
549 OperandDesc->Integer.Value;
550 AcpiUtRemoveReference (OperandDesc);
551
552 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
553 ObjDesc,
554 ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
555 ObjDesc->Region.Length));
556
557 /* Now the address and length are valid for this opregion */
558
559 ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
560
561 return_ACPI_STATUS (Status);
562 }
563
564
565 /*******************************************************************************
566 *
567 * FUNCTION: AcpiDsEvalTableRegionOperands
568 *
569 * PARAMETERS: WalkState - Current walk
570 * Op - A valid region Op object
571 *
572 * RETURN: Status
573 *
574 * DESCRIPTION: Get region address and length.
575 * Called from AcpiDsExecEndOp during DataTableRegion parse
576 * tree walk.
577 *
578 ******************************************************************************/
579
580 ACPI_STATUS
581 AcpiDsEvalTableRegionOperands (
582 ACPI_WALK_STATE *WalkState,
583 ACPI_PARSE_OBJECT *Op)
584 {
585 ACPI_STATUS Status;
586 ACPI_OPERAND_OBJECT *ObjDesc;
587 ACPI_OPERAND_OBJECT **Operand;
588 ACPI_NAMESPACE_NODE *Node;
589 ACPI_PARSE_OBJECT *NextOp;
590 UINT32 TableIndex;
591 ACPI_TABLE_HEADER *Table;
592
593
594 ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
595
596
597 /*
598 * This is where we evaluate the Signature string, OemId string,
599 * and OemTableId string of the Data Table Region declaration
600 */
601 Node = Op->Common.Node;
602
603 /* NextOp points to Signature string op */
604
605 NextOp = Op->Common.Value.Arg;
606
607 /*
608 * Evaluate/create the Signature string, OemId string,
609 * and OemTableId string operands
610 */
611 Status = AcpiDsCreateOperands (WalkState, NextOp);
612 if (ACPI_FAILURE (Status))
613 {
614 return_ACPI_STATUS (Status);
615 }
616
617 /*
618 * Resolve the Signature string, OemId string,
619 * and OemTableId string operands
620 */
621 Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
622 ACPI_WALK_OPERANDS, WalkState);
623 if (ACPI_FAILURE (Status))
624 {
625 return_ACPI_STATUS (Status);
626 }
627
628 Operand = &WalkState->Operands[0];
629
630 /* Find the ACPI table */
631
632 Status = AcpiTbFindTable (Operand[0]->String.Pointer,
633 Operand[1]->String.Pointer, Operand[2]->String.Pointer,
634 &TableIndex);
635 if (ACPI_FAILURE (Status))
636 {
637 return_ACPI_STATUS (Status);
638 }
639
640 AcpiUtRemoveReference (Operand[0]);
641 AcpiUtRemoveReference (Operand[1]);
642 AcpiUtRemoveReference (Operand[2]);
643
644 Status = AcpiGetTableByIndex (TableIndex, &Table);
645 if (ACPI_FAILURE (Status))
646 {
647 return_ACPI_STATUS (Status);
648 }
649
650 ObjDesc = AcpiNsGetAttachedObject (Node);
651 if (!ObjDesc)
652 {
653 return_ACPI_STATUS (AE_NOT_EXIST);
654 }
655
656 ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
657 ObjDesc->Region.Length = Table->Length;
658
659 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
660 ObjDesc,
661 ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
662 ObjDesc->Region.Length));
663
664 /* Now the address and length are valid for this opregion */
665
666 ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
667
668 return_ACPI_STATUS (Status);
669 }
670
671
672 /*******************************************************************************
673 *
674 * FUNCTION: AcpiDsEvalDataObjectOperands
675 *
676 * PARAMETERS: WalkState - Current walk
677 * Op - A valid DataObject Op object
678 * ObjDesc - DataObject
679 *
680 * RETURN: Status
681 *
682 * DESCRIPTION: Get the operands and complete the following data object types:
683 * Buffer, Package.
684 *
685 ******************************************************************************/
686
687 ACPI_STATUS
688 AcpiDsEvalDataObjectOperands (
689 ACPI_WALK_STATE *WalkState,
690 ACPI_PARSE_OBJECT *Op,
691 ACPI_OPERAND_OBJECT *ObjDesc)
692 {
693 ACPI_STATUS Status;
694 ACPI_OPERAND_OBJECT *ArgDesc;
695 UINT32 Length;
696
697
698 ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
699
700
701 /* The first operand (for all of these data objects) is the length */
702
703 /*
704 * Set proper index into operand stack for AcpiDsObjStackPush
705 * invoked inside AcpiDsCreateOperand.
706 */
707 WalkState->OperandIndex = WalkState->NumOperands;
708
709 Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
710 if (ACPI_FAILURE (Status))
711 {
712 return_ACPI_STATUS (Status);
713 }
714
715 Status = AcpiExResolveOperands (WalkState->Opcode,
716 &(WalkState->Operands [WalkState->NumOperands -1]),
717 WalkState);
718 if (ACPI_FAILURE (Status))
719 {
720 return_ACPI_STATUS (Status);
721 }
722
723 /* Extract length operand */
724
725 ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
726 Length = (UINT32) ArgDesc->Integer.Value;
727
728 /* Cleanup for length operand */
729
730 Status = AcpiDsObjStackPop (1, WalkState);
731 if (ACPI_FAILURE (Status))
732 {
733 return_ACPI_STATUS (Status);
734 }
735
736 AcpiUtRemoveReference (ArgDesc);
737
738 /*
739 * Create the actual data object
740 */
741 switch (Op->Common.AmlOpcode)
742 {
743 case AML_BUFFER_OP:
744
745 Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
746 break;
747
748 case AML_PACKAGE_OP:
749 case AML_VAR_PACKAGE_OP:
750
751 Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
752 break;
753
754 default:
755
756 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
757 }
758
759 if (ACPI_SUCCESS (Status))
760 {
761 /*
762 * Return the object in the WalkState, unless the parent is a package -
763 * in this case, the return object will be stored in the parse tree
764 * for the package.
765 */
766 if ((!Op->Common.Parent) ||
767 ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
768 (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
769 (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
770 {
771 WalkState->ResultObj = ObjDesc;
772 }
773 }
774
775 return_ACPI_STATUS (Status);
776 }
777
778
779 /*******************************************************************************
780 *
781 * FUNCTION: AcpiDsEvalBankFieldOperands
782 *
783 * PARAMETERS: WalkState - Current walk
784 * Op - A valid BankField Op object
785 *
786 * RETURN: Status
787 *
788 * DESCRIPTION: Get BankField BankValue
789 * Called from AcpiDsExecEndOp during BankField parse tree walk
790 *
791 ******************************************************************************/
792
793 ACPI_STATUS
794 AcpiDsEvalBankFieldOperands (
795 ACPI_WALK_STATE *WalkState,
796 ACPI_PARSE_OBJECT *Op)
797 {
798 ACPI_STATUS Status;
799 ACPI_OPERAND_OBJECT *ObjDesc;
800 ACPI_OPERAND_OBJECT *OperandDesc;
801 ACPI_NAMESPACE_NODE *Node;
802 ACPI_PARSE_OBJECT *NextOp;
803 ACPI_PARSE_OBJECT *Arg;
804
805
806 ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
807
808
809 /*
810 * This is where we evaluate the BankValue field of the
811 * BankField declaration
812 */
813
814 /* NextOp points to the op that holds the Region */
815
816 NextOp = Op->Common.Value.Arg;
817
818 /* NextOp points to the op that holds the Bank Register */
819
820 NextOp = NextOp->Common.Next;
821
822 /* NextOp points to the op that holds the Bank Value */
823
824 NextOp = NextOp->Common.Next;
825
826 /*
827 * Set proper index into operand stack for AcpiDsObjStackPush
828 * invoked inside AcpiDsCreateOperand.
829 *
830 * We use WalkState->Operands[0] to store the evaluated BankValue
831 */
832 WalkState->OperandIndex = 0;
833
834 Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
835 if (ACPI_FAILURE (Status))
836 {
837 return_ACPI_STATUS (Status);
838 }
839
840 Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
841 if (ACPI_FAILURE (Status))
842 {
843 return_ACPI_STATUS (Status);
844 }
845
846 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
847 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
848 /*
849 * Get the BankValue operand and save it
850 * (at Top of stack)
851 */
852 OperandDesc = WalkState->Operands[0];
853
854 /* Arg points to the start Bank Field */
855
856 Arg = AcpiPsGetArg (Op, 4);
857 while (Arg)
858 {
859 /* Ignore OFFSET and ACCESSAS terms here */
860
861 if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
862 {
863 Node = Arg->Common.Node;
864
865 ObjDesc = AcpiNsGetAttachedObject (Node);
866 if (!ObjDesc)
867 {
868 return_ACPI_STATUS (AE_NOT_EXIST);
869 }
870
871 ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
872 }
873
874 /* Move to next field in the list */
875
876 Arg = Arg->Common.Next;
877 }
878
879 AcpiUtRemoveReference (OperandDesc);
880 return_ACPI_STATUS (Status);
881 }