Deleted Added
sdiff udiff text old ( 85756 ) new ( 87031 )
full compact
1/******************************************************************************
2 *
3 * Module Name: dsopcode - Dispatcher Op Region support and handling of
4 * "control" opcodes
5 * $Revision: 66 $
6 *
7 *****************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14 * All rights reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights. You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code. No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision. In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change. Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee. Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution. In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government. In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118#define __DSOPCODE_C__
119
120#include "acpi.h"
121#include "acparser.h"
122#include "amlcode.h"
123#include "acdispat.h"
124#include "acinterp.h"
125#include "acnamesp.h"
126#include "acevents.h"
127#include "actables.h"
128
129#define _COMPONENT ACPI_DISPATCHER
130 MODULE_NAME ("dsopcode")
131
132
133/*****************************************************************************
134 *
135 * FUNCTION: AcpiDsExecuteArguments
136 *
137 * PARAMETERS: Node - Parent NS node
138 * ExtraDesc - Has AML pointer and length
139 *
140 * RETURN: Status.
141 *
142 * DESCRIPTION: Late execution of region or field arguments
143 *
144 ****************************************************************************/
145
146ACPI_STATUS
147AcpiDsExecuteArguments (
148 ACPI_NAMESPACE_NODE *Node,
149 ACPI_OPERAND_OBJECT *ExtraDesc)
150{
151 ACPI_STATUS Status;
152 ACPI_PARSE_OBJECT *Op;
153 ACPI_WALK_STATE *WalkState;
154 ACPI_PARSE_OBJECT *Arg;
155
156
157 FUNCTION_TRACE ("AcpiDsExecuteArguments");
158
159
160 /*
161 * Allocate a new parser op to be the root of the parsed
162 * BufferField tree
163 */
164 Op = AcpiPsAllocOp (AML_SCOPE_OP);
165 if (!Op)
166 {
167 return_ACPI_STATUS (AE_NO_MEMORY);
168 }
169
170 /* Save the Node for use in AcpiPsParseAml */
171
172 Op->Node = AcpiNsGetParentObject (Node);
173
174 /* Create and initialize a new parser state */
175
176 WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
177 if (!WalkState)
178 {
179 return_ACPI_STATUS (AE_NO_MEMORY);
180 }
181
182 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, ExtraDesc->Extra.AmlStart,
183 ExtraDesc->Extra.AmlLength, NULL, NULL, 1);
184 if (ACPI_FAILURE (Status))
185 {
186 AcpiDsDeleteWalkState (WalkState);
187 return_ACPI_STATUS (Status);
188 }
189
190 WalkState->ParseFlags = 0;
191
192 /* Pass1: Parse the entire BufferField declaration */
193
194 Status = AcpiPsParseAml (WalkState);
195 if (ACPI_FAILURE (Status))
196 {
197 AcpiPsDeleteParseTree (Op);
198 return_ACPI_STATUS (Status);
199 }
200
201 /* Get and init the actual FieldUnit Op created above */
202
203 Arg = Op->Value.Arg;
204 Op->Node = Node;
205 Arg->Node = Node;
206 AcpiPsDeleteParseTree (Op);
207
208 /* Evaluate the address and length arguments for the Buffer Field */
209
210 Op = AcpiPsAllocOp (AML_SCOPE_OP);
211 if (!Op)
212 {
213 return_ACPI_STATUS (AE_NO_MEMORY);
214 }
215
216 Op->Node = AcpiNsGetParentObject (Node);
217
218 /* Create and initialize a new parser state */
219
220 WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
221 if (!WalkState)
222 {
223 return_ACPI_STATUS (AE_NO_MEMORY);
224 }
225
226 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, ExtraDesc->Extra.AmlStart,
227 ExtraDesc->Extra.AmlLength, NULL, NULL, 3);
228 if (ACPI_FAILURE (Status))
229 {
230 AcpiDsDeleteWalkState (WalkState);
231 return_ACPI_STATUS (Status);
232 }
233
234 Status = AcpiPsParseAml (WalkState);
235 AcpiPsDeleteParseTree (Op);
236
237 return_ACPI_STATUS (Status);
238}
239
240
241/*****************************************************************************
242 *
243 * FUNCTION: AcpiDsGetBufferFieldArguments
244 *
245 * PARAMETERS: ObjDesc - A valid BufferField object
246 *
247 * RETURN: Status.
248 *
249 * DESCRIPTION: Get BufferField Buffer and Index. This implements the late
250 * evaluation of these field attributes.
251 *
252 ****************************************************************************/
253
254ACPI_STATUS
255AcpiDsGetBufferFieldArguments (
256 ACPI_OPERAND_OBJECT *ObjDesc)
257{
258 ACPI_OPERAND_OBJECT *ExtraDesc;
259 ACPI_NAMESPACE_NODE *Node;
260 ACPI_STATUS Status;
261
262
263 FUNCTION_TRACE_PTR ("DsGetBufferFieldArguments", ObjDesc);
264
265
266 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
267 {
268 return_ACPI_STATUS (AE_OK);
269 }
270
271 /* Get the AML pointer (method object) and BufferField node */
272
273 ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
274 Node = ObjDesc->BufferField.Node;
275
276 DEBUG_EXEC(AcpiUtDisplayInitPathname (Node, " [Field]"));
277 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField JIT Init\n",
278 (char *) &Node->Name));
279
280 /* Execute the AML code for the TermArg arguments */
281
282 Status = AcpiDsExecuteArguments (Node, ExtraDesc);
283 return_ACPI_STATUS (Status);
284}
285
286
287/*****************************************************************************
288 *
289 * FUNCTION: AcpiDsGetRegionArguments
290 *
291 * PARAMETERS: ObjDesc - A valid region object
292 *
293 * RETURN: Status.
294 *
295 * DESCRIPTION: Get region address and length. This implements the late
296 * evaluation of these region attributes.
297 *
298 ****************************************************************************/
299
300ACPI_STATUS
301AcpiDsGetRegionArguments (
302 ACPI_OPERAND_OBJECT *ObjDesc)
303{
304 ACPI_NAMESPACE_NODE *Node;
305 ACPI_STATUS Status;
306 ACPI_OPERAND_OBJECT *RegionObj2;
307
308
309 FUNCTION_TRACE_PTR ("DsGetRegionArguments", ObjDesc);
310
311
312 if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
313 {
314 return_ACPI_STATUS (AE_OK);
315 }
316
317 RegionObj2 = AcpiNsGetSecondaryObject (ObjDesc);
318 if (!RegionObj2)
319 {
320 return_ACPI_STATUS (AE_NOT_EXIST);
321 }
322
323 /* Get the AML pointer (method object) and region node */
324
325 Node = ObjDesc->Region.Node;
326
327 DEBUG_EXEC(AcpiUtDisplayInitPathname (Node, " [Operation Region]"));
328
329 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Init at AML %p\n",
330 (char *) &Node->Name, RegionObj2->Extra.AmlStart));
331
332
333 Status = AcpiDsExecuteArguments (Node, RegionObj2);
334
335 return_ACPI_STATUS (Status);
336}
337
338
339/*****************************************************************************
340 *
341 * FUNCTION: AcpiDsInitializeRegion
342 *
343 * PARAMETERS: Op - A valid region Op object
344 *
345 * RETURN: Status
346 *
347 * DESCRIPTION:
348 *
349 ****************************************************************************/
350
351ACPI_STATUS
352AcpiDsInitializeRegion (
353 ACPI_HANDLE ObjHandle)
354{
355 ACPI_OPERAND_OBJECT *ObjDesc;
356 ACPI_STATUS Status;
357
358
359 ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
360
361 /* Namespace is NOT locked */
362
363 Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
364
365 return (Status);
366}
367
368
369/*****************************************************************************
370 *
371 * FUNCTION: AcpiDsEvalBufferFieldOperands
372 *
373 * PARAMETERS: Op - A valid BufferField Op object
374 *
375 * RETURN: Status
376 *
377 * DESCRIPTION: Get BufferField Buffer and Index
378 * Called from AcpiDsExecEndOp during BufferField parse tree walk
379 *
380 ****************************************************************************/
381
382ACPI_STATUS
383AcpiDsEvalBufferFieldOperands (
384 ACPI_WALK_STATE *WalkState,
385 ACPI_PARSE_OBJECT *Op)
386{
387 ACPI_STATUS Status;
388 ACPI_OPERAND_OBJECT *ObjDesc;
389 ACPI_NAMESPACE_NODE *Node;
390 ACPI_PARSE_OBJECT *NextOp;
391 UINT32 Offset;
392 UINT32 BitOffset;
393 UINT32 BitCount;
394 UINT8 FieldFlags;
395 ACPI_OPERAND_OBJECT *ResDesc = NULL;
396 ACPI_OPERAND_OBJECT *CntDesc = NULL;
397 ACPI_OPERAND_OBJECT *OffDesc = NULL;
398 ACPI_OPERAND_OBJECT *SrcDesc = NULL;
399
400
401 FUNCTION_TRACE_PTR ("DsEvalBufferFieldOperands", Op);
402
403
404 /*
405 * This is where we evaluate the address and length fields of the
406 * CreateXxxField declaration
407 */
408 Node = Op->Node;
409
410 /* NextOp points to the op that holds the Buffer */
411
412 NextOp = Op->Value.Arg;
413
414 /* AcpiEvaluate/create the address and length operands */
415
416 Status = AcpiDsCreateOperands (WalkState, NextOp);
417 if (ACPI_FAILURE (Status))
418 {
419 return_ACPI_STATUS (Status);
420 }
421
422 ObjDesc = AcpiNsGetAttachedObject (Node);
423 if (!ObjDesc)
424 {
425 return_ACPI_STATUS (AE_NOT_EXIST);
426 }
427
428 /* Resolve the operands */
429
430 Status = AcpiExResolveOperands (Op->Opcode, WALK_OPERANDS, WalkState);
431 DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE, AcpiPsGetOpcodeName (Op->Opcode),
432 WalkState->NumOperands, "after AcpiExResolveOperands");
433
434 if (ACPI_FAILURE (Status))
435 {
436 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
437 AcpiPsGetOpcodeName (Op->Opcode), Status));
438
439 goto Cleanup;
440 }
441
442 /* Get the operands */
443
444 if (AML_CREATE_FIELD_OP == Op->Opcode)
445 {
446 ResDesc = WalkState->Operands[3];
447 CntDesc = WalkState->Operands[2];
448 }
449 else
450 {
451 ResDesc = WalkState->Operands[2];
452 }
453
454 OffDesc = WalkState->Operands[1];
455 SrcDesc = WalkState->Operands[0];
456 Offset = (UINT32) OffDesc->Integer.Value;
457
458 /*
459 * If ResDesc is a Name, it will be a direct name pointer after
460 * AcpiExResolveOperands()
461 */
462 if (!VALID_DESCRIPTOR_TYPE (ResDesc, ACPI_DESC_TYPE_NAMED))
463 {
464 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a Node\n",
465 AcpiPsGetOpcodeName (Op->Opcode)));
466
467 Status = AE_AML_OPERAND_TYPE;
468 goto Cleanup;
469 }
470
471 /*
472 * Setup the Bit offsets and counts, according to the opcode
473 */
474 switch (Op->Opcode)
475 {
476
477 case AML_CREATE_FIELD_OP:
478
479 /* Offset is in bits, count is in bits */
480
481 BitOffset = Offset;
482 BitCount = (UINT32) CntDesc->Integer.Value;
483 FieldFlags = AML_FIELD_ACCESS_BYTE;
484 break;
485
486 case AML_CREATE_BIT_FIELD_OP:
487
488 /* Offset is in bits, Field is one bit */
489
490 BitOffset = Offset;
491 BitCount = 1;
492 FieldFlags = AML_FIELD_ACCESS_BYTE;
493 break;
494
495 case AML_CREATE_BYTE_FIELD_OP:
496
497 /* Offset is in bytes, field is one byte */
498
499 BitOffset = 8 * Offset;
500 BitCount = 8;
501 FieldFlags = AML_FIELD_ACCESS_BYTE;
502 break;
503
504 case AML_CREATE_WORD_FIELD_OP:
505
506 /* Offset is in bytes, field is one word */
507
508 BitOffset = 8 * Offset;
509 BitCount = 16;
510 FieldFlags = AML_FIELD_ACCESS_WORD;
511 break;
512
513 case AML_CREATE_DWORD_FIELD_OP:
514
515 /* Offset is in bytes, field is one dword */
516
517 BitOffset = 8 * Offset;
518 BitCount = 32;
519 FieldFlags = AML_FIELD_ACCESS_DWORD;
520 break;
521
522 case AML_CREATE_QWORD_FIELD_OP:
523
524 /* Offset is in bytes, field is one qword */
525
526 BitOffset = 8 * Offset;
527 BitCount = 64;
528 FieldFlags = AML_FIELD_ACCESS_QWORD;
529 break;
530
531 default:
532
533 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
534 "Internal error - unknown field creation opcode %02x\n",
535 Op->Opcode));
536 Status = AE_AML_BAD_OPCODE;
537 goto Cleanup;
538 }
539
540 /*
541 * Setup field according to the object type
542 */
543 switch (SrcDesc->Common.Type)
544 {
545
546 /* SourceBuff := TermArg=>Buffer */
547
548 case ACPI_TYPE_BUFFER:
549
550 if ((BitOffset + BitCount) >
551 (8 * (UINT32) SrcDesc->Buffer.Length))
552 {
553 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
554 "Field size %d exceeds Buffer size %d (bits)\n",
555 BitOffset + BitCount, 8 * (UINT32) SrcDesc->Buffer.Length));
556 Status = AE_AML_BUFFER_LIMIT;
557 goto Cleanup;
558 }
559
560 /*
561 * Initialize areas of the field object that are common to all fields
562 * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
563 */
564 Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
565 BitOffset, BitCount);
566 if (ACPI_FAILURE (Status))
567 {
568 return_ACPI_STATUS (Status);
569 }
570
571 ObjDesc->BufferField.BufferObj = SrcDesc;
572
573 /* Reference count for SrcDesc inherits ObjDesc count */
574
575 SrcDesc->Common.ReferenceCount = (UINT16) (SrcDesc->Common.ReferenceCount +
576 ObjDesc->Common.ReferenceCount);
577 break;
578
579
580 /* Improper object type */
581
582 default:
583
584 if ((SrcDesc->Common.Type > (UINT8) INTERNAL_TYPE_REFERENCE) || !AcpiUtValidObjectType (SrcDesc->Common.Type)) /* This line MUST be a single line until AcpiSrc can handle it (block deletion) */
585 {
586 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
587 "Tried to create field in invalid object type %X\n",
588 SrcDesc->Common.Type));
589 }
590
591 else
592 {
593 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
594 "Tried to create field in improper object type - %s\n",
595 AcpiUtGetTypeName (SrcDesc->Common.Type)));
596 }
597
598 Status = AE_AML_OPERAND_TYPE;
599 goto Cleanup;
600 }
601
602
603 if (AML_CREATE_FIELD_OP == Op->Opcode)
604 {
605 /* Delete object descriptor unique to CreateField */
606
607 AcpiUtRemoveReference (CntDesc);
608 CntDesc = NULL;
609 }
610
611
612Cleanup:
613
614 /* Always delete the operands */
615
616 AcpiUtRemoveReference (OffDesc);
617 AcpiUtRemoveReference (SrcDesc);
618
619 if (AML_CREATE_FIELD_OP == Op->Opcode)
620 {
621 AcpiUtRemoveReference (CntDesc);
622 }
623
624 /* On failure, delete the result descriptor */
625
626 if (ACPI_FAILURE (Status))
627 {
628 AcpiUtRemoveReference (ResDesc); /* Result descriptor */
629 }
630
631 else
632 {
633 /* Now the address and length are valid for this BufferField */
634
635 ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
636 }
637
638 return_ACPI_STATUS (Status);
639}
640
641
642/*****************************************************************************
643 *
644 * FUNCTION: AcpiDsEvalRegionOperands
645 *
646 * PARAMETERS: Op - A valid region Op object
647 *
648 * RETURN: Status
649 *
650 * DESCRIPTION: Get region address and length
651 * Called from AcpiDsExecEndOp during OpRegion parse tree walk
652 *
653 ****************************************************************************/
654
655ACPI_STATUS
656AcpiDsEvalRegionOperands (
657 ACPI_WALK_STATE *WalkState,
658 ACPI_PARSE_OBJECT *Op)
659{
660 ACPI_STATUS Status;
661 ACPI_OPERAND_OBJECT *ObjDesc;
662 ACPI_OPERAND_OBJECT *OperandDesc;
663 ACPI_NAMESPACE_NODE *Node;
664 ACPI_PARSE_OBJECT *NextOp;
665
666
667 FUNCTION_TRACE_PTR ("DsEvalRegionOperands", Op);
668
669
670 /*
671 * This is where we evaluate the address and length fields of the OpRegion declaration
672 */
673 Node = Op->Node;
674
675 /* NextOp points to the op that holds the SpaceID */
676
677 NextOp = Op->Value.Arg;
678
679 /* NextOp points to address op */
680
681 NextOp = NextOp->Next;
682
683 /* AcpiEvaluate/create the address and length operands */
684
685 Status = AcpiDsCreateOperands (WalkState, NextOp);
686 if (ACPI_FAILURE (Status))
687 {
688 return_ACPI_STATUS (Status);
689 }
690
691 /* Resolve the length and address operands to numbers */
692
693 Status = AcpiExResolveOperands (Op->Opcode, WALK_OPERANDS, WalkState);
694 if (ACPI_FAILURE (Status))
695 {
696 return_ACPI_STATUS (Status);
697 }
698
699 DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE,
700 AcpiPsGetOpcodeName (Op->Opcode),
701 1, "after AcpiExResolveOperands");
702
703
704 ObjDesc = AcpiNsGetAttachedObject (Node);
705 if (!ObjDesc)
706 {
707 return_ACPI_STATUS (AE_NOT_EXIST);
708 }
709
710 /*
711 * Get the length operand and save it
712 * (at Top of stack)
713 */
714 OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
715
716 ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
717 AcpiUtRemoveReference (OperandDesc);
718
719 /*
720 * Get the address and save it
721 * (at top of stack - 1)
722 */
723 OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
724
725 ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) OperandDesc->Integer.Value;
726 AcpiUtRemoveReference (OperandDesc);
727
728
729 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
730 ObjDesc, HIDWORD(ObjDesc->Region.Address), LODWORD(ObjDesc->Region.Address),
731 ObjDesc->Region.Length));
732
733 /* Now the address and length are valid for this opregion */
734
735 ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
736
737 return_ACPI_STATUS (Status);
738}
739
740
741/*******************************************************************************
742 *
743 * FUNCTION: AcpiDsExecBeginControlOp
744 *
745 * PARAMETERS: WalkList - The list that owns the walk stack
746 * Op - The control Op
747 *
748 * RETURN: Status
749 *
750 * DESCRIPTION: Handles all control ops encountered during control method
751 * execution.
752 *
753 ******************************************************************************/
754
755ACPI_STATUS
756AcpiDsExecBeginControlOp (
757 ACPI_WALK_STATE *WalkState,
758 ACPI_PARSE_OBJECT *Op)
759{
760 ACPI_STATUS Status = AE_OK;
761 ACPI_GENERIC_STATE *ControlState;
762
763
764 PROC_NAME ("DsExecBeginControlOp");
765
766
767 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
768 Op->Opcode, WalkState));
769
770 switch (Op->Opcode)
771 {
772 case AML_IF_OP:
773 case AML_WHILE_OP:
774
775 /*
776 * IF/WHILE: Create a new control state to manage these
777 * constructs. We need to manage these as a stack, in order
778 * to handle nesting.
779 */
780 ControlState = AcpiUtCreateControlState ();
781 if (!ControlState)
782 {
783 Status = AE_NO_MEMORY;
784 break;
785 }
786
787 AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
788
789 /*
790 * Save a pointer to the predicate for multiple executions
791 * of a loop
792 */
793 WalkState->ControlState->Control.AmlPredicateStart =
794 WalkState->ParserState.Aml - 1;
795 break;
796
797 case AML_ELSE_OP:
798
799 /* Predicate is in the state object */
800 /* If predicate is true, the IF was executed, ignore ELSE part */
801
802 if (WalkState->LastPredicate)
803 {
804 Status = AE_CTRL_TRUE;
805 }
806
807 break;
808
809 case AML_RETURN_OP:
810
811 break;
812
813 default:
814 break;
815 }
816
817 return (Status);
818}
819
820
821/*******************************************************************************
822 *
823 * FUNCTION: AcpiDsExecEndControlOp
824 *
825 * PARAMETERS: WalkList - The list that owns the walk stack
826 * Op - The control Op
827 *
828 * RETURN: Status
829 *
830 * DESCRIPTION: Handles all control ops encountered during control method
831 * execution.
832 *
833 ******************************************************************************/
834
835ACPI_STATUS
836AcpiDsExecEndControlOp (
837 ACPI_WALK_STATE *WalkState,
838 ACPI_PARSE_OBJECT *Op)
839{
840 ACPI_STATUS Status = AE_OK;
841 ACPI_GENERIC_STATE *ControlState;
842
843
844 PROC_NAME ("DsExecEndControlOp");
845
846
847 switch (Op->Opcode)
848 {
849 case AML_IF_OP:
850
851 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
852
853 /*
854 * Save the result of the predicate in case there is an
855 * ELSE to come
856 */
857 WalkState->LastPredicate =
858 (BOOLEAN) WalkState->ControlState->Common.Value;
859
860 /*
861 * Pop the control state that was created at the start
862 * of the IF and free it
863 */
864 ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
865 AcpiUtDeleteGenericState (ControlState);
866 break;
867
868
869 case AML_ELSE_OP:
870
871 break;
872
873
874 case AML_WHILE_OP:
875
876 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
877
878 if (WalkState->ControlState->Common.Value)
879 {
880 /* Predicate was true, go back and evaluate it again! */
881
882 Status = AE_CTRL_PENDING;
883 }
884
885 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", Op));
886
887 /* Pop this control state and free it */
888
889 ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
890
891 WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
892 AcpiUtDeleteGenericState (ControlState);
893 break;
894
895
896 case AML_RETURN_OP:
897
898 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
899 "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Value.Arg));
900
901 /*
902 * One optional operand -- the return value
903 * It can be either an immediate operand or a result that
904 * has been bubbled up the tree
905 */
906 if (Op->Value.Arg)
907 {
908 /* Return statement has an immediate operand */
909
910 Status = AcpiDsCreateOperands (WalkState, Op->Value.Arg);
911 if (ACPI_FAILURE (Status))
912 {
913 return (Status);
914 }
915
916 /*
917 * If value being returned is a Reference (such as
918 * an arg or local), resolve it now because it may
919 * cease to exist at the end of the method.
920 */
921 Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
922 if (ACPI_FAILURE (Status))
923 {
924 return (Status);
925 }
926
927 /*
928 * Get the return value and save as the last result
929 * value. This is the only place where WalkState->ReturnDesc
930 * is set to anything other than zero!
931 */
932 WalkState->ReturnDesc = WalkState->Operands[0];
933 }
934
935 else if ((WalkState->Results) &&
936 (WalkState->Results->Results.NumResults > 0))
937 {
938 /*
939 * The return value has come from a previous calculation.
940 *
941 * If value being returned is a Reference (such as
942 * an arg or local), resolve it now because it may
943 * cease to exist at the end of the method.
944 *
945 * Allow references created by the Index operator to return unchanged.
946 */
947 if (VALID_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc [0], ACPI_DESC_TYPE_INTERNAL) &&
948 ((WalkState->Results->Results.ObjDesc [0])->Common.Type == INTERNAL_TYPE_REFERENCE) &&
949 ((WalkState->Results->Results.ObjDesc [0])->Reference.Opcode != AML_INDEX_OP))
950 {
951 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
952 if (ACPI_FAILURE (Status))
953 {
954 return (Status);
955 }
956 }
957
958 WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
959 }
960
961 else
962 {
963 /* No return operand */
964
965 if (WalkState->NumOperands)
966 {
967 AcpiUtRemoveReference (WalkState->Operands [0]);
968 }
969
970 WalkState->Operands [0] = NULL;
971 WalkState->NumOperands = 0;
972 WalkState->ReturnDesc = NULL;
973 }
974
975
976 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
977 "Completed RETURN_OP State=%p, RetVal=%p\n",
978 WalkState, WalkState->ReturnDesc));
979
980 /* End the control method execution right now */
981
982 Status = AE_CTRL_TERMINATE;
983 break;
984
985
986 case AML_NOOP_OP:
987
988 /* Just do nothing! */
989 break;
990
991
992 case AML_BREAK_POINT_OP:
993
994 /* Call up to the OS service layer to handle this */
995
996 AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
997
998 /* If and when it returns, all done. */
999
1000 break;
1001
1002
1003 case AML_BREAK_OP:
1004
1005 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
1006 "Break to end of current package, Op=%p\n", Op));
1007
1008 /* TBD: update behavior for ACPI 2.0 */
1009
1010 /*
1011 * As per the ACPI specification:
1012 * "The break operation causes the current package
1013 * execution to complete"
1014 * "Break -- Stop executing the current code package
1015 * at this point"
1016 *
1017 * Returning AE_FALSE here will cause termination of
1018 * the current package, and execution will continue one
1019 * level up, starting with the completion of the parent Op.
1020 */
1021 Status = AE_CTRL_FALSE;
1022 break;
1023
1024
1025 case AML_CONTINUE_OP: /* ACPI 2.0 */
1026
1027 Status = AE_NOT_IMPLEMENTED;
1028 break;
1029
1030
1031 default:
1032
1033 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
1034 Op->Opcode, Op));
1035
1036 Status = AE_AML_BAD_OPCODE;
1037 break;
1038 }
1039
1040 return (Status);
1041}
1042