Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: dsopcode - Dispatcher Op Region support and handling of
4
 *                         "control" opcodes
5
 *
6
 *****************************************************************************/
7
 
8
/******************************************************************************
9
 *
10
 * 1. Copyright Notice
11
 *
12
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
13
 * All rights reserved.
14
 *
15
 * 2. License
16
 *
17
 * 2.1. This is your license from Intel Corp. under its intellectual property
18
 * rights.  You may have additional license terms from the party that provided
19
 * you this software, covering your right to use that party's intellectual
20
 * property rights.
21
 *
22
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23
 * copy of the source code appearing in this file ("Covered Code") an
24
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25
 * base code distributed originally by Intel ("Original Intel Code") to copy,
26
 * make derivatives, distribute, use and display any portion of the Covered
27
 * Code in any form, with the right to sublicense such rights; and
28
 *
29
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30
 * license (with the right to sublicense), under only those claims of Intel
31
 * patents that are infringed by the Original Intel Code, to make, use, sell,
32
 * offer to sell, and import the Covered Code and derivative works thereof
33
 * solely to the minimum extent necessary to exercise the above copyright
34
 * license, and in no event shall the patent license extend to any additions
35
 * to or modifications of the Original Intel Code.  No other license or right
36
 * is granted directly or by implication, estoppel or otherwise;
37
 *
38
 * The above copyright and patent license is granted only if the following
39
 * conditions are met:
40
 *
41
 * 3. Conditions
42
 *
43
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44
 * Redistribution of source code of any substantial portion of the Covered
45
 * Code or modification with rights to further distribute source must include
46
 * the above Copyright Notice, the above License, this list of Conditions,
47
 * and the following Disclaimer and Export Compliance provision.  In addition,
48
 * Licensee must cause all Covered Code to which Licensee contributes to
49
 * contain a file documenting the changes Licensee made to create that Covered
50
 * Code and the date of any change.  Licensee must include in that file the
51
 * documentation of any changes made by any predecessor Licensee.  Licensee
52
 * must include a prominent statement that the modification is derived,
53
 * directly or indirectly, from Original Intel Code.
54
 *
55
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56
 * Redistribution of source code of any substantial portion of the Covered
57
 * Code or modification without rights to further distribute source must
58
 * include the following Disclaimer and Export Compliance provision in the
59
 * documentation and/or other materials provided with distribution.  In
60
 * addition, Licensee may not authorize further sublicense of source of any
61
 * portion of the Covered Code, and must include terms to the effect that the
62
 * license from Licensee to its licensee is limited to the intellectual
63
 * property embodied in the software Licensee provides to its licensee, and
64
 * not to intellectual property embodied in modifications its licensee may
65
 * make.
66
 *
67
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68
 * substantial portion of the Covered Code or modification must reproduce the
69
 * above Copyright Notice, and the following Disclaimer and Export Compliance
70
 * provision in the documentation and/or other materials provided with the
71
 * distribution.
72
 *
73
 * 3.4. Intel retains all right, title, and interest in and to the Original
74
 * Intel Code.
75
 *
76
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77
 * Intel shall be used in advertising or otherwise to promote the sale, use or
78
 * other dealings in products derived from or relating to the Covered Code
79
 * without prior written authorization from Intel.
80
 *
81
 * 4. Disclaimer and Export Compliance
82
 *
83
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89
 * PARTICULAR PURPOSE.
90
 *
91
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98
 * LIMITED REMEDY.
99
 *
100
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101
 * software or system incorporating such software without first obtaining any
102
 * required license or other approval from the U. S. Department of Commerce or
103
 * any other agency or department of the United States Government.  In the
104
 * event Licensee exports any such software from the United States or
105
 * re-exports any such software from a foreign destination, Licensee shall
106
 * ensure that the distribution and export/re-export of the software is in
107
 * compliance with all laws, regulations, orders, or other restrictions of the
108
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109
 * any of its subsidiaries will export/re-export any technical data, process,
110
 * software, or service, directly or indirectly, to any country for which the
111
 * United States government or any agency thereof requires an export license,
112
 * other governmental approval, or letter of assurance, without first obtaining
113
 * such license, approval or letter.
114
 *
115
 *****************************************************************************/
116
 
117
#define __DSOPCODE_C__
118
 
119
#include "acpi.h"
120
#include "accommon.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
        ACPI_MODULE_NAME    ("dsopcode")
131
 
132
/* Local prototypes */
133
 
134
static ACPI_STATUS
135
AcpiDsExecuteArguments (
136
    ACPI_NAMESPACE_NODE     *Node,
137
    ACPI_NAMESPACE_NODE     *ScopeNode,
138
    UINT32                  AmlLength,
139
    UINT8                   *AmlStart);
140
 
141
static ACPI_STATUS
142
AcpiDsInitBufferField (
143
    UINT16                  AmlOpcode,
144
    ACPI_OPERAND_OBJECT     *ObjDesc,
145
    ACPI_OPERAND_OBJECT     *BufferDesc,
146
    ACPI_OPERAND_OBJECT     *OffsetDesc,
147
    ACPI_OPERAND_OBJECT     *LengthDesc,
148
    ACPI_OPERAND_OBJECT     *ResultDesc);
149
 
150
 
151
/*******************************************************************************
152
 *
153
 * FUNCTION:    AcpiDsExecuteArguments
154
 *
155
 * PARAMETERS:  Node                - Object NS node
156
 *              ScopeNode           - Parent NS node
157
 *              AmlLength           - Length of executable AML
158
 *              AmlStart            - Pointer to the AML
159
 *
160
 * RETURN:      Status.
161
 *
162
 * DESCRIPTION: Late (deferred) execution of region or field arguments
163
 *
164
 ******************************************************************************/
165
 
166
static ACPI_STATUS
167
AcpiDsExecuteArguments (
168
    ACPI_NAMESPACE_NODE     *Node,
169
    ACPI_NAMESPACE_NODE     *ScopeNode,
170
    UINT32                  AmlLength,
171
    UINT8                   *AmlStart)
172
{
173
    ACPI_STATUS             Status;
174
    ACPI_PARSE_OBJECT       *Op;
175
    ACPI_WALK_STATE         *WalkState;
176
 
177
 
178
    ACPI_FUNCTION_TRACE (DsExecuteArguments);
179
 
180
 
181
    /*
182
     * Allocate a new parser op to be the root of the parsed tree
183
     */
184
    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
185
    if (!Op)
186
    {
187
        return_ACPI_STATUS (AE_NO_MEMORY);
188
    }
189
 
190
    /* Save the Node for use in AcpiPsParseAml */
191
 
192
    Op->Common.Node = ScopeNode;
193
 
194
    /* Create and initialize a new parser state */
195
 
196
    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
197
    if (!WalkState)
198
    {
199
        Status = AE_NO_MEMORY;
200
        goto Cleanup;
201
    }
202
 
203
    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
204
                    AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
205
    if (ACPI_FAILURE (Status))
206
    {
207
        AcpiDsDeleteWalkState (WalkState);
208
        goto Cleanup;
209
    }
210
 
211
    /* Mark this parse as a deferred opcode */
212
 
213
    WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
214
    WalkState->DeferredNode = Node;
215
 
216
    /* Pass1: Parse the entire declaration */
217
 
218
    Status = AcpiPsParseAml (WalkState);
219
    if (ACPI_FAILURE (Status))
220
    {
221
        goto Cleanup;
222
    }
223
 
224
    /* Get and init the Op created above */
225
 
226
    Op->Common.Node = Node;
227
    AcpiPsDeleteParseTree (Op);
228
 
229
    /* Evaluate the deferred arguments */
230
 
231
    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
232
    if (!Op)
233
    {
234
        return_ACPI_STATUS (AE_NO_MEMORY);
235
    }
236
 
237
    Op->Common.Node = ScopeNode;
238
 
239
    /* Create and initialize a new parser state */
240
 
241
    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
242
    if (!WalkState)
243
    {
244
        Status = AE_NO_MEMORY;
245
        goto Cleanup;
246
    }
247
 
248
    /* Execute the opcode and arguments */
249
 
250
    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
251
                    AmlLength, NULL, ACPI_IMODE_EXECUTE);
252
    if (ACPI_FAILURE (Status))
253
    {
254
        AcpiDsDeleteWalkState (WalkState);
255
        goto Cleanup;
256
    }
257
 
258
    /* Mark this execution as a deferred opcode */
259
 
260
    WalkState->DeferredNode = Node;
261
    Status = AcpiPsParseAml (WalkState);
262
 
263
Cleanup:
264
    AcpiPsDeleteParseTree (Op);
265
    return_ACPI_STATUS (Status);
266
}
267
 
268
 
269
/*******************************************************************************
270
 *
271
 * FUNCTION:    AcpiDsGetBufferFieldArguments
272
 *
273
 * PARAMETERS:  ObjDesc         - A valid BufferField object
274
 *
275
 * RETURN:      Status.
276
 *
277
 * DESCRIPTION: Get BufferField Buffer and Index.  This implements the late
278
 *              evaluation of these field attributes.
279
 *
280
 ******************************************************************************/
281
 
282
ACPI_STATUS
283
AcpiDsGetBufferFieldArguments (
284
    ACPI_OPERAND_OBJECT     *ObjDesc)
285
{
286
    ACPI_OPERAND_OBJECT     *ExtraDesc;
287
    ACPI_NAMESPACE_NODE     *Node;
288
    ACPI_STATUS             Status;
289
 
290
 
291
    ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
292
 
293
 
294
    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
295
    {
296
        return_ACPI_STATUS (AE_OK);
297
    }
298
 
299
    /* Get the AML pointer (method object) and BufferField node */
300
 
301
    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
302
    Node = ObjDesc->BufferField.Node;
303
 
304
    ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL));
305
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
306
        AcpiUtGetNodeName (Node)));
307
 
308
    /* Execute the AML code for the TermArg arguments */
309
 
310
    Status = AcpiDsExecuteArguments (Node, Node->Parent,
311
                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
312
    return_ACPI_STATUS (Status);
313
}
314
 
315
 
316
/*******************************************************************************
317
 *
318
 * FUNCTION:    AcpiDsGetBankFieldArguments
319
 *
320
 * PARAMETERS:  ObjDesc         - A valid BankField object
321
 *
322
 * RETURN:      Status.
323
 *
324
 * DESCRIPTION: Get BankField BankValue.  This implements the late
325
 *              evaluation of these field attributes.
326
 *
327
 ******************************************************************************/
328
 
329
ACPI_STATUS
330
AcpiDsGetBankFieldArguments (
331
    ACPI_OPERAND_OBJECT     *ObjDesc)
332
{
333
    ACPI_OPERAND_OBJECT     *ExtraDesc;
334
    ACPI_NAMESPACE_NODE     *Node;
335
    ACPI_STATUS             Status;
336
 
337
 
338
    ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
339
 
340
 
341
    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
342
    {
343
        return_ACPI_STATUS (AE_OK);
344
    }
345
 
346
    /* Get the AML pointer (method object) and BankField node */
347
 
348
    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
349
    Node = ObjDesc->BankField.Node;
350
 
351
    ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL));
352
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
353
        AcpiUtGetNodeName (Node)));
354
 
355
    /* Execute the AML code for the TermArg arguments */
356
 
357
    Status = AcpiDsExecuteArguments (Node, Node->Parent,
358
                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
359
    return_ACPI_STATUS (Status);
360
}
361
 
362
 
363
/*******************************************************************************
364
 *
365
 * FUNCTION:    AcpiDsGetBufferArguments
366
 *
367
 * PARAMETERS:  ObjDesc         - A valid Buffer object
368
 *
369
 * RETURN:      Status.
370
 *
371
 * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
372
 *              the late evaluation of these attributes.
373
 *
374
 ******************************************************************************/
375
 
376
ACPI_STATUS
377
AcpiDsGetBufferArguments (
378
    ACPI_OPERAND_OBJECT     *ObjDesc)
379
{
380
    ACPI_NAMESPACE_NODE     *Node;
381
    ACPI_STATUS             Status;
382
 
383
 
384
    ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
385
 
386
 
387
    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
388
    {
389
        return_ACPI_STATUS (AE_OK);
390
    }
391
 
392
    /* Get the Buffer node */
393
 
394
    Node = ObjDesc->Buffer.Node;
395
    if (!Node)
396
    {
397
        ACPI_ERROR ((AE_INFO,
398
            "No pointer back to namespace node in buffer object %p", ObjDesc));
399
        return_ACPI_STATUS (AE_AML_INTERNAL);
400
    }
401
 
402
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
403
 
404
    /* Execute the AML code for the TermArg arguments */
405
 
406
    Status = AcpiDsExecuteArguments (Node, Node,
407
                ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
408
    return_ACPI_STATUS (Status);
409
}
410
 
411
 
412
/*******************************************************************************
413
 *
414
 * FUNCTION:    AcpiDsGetPackageArguments
415
 *
416
 * PARAMETERS:  ObjDesc         - A valid Package object
417
 *
418
 * RETURN:      Status.
419
 *
420
 * DESCRIPTION: Get Package length and initializer byte list.  This implements
421
 *              the late evaluation of these attributes.
422
 *
423
 ******************************************************************************/
424
 
425
ACPI_STATUS
426
AcpiDsGetPackageArguments (
427
    ACPI_OPERAND_OBJECT     *ObjDesc)
428
{
429
    ACPI_NAMESPACE_NODE     *Node;
430
    ACPI_STATUS             Status;
431
 
432
 
433
    ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
434
 
435
 
436
    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
437
    {
438
        return_ACPI_STATUS (AE_OK);
439
    }
440
 
441
    /* Get the Package node */
442
 
443
    Node = ObjDesc->Package.Node;
444
    if (!Node)
445
    {
446
        ACPI_ERROR ((AE_INFO,
447
            "No pointer back to namespace node in package %p", ObjDesc));
448
        return_ACPI_STATUS (AE_AML_INTERNAL);
449
    }
450
 
451
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
452
 
453
    /* Execute the AML code for the TermArg arguments */
454
 
455
    Status = AcpiDsExecuteArguments (Node, Node,
456
                ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
457
    return_ACPI_STATUS (Status);
458
}
459
 
460
 
461
/*****************************************************************************
462
 *
463
 * FUNCTION:    AcpiDsGetRegionArguments
464
 *
465
 * PARAMETERS:  ObjDesc         - A valid region object
466
 *
467
 * RETURN:      Status.
468
 *
469
 * DESCRIPTION: Get region address and length.  This implements the late
470
 *              evaluation of these region attributes.
471
 *
472
 ****************************************************************************/
473
 
474
ACPI_STATUS
475
AcpiDsGetRegionArguments (
476
    ACPI_OPERAND_OBJECT     *ObjDesc)
477
{
478
    ACPI_NAMESPACE_NODE     *Node;
479
    ACPI_STATUS             Status;
480
    ACPI_OPERAND_OBJECT     *ExtraDesc;
481
 
482
 
483
    ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
484
 
485
 
486
    if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
487
    {
488
        return_ACPI_STATUS (AE_OK);
489
    }
490
 
491
    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
492
    if (!ExtraDesc)
493
    {
494
        return_ACPI_STATUS (AE_NOT_EXIST);
495
    }
496
 
497
    /* Get the Region node */
498
 
499
    Node = ObjDesc->Region.Node;
500
 
501
    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
502
 
503
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
504
        AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
505
 
506
    /* Execute the argument AML */
507
 
508
    Status = AcpiDsExecuteArguments (Node, Node->Parent,
509
                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
510
    return_ACPI_STATUS (Status);
511
}
512
 
513
 
514
/*******************************************************************************
515
 *
516
 * FUNCTION:    AcpiDsInitializeRegion
517
 *
518
 * PARAMETERS:  ObjHandle       - Region namespace node
519
 *
520
 * RETURN:      Status
521
 *
522
 * DESCRIPTION: Front end to EvInitializeRegion
523
 *
524
 ******************************************************************************/
525
 
526
ACPI_STATUS
527
AcpiDsInitializeRegion (
528
    ACPI_HANDLE             ObjHandle)
529
{
530
    ACPI_OPERAND_OBJECT     *ObjDesc;
531
    ACPI_STATUS             Status;
532
 
533
 
534
    ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
535
 
536
    /* Namespace is NOT locked */
537
 
538
    Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
539
    return (Status);
540
}
541
 
542
 
543
/*******************************************************************************
544
 *
545
 * FUNCTION:    AcpiDsInitBufferField
546
 *
547
 * PARAMETERS:  AmlOpcode       - CreateXxxField
548
 *              ObjDesc         - BufferField object
549
 *              BufferDesc      - Host Buffer
550
 *              OffsetDesc      - Offset into buffer
551
 *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
552
 *              ResultDesc      - Where to store the result
553
 *
554
 * RETURN:      Status
555
 *
556
 * DESCRIPTION: Perform actual initialization of a buffer field
557
 *
558
 ******************************************************************************/
559
 
560
static ACPI_STATUS
561
AcpiDsInitBufferField (
562
    UINT16                  AmlOpcode,
563
    ACPI_OPERAND_OBJECT     *ObjDesc,
564
    ACPI_OPERAND_OBJECT     *BufferDesc,
565
    ACPI_OPERAND_OBJECT     *OffsetDesc,
566
    ACPI_OPERAND_OBJECT     *LengthDesc,
567
    ACPI_OPERAND_OBJECT     *ResultDesc)
568
{
569
    UINT32                  Offset;
570
    UINT32                  BitOffset;
571
    UINT32                  BitCount;
572
    UINT8                   FieldFlags;
573
    ACPI_STATUS             Status;
574
 
575
 
576
    ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
577
 
578
 
579
    /* Host object must be a Buffer */
580
 
581
    if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
582
    {
583
        ACPI_ERROR ((AE_INFO,
584
            "Target of Create Field is not a Buffer object - %s",
585
            AcpiUtGetObjectTypeName (BufferDesc)));
586
 
587
        Status = AE_AML_OPERAND_TYPE;
588
        goto Cleanup;
589
    }
590
 
591
    /*
592
     * The last parameter to all of these opcodes (ResultDesc) started
593
     * out as a NameString, and should therefore now be a NS node
594
     * after resolution in AcpiExResolveOperands().
595
     */
596
    if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
597
    {
598
        ACPI_ERROR ((AE_INFO,
599
            "(%s) destination not a NS Node [%s]",
600
            AcpiPsGetOpcodeName (AmlOpcode),
601
            AcpiUtGetDescriptorName (ResultDesc)));
602
 
603
        Status = AE_AML_OPERAND_TYPE;
604
        goto Cleanup;
605
    }
606
 
607
    Offset = (UINT32) OffsetDesc->Integer.Value;
608
 
609
    /*
610
     * Setup the Bit offsets and counts, according to the opcode
611
     */
612
    switch (AmlOpcode)
613
    {
614
    case AML_CREATE_FIELD_OP:
615
 
616
        /* Offset is in bits, count is in bits */
617
 
618
        FieldFlags = AML_FIELD_ACCESS_BYTE;
619
        BitOffset  = Offset;
620
        BitCount   = (UINT32) LengthDesc->Integer.Value;
621
 
622
        /* Must have a valid (>0) bit count */
623
 
624
        if (BitCount == 0)
625
        {
626
            ACPI_ERROR ((AE_INFO,
627
                "Attempt to CreateField of length zero"));
628
            Status = AE_AML_OPERAND_VALUE;
629
            goto Cleanup;
630
        }
631
        break;
632
 
633
    case AML_CREATE_BIT_FIELD_OP:
634
 
635
        /* Offset is in bits, Field is one bit */
636
 
637
        BitOffset  = Offset;
638
        BitCount   = 1;
639
        FieldFlags = AML_FIELD_ACCESS_BYTE;
640
        break;
641
 
642
    case AML_CREATE_BYTE_FIELD_OP:
643
 
644
        /* Offset is in bytes, field is one byte */
645
 
646
        BitOffset  = 8 * Offset;
647
        BitCount   = 8;
648
        FieldFlags = AML_FIELD_ACCESS_BYTE;
649
        break;
650
 
651
    case AML_CREATE_WORD_FIELD_OP:
652
 
653
        /* Offset is in bytes, field is one word */
654
 
655
        BitOffset  = 8 * Offset;
656
        BitCount   = 16;
657
        FieldFlags = AML_FIELD_ACCESS_WORD;
658
        break;
659
 
660
    case AML_CREATE_DWORD_FIELD_OP:
661
 
662
        /* Offset is in bytes, field is one dword */
663
 
664
        BitOffset  = 8 * Offset;
665
        BitCount   = 32;
666
        FieldFlags = AML_FIELD_ACCESS_DWORD;
667
        break;
668
 
669
    case AML_CREATE_QWORD_FIELD_OP:
670
 
671
        /* Offset is in bytes, field is one qword */
672
 
673
        BitOffset  = 8 * Offset;
674
        BitCount   = 64;
675
        FieldFlags = AML_FIELD_ACCESS_QWORD;
676
        break;
677
 
678
    default:
679
 
680
        ACPI_ERROR ((AE_INFO,
681
            "Unknown field creation opcode 0x%02X",
682
            AmlOpcode));
683
        Status = AE_AML_BAD_OPCODE;
684
        goto Cleanup;
685
    }
686
 
687
    /* Entire field must fit within the current length of the buffer */
688
 
689
    if ((BitOffset + BitCount) >
690
        (8 * (UINT32) BufferDesc->Buffer.Length))
691
    {
692
        ACPI_ERROR ((AE_INFO,
693
            "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
694
            AcpiUtGetNodeName (ResultDesc),
695
            BitOffset + BitCount,
696
            AcpiUtGetNodeName (BufferDesc->Buffer.Node),
697
            8 * (UINT32) BufferDesc->Buffer.Length));
698
        Status = AE_AML_BUFFER_LIMIT;
699
        goto Cleanup;
700
    }
701
 
702
    /*
703
     * Initialize areas of the field object that are common to all fields
704
     * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
705
     * UPDATE_RULE = 0 (UPDATE_PRESERVE)
706
     */
707
    Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
708
                                            BitOffset, BitCount);
709
    if (ACPI_FAILURE (Status))
710
    {
711
        goto Cleanup;
712
    }
713
 
714
    ObjDesc->BufferField.BufferObj = BufferDesc;
715
 
716
    /* Reference count for BufferDesc inherits ObjDesc count */
717
 
718
    BufferDesc->Common.ReferenceCount = (UINT16)
719
        (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
720
 
721
 
722
Cleanup:
723
 
724
    /* Always delete the operands */
725
 
726
    AcpiUtRemoveReference (OffsetDesc);
727
    AcpiUtRemoveReference (BufferDesc);
728
 
729
    if (AmlOpcode == AML_CREATE_FIELD_OP)
730
    {
731
        AcpiUtRemoveReference (LengthDesc);
732
    }
733
 
734
    /* On failure, delete the result descriptor */
735
 
736
    if (ACPI_FAILURE (Status))
737
    {
738
        AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
739
    }
740
    else
741
    {
742
        /* Now the address and length are valid for this BufferField */
743
 
744
        ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
745
    }
746
 
747
    return_ACPI_STATUS (Status);
748
}
749
 
750
 
751
/*******************************************************************************
752
 *
753
 * FUNCTION:    AcpiDsEvalBufferFieldOperands
754
 *
755
 * PARAMETERS:  WalkState       - Current walk
756
 *              Op              - A valid BufferField Op object
757
 *
758
 * RETURN:      Status
759
 *
760
 * DESCRIPTION: Get BufferField Buffer and Index
761
 *              Called from AcpiDsExecEndOp during BufferField parse tree walk
762
 *
763
 ******************************************************************************/
764
 
765
ACPI_STATUS
766
AcpiDsEvalBufferFieldOperands (
767
    ACPI_WALK_STATE         *WalkState,
768
    ACPI_PARSE_OBJECT       *Op)
769
{
770
    ACPI_STATUS             Status;
771
    ACPI_OPERAND_OBJECT     *ObjDesc;
772
    ACPI_NAMESPACE_NODE     *Node;
773
    ACPI_PARSE_OBJECT       *NextOp;
774
 
775
 
776
    ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
777
 
778
 
779
    /*
780
     * This is where we evaluate the address and length fields of the
781
     * CreateXxxField declaration
782
     */
783
    Node =  Op->Common.Node;
784
 
785
    /* NextOp points to the op that holds the Buffer */
786
 
787
    NextOp = Op->Common.Value.Arg;
788
 
789
    /* Evaluate/create the address and length operands */
790
 
791
    Status = AcpiDsCreateOperands (WalkState, NextOp);
792
    if (ACPI_FAILURE (Status))
793
    {
794
        return_ACPI_STATUS (Status);
795
    }
796
 
797
    ObjDesc = AcpiNsGetAttachedObject (Node);
798
    if (!ObjDesc)
799
    {
800
        return_ACPI_STATUS (AE_NOT_EXIST);
801
    }
802
 
803
    /* Resolve the operands */
804
 
805
    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
806
                    ACPI_WALK_OPERANDS, WalkState);
807
    if (ACPI_FAILURE (Status))
808
    {
809
        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
810
            AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
811
 
812
        return_ACPI_STATUS (Status);
813
    }
814
 
815
    /* Initialize the Buffer Field */
816
 
817
    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
818
    {
819
        /* NOTE: Slightly different operands for this opcode */
820
 
821
        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
822
                    WalkState->Operands[0], WalkState->Operands[1],
823
                    WalkState->Operands[2], WalkState->Operands[3]);
824
    }
825
    else
826
    {
827
        /* All other, CreateXxxField opcodes */
828
 
829
        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
830
                    WalkState->Operands[0], WalkState->Operands[1],
831
                                      NULL, WalkState->Operands[2]);
832
    }
833
 
834
    return_ACPI_STATUS (Status);
835
}
836
 
837
 
838
/*******************************************************************************
839
 *
840
 * FUNCTION:    AcpiDsEvalRegionOperands
841
 *
842
 * PARAMETERS:  WalkState       - Current walk
843
 *              Op              - A valid region Op object
844
 *
845
 * RETURN:      Status
846
 *
847
 * DESCRIPTION: Get region address and length
848
 *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
849
 *
850
 ******************************************************************************/
851
 
852
ACPI_STATUS
853
AcpiDsEvalRegionOperands (
854
    ACPI_WALK_STATE         *WalkState,
855
    ACPI_PARSE_OBJECT       *Op)
856
{
857
    ACPI_STATUS             Status;
858
    ACPI_OPERAND_OBJECT     *ObjDesc;
859
    ACPI_OPERAND_OBJECT     *OperandDesc;
860
    ACPI_NAMESPACE_NODE     *Node;
861
    ACPI_PARSE_OBJECT       *NextOp;
862
 
863
 
864
    ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
865
 
866
 
867
    /*
868
     * This is where we evaluate the address and length fields of the
869
     * OpRegion declaration
870
     */
871
    Node =  Op->Common.Node;
872
 
873
    /* NextOp points to the op that holds the SpaceID */
874
 
875
    NextOp = Op->Common.Value.Arg;
876
 
877
    /* NextOp points to address op */
878
 
879
    NextOp = NextOp->Common.Next;
880
 
881
    /* Evaluate/create the address and length operands */
882
 
883
    Status = AcpiDsCreateOperands (WalkState, NextOp);
884
    if (ACPI_FAILURE (Status))
885
    {
886
        return_ACPI_STATUS (Status);
887
    }
888
 
889
    /* Resolve the length and address operands to numbers */
890
 
891
    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
892
                ACPI_WALK_OPERANDS, WalkState);
893
    if (ACPI_FAILURE (Status))
894
    {
895
        return_ACPI_STATUS (Status);
896
    }
897
 
898
    ObjDesc = AcpiNsGetAttachedObject (Node);
899
    if (!ObjDesc)
900
    {
901
        return_ACPI_STATUS (AE_NOT_EXIST);
902
    }
903
 
904
    /*
905
     * Get the length operand and save it
906
     * (at Top of stack)
907
     */
908
    OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
909
 
910
    ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
911
    AcpiUtRemoveReference (OperandDesc);
912
 
913
    /*
914
     * Get the address and save it
915
     * (at top of stack - 1)
916
     */
917
    OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
918
 
919
    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
920
                                OperandDesc->Integer.Value;
921
    AcpiUtRemoveReference (OperandDesc);
922
 
923
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
924
        ObjDesc,
925
        ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
926
        ObjDesc->Region.Length));
927
 
928
    /* Now the address and length are valid for this opregion */
929
 
930
    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
931
 
932
    return_ACPI_STATUS (Status);
933
}
934
 
935
 
936
/*******************************************************************************
937
 *
938
 * FUNCTION:    AcpiDsEvalTableRegionOperands
939
 *
940
 * PARAMETERS:  WalkState       - Current walk
941
 *              Op              - A valid region Op object
942
 *
943
 * RETURN:      Status
944
 *
945
 * DESCRIPTION: Get region address and length
946
 *              Called from AcpiDsExecEndOp during DataTableRegion parse tree walk
947
 *
948
 ******************************************************************************/
949
 
950
ACPI_STATUS
951
AcpiDsEvalTableRegionOperands (
952
    ACPI_WALK_STATE         *WalkState,
953
    ACPI_PARSE_OBJECT       *Op)
954
{
955
    ACPI_STATUS             Status;
956
    ACPI_OPERAND_OBJECT     *ObjDesc;
957
    ACPI_OPERAND_OBJECT     **Operand;
958
    ACPI_NAMESPACE_NODE     *Node;
959
    ACPI_PARSE_OBJECT       *NextOp;
960
    UINT32                  TableIndex;
961
    ACPI_TABLE_HEADER       *Table;
962
 
963
 
964
    ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
965
 
966
 
967
    /*
968
     * This is where we evaluate the SignatureString and OemIDString
969
     * and OemTableIDString of the DataTableRegion declaration
970
     */
971
    Node =  Op->Common.Node;
972
 
973
    /* NextOp points to SignatureString op */
974
 
975
    NextOp = Op->Common.Value.Arg;
976
 
977
    /*
978
     * Evaluate/create the SignatureString and OemIDString
979
     * and OemTableIDString operands
980
     */
981
    Status = AcpiDsCreateOperands (WalkState, NextOp);
982
    if (ACPI_FAILURE (Status))
983
    {
984
        return_ACPI_STATUS (Status);
985
    }
986
 
987
    /*
988
     * Resolve the SignatureString and OemIDString
989
     * and OemTableIDString operands
990
     */
991
    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
992
                ACPI_WALK_OPERANDS, WalkState);
993
    if (ACPI_FAILURE (Status))
994
    {
995
        return_ACPI_STATUS (Status);
996
    }
997
 
998
    Operand = &WalkState->Operands[0];
999
 
1000
    /* Find the ACPI table */
1001
 
1002
    Status = AcpiTbFindTable (Operand[0]->String.Pointer,
1003
                Operand[1]->String.Pointer, Operand[2]->String.Pointer,
1004
                &TableIndex);
1005
    if (ACPI_FAILURE (Status))
1006
    {
1007
        return_ACPI_STATUS (Status);
1008
    }
1009
 
1010
    AcpiUtRemoveReference (Operand[0]);
1011
    AcpiUtRemoveReference (Operand[1]);
1012
    AcpiUtRemoveReference (Operand[2]);
1013
 
1014
    Status = AcpiGetTableByIndex (TableIndex, &Table);
1015
    if (ACPI_FAILURE (Status))
1016
    {
1017
        return_ACPI_STATUS (Status);
1018
    }
1019
 
1020
    ObjDesc = AcpiNsGetAttachedObject (Node);
1021
    if (!ObjDesc)
1022
    {
1023
        return_ACPI_STATUS (AE_NOT_EXIST);
1024
    }
1025
 
1026
    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
1027
    ObjDesc->Region.Length = Table->Length;
1028
 
1029
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
1030
        ObjDesc,
1031
        ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
1032
        ObjDesc->Region.Length));
1033
 
1034
    /* Now the address and length are valid for this opregion */
1035
 
1036
    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
1037
 
1038
    return_ACPI_STATUS (Status);
1039
}
1040
 
1041
 
1042
/*******************************************************************************
1043
 *
1044
 * FUNCTION:    AcpiDsEvalDataObjectOperands
1045
 *
1046
 * PARAMETERS:  WalkState       - Current walk
1047
 *              Op              - A valid DataObject Op object
1048
 *              ObjDesc         - DataObject
1049
 *
1050
 * RETURN:      Status
1051
 *
1052
 * DESCRIPTION: Get the operands and complete the following data object types:
1053
 *              Buffer, Package.
1054
 *
1055
 ******************************************************************************/
1056
 
1057
ACPI_STATUS
1058
AcpiDsEvalDataObjectOperands (
1059
    ACPI_WALK_STATE         *WalkState,
1060
    ACPI_PARSE_OBJECT       *Op,
1061
    ACPI_OPERAND_OBJECT     *ObjDesc)
1062
{
1063
    ACPI_STATUS             Status;
1064
    ACPI_OPERAND_OBJECT     *ArgDesc;
1065
    UINT32                  Length;
1066
 
1067
 
1068
    ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
1069
 
1070
 
1071
    /* The first operand (for all of these data objects) is the length */
1072
 
1073
    /*
1074
     * Set proper index into operand stack for AcpiDsObjStackPush
1075
     * invoked inside AcpiDsCreateOperand.
1076
     */
1077
    WalkState->OperandIndex = WalkState->NumOperands;
1078
 
1079
    Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
1080
    if (ACPI_FAILURE (Status))
1081
    {
1082
        return_ACPI_STATUS (Status);
1083
    }
1084
 
1085
    Status = AcpiExResolveOperands (WalkState->Opcode,
1086
                    &(WalkState->Operands [WalkState->NumOperands -1]),
1087
                    WalkState);
1088
    if (ACPI_FAILURE (Status))
1089
    {
1090
        return_ACPI_STATUS (Status);
1091
    }
1092
 
1093
    /* Extract length operand */
1094
 
1095
    ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
1096
    Length = (UINT32) ArgDesc->Integer.Value;
1097
 
1098
    /* Cleanup for length operand */
1099
 
1100
    Status = AcpiDsObjStackPop (1, WalkState);
1101
    if (ACPI_FAILURE (Status))
1102
    {
1103
        return_ACPI_STATUS (Status);
1104
    }
1105
 
1106
    AcpiUtRemoveReference (ArgDesc);
1107
 
1108
    /*
1109
     * Create the actual data object
1110
     */
1111
    switch (Op->Common.AmlOpcode)
1112
    {
1113
    case AML_BUFFER_OP:
1114
 
1115
        Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
1116
        break;
1117
 
1118
    case AML_PACKAGE_OP:
1119
    case AML_VAR_PACKAGE_OP:
1120
 
1121
        Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
1122
        break;
1123
 
1124
    default:
1125
        return_ACPI_STATUS (AE_AML_BAD_OPCODE);
1126
    }
1127
 
1128
    if (ACPI_SUCCESS (Status))
1129
    {
1130
        /*
1131
         * Return the object in the WalkState, unless the parent is a package -
1132
         * in this case, the return object will be stored in the parse tree
1133
         * for the package.
1134
         */
1135
        if ((!Op->Common.Parent) ||
1136
            ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
1137
             (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
1138
             (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
1139
        {
1140
            WalkState->ResultObj = ObjDesc;
1141
        }
1142
    }
1143
 
1144
    return_ACPI_STATUS (Status);
1145
}
1146
 
1147
 
1148
/*******************************************************************************
1149
 *
1150
 * FUNCTION:    AcpiDsEvalBankFieldOperands
1151
 *
1152
 * PARAMETERS:  WalkState       - Current walk
1153
 *              Op              - A valid BankField Op object
1154
 *
1155
 * RETURN:      Status
1156
 *
1157
 * DESCRIPTION: Get BankField BankValue
1158
 *              Called from AcpiDsExecEndOp during BankField parse tree walk
1159
 *
1160
 ******************************************************************************/
1161
 
1162
ACPI_STATUS
1163
AcpiDsEvalBankFieldOperands (
1164
    ACPI_WALK_STATE         *WalkState,
1165
    ACPI_PARSE_OBJECT       *Op)
1166
{
1167
    ACPI_STATUS             Status;
1168
    ACPI_OPERAND_OBJECT     *ObjDesc;
1169
    ACPI_OPERAND_OBJECT     *OperandDesc;
1170
    ACPI_NAMESPACE_NODE     *Node;
1171
    ACPI_PARSE_OBJECT       *NextOp;
1172
    ACPI_PARSE_OBJECT       *Arg;
1173
 
1174
 
1175
    ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
1176
 
1177
 
1178
    /*
1179
     * This is where we evaluate the BankValue field of the
1180
     * BankField declaration
1181
     */
1182
 
1183
    /* NextOp points to the op that holds the Region */
1184
 
1185
    NextOp = Op->Common.Value.Arg;
1186
 
1187
    /* NextOp points to the op that holds the Bank Register */
1188
 
1189
    NextOp = NextOp->Common.Next;
1190
 
1191
    /* NextOp points to the op that holds the Bank Value */
1192
 
1193
    NextOp = NextOp->Common.Next;
1194
 
1195
    /*
1196
     * Set proper index into operand stack for AcpiDsObjStackPush
1197
     * invoked inside AcpiDsCreateOperand.
1198
     *
1199
     * We use WalkState->Operands[0] to store the evaluated BankValue
1200
     */
1201
    WalkState->OperandIndex = 0;
1202
 
1203
    Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
1204
    if (ACPI_FAILURE (Status))
1205
    {
1206
        return_ACPI_STATUS (Status);
1207
    }
1208
 
1209
    Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
1210
    if (ACPI_FAILURE (Status))
1211
    {
1212
        return_ACPI_STATUS (Status);
1213
    }
1214
 
1215
    ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
1216
        AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
1217
    /*
1218
     * Get the BankValue operand and save it
1219
     * (at Top of stack)
1220
     */
1221
    OperandDesc = WalkState->Operands[0];
1222
 
1223
    /* Arg points to the start Bank Field */
1224
 
1225
    Arg = AcpiPsGetArg (Op, 4);
1226
    while (Arg)
1227
    {
1228
        /* Ignore OFFSET and ACCESSAS terms here */
1229
 
1230
        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
1231
        {
1232
            Node = Arg->Common.Node;
1233
 
1234
            ObjDesc = AcpiNsGetAttachedObject (Node);
1235
            if (!ObjDesc)
1236
            {
1237
                return_ACPI_STATUS (AE_NOT_EXIST);
1238
            }
1239
 
1240
            ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
1241
        }
1242
 
1243
        /* Move to next field in the list */
1244
 
1245
        Arg = Arg->Common.Next;
1246
    }
1247
 
1248
    AcpiUtRemoveReference (OperandDesc);
1249
    return_ACPI_STATUS (Status);
1250
}
1251
 
1252
 
1253
/*******************************************************************************
1254
 *
1255
 * FUNCTION:    AcpiDsExecBeginControlOp
1256
 *
1257
 * PARAMETERS:  WalkList        - The list that owns the walk stack
1258
 *              Op              - The control Op
1259
 *
1260
 * RETURN:      Status
1261
 *
1262
 * DESCRIPTION: Handles all control ops encountered during control method
1263
 *              execution.
1264
 *
1265
 ******************************************************************************/
1266
 
1267
ACPI_STATUS
1268
AcpiDsExecBeginControlOp (
1269
    ACPI_WALK_STATE         *WalkState,
1270
    ACPI_PARSE_OBJECT       *Op)
1271
{
1272
    ACPI_STATUS             Status = AE_OK;
1273
    ACPI_GENERIC_STATE      *ControlState;
1274
 
1275
 
1276
    ACPI_FUNCTION_NAME (DsExecBeginControlOp);
1277
 
1278
 
1279
    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
1280
        Op->Common.AmlOpcode, WalkState));
1281
 
1282
    switch (Op->Common.AmlOpcode)
1283
    {
1284
    case AML_WHILE_OP:
1285
 
1286
        /*
1287
         * If this is an additional iteration of a while loop, continue.
1288
         * There is no need to allocate a new control state.
1289
         */
1290
        if (WalkState->ControlState)
1291
        {
1292
            if (WalkState->ControlState->Control.AmlPredicateStart ==
1293
                (WalkState->ParserState.Aml - 1))
1294
            {
1295
                /* Reset the state to start-of-loop */
1296
 
1297
                WalkState->ControlState->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
1298
                break;
1299
            }
1300
        }
1301
 
1302
        /*lint -fallthrough */
1303
 
1304
    case AML_IF_OP:
1305
 
1306
        /*
1307
         * IF/WHILE: Create a new control state to manage these
1308
         * constructs. We need to manage these as a stack, in order
1309
         * to handle nesting.
1310
         */
1311
        ControlState = AcpiUtCreateControlState ();
1312
        if (!ControlState)
1313
        {
1314
            Status = AE_NO_MEMORY;
1315
            break;
1316
        }
1317
        /*
1318
         * Save a pointer to the predicate for multiple executions
1319
         * of a loop
1320
         */
1321
        ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
1322
        ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
1323
        ControlState->Control.Opcode = Op->Common.AmlOpcode;
1324
 
1325
 
1326
        /* Push the control state on this walk's control stack */
1327
 
1328
        AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
1329
        break;
1330
 
1331
    case AML_ELSE_OP:
1332
 
1333
        /* Predicate is in the state object */
1334
        /* If predicate is true, the IF was executed, ignore ELSE part */
1335
 
1336
        if (WalkState->LastPredicate)
1337
        {
1338
            Status = AE_CTRL_TRUE;
1339
        }
1340
 
1341
        break;
1342
 
1343
    case AML_RETURN_OP:
1344
 
1345
        break;
1346
 
1347
    default:
1348
        break;
1349
    }
1350
 
1351
    return (Status);
1352
}
1353
 
1354
 
1355
/*******************************************************************************
1356
 *
1357
 * FUNCTION:    AcpiDsExecEndControlOp
1358
 *
1359
 * PARAMETERS:  WalkList        - The list that owns the walk stack
1360
 *              Op              - The control Op
1361
 *
1362
 * RETURN:      Status
1363
 *
1364
 * DESCRIPTION: Handles all control ops encountered during control method
1365
 *              execution.
1366
 *
1367
 ******************************************************************************/
1368
 
1369
ACPI_STATUS
1370
AcpiDsExecEndControlOp (
1371
    ACPI_WALK_STATE         *WalkState,
1372
    ACPI_PARSE_OBJECT       *Op)
1373
{
1374
    ACPI_STATUS             Status = AE_OK;
1375
    ACPI_GENERIC_STATE      *ControlState;
1376
 
1377
 
1378
    ACPI_FUNCTION_NAME (DsExecEndControlOp);
1379
 
1380
 
1381
    switch (Op->Common.AmlOpcode)
1382
    {
1383
    case AML_IF_OP:
1384
 
1385
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
1386
 
1387
        /*
1388
         * Save the result of the predicate in case there is an
1389
         * ELSE to come
1390
         */
1391
        WalkState->LastPredicate =
1392
            (BOOLEAN) WalkState->ControlState->Common.Value;
1393
 
1394
        /*
1395
         * Pop the control state that was created at the start
1396
         * of the IF and free it
1397
         */
1398
        ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1399
        AcpiUtDeleteGenericState (ControlState);
1400
        break;
1401
 
1402
 
1403
    case AML_ELSE_OP:
1404
 
1405
        break;
1406
 
1407
 
1408
    case AML_WHILE_OP:
1409
 
1410
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
1411
 
1412
        ControlState = WalkState->ControlState;
1413
        if (ControlState->Common.Value)
1414
        {
1415
            /* Predicate was true, the body of the loop was just executed */
1416
 
1417
            /*
1418
             * This loop counter mechanism allows the interpreter to escape
1419
             * possibly infinite loops. This can occur in poorly written AML
1420
             * when the hardware does not respond within a while loop and the
1421
             * loop does not implement a timeout.
1422
             */
1423
            ControlState->Control.LoopCount++;
1424
            if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
1425
            {
1426
                Status = AE_AML_INFINITE_LOOP;
1427
                break;
1428
            }
1429
 
1430
            /*
1431
             * Go back and evaluate the predicate and maybe execute the loop
1432
             * another time
1433
             */
1434
            Status = AE_CTRL_PENDING;
1435
            WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
1436
            break;
1437
        }
1438
 
1439
        /* Predicate was false, terminate this while loop */
1440
 
1441
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1442
            "[WHILE_OP] termination! Op=%p\n",Op));
1443
 
1444
        /* Pop this control state and free it */
1445
 
1446
        ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1447
        AcpiUtDeleteGenericState (ControlState);
1448
        break;
1449
 
1450
 
1451
    case AML_RETURN_OP:
1452
 
1453
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1454
            "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
1455
 
1456
        /*
1457
         * One optional operand -- the return value
1458
         * It can be either an immediate operand or a result that
1459
         * has been bubbled up the tree
1460
         */
1461
        if (Op->Common.Value.Arg)
1462
        {
1463
            /* Since we have a real Return(), delete any implicit return */
1464
 
1465
            AcpiDsClearImplicitReturn (WalkState);
1466
 
1467
            /* Return statement has an immediate operand */
1468
 
1469
            Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
1470
            if (ACPI_FAILURE (Status))
1471
            {
1472
                return (Status);
1473
            }
1474
 
1475
            /*
1476
             * If value being returned is a Reference (such as
1477
             * an arg or local), resolve it now because it may
1478
             * cease to exist at the end of the method.
1479
             */
1480
            Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
1481
            if (ACPI_FAILURE (Status))
1482
            {
1483
                return (Status);
1484
            }
1485
 
1486
            /*
1487
             * Get the return value and save as the last result
1488
             * value.  This is the only place where WalkState->ReturnDesc
1489
             * is set to anything other than zero!
1490
             */
1491
            WalkState->ReturnDesc = WalkState->Operands[0];
1492
        }
1493
        else if (WalkState->ResultCount)
1494
        {
1495
            /* Since we have a real Return(), delete any implicit return */
1496
 
1497
            AcpiDsClearImplicitReturn (WalkState);
1498
 
1499
            /*
1500
             * The return value has come from a previous calculation.
1501
             *
1502
             * If value being returned is a Reference (such as
1503
             * an arg or local), resolve it now because it may
1504
             * cease to exist at the end of the method.
1505
             *
1506
             * Allow references created by the Index operator to return unchanged.
1507
             */
1508
            if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1509
                ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
1510
                ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
1511
            {
1512
                Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
1513
                if (ACPI_FAILURE (Status))
1514
                {
1515
                    return (Status);
1516
                }
1517
            }
1518
 
1519
            WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
1520
        }
1521
        else
1522
        {
1523
            /* No return operand */
1524
 
1525
            if (WalkState->NumOperands)
1526
            {
1527
                AcpiUtRemoveReference (WalkState->Operands [0]);
1528
            }
1529
 
1530
            WalkState->Operands [0]     = NULL;
1531
            WalkState->NumOperands      = 0;
1532
            WalkState->ReturnDesc       = NULL;
1533
        }
1534
 
1535
 
1536
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1537
            "Completed RETURN_OP State=%p, RetVal=%p\n",
1538
            WalkState, WalkState->ReturnDesc));
1539
 
1540
        /* End the control method execution right now */
1541
 
1542
        Status = AE_CTRL_TERMINATE;
1543
        break;
1544
 
1545
 
1546
    case AML_NOOP_OP:
1547
 
1548
        /* Just do nothing! */
1549
        break;
1550
 
1551
 
1552
    case AML_BREAK_POINT_OP:
1553
 
1554
        /*
1555
         * Set the single-step flag. This will cause the debugger (if present)
1556
         * to break to the console within the AML debugger at the start of the
1557
         * next AML instruction.
1558
         */
1559
        ACPI_DEBUGGER_EXEC (
1560
            AcpiGbl_CmSingleStep = TRUE);
1561
        ACPI_DEBUGGER_EXEC (
1562
            AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
1563
 
1564
        /* Call to the OSL in case OS wants a piece of the action */
1565
 
1566
        Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
1567
                    "Executed AML Breakpoint opcode");
1568
        break;
1569
 
1570
 
1571
    case AML_BREAK_OP:
1572
    case AML_CONTINUE_OP: /* ACPI 2.0 */
1573
 
1574
 
1575
        /* Pop and delete control states until we find a while */
1576
 
1577
        while (WalkState->ControlState &&
1578
                (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
1579
        {
1580
            ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1581
            AcpiUtDeleteGenericState (ControlState);
1582
        }
1583
 
1584
        /* No while found? */
1585
 
1586
        if (!WalkState->ControlState)
1587
        {
1588
            return (AE_AML_NO_WHILE);
1589
        }
1590
 
1591
        /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
1592
 
1593
        WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
1594
 
1595
        /* Return status depending on opcode */
1596
 
1597
        if (Op->Common.AmlOpcode == AML_BREAK_OP)
1598
        {
1599
            Status = AE_CTRL_BREAK;
1600
        }
1601
        else
1602
        {
1603
            Status = AE_CTRL_CONTINUE;
1604
        }
1605
        break;
1606
 
1607
 
1608
    default:
1609
 
1610
        ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
1611
            Op->Common.AmlOpcode, Op));
1612
 
1613
        Status = AE_AML_BAD_OPCODE;
1614
        break;
1615
    }
1616
 
1617
    return (Status);
1618
}
1619