Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/parser/psobject.c
48524 views
1
/******************************************************************************
2
*
3
* Module Name: psobject - Support for parse objects
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/include/acpi.h>
153
#include <contrib/dev/acpica/include/accommon.h>
154
#include <contrib/dev/acpica/include/acparser.h>
155
#include <contrib/dev/acpica/include/amlcode.h>
156
#include <contrib/dev/acpica/include/acconvert.h>
157
#include <contrib/dev/acpica/include/acnamesp.h>
158
159
#define _COMPONENT ACPI_PARSER
160
ACPI_MODULE_NAME ("psobject")
161
162
163
/* Local prototypes */
164
165
static ACPI_STATUS
166
AcpiPsGetAmlOpcode (
167
ACPI_WALK_STATE *WalkState);
168
169
170
/*******************************************************************************
171
*
172
* FUNCTION: AcpiPsGetAmlOpcode
173
*
174
* PARAMETERS: WalkState - Current state
175
*
176
* RETURN: Status
177
*
178
* DESCRIPTION: Extract the next AML opcode from the input stream.
179
*
180
******************************************************************************/
181
182
static ACPI_STATUS
183
AcpiPsGetAmlOpcode (
184
ACPI_WALK_STATE *WalkState)
185
{
186
ACPI_ERROR_ONLY (UINT32 AmlOffset);
187
188
189
ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
190
191
192
WalkState->Aml = WalkState->ParserState.Aml;
193
WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
194
195
/*
196
* First cut to determine what we have found:
197
* 1) A valid AML opcode
198
* 2) A name string
199
* 3) An unknown/invalid opcode
200
*/
201
WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
202
203
switch (WalkState->OpInfo->Class)
204
{
205
case AML_CLASS_ASCII:
206
case AML_CLASS_PREFIX:
207
/*
208
* Starts with a valid prefix or ASCII char, this is a name
209
* string. Convert the bare name string to a namepath.
210
*/
211
WalkState->Opcode = AML_INT_NAMEPATH_OP;
212
WalkState->ArgTypes = ARGP_NAMESTRING;
213
break;
214
215
case AML_CLASS_UNKNOWN:
216
217
/* The opcode is unrecognized. Complain and skip unknown opcodes */
218
219
if (WalkState->PassNumber == 2)
220
{
221
ACPI_ERROR_ONLY(AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
222
WalkState->ParserState.AmlStart));
223
224
ACPI_ERROR ((AE_INFO,
225
"Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
226
WalkState->Opcode,
227
(UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER))));
228
229
ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48);
230
231
#ifdef ACPI_ASL_COMPILER
232
/*
233
* This is executed for the disassembler only. Output goes
234
* to the disassembled ASL output file.
235
*/
236
AcpiOsPrintf (
237
"/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
238
WalkState->Opcode,
239
(UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER)));
240
241
ACPI_ERROR ((AE_INFO,
242
"Aborting disassembly, AML byte code is corrupt"));
243
244
/* Dump the context surrounding the invalid opcode */
245
246
AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16),
247
48, DB_BYTE_DISPLAY,
248
(AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16));
249
AcpiOsPrintf (" */\n");
250
251
/*
252
* Just abort the disassembly, cannot continue because the
253
* parser is essentially lost. The disassembler can then
254
* randomly fail because an ill-constructed parse tree
255
* can result.
256
*/
257
return_ACPI_STATUS (AE_AML_BAD_OPCODE);
258
#endif
259
}
260
261
/* Increment past one-byte or two-byte opcode */
262
263
WalkState->ParserState.Aml++;
264
if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */
265
{
266
WalkState->ParserState.Aml++;
267
}
268
269
return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
270
271
default:
272
273
/* Found opcode info, this is a normal opcode */
274
275
WalkState->ParserState.Aml +=
276
AcpiPsGetOpcodeSize (WalkState->Opcode);
277
WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
278
break;
279
}
280
281
return_ACPI_STATUS (AE_OK);
282
}
283
284
285
/*******************************************************************************
286
*
287
* FUNCTION: AcpiPsBuildNamedOp
288
*
289
* PARAMETERS: WalkState - Current state
290
* AmlOpStart - Begin of named Op in AML
291
* UnnamedOp - Early Op (not a named Op)
292
* Op - Returned Op
293
*
294
* RETURN: Status
295
*
296
* DESCRIPTION: Parse a named Op
297
*
298
******************************************************************************/
299
300
ACPI_STATUS
301
AcpiPsBuildNamedOp (
302
ACPI_WALK_STATE *WalkState,
303
UINT8 *AmlOpStart,
304
ACPI_PARSE_OBJECT *UnnamedOp,
305
ACPI_PARSE_OBJECT **Op)
306
{
307
ACPI_STATUS Status = AE_OK;
308
ACPI_PARSE_OBJECT *Arg = NULL;
309
310
311
ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
312
313
314
UnnamedOp->Common.Value.Arg = NULL;
315
UnnamedOp->Common.ArgListLength = 0;
316
UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
317
318
/*
319
* Get and append arguments until we find the node that contains
320
* the name (the type ARGP_NAME).
321
*/
322
while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
323
(GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
324
{
325
ASL_CV_CAPTURE_COMMENTS (WalkState);
326
Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
327
GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
328
if (ACPI_FAILURE (Status))
329
{
330
return_ACPI_STATUS (Status);
331
}
332
333
AcpiPsAppendArg (UnnamedOp, Arg);
334
INCREMENT_ARG_LIST (WalkState->ArgTypes);
335
}
336
337
/* are there any inline comments associated with the NameSeg?? If so, save this. */
338
339
ASL_CV_CAPTURE_COMMENTS (WalkState);
340
341
#ifdef ACPI_ASL_COMPILER
342
if (AcpiGbl_CurrentInlineComment != NULL)
343
{
344
UnnamedOp->Common.NameComment = AcpiGbl_CurrentInlineComment;
345
AcpiGbl_CurrentInlineComment = NULL;
346
}
347
#endif
348
349
/*
350
* Make sure that we found a NAME and didn't run out of arguments
351
*/
352
if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
353
{
354
return_ACPI_STATUS (AE_AML_NO_OPERAND);
355
}
356
357
/* We know that this arg is a name, move to next arg */
358
359
INCREMENT_ARG_LIST (WalkState->ArgTypes);
360
361
/*
362
* Find the object. This will either insert the object into
363
* the namespace or simply look it up
364
*/
365
WalkState->Op = NULL;
366
367
Status = WalkState->DescendingCallback (WalkState, Op);
368
if (ACPI_FAILURE (Status))
369
{
370
if (Status != AE_CTRL_TERMINATE)
371
{
372
ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
373
}
374
return_ACPI_STATUS (Status);
375
}
376
377
if (!*Op)
378
{
379
return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
380
}
381
382
Status = AcpiPsNextParseState (WalkState, *Op, Status);
383
if (ACPI_FAILURE (Status))
384
{
385
if (Status == AE_CTRL_PENDING)
386
{
387
Status = AE_CTRL_PARSE_PENDING;
388
}
389
return_ACPI_STATUS (Status);
390
}
391
392
AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
393
394
#ifdef ACPI_ASL_COMPILER
395
396
/* save any comments that might be associated with UnnamedOp. */
397
398
(*Op)->Common.InlineComment = UnnamedOp->Common.InlineComment;
399
(*Op)->Common.EndNodeComment = UnnamedOp->Common.EndNodeComment;
400
(*Op)->Common.CloseBraceComment = UnnamedOp->Common.CloseBraceComment;
401
(*Op)->Common.NameComment = UnnamedOp->Common.NameComment;
402
(*Op)->Common.CommentList = UnnamedOp->Common.CommentList;
403
(*Op)->Common.EndBlkComment = UnnamedOp->Common.EndBlkComment;
404
(*Op)->Common.CvFilename = UnnamedOp->Common.CvFilename;
405
(*Op)->Common.CvParentFilename = UnnamedOp->Common.CvParentFilename;
406
(*Op)->Named.Aml = UnnamedOp->Common.Aml;
407
408
UnnamedOp->Common.InlineComment = NULL;
409
UnnamedOp->Common.EndNodeComment = NULL;
410
UnnamedOp->Common.CloseBraceComment = NULL;
411
UnnamedOp->Common.NameComment = NULL;
412
UnnamedOp->Common.CommentList = NULL;
413
UnnamedOp->Common.EndBlkComment = NULL;
414
#endif
415
416
if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
417
(*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
418
{
419
/*
420
* Defer final parsing of an OperationRegion body, because we don't
421
* have enough info in the first pass to parse it correctly (i.e.,
422
* there may be method calls within the TermArg elements of the body.)
423
*
424
* However, we must continue parsing because the opregion is not a
425
* standalone package -- we don't know where the end is at this point.
426
*
427
* (Length is unknown until parse of the body complete)
428
*/
429
(*Op)->Named.Data = AmlOpStart;
430
(*Op)->Named.Length = 0;
431
}
432
433
return_ACPI_STATUS (AE_OK);
434
}
435
436
437
/*******************************************************************************
438
*
439
* FUNCTION: AcpiPsCreateOp
440
*
441
* PARAMETERS: WalkState - Current state
442
* AmlOpStart - Op start in AML
443
* NewOp - Returned Op
444
*
445
* RETURN: Status
446
*
447
* DESCRIPTION: Get Op from AML
448
*
449
******************************************************************************/
450
451
ACPI_STATUS
452
AcpiPsCreateOp (
453
ACPI_WALK_STATE *WalkState,
454
UINT8 *AmlOpStart,
455
ACPI_PARSE_OBJECT **NewOp)
456
{
457
ACPI_STATUS Status = AE_OK;
458
ACPI_PARSE_OBJECT *Op;
459
ACPI_PARSE_OBJECT *NamedOp = NULL;
460
ACPI_PARSE_OBJECT *ParentScope;
461
UINT8 ArgumentCount;
462
const ACPI_OPCODE_INFO *OpInfo;
463
464
465
ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
466
467
468
Status = AcpiPsGetAmlOpcode (WalkState);
469
if (Status == AE_CTRL_PARSE_CONTINUE)
470
{
471
return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
472
}
473
if (ACPI_FAILURE (Status))
474
{
475
return_ACPI_STATUS (Status);
476
}
477
478
/* Create Op structure and append to parent's argument list */
479
480
WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
481
Op = AcpiPsAllocOp (WalkState->Opcode, AmlOpStart);
482
if (!Op)
483
{
484
return_ACPI_STATUS (AE_NO_MEMORY);
485
}
486
487
if (WalkState->OpInfo->Flags & AML_NAMED)
488
{
489
Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
490
AcpiPsFreeOp (Op);
491
492
#ifdef ACPI_ASL_COMPILER
493
if (AcpiGbl_DisasmFlag && WalkState->Opcode == AML_EXTERNAL_OP &&
494
Status == AE_NOT_FOUND)
495
{
496
/*
497
* If parsing of AML_EXTERNAL_OP's name path fails, then skip
498
* past this opcode and keep parsing. This is a much better
499
* alternative than to abort the entire disassembler. At this
500
* point, the ParserState is at the end of the namepath of the
501
* external declaration opcode. Setting WalkState->Aml to
502
* WalkState->ParserState.Aml + 2 moves increments the
503
* WalkState->Aml past the object type and the paramcount of the
504
* external opcode.
505
*/
506
WalkState->Aml = WalkState->ParserState.Aml + 2;
507
WalkState->ParserState.Aml = WalkState->Aml;
508
return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
509
}
510
#endif
511
if (ACPI_FAILURE (Status))
512
{
513
return_ACPI_STATUS (Status);
514
}
515
516
*NewOp = NamedOp;
517
return_ACPI_STATUS (AE_OK);
518
}
519
520
/* Not a named opcode, just allocate Op and append to parent */
521
522
if (WalkState->OpInfo->Flags & AML_CREATE)
523
{
524
/*
525
* Backup to beginning of CreateXXXfield declaration
526
* BodyLength is unknown until we parse the body
527
*/
528
Op->Named.Data = AmlOpStart;
529
Op->Named.Length = 0;
530
}
531
532
if (WalkState->Opcode == AML_BANK_FIELD_OP)
533
{
534
/*
535
* Backup to beginning of BankField declaration
536
* BodyLength is unknown until we parse the body
537
*/
538
Op->Named.Data = AmlOpStart;
539
Op->Named.Length = 0;
540
}
541
542
ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
543
AcpiPsAppendArg (ParentScope, Op);
544
545
if (ParentScope)
546
{
547
OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
548
if (OpInfo->Flags & AML_HAS_TARGET)
549
{
550
ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
551
if (ParentScope->Common.ArgListLength > ArgumentCount)
552
{
553
Op->Common.Flags |= ACPI_PARSEOP_TARGET;
554
}
555
}
556
557
/*
558
* Special case for both Increment() and Decrement(), where
559
* the lone argument is both a source and a target.
560
*/
561
else if ((ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) ||
562
(ParentScope->Common.AmlOpcode == AML_DECREMENT_OP))
563
{
564
Op->Common.Flags |= ACPI_PARSEOP_TARGET;
565
}
566
}
567
568
if (WalkState->DescendingCallback != NULL)
569
{
570
/*
571
* Find the object. This will either insert the object into
572
* the namespace or simply look it up
573
*/
574
WalkState->Op = *NewOp = Op;
575
576
Status = WalkState->DescendingCallback (WalkState, &Op);
577
Status = AcpiPsNextParseState (WalkState, Op, Status);
578
if (Status == AE_CTRL_PENDING)
579
{
580
Status = AE_CTRL_PARSE_PENDING;
581
}
582
}
583
584
return_ACPI_STATUS (Status);
585
}
586
587
588
/*******************************************************************************
589
*
590
* FUNCTION: AcpiPsCompleteOp
591
*
592
* PARAMETERS: WalkState - Current state
593
* Op - Returned Op
594
* Status - Parse status before complete Op
595
*
596
* RETURN: Status
597
*
598
* DESCRIPTION: Complete Op
599
*
600
******************************************************************************/
601
602
ACPI_STATUS
603
AcpiPsCompleteOp (
604
ACPI_WALK_STATE *WalkState,
605
ACPI_PARSE_OBJECT **Op,
606
ACPI_STATUS Status)
607
{
608
ACPI_STATUS Status2;
609
610
611
ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
612
613
614
/*
615
* Finished one argument of the containing scope
616
*/
617
WalkState->ParserState.Scope->ParseScope.ArgCount--;
618
619
/* Close this Op (will result in parse subtree deletion) */
620
621
Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
622
if (ACPI_FAILURE (Status2))
623
{
624
return_ACPI_STATUS (Status2);
625
}
626
627
*Op = NULL;
628
629
switch (Status)
630
{
631
case AE_OK:
632
633
break;
634
635
case AE_CTRL_TRANSFER:
636
637
/* We are about to transfer to a called method */
638
639
WalkState->PrevOp = NULL;
640
WalkState->PrevArgTypes = WalkState->ArgTypes;
641
return_ACPI_STATUS (Status);
642
643
case AE_CTRL_END:
644
645
AcpiPsPopScope (&(WalkState->ParserState), Op,
646
&WalkState->ArgTypes, &WalkState->ArgCount);
647
648
if (*Op)
649
{
650
WalkState->Op = *Op;
651
WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
652
WalkState->Opcode = (*Op)->Common.AmlOpcode;
653
654
Status = WalkState->AscendingCallback (WalkState);
655
(void) AcpiPsNextParseState (WalkState, *Op, Status);
656
657
Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
658
if (ACPI_FAILURE (Status2))
659
{
660
return_ACPI_STATUS (Status2);
661
}
662
}
663
664
break;
665
666
case AE_CTRL_BREAK:
667
case AE_CTRL_CONTINUE:
668
669
/* Pop off scopes until we find the While */
670
671
while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
672
{
673
AcpiPsPopScope (&(WalkState->ParserState), Op,
674
&WalkState->ArgTypes, &WalkState->ArgCount);
675
}
676
677
/* Close this iteration of the While loop */
678
679
WalkState->Op = *Op;
680
WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
681
WalkState->Opcode = (*Op)->Common.AmlOpcode;
682
683
Status = WalkState->AscendingCallback (WalkState);
684
(void) AcpiPsNextParseState (WalkState, *Op, Status);
685
686
Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
687
if (ACPI_FAILURE (Status2))
688
{
689
return_ACPI_STATUS (Status2);
690
}
691
692
break;
693
694
case AE_CTRL_TERMINATE:
695
696
/* Clean up */
697
do
698
{
699
if (*Op)
700
{
701
Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
702
if (ACPI_FAILURE (Status2))
703
{
704
return_ACPI_STATUS (Status2);
705
}
706
707
AcpiUtDeleteGenericState (
708
AcpiUtPopGenericState (&WalkState->ControlState));
709
}
710
711
AcpiPsPopScope (&(WalkState->ParserState), Op,
712
&WalkState->ArgTypes, &WalkState->ArgCount);
713
714
} while (*Op);
715
716
return_ACPI_STATUS (AE_OK);
717
718
default: /* All other non-AE_OK status */
719
720
do
721
{
722
if (*Op)
723
{
724
/*
725
* These Opcodes need to be removed from the namespace because they
726
* get created even if these opcodes cannot be created due to
727
* errors.
728
*/
729
if (((*Op)->Common.AmlOpcode == AML_REGION_OP) ||
730
((*Op)->Common.AmlOpcode == AML_DATA_REGION_OP))
731
{
732
AcpiNsDeleteChildren ((*Op)->Common.Node);
733
AcpiNsRemoveNode ((*Op)->Common.Node);
734
(*Op)->Common.Node = NULL;
735
AcpiPsDeleteParseTree (*Op);
736
}
737
738
Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
739
if (ACPI_FAILURE (Status2))
740
{
741
return_ACPI_STATUS (Status2);
742
}
743
}
744
745
AcpiPsPopScope (&(WalkState->ParserState), Op,
746
&WalkState->ArgTypes, &WalkState->ArgCount);
747
748
} while (*Op);
749
750
751
#if 0
752
/*
753
* TBD: Cleanup parse ops on error
754
*/
755
if (*Op == NULL)
756
{
757
AcpiPsPopScope (ParserState, Op,
758
&WalkState->ArgTypes, &WalkState->ArgCount);
759
}
760
#endif
761
WalkState->PrevOp = NULL;
762
WalkState->PrevArgTypes = WalkState->ArgTypes;
763
764
if (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)
765
{
766
/*
767
* There was something that went wrong while executing code at the
768
* module-level. We need to skip parsing whatever caused the
769
* error and keep going. One runtime error during the table load
770
* should not cause the entire table to not be loaded. This is
771
* because there could be correct AML beyond the parts that caused
772
* the runtime error.
773
*/
774
ACPI_INFO (("Ignoring error and continuing table load"));
775
return_ACPI_STATUS (AE_OK);
776
}
777
return_ACPI_STATUS (Status);
778
}
779
780
/* This scope complete? */
781
782
if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
783
{
784
AcpiPsPopScope (&(WalkState->ParserState), Op,
785
&WalkState->ArgTypes, &WalkState->ArgCount);
786
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
787
}
788
else
789
{
790
*Op = NULL;
791
}
792
793
return_ACPI_STATUS (AE_OK);
794
}
795
796
797
/*******************************************************************************
798
*
799
* FUNCTION: AcpiPsCompleteFinalOp
800
*
801
* PARAMETERS: WalkState - Current state
802
* Op - Current Op
803
* Status - Current parse status before complete last
804
* Op
805
*
806
* RETURN: Status
807
*
808
* DESCRIPTION: Complete last Op.
809
*
810
******************************************************************************/
811
812
ACPI_STATUS
813
AcpiPsCompleteFinalOp (
814
ACPI_WALK_STATE *WalkState,
815
ACPI_PARSE_OBJECT *Op,
816
ACPI_STATUS Status)
817
{
818
ACPI_STATUS ReturnStatus = Status;
819
BOOLEAN Ascending = TRUE;
820
821
822
ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
823
824
825
/*
826
* Complete the last Op (if not completed), and clear the scope stack.
827
* It is easily possible to end an AML "package" with an unbounded number
828
* of open scopes (such as when several ASL blocks are closed with
829
* sequential closing braces). We want to terminate each one cleanly.
830
*/
831
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
832
do
833
{
834
if (Op)
835
{
836
if (Ascending && WalkState->AscendingCallback != NULL)
837
{
838
WalkState->Op = Op;
839
WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
840
WalkState->Opcode = Op->Common.AmlOpcode;
841
842
Status = WalkState->AscendingCallback (WalkState);
843
Status = AcpiPsNextParseState (WalkState, Op, Status);
844
if (Status == AE_CTRL_PENDING)
845
{
846
Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
847
if (ACPI_FAILURE (Status))
848
{
849
return_ACPI_STATUS (Status);
850
}
851
}
852
853
if (Status == AE_CTRL_TERMINATE)
854
{
855
Ascending = FALSE;
856
ReturnStatus = AE_CTRL_TERMINATE;
857
}
858
859
else if (ACPI_FAILURE (Status))
860
{
861
/* First error is most important */
862
863
Ascending = FALSE;
864
ReturnStatus = Status;
865
}
866
}
867
868
Status = AcpiPsCompleteThisOp (WalkState, Op);
869
if (ACPI_FAILURE (Status))
870
{
871
Ascending = FALSE;
872
if (ACPI_SUCCESS (ReturnStatus) ||
873
ReturnStatus == AE_CTRL_TERMINATE)
874
{
875
ReturnStatus = Status;
876
}
877
}
878
}
879
880
AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
881
&WalkState->ArgCount);
882
883
} while (Op);
884
885
return_ACPI_STATUS (ReturnStatus);
886
}
887
888