Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: psloop - Main AML parse loop
4
 *
5
 *****************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 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
 
117
/*
118
 * Parse the AML and build an operation tree as most interpreters, (such as
119
 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
120
 * to tightly constrain stack and dynamic memory usage. Parsing is kept
121
 * flexible and the code fairly compact by parsing based on a list of AML
122
 * opcode templates in AmlOpInfo[].
123
 */
124
 
125
#include "acpi.h"
126
#include "accommon.h"
127
#include "acparser.h"
128
#include "acdispat.h"
129
#include "amlcode.h"
130
 
131
#define _COMPONENT          ACPI_PARSER
132
        ACPI_MODULE_NAME    ("psloop")
133
 
134
static UINT32               AcpiGbl_Depth = 0;
135
 
136
 
137
/* Local prototypes */
138
 
139
static ACPI_STATUS
140
AcpiPsGetAmlOpcode (
141
    ACPI_WALK_STATE         *WalkState);
142
 
143
static ACPI_STATUS
144
AcpiPsBuildNamedOp (
145
    ACPI_WALK_STATE         *WalkState,
146
    UINT8                   *AmlOpStart,
147
    ACPI_PARSE_OBJECT       *UnnamedOp,
148
    ACPI_PARSE_OBJECT       **Op);
149
 
150
static ACPI_STATUS
151
AcpiPsCreateOp (
152
    ACPI_WALK_STATE         *WalkState,
153
    UINT8                   *AmlOpStart,
154
    ACPI_PARSE_OBJECT       **NewOp);
155
 
156
static ACPI_STATUS
157
AcpiPsGetArguments (
158
    ACPI_WALK_STATE         *WalkState,
159
    UINT8                   *AmlOpStart,
160
    ACPI_PARSE_OBJECT       *Op);
161
 
162
static ACPI_STATUS
163
AcpiPsCompleteOp (
164
    ACPI_WALK_STATE         *WalkState,
165
    ACPI_PARSE_OBJECT       **Op,
166
    ACPI_STATUS             Status);
167
 
168
static ACPI_STATUS
169
AcpiPsCompleteFinalOp (
170
    ACPI_WALK_STATE         *WalkState,
171
    ACPI_PARSE_OBJECT       *Op,
172
    ACPI_STATUS             Status);
173
 
174
static void
175
AcpiPsLinkModuleCode (
176
    ACPI_PARSE_OBJECT       *ParentOp,
177
    UINT8                   *AmlStart,
178
    UINT32                  AmlLength,
179
    ACPI_OWNER_ID           OwnerId);
180
 
181
 
182
/*******************************************************************************
183
 *
184
 * FUNCTION:    AcpiPsGetAmlOpcode
185
 *
186
 * PARAMETERS:  WalkState           - Current state
187
 *
188
 * RETURN:      Status
189
 *
190
 * DESCRIPTION: Extract the next AML opcode from the input stream.
191
 *
192
 ******************************************************************************/
193
 
194
static ACPI_STATUS
195
AcpiPsGetAmlOpcode (
196
    ACPI_WALK_STATE         *WalkState)
197
{
198
 
199
    ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
200
 
201
 
202
    WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
203
                                WalkState->ParserState.AmlStart);
204
    WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
205
 
206
    /*
207
     * First cut to determine what we have found:
208
     * 1) A valid AML opcode
209
     * 2) A name string
210
     * 3) An unknown/invalid opcode
211
     */
212
    WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
213
 
214
    switch (WalkState->OpInfo->Class)
215
    {
216
    case AML_CLASS_ASCII:
217
    case AML_CLASS_PREFIX:
218
        /*
219
         * Starts with a valid prefix or ASCII char, this is a name
220
         * string. Convert the bare name string to a namepath.
221
         */
222
        WalkState->Opcode = AML_INT_NAMEPATH_OP;
223
        WalkState->ArgTypes = ARGP_NAMESTRING;
224
        break;
225
 
226
    case AML_CLASS_UNKNOWN:
227
 
228
        /* The opcode is unrecognized. Just skip unknown opcodes */
229
 
230
        ACPI_ERROR ((AE_INFO,
231
             "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring",
232
              WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));
233
 
234
        ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128);
235
 
236
        /* Assume one-byte bad opcode */
237
 
238
        WalkState->ParserState.Aml++;
239
        return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
240
 
241
    default:
242
 
243
        /* Found opcode info, this is a normal opcode */
244
 
245
        WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
246
        WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
247
        break;
248
    }
249
 
250
    return_ACPI_STATUS (AE_OK);
251
}
252
 
253
 
254
/*******************************************************************************
255
 *
256
 * FUNCTION:    AcpiPsBuildNamedOp
257
 *
258
 * PARAMETERS:  WalkState           - Current state
259
 *              AmlOpStart          - Begin of named Op in AML
260
 *              UnnamedOp           - Early Op (not a named Op)
261
 *              Op                  - Returned Op
262
 *
263
 * RETURN:      Status
264
 *
265
 * DESCRIPTION: Parse a named Op
266
 *
267
 ******************************************************************************/
268
 
269
static ACPI_STATUS
270
AcpiPsBuildNamedOp (
271
    ACPI_WALK_STATE         *WalkState,
272
    UINT8                   *AmlOpStart,
273
    ACPI_PARSE_OBJECT       *UnnamedOp,
274
    ACPI_PARSE_OBJECT       **Op)
275
{
276
    ACPI_STATUS             Status = AE_OK;
277
    ACPI_PARSE_OBJECT       *Arg = NULL;
278
 
279
 
280
    ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
281
 
282
 
283
    UnnamedOp->Common.Value.Arg = NULL;
284
    UnnamedOp->Common.ArgListLength = 0;
285
    UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
286
 
287
    /*
288
     * Get and append arguments until we find the node that contains
289
     * the name (the type ARGP_NAME).
290
     */
291
    while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
292
          (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
293
    {
294
        Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
295
                    GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
296
        if (ACPI_FAILURE (Status))
297
        {
298
            return_ACPI_STATUS (Status);
299
        }
300
 
301
        AcpiPsAppendArg (UnnamedOp, Arg);
302
        INCREMENT_ARG_LIST (WalkState->ArgTypes);
303
    }
304
 
305
    /*
306
     * Make sure that we found a NAME and didn't run out of arguments
307
     */
308
    if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
309
    {
310
        return_ACPI_STATUS (AE_AML_NO_OPERAND);
311
    }
312
 
313
    /* We know that this arg is a name, move to next arg */
314
 
315
    INCREMENT_ARG_LIST (WalkState->ArgTypes);
316
 
317
    /*
318
     * Find the object. This will either insert the object into
319
     * the namespace or simply look it up
320
     */
321
    WalkState->Op = NULL;
322
 
323
    Status = WalkState->DescendingCallback (WalkState, Op);
324
    if (ACPI_FAILURE (Status))
325
    {
326
        ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
327
        return_ACPI_STATUS (Status);
328
    }
329
 
330
    if (!*Op)
331
    {
332
        return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
333
    }
334
 
335
    Status = AcpiPsNextParseState (WalkState, *Op, Status);
336
    if (ACPI_FAILURE (Status))
337
    {
338
        if (Status == AE_CTRL_PENDING)
339
        {
340
            return_ACPI_STATUS (AE_CTRL_PARSE_PENDING);
341
        }
342
        return_ACPI_STATUS (Status);
343
    }
344
 
345
    AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
346
    AcpiGbl_Depth++;
347
 
348
    if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
349
        (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
350
    {
351
        /*
352
         * Defer final parsing of an OperationRegion body, because we don't
353
         * have enough info in the first pass to parse it correctly (i.e.,
354
         * there may be method calls within the TermArg elements of the body.)
355
         *
356
         * However, we must continue parsing because the opregion is not a
357
         * standalone package -- we don't know where the end is at this point.
358
         *
359
         * (Length is unknown until parse of the body complete)
360
         */
361
        (*Op)->Named.Data = AmlOpStart;
362
        (*Op)->Named.Length = 0;
363
    }
364
 
365
    return_ACPI_STATUS (AE_OK);
366
}
367
 
368
 
369
/*******************************************************************************
370
 *
371
 * FUNCTION:    AcpiPsCreateOp
372
 *
373
 * PARAMETERS:  WalkState           - Current state
374
 *              AmlOpStart          - Op start in AML
375
 *              NewOp               - Returned Op
376
 *
377
 * RETURN:      Status
378
 *
379
 * DESCRIPTION: Get Op from AML
380
 *
381
 ******************************************************************************/
382
 
383
static ACPI_STATUS
384
AcpiPsCreateOp (
385
    ACPI_WALK_STATE         *WalkState,
386
    UINT8                   *AmlOpStart,
387
    ACPI_PARSE_OBJECT       **NewOp)
388
{
389
    ACPI_STATUS             Status = AE_OK;
390
    ACPI_PARSE_OBJECT       *Op;
391
    ACPI_PARSE_OBJECT       *NamedOp = NULL;
392
    ACPI_PARSE_OBJECT       *ParentScope;
393
    UINT8                   ArgumentCount;
394
    const ACPI_OPCODE_INFO  *OpInfo;
395
 
396
 
397
    ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
398
 
399
 
400
    Status = AcpiPsGetAmlOpcode (WalkState);
401
    if (Status == AE_CTRL_PARSE_CONTINUE)
402
    {
403
        return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
404
    }
405
 
406
    /* Create Op structure and append to parent's argument list */
407
 
408
    WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
409
    Op = AcpiPsAllocOp (WalkState->Opcode);
410
    if (!Op)
411
    {
412
        return_ACPI_STATUS (AE_NO_MEMORY);
413
    }
414
 
415
    if (WalkState->OpInfo->Flags & AML_NAMED)
416
    {
417
        Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
418
        AcpiPsFreeOp (Op);
419
        if (ACPI_FAILURE (Status))
420
        {
421
            return_ACPI_STATUS (Status);
422
        }
423
 
424
        *NewOp = NamedOp;
425
        return_ACPI_STATUS (AE_OK);
426
    }
427
 
428
    /* Not a named opcode, just allocate Op and append to parent */
429
 
430
    if (WalkState->OpInfo->Flags & AML_CREATE)
431
    {
432
        /*
433
         * Backup to beginning of CreateXXXfield declaration
434
         * BodyLength is unknown until we parse the body
435
         */
436
        Op->Named.Data = AmlOpStart;
437
        Op->Named.Length = 0;
438
    }
439
 
440
    if (WalkState->Opcode == AML_BANK_FIELD_OP)
441
    {
442
        /*
443
         * Backup to beginning of BankField declaration
444
         * BodyLength is unknown until we parse the body
445
         */
446
        Op->Named.Data = AmlOpStart;
447
        Op->Named.Length = 0;
448
    }
449
 
450
    ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
451
    AcpiPsAppendArg (ParentScope, Op);
452
 
453
    if (ParentScope)
454
    {
455
        OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
456
        if (OpInfo->Flags & AML_HAS_TARGET)
457
        {
458
            ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
459
            if (ParentScope->Common.ArgListLength > ArgumentCount)
460
            {
461
                Op->Common.Flags |= ACPI_PARSEOP_TARGET;
462
            }
463
        }
464
        else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
465
        {
466
            Op->Common.Flags |= ACPI_PARSEOP_TARGET;
467
        }
468
    }
469
 
470
    if (WalkState->DescendingCallback != NULL)
471
    {
472
        /*
473
         * Find the object. This will either insert the object into
474
         * the namespace or simply look it up
475
         */
476
        WalkState->Op = *NewOp = Op;
477
 
478
        Status = WalkState->DescendingCallback (WalkState, &Op);
479
        Status = AcpiPsNextParseState (WalkState, Op, Status);
480
        if (Status == AE_CTRL_PENDING)
481
        {
482
            Status = AE_CTRL_PARSE_PENDING;
483
        }
484
    }
485
 
486
    return_ACPI_STATUS (Status);
487
}
488
 
489
 
490
/*******************************************************************************
491
 *
492
 * FUNCTION:    AcpiPsGetArguments
493
 *
494
 * PARAMETERS:  WalkState           - Current state
495
 *              AmlOpStart          - Op start in AML
496
 *              Op                  - Current Op
497
 *
498
 * RETURN:      Status
499
 *
500
 * DESCRIPTION: Get arguments for passed Op.
501
 *
502
 ******************************************************************************/
503
 
504
static ACPI_STATUS
505
AcpiPsGetArguments (
506
    ACPI_WALK_STATE         *WalkState,
507
    UINT8                   *AmlOpStart,
508
    ACPI_PARSE_OBJECT       *Op)
509
{
510
    ACPI_STATUS             Status = AE_OK;
511
    ACPI_PARSE_OBJECT       *Arg = NULL;
512
    const ACPI_OPCODE_INFO  *OpInfo;
513
 
514
 
515
    ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
516
 
517
 
518
    switch (Op->Common.AmlOpcode)
519
    {
520
    case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
521
    case AML_WORD_OP:       /* AML_WORDDATA_ARG */
522
    case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
523
    case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
524
    case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
525
 
526
        /* Fill in constant or string argument directly */
527
 
528
        AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
529
            GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
530
        break;
531
 
532
    case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
533
 
534
        Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
535
        if (ACPI_FAILURE (Status))
536
        {
537
            return_ACPI_STATUS (Status);
538
        }
539
 
540
        WalkState->ArgTypes = 0;
541
        break;
542
 
543
    default:
544
        /*
545
         * Op is not a constant or string, append each argument to the Op
546
         */
547
        while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount)
548
        {
549
            WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
550
                WalkState->ParserState.AmlStart);
551
 
552
            Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
553
                        GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
554
            if (ACPI_FAILURE (Status))
555
            {
556
                return_ACPI_STATUS (Status);
557
            }
558
 
559
            if (Arg)
560
            {
561
                Arg->Common.AmlOffset = WalkState->AmlOffset;
562
                AcpiPsAppendArg (Op, Arg);
563
            }
564
 
565
            INCREMENT_ARG_LIST (WalkState->ArgTypes);
566
        }
567
 
568
 
569
        /*
570
         * Handle executable code at "module-level". This refers to
571
         * executable opcodes that appear outside of any control method.
572
         */
573
        if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2) &&
574
            ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
575
        {
576
            /*
577
             * We want to skip If/Else/While constructs during Pass1 because we
578
             * want to actually conditionally execute the code during Pass2.
579
             *
580
             * Except for disassembly, where we always want to walk the
581
             * If/Else/While packages
582
             */
583
            switch (Op->Common.AmlOpcode)
584
            {
585
            case AML_IF_OP:
586
            case AML_ELSE_OP:
587
            case AML_WHILE_OP:
588
 
589
                /*
590
                 * Currently supported module-level opcodes are:
591
                 * IF/ELSE/WHILE. These appear to be the most common,
592
                 * and easiest to support since they open an AML
593
                 * package.
594
                 */
595
                if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1)
596
                {
597
                    AcpiPsLinkModuleCode (Op->Common.Parent, AmlOpStart,
598
                        (UINT32) (WalkState->ParserState.PkgEnd - AmlOpStart),
599
                        WalkState->OwnerId);
600
                }
601
 
602
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
603
                    "Pass1: Skipping an If/Else/While body\n"));
604
 
605
                /* Skip body of if/else/while in pass 1 */
606
 
607
                WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
608
                WalkState->ArgCount = 0;
609
                break;
610
 
611
            default:
612
                /*
613
                 * Check for an unsupported executable opcode at module
614
                 * level. We must be in PASS1, the parent must be a SCOPE,
615
                 * The opcode class must be EXECUTE, and the opcode must
616
                 * not be an argument to another opcode.
617
                 */
618
                if ((WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) &&
619
                    (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
620
                {
621
                    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
622
                    if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
623
                        (!Arg))
624
                    {
625
                        ACPI_WARNING ((AE_INFO,
626
                            "Detected an unsupported executable opcode "
627
                            "at module-level: [0x%.4X] at table offset 0x%.4X",
628
                            Op->Common.AmlOpcode,
629
                            (UINT32) (ACPI_PTR_DIFF (AmlOpStart,
630
                                WalkState->ParserState.AmlStart) +
631
                                sizeof (ACPI_TABLE_HEADER))));
632
                    }
633
                }
634
                break;
635
            }
636
        }
637
 
638
        /* Special processing for certain opcodes */
639
 
640
        switch (Op->Common.AmlOpcode)
641
        {
642
        case AML_METHOD_OP:
643
            /*
644
             * Skip parsing of control method because we don't have enough
645
             * info in the first pass to parse it correctly.
646
             *
647
             * Save the length and address of the body
648
             */
649
            Op->Named.Data = WalkState->ParserState.Aml;
650
            Op->Named.Length = (UINT32)
651
                (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
652
 
653
            /* Skip body of method */
654
 
655
            WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
656
            WalkState->ArgCount = 0;
657
            break;
658
 
659
        case AML_BUFFER_OP:
660
        case AML_PACKAGE_OP:
661
        case AML_VAR_PACKAGE_OP:
662
 
663
            if ((Op->Common.Parent) &&
664
                (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
665
                (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
666
            {
667
                /*
668
                 * Skip parsing of Buffers and Packages because we don't have
669
                 * enough info in the first pass to parse them correctly.
670
                 */
671
                Op->Named.Data = AmlOpStart;
672
                Op->Named.Length = (UINT32)
673
                    (WalkState->ParserState.PkgEnd - AmlOpStart);
674
 
675
                /* Skip body */
676
 
677
                WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
678
                WalkState->ArgCount = 0;
679
            }
680
            break;
681
 
682
        case AML_WHILE_OP:
683
 
684
            if (WalkState->ControlState)
685
            {
686
                WalkState->ControlState->Control.PackageEnd =
687
                    WalkState->ParserState.PkgEnd;
688
            }
689
            break;
690
 
691
        default:
692
 
693
            /* No action for all other opcodes */
694
            break;
695
        }
696
 
697
        break;
698
    }
699
 
700
    return_ACPI_STATUS (AE_OK);
701
}
702
 
703
 
704
/*******************************************************************************
705
 *
706
 * FUNCTION:    AcpiPsLinkModuleCode
707
 *
708
 * PARAMETERS:  ParentOp            - Parent parser op
709
 *              AmlStart            - Pointer to the AML
710
 *              AmlLength           - Length of executable AML
711
 *              OwnerId             - OwnerId of module level code
712
 *
713
 * RETURN:      None.
714
 *
715
 * DESCRIPTION: Wrap the module-level code with a method object and link the
716
 *              object to the global list. Note, the mutex field of the method
717
 *              object is used to link multiple module-level code objects.
718
 *
719
 ******************************************************************************/
720
 
721
static void
722
AcpiPsLinkModuleCode (
723
    ACPI_PARSE_OBJECT       *ParentOp,
724
    UINT8                   *AmlStart,
725
    UINT32                  AmlLength,
726
    ACPI_OWNER_ID           OwnerId)
727
{
728
    ACPI_OPERAND_OBJECT     *Prev;
729
    ACPI_OPERAND_OBJECT     *Next;
730
    ACPI_OPERAND_OBJECT     *MethodObj;
731
    ACPI_NAMESPACE_NODE     *ParentNode;
732
 
733
 
734
    /* Get the tail of the list */
735
 
736
    Prev = Next = AcpiGbl_ModuleCodeList;
737
    while (Next)
738
    {
739
        Prev = Next;
740
        Next = Next->Method.Mutex;
741
    }
742
 
743
    /*
744
     * Insert the module level code into the list. Merge it if it is
745
     * adjacent to the previous element.
746
     */
747
    if (!Prev ||
748
       ((Prev->Method.AmlStart + Prev->Method.AmlLength) != AmlStart))
749
    {
750
        /* Create, initialize, and link a new temporary method object */
751
 
752
        MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
753
        if (!MethodObj)
754
        {
755
            return;
756
        }
757
 
758
        if (ParentOp->Common.Node)
759
        {
760
            ParentNode = ParentOp->Common.Node;
761
        }
762
        else
763
        {
764
            ParentNode = AcpiGbl_RootNode;
765
        }
766
 
767
        MethodObj->Method.AmlStart = AmlStart;
768
        MethodObj->Method.AmlLength = AmlLength;
769
        MethodObj->Method.OwnerId = OwnerId;
2216 Serge 770
        MethodObj->Method.InfoFlags |= ACPI_METHOD_MODULE_LEVEL;
1498 serge 771
 
772
        /*
773
         * Save the parent node in NextObject. This is cheating, but we
774
         * don't want to expand the method object.
775
         */
776
        MethodObj->Method.NextObject =
777
            ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParentNode);
778
 
779
        if (!Prev)
780
        {
781
            AcpiGbl_ModuleCodeList = MethodObj;
782
        }
783
        else
784
        {
785
            Prev->Method.Mutex = MethodObj;
786
        }
787
    }
788
    else
789
    {
790
        Prev->Method.AmlLength += AmlLength;
791
    }
792
}
793
 
794
 
795
/*******************************************************************************
796
 *
797
 * FUNCTION:    AcpiPsCompleteOp
798
 *
799
 * PARAMETERS:  WalkState           - Current state
800
 *              Op                  - Returned Op
801
 *              Status              - Parse status before complete Op
802
 *
803
 * RETURN:      Status
804
 *
805
 * DESCRIPTION: Complete Op
806
 *
807
 ******************************************************************************/
808
 
809
static ACPI_STATUS
810
AcpiPsCompleteOp (
811
    ACPI_WALK_STATE         *WalkState,
812
    ACPI_PARSE_OBJECT       **Op,
813
    ACPI_STATUS             Status)
814
{
815
    ACPI_STATUS             Status2;
816
 
817
 
818
    ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
819
 
820
 
821
    /*
822
     * Finished one argument of the containing scope
823
     */
824
    WalkState->ParserState.Scope->ParseScope.ArgCount--;
825
 
826
    /* Close this Op (will result in parse subtree deletion) */
827
 
828
    Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
829
    if (ACPI_FAILURE (Status2))
830
    {
831
        return_ACPI_STATUS (Status2);
832
    }
833
 
834
    *Op = NULL;
835
 
836
    switch (Status)
837
    {
838
    case AE_OK:
839
        break;
840
 
841
 
842
    case AE_CTRL_TRANSFER:
843
 
844
        /* We are about to transfer to a called method */
845
 
846
        WalkState->PrevOp = NULL;
847
        WalkState->PrevArgTypes = WalkState->ArgTypes;
848
        return_ACPI_STATUS (Status);
849
 
850
 
851
    case AE_CTRL_END:
852
 
853
        AcpiPsPopScope (&(WalkState->ParserState), Op,
854
            &WalkState->ArgTypes, &WalkState->ArgCount);
855
 
856
        if (*Op)
857
        {
858
            WalkState->Op = *Op;
859
            WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
860
            WalkState->Opcode = (*Op)->Common.AmlOpcode;
861
 
862
            Status = WalkState->AscendingCallback (WalkState);
863
            Status = AcpiPsNextParseState (WalkState, *Op, Status);
864
 
865
            Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
866
            if (ACPI_FAILURE (Status2))
867
            {
868
                return_ACPI_STATUS (Status2);
869
            }
870
        }
871
 
872
        Status = AE_OK;
873
        break;
874
 
875
 
876
    case AE_CTRL_BREAK:
877
    case AE_CTRL_CONTINUE:
878
 
879
        /* Pop off scopes until we find the While */
880
 
881
        while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
882
        {
883
            AcpiPsPopScope (&(WalkState->ParserState), Op,
884
                &WalkState->ArgTypes, &WalkState->ArgCount);
885
        }
886
 
887
        /* Close this iteration of the While loop */
888
 
889
        WalkState->Op = *Op;
890
        WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
891
        WalkState->Opcode = (*Op)->Common.AmlOpcode;
892
 
893
        Status = WalkState->AscendingCallback (WalkState);
894
        Status = AcpiPsNextParseState (WalkState, *Op, Status);
895
 
896
        Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
897
        if (ACPI_FAILURE (Status2))
898
        {
899
            return_ACPI_STATUS (Status2);
900
        }
901
 
902
        Status = AE_OK;
903
        break;
904
 
905
 
906
    case AE_CTRL_TERMINATE:
907
 
908
        /* Clean up */
909
        do
910
        {
911
            if (*Op)
912
            {
913
                Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
914
                if (ACPI_FAILURE (Status2))
915
                {
916
                    return_ACPI_STATUS (Status2);
917
                }
918
 
919
                AcpiUtDeleteGenericState (
920
                    AcpiUtPopGenericState (&WalkState->ControlState));
921
            }
922
 
923
            AcpiPsPopScope (&(WalkState->ParserState), Op,
924
                &WalkState->ArgTypes, &WalkState->ArgCount);
925
 
926
        } while (*Op);
927
 
928
        return_ACPI_STATUS (AE_OK);
929
 
930
 
931
    default:  /* All other non-AE_OK status */
932
 
933
        do
934
        {
935
            if (*Op)
936
            {
937
                Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
938
                if (ACPI_FAILURE (Status2))
939
                {
940
                    return_ACPI_STATUS (Status2);
941
                }
942
            }
943
 
944
            AcpiPsPopScope (&(WalkState->ParserState), Op,
945
                &WalkState->ArgTypes, &WalkState->ArgCount);
946
 
947
        } while (*Op);
948
 
949
 
950
#if 0
951
        /*
952
         * TBD: Cleanup parse ops on error
953
         */
954
        if (*Op == NULL)
955
        {
956
            AcpiPsPopScope (ParserState, Op,
957
                &WalkState->ArgTypes, &WalkState->ArgCount);
958
        }
959
#endif
960
        WalkState->PrevOp = NULL;
961
        WalkState->PrevArgTypes = WalkState->ArgTypes;
962
        return_ACPI_STATUS (Status);
963
    }
964
 
965
    /* This scope complete? */
966
 
967
    if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
968
    {
969
        AcpiPsPopScope (&(WalkState->ParserState), Op,
970
            &WalkState->ArgTypes, &WalkState->ArgCount);
971
        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
972
    }
973
    else
974
    {
975
        *Op = NULL;
976
    }
977
 
978
    return_ACPI_STATUS (AE_OK);
979
}
980
 
981
 
982
/*******************************************************************************
983
 *
984
 * FUNCTION:    AcpiPsCompleteFinalOp
985
 *
986
 * PARAMETERS:  WalkState           - Current state
987
 *              Op                  - Current Op
988
 *              Status              - Current parse status before complete last
989
 *                                    Op
990
 *
991
 * RETURN:      Status
992
 *
993
 * DESCRIPTION: Complete last Op.
994
 *
995
 ******************************************************************************/
996
 
997
static ACPI_STATUS
998
AcpiPsCompleteFinalOp (
999
    ACPI_WALK_STATE         *WalkState,
1000
    ACPI_PARSE_OBJECT       *Op,
1001
    ACPI_STATUS             Status)
1002
{
1003
    ACPI_STATUS             Status2;
1004
 
1005
 
1006
    ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
1007
 
1008
 
1009
    /*
1010
     * Complete the last Op (if not completed), and clear the scope stack.
1011
     * It is easily possible to end an AML "package" with an unbounded number
1012
     * of open scopes (such as when several ASL blocks are closed with
1013
     * sequential closing braces). We want to terminate each one cleanly.
1014
     */
1015
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
1016
    do
1017
    {
1018
        if (Op)
1019
        {
1020
            if (WalkState->AscendingCallback != NULL)
1021
            {
1022
                WalkState->Op = Op;
1023
                WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1024
                WalkState->Opcode = Op->Common.AmlOpcode;
1025
 
1026
                Status = WalkState->AscendingCallback (WalkState);
1027
                Status = AcpiPsNextParseState (WalkState, Op, Status);
1028
                if (Status == AE_CTRL_PENDING)
1029
                {
1030
                    Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
1031
                    if (ACPI_FAILURE (Status))
1032
                    {
1033
                        return_ACPI_STATUS (Status);
1034
                    }
1035
                }
1036
 
1037
                if (Status == AE_CTRL_TERMINATE)
1038
                {
1039
                    Status = AE_OK;
1040
 
1041
                    /* Clean up */
1042
                    do
1043
                    {
1044
                        if (Op)
1045
                        {
1046
                            Status2 = AcpiPsCompleteThisOp (WalkState, Op);
1047
                            if (ACPI_FAILURE (Status2))
1048
                            {
1049
                                return_ACPI_STATUS (Status2);
1050
                            }
1051
                        }
1052
 
1053
                        AcpiPsPopScope (&(WalkState->ParserState), &Op,
1054
                            &WalkState->ArgTypes, &WalkState->ArgCount);
1055
 
1056
                    } while (Op);
1057
 
1058
                    return_ACPI_STATUS (Status);
1059
                }
1060
 
1061
                else if (ACPI_FAILURE (Status))
1062
                {
1063
                    /* First error is most important */
1064
 
1065
                    (void) AcpiPsCompleteThisOp (WalkState, Op);
1066
                    return_ACPI_STATUS (Status);
1067
                }
1068
            }
1069
 
1070
            Status2 = AcpiPsCompleteThisOp (WalkState, Op);
1071
            if (ACPI_FAILURE (Status2))
1072
            {
1073
                return_ACPI_STATUS (Status2);
1074
            }
1075
        }
1076
 
1077
        AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
1078
            &WalkState->ArgCount);
1079
 
1080
    } while (Op);
1081
 
1082
    return_ACPI_STATUS (Status);
1083
}
1084
 
1085
 
1086
/*******************************************************************************
1087
 *
1088
 * FUNCTION:    AcpiPsParseLoop
1089
 *
1090
 * PARAMETERS:  WalkState           - Current state
1091
 *
1092
 * RETURN:      Status
1093
 *
1094
 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
1095
 *              a tree of ops.
1096
 *
1097
 ******************************************************************************/
1098
 
1099
ACPI_STATUS
1100
AcpiPsParseLoop (
1101
    ACPI_WALK_STATE         *WalkState)
1102
{
1103
    ACPI_STATUS             Status = AE_OK;
1104
    ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
1105
    ACPI_PARSE_STATE        *ParserState;
1106
    UINT8                   *AmlOpStart = NULL;
1107
 
1108
 
1109
    ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState);
1110
 
1111
 
1112
    if (WalkState->DescendingCallback == NULL)
1113
    {
1114
        return_ACPI_STATUS (AE_BAD_PARAMETER);
1115
    }
1116
 
1117
    ParserState = &WalkState->ParserState;
1118
    WalkState->ArgTypes = 0;
1119
 
1120
#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
1121
 
1122
    if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
1123
    {
1124
        /* We are restarting a preempted control method */
1125
 
1126
        if (AcpiPsHasCompletedScope (ParserState))
1127
        {
1128
            /*
1129
             * We must check if a predicate to an IF or WHILE statement
1130
             * was just completed
1131
             */
1132
            if ((ParserState->Scope->ParseScope.Op) &&
1133
               ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
1134
                (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
1135
                (WalkState->ControlState) &&
1136
                (WalkState->ControlState->Common.State ==
1137
                    ACPI_CONTROL_PREDICATE_EXECUTING))
1138
            {
1139
                /*
1140
                 * A predicate was just completed, get the value of the
1141
                 * predicate and branch based on that value
1142
                 */
1143
                WalkState->Op = NULL;
1144
                Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
1145
                if (ACPI_FAILURE (Status) &&
1146
                    ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
1147
                {
1148
                    if (Status == AE_AML_NO_RETURN_VALUE)
1149
                    {
1150
                        ACPI_EXCEPTION ((AE_INFO, Status,
1151
                            "Invoked method did not return a value"));
1152
                    }
1153
 
1154
                    ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
1155
                    return_ACPI_STATUS (Status);
1156
                }
1157
 
1158
                Status = AcpiPsNextParseState (WalkState, Op, Status);
1159
            }
1160
 
1161
            AcpiPsPopScope (ParserState, &Op,
1162
                &WalkState->ArgTypes, &WalkState->ArgCount);
1163
            ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
1164
        }
1165
        else if (WalkState->PrevOp)
1166
        {
1167
            /* We were in the middle of an op */
1168
 
1169
            Op = WalkState->PrevOp;
1170
            WalkState->ArgTypes = WalkState->PrevArgTypes;
1171
        }
1172
    }
1173
#endif
1174
 
1175
    /* Iterative parsing loop, while there is more AML to process: */
1176
 
1177
    while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
1178
    {
1179
        AmlOpStart = ParserState->Aml;
1180
        if (!Op)
1181
        {
1182
            Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
1183
            if (ACPI_FAILURE (Status))
1184
            {
1185
                if (Status == AE_CTRL_PARSE_CONTINUE)
1186
                {
1187
                    continue;
1188
                }
1189
 
1190
                if (Status == AE_CTRL_PARSE_PENDING)
1191
                {
1192
                    Status = AE_OK;
1193
                }
1194
 
1195
                Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1196
                if (ACPI_FAILURE (Status))
1197
                {
1198
                    return_ACPI_STATUS (Status);
1199
                }
1200
 
1201
                continue;
1202
            }
1203
 
1204
            Op->Common.AmlOffset = WalkState->AmlOffset;
1205
 
1206
            if (WalkState->OpInfo)
1207
            {
1208
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1209
                    "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1210
                     (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name,
1211
                     Op, ParserState->Aml, Op->Common.AmlOffset));
1212
            }
1213
        }
1214
 
1215
 
1216
        /*
1217
         * Start ArgCount at zero because we don't know if there are
1218
         * any args yet
1219
         */
1220
        WalkState->ArgCount  = 0;
1221
 
1222
        /* Are there any arguments that must be processed? */
1223
 
1224
        if (WalkState->ArgTypes)
1225
        {
1226
            /* Get arguments */
1227
 
1228
            Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
1229
            if (ACPI_FAILURE (Status))
1230
            {
1231
                Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1232
                if (ACPI_FAILURE (Status))
1233
                {
1234
                    return_ACPI_STATUS (Status);
1235
                }
1236
 
1237
                continue;
1238
            }
1239
        }
1240
 
1241
        /* Check for arguments that need to be processed */
1242
 
1243
        if (WalkState->ArgCount)
1244
        {
1245
            /*
1246
             * There are arguments (complex ones), push Op and
1247
             * prepare for argument
1248
             */
1249
            Status = AcpiPsPushScope (ParserState, Op,
1250
                        WalkState->ArgTypes, WalkState->ArgCount);
1251
            if (ACPI_FAILURE (Status))
1252
            {
1253
                Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1254
                if (ACPI_FAILURE (Status))
1255
                {
1256
                    return_ACPI_STATUS (Status);
1257
                }
1258
 
1259
                continue;
1260
            }
1261
 
1262
            Op = NULL;
1263
            continue;
1264
        }
1265
 
1266
        /*
1267
         * All arguments have been processed -- Op is complete,
1268
         * prepare for next
1269
         */
1270
        WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1271
        if (WalkState->OpInfo->Flags & AML_NAMED)
1272
        {
1273
            if (AcpiGbl_Depth)
1274
            {
1275
                AcpiGbl_Depth--;
1276
            }
1277
 
1278
            if (Op->Common.AmlOpcode == AML_REGION_OP ||
1279
                Op->Common.AmlOpcode == AML_DATA_REGION_OP)
1280
            {
1281
                /*
1282
                 * Skip parsing of control method or opregion body,
1283
                 * because we don't have enough info in the first pass
1284
                 * to parse them correctly.
1285
                 *
1286
                 * Completed parsing an OpRegion declaration, we now
1287
                 * know the length.
1288
                 */
1289
                Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1290
            }
1291
        }
1292
 
1293
        if (WalkState->OpInfo->Flags & AML_CREATE)
1294
        {
1295
            /*
1296
             * Backup to beginning of CreateXXXfield declaration (1 for
1297
             * Opcode)
1298
             *
1299
             * BodyLength is unknown until we parse the body
1300
             */
1301
            Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1302
        }
1303
 
1304
        if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
1305
        {
1306
            /*
1307
             * Backup to beginning of BankField declaration
1308
             *
1309
             * BodyLength is unknown until we parse the body
1310
             */
1311
            Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1312
        }
1313
 
1314
        /* This op complete, notify the dispatcher */
1315
 
1316
        if (WalkState->AscendingCallback != NULL)
1317
        {
1318
            WalkState->Op = Op;
1319
            WalkState->Opcode = Op->Common.AmlOpcode;
1320
 
1321
            Status = WalkState->AscendingCallback (WalkState);
1322
            Status = AcpiPsNextParseState (WalkState, Op, Status);
1323
            if (Status == AE_CTRL_PENDING)
1324
            {
1325
                Status = AE_OK;
1326
            }
1327
        }
1328
 
1329
        Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1330
        if (ACPI_FAILURE (Status))
1331
        {
1332
            return_ACPI_STATUS (Status);
1333
        }
1334
 
1335
    } /* while ParserState->Aml */
1336
 
1337
    Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
1338
    return_ACPI_STATUS (Status);
1339
}
1340