Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/parser/psargs.c
48524 views
1
/******************************************************************************
2
*
3
* Module Name: psargs - Parse AML opcode arguments
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/acnamesp.h>
157
#include <contrib/dev/acpica/include/acdispat.h>
158
#include <contrib/dev/acpica/include/acconvert.h>
159
160
#define _COMPONENT ACPI_PARSER
161
ACPI_MODULE_NAME ("psargs")
162
163
/* Local prototypes */
164
165
static UINT32
166
AcpiPsGetNextPackageLength (
167
ACPI_PARSE_STATE *ParserState);
168
169
static ACPI_PARSE_OBJECT *
170
AcpiPsGetNextField (
171
ACPI_PARSE_STATE *ParserState);
172
173
static void
174
AcpiPsFreeFieldList (
175
ACPI_PARSE_OBJECT *Start);
176
177
178
/*******************************************************************************
179
*
180
* FUNCTION: AcpiPsGetNextPackageLength
181
*
182
* PARAMETERS: ParserState - Current parser state object
183
*
184
* RETURN: Decoded package length. On completion, the AML pointer points
185
* past the length byte or bytes.
186
*
187
* DESCRIPTION: Decode and return a package length field.
188
* Note: Largest package length is 28 bits, from ACPI specification
189
*
190
******************************************************************************/
191
192
static UINT32
193
AcpiPsGetNextPackageLength (
194
ACPI_PARSE_STATE *ParserState)
195
{
196
UINT8 *Aml = ParserState->Aml;
197
UINT32 PackageLength = 0;
198
UINT32 ByteCount;
199
UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */
200
201
202
ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
203
204
205
/*
206
* Byte 0 bits [6:7] contain the number of additional bytes
207
* used to encode the package length, either 0,1,2, or 3
208
*/
209
ByteCount = (Aml[0] >> 6);
210
ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
211
212
/* Get bytes 3, 2, 1 as needed */
213
214
while (ByteCount)
215
{
216
/*
217
* Final bit positions for the package length bytes:
218
* Byte3->[20:27]
219
* Byte2->[12:19]
220
* Byte1->[04:11]
221
* Byte0->[00:03]
222
*/
223
PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
224
225
ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
226
ByteCount--;
227
}
228
229
/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
230
231
PackageLength |= (Aml[0] & ByteZeroMask);
232
return_UINT32 (PackageLength);
233
}
234
235
236
/*******************************************************************************
237
*
238
* FUNCTION: AcpiPsGetNextPackageEnd
239
*
240
* PARAMETERS: ParserState - Current parser state object
241
*
242
* RETURN: Pointer to end-of-package +1
243
*
244
* DESCRIPTION: Get next package length and return a pointer past the end of
245
* the package. Consumes the package length field
246
*
247
******************************************************************************/
248
249
UINT8 *
250
AcpiPsGetNextPackageEnd (
251
ACPI_PARSE_STATE *ParserState)
252
{
253
UINT8 *Start = ParserState->Aml;
254
UINT32 PackageLength;
255
256
257
ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
258
259
260
/* Function below updates ParserState->Aml */
261
262
PackageLength = AcpiPsGetNextPackageLength (ParserState);
263
264
return_PTR (Start + PackageLength); /* end of package */
265
}
266
267
268
/*******************************************************************************
269
*
270
* FUNCTION: AcpiPsGetNextNamestring
271
*
272
* PARAMETERS: ParserState - Current parser state object
273
*
274
* RETURN: Pointer to the start of the name string (pointer points into
275
* the AML.
276
*
277
* DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
278
* prefix characters. Set parser state to point past the string.
279
* (Name is consumed from the AML.)
280
*
281
******************************************************************************/
282
283
char *
284
AcpiPsGetNextNamestring (
285
ACPI_PARSE_STATE *ParserState)
286
{
287
UINT8 *Start = ParserState->Aml;
288
UINT8 *End = ParserState->Aml;
289
290
291
ACPI_FUNCTION_TRACE (PsGetNextNamestring);
292
293
294
/* Point past any namestring prefix characters (backslash or carat) */
295
296
while (ACPI_IS_ROOT_PREFIX (*End) ||
297
ACPI_IS_PARENT_PREFIX (*End))
298
{
299
End++;
300
}
301
302
/* Decode the path prefix character */
303
304
switch (*End)
305
{
306
case 0:
307
308
/* NullName */
309
310
if (End == Start)
311
{
312
Start = NULL;
313
}
314
End++;
315
break;
316
317
case AML_DUAL_NAME_PREFIX:
318
319
/* Two name segments */
320
321
End += 1 + (2 * ACPI_NAMESEG_SIZE);
322
break;
323
324
case AML_MULTI_NAME_PREFIX:
325
326
/* Multiple name segments, 4 chars each, count in next byte */
327
328
End += 2 + (*(End + 1) * ACPI_NAMESEG_SIZE);
329
break;
330
331
default:
332
333
/* Single name segment */
334
335
End += ACPI_NAMESEG_SIZE;
336
break;
337
}
338
339
ParserState->Aml = End;
340
return_PTR ((char *) Start);
341
}
342
343
344
/*******************************************************************************
345
*
346
* FUNCTION: AcpiPsGetNextNamepath
347
*
348
* PARAMETERS: ParserState - Current parser state object
349
* Arg - Where the namepath will be stored
350
* ArgCount - If the namepath points to a control method
351
* the method's argument is returned here.
352
* PossibleMethodCall - Whether the namepath can possibly be the
353
* start of a method call
354
*
355
* RETURN: Status
356
*
357
* DESCRIPTION: Get next name (if method call, return # of required args).
358
* Names are looked up in the internal namespace to determine
359
* if the name represents a control method. If a method
360
* is found, the number of arguments to the method is returned.
361
* This information is critical for parsing to continue correctly.
362
*
363
******************************************************************************/
364
365
ACPI_STATUS
366
AcpiPsGetNextNamepath (
367
ACPI_WALK_STATE *WalkState,
368
ACPI_PARSE_STATE *ParserState,
369
ACPI_PARSE_OBJECT *Arg,
370
BOOLEAN PossibleMethodCall)
371
{
372
ACPI_STATUS Status;
373
char *Path;
374
ACPI_PARSE_OBJECT *NameOp;
375
ACPI_OPERAND_OBJECT *MethodDesc;
376
ACPI_NAMESPACE_NODE *Node;
377
UINT8 *Start = ParserState->Aml;
378
379
380
ACPI_FUNCTION_TRACE (PsGetNextNamepath);
381
382
383
Path = AcpiPsGetNextNamestring (ParserState);
384
AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
385
386
/* Null path case is allowed, just exit */
387
388
if (!Path)
389
{
390
Arg->Common.Value.Name = Path;
391
return_ACPI_STATUS (AE_OK);
392
}
393
394
/*
395
* Lookup the name in the internal namespace, starting with the current
396
* scope. We don't want to add anything new to the namespace here,
397
* however, so we use MODE_EXECUTE.
398
* Allow searching of the parent tree, but don't open a new scope -
399
* we just want to lookup the object (must be mode EXECUTE to perform
400
* the upsearch)
401
*/
402
Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
403
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
404
ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
405
406
/*
407
* If this name is a control method invocation, we must
408
* setup the method call
409
*/
410
if (ACPI_SUCCESS (Status) &&
411
PossibleMethodCall &&
412
(Node->Type == ACPI_TYPE_METHOD))
413
{
414
if ((GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_SUPERNAME) ||
415
(GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_TARGET))
416
{
417
/*
418
* AcpiPsGetNextNamestring has increased the AML pointer past
419
* the method invocation namestring, so we need to restore the
420
* saved AML pointer back to the original method invocation
421
* namestring.
422
*/
423
WalkState->ParserState.Aml = Start;
424
WalkState->ArgCount = 1;
425
AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
426
}
427
428
/* This name is actually a control method invocation */
429
430
MethodDesc = AcpiNsGetAttachedObject (Node);
431
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
432
"Control Method invocation %4.4s - %p Desc %p Path=%p\n",
433
Node->Name.Ascii, Node, MethodDesc, Path));
434
435
NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
436
if (!NameOp)
437
{
438
return_ACPI_STATUS (AE_NO_MEMORY);
439
}
440
441
/* Change Arg into a METHOD CALL and attach name to it */
442
443
AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
444
NameOp->Common.Value.Name = Path;
445
446
/* Point METHODCALL/NAME to the METHOD Node */
447
448
NameOp->Common.Node = Node;
449
AcpiPsAppendArg (Arg, NameOp);
450
451
if (!MethodDesc)
452
{
453
ACPI_ERROR ((AE_INFO,
454
"Control Method %p has no attached object",
455
Node));
456
return_ACPI_STATUS (AE_AML_INTERNAL);
457
}
458
459
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
460
"Control Method - %p Args %X\n",
461
Node, MethodDesc->Method.ParamCount));
462
463
/* Get the number of arguments to expect */
464
465
WalkState->ArgCount = MethodDesc->Method.ParamCount;
466
return_ACPI_STATUS (AE_OK);
467
}
468
469
/*
470
* Special handling if the name was not found during the lookup -
471
* some NotFound cases are allowed
472
*/
473
if (Status == AE_NOT_FOUND)
474
{
475
/* 1) NotFound is ok during load pass 1/2 (allow forward references) */
476
477
if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
478
ACPI_PARSE_EXECUTE)
479
{
480
Status = AE_OK;
481
}
482
483
/* 2) NotFound during a CondRefOf(x) is ok by definition */
484
485
else if (WalkState->Op->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)
486
{
487
Status = AE_OK;
488
}
489
490
/*
491
* 3) NotFound while building a Package is ok at this point, we
492
* may flag as an error later if slack mode is not enabled.
493
* (Some ASL code depends on allowing this behavior)
494
*/
495
else if ((Arg->Common.Parent) &&
496
((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
497
(Arg->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)))
498
{
499
Status = AE_OK;
500
}
501
}
502
503
/* Final exception check (may have been changed from code above) */
504
505
if (ACPI_FAILURE (Status))
506
{
507
ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status);
508
509
if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
510
ACPI_PARSE_EXECUTE)
511
{
512
/* Report a control method execution error */
513
514
Status = AcpiDsMethodError (Status, WalkState);
515
}
516
}
517
518
/* Save the namepath */
519
520
Arg->Common.Value.Name = Path;
521
return_ACPI_STATUS (Status);
522
}
523
524
525
/*******************************************************************************
526
*
527
* FUNCTION: AcpiPsGetNextSimpleArg
528
*
529
* PARAMETERS: ParserState - Current parser state object
530
* ArgType - The argument type (AML_*_ARG)
531
* Arg - Where the argument is returned
532
*
533
* RETURN: None
534
*
535
* DESCRIPTION: Get the next simple argument (constant, string, or namestring)
536
*
537
******************************************************************************/
538
539
void
540
AcpiPsGetNextSimpleArg (
541
ACPI_PARSE_STATE *ParserState,
542
UINT32 ArgType,
543
ACPI_PARSE_OBJECT *Arg)
544
{
545
UINT32 Length;
546
UINT16 Opcode;
547
UINT8 *Aml = ParserState->Aml;
548
549
550
ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
551
552
553
switch (ArgType)
554
{
555
case ARGP_BYTEDATA:
556
557
/* Get 1 byte from the AML stream */
558
559
Opcode = AML_BYTE_OP;
560
Arg->Common.Value.Integer = (UINT64) *Aml;
561
Length = 1;
562
break;
563
564
case ARGP_WORDDATA:
565
566
/* Get 2 bytes from the AML stream */
567
568
Opcode = AML_WORD_OP;
569
ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
570
Length = 2;
571
break;
572
573
case ARGP_DWORDDATA:
574
575
/* Get 4 bytes from the AML stream */
576
577
Opcode = AML_DWORD_OP;
578
ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
579
Length = 4;
580
break;
581
582
case ARGP_QWORDDATA:
583
584
/* Get 8 bytes from the AML stream */
585
586
Opcode = AML_QWORD_OP;
587
ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
588
Length = 8;
589
break;
590
591
case ARGP_CHARLIST:
592
593
/* Get a pointer to the string, point past the string */
594
595
Opcode = AML_STRING_OP;
596
Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
597
598
/* Find the null terminator */
599
600
Length = 0;
601
while (Aml[Length])
602
{
603
Length++;
604
}
605
Length++;
606
break;
607
608
case ARGP_NAME:
609
case ARGP_NAMESTRING:
610
611
AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
612
Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
613
return_VOID;
614
615
default:
616
617
ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
618
return_VOID;
619
}
620
621
AcpiPsInitOp (Arg, Opcode);
622
ParserState->Aml += Length;
623
return_VOID;
624
}
625
626
627
/*******************************************************************************
628
*
629
* FUNCTION: AcpiPsGetNextField
630
*
631
* PARAMETERS: ParserState - Current parser state object
632
*
633
* RETURN: A newly allocated FIELD op
634
*
635
* DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
636
*
637
******************************************************************************/
638
639
static ACPI_PARSE_OBJECT *
640
AcpiPsGetNextField (
641
ACPI_PARSE_STATE *ParserState)
642
{
643
UINT8 *Aml;
644
ACPI_PARSE_OBJECT *Field;
645
ACPI_PARSE_OBJECT *Arg = NULL;
646
UINT16 Opcode;
647
UINT32 Name;
648
UINT8 AccessType;
649
UINT8 AccessAttribute;
650
UINT8 AccessLength;
651
UINT32 PkgLength;
652
UINT8 *PkgEnd;
653
UINT32 BufferLength;
654
655
656
ACPI_FUNCTION_TRACE (PsGetNextField);
657
658
659
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
660
Aml = ParserState->Aml;
661
662
/* Determine field type */
663
664
switch (ACPI_GET8 (ParserState->Aml))
665
{
666
case AML_FIELD_OFFSET_OP:
667
668
Opcode = AML_INT_RESERVEDFIELD_OP;
669
ParserState->Aml++;
670
break;
671
672
case AML_FIELD_ACCESS_OP:
673
674
Opcode = AML_INT_ACCESSFIELD_OP;
675
ParserState->Aml++;
676
break;
677
678
case AML_FIELD_CONNECTION_OP:
679
680
Opcode = AML_INT_CONNECTION_OP;
681
ParserState->Aml++;
682
break;
683
684
case AML_FIELD_EXT_ACCESS_OP:
685
686
Opcode = AML_INT_EXTACCESSFIELD_OP;
687
ParserState->Aml++;
688
break;
689
690
default:
691
692
Opcode = AML_INT_NAMEDFIELD_OP;
693
break;
694
}
695
696
/* Allocate a new field op */
697
698
Field = AcpiPsAllocOp (Opcode, Aml);
699
if (!Field)
700
{
701
return_PTR (NULL);
702
}
703
704
/* Decode the field type */
705
706
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
707
switch (Opcode)
708
{
709
case AML_INT_NAMEDFIELD_OP:
710
711
/* Get the 4-character name */
712
713
ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
714
AcpiPsSetName (Field, Name);
715
ParserState->Aml += ACPI_NAMESEG_SIZE;
716
717
718
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
719
720
#ifdef ACPI_ASL_COMPILER
721
/*
722
* Because the package length isn't represented as a parse tree object,
723
* take comments surrounding this and add to the previously created
724
* parse node.
725
*/
726
if (Field->Common.InlineComment)
727
{
728
Field->Common.NameComment = Field->Common.InlineComment;
729
}
730
Field->Common.InlineComment = AcpiGbl_CurrentInlineComment;
731
AcpiGbl_CurrentInlineComment = NULL;
732
#endif
733
734
/* Get the length which is encoded as a package length */
735
736
Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
737
break;
738
739
740
case AML_INT_RESERVEDFIELD_OP:
741
742
/* Get the length which is encoded as a package length */
743
744
Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
745
break;
746
747
748
case AML_INT_ACCESSFIELD_OP:
749
case AML_INT_EXTACCESSFIELD_OP:
750
751
/*
752
* Get AccessType and AccessAttrib and merge into the field Op
753
* AccessType is first operand, AccessAttribute is second. stuff
754
* these bytes into the node integer value for convenience.
755
*/
756
757
/* Get the two bytes (Type/Attribute) */
758
759
AccessType = ACPI_GET8 (ParserState->Aml);
760
ParserState->Aml++;
761
AccessAttribute = ACPI_GET8 (ParserState->Aml);
762
ParserState->Aml++;
763
764
Field->Common.Value.Integer = (UINT8) AccessType;
765
Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
766
767
/* This opcode has a third byte, AccessLength */
768
769
if (Opcode == AML_INT_EXTACCESSFIELD_OP)
770
{
771
AccessLength = ACPI_GET8 (ParserState->Aml);
772
ParserState->Aml++;
773
774
Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
775
}
776
break;
777
778
779
case AML_INT_CONNECTION_OP:
780
781
/*
782
* Argument for Connection operator can be either a Buffer
783
* (resource descriptor), or a NameString.
784
*/
785
Aml = ParserState->Aml;
786
if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
787
{
788
ParserState->Aml++;
789
790
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
791
PkgEnd = ParserState->Aml;
792
PkgLength = AcpiPsGetNextPackageLength (ParserState);
793
PkgEnd += PkgLength;
794
795
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
796
if (ParserState->Aml < PkgEnd)
797
{
798
/* Non-empty list */
799
800
Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
801
if (!Arg)
802
{
803
AcpiPsFreeOp (Field);
804
return_PTR (NULL);
805
}
806
807
/* Get the actual buffer length argument */
808
809
Opcode = ACPI_GET8 (ParserState->Aml);
810
ParserState->Aml++;
811
812
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
813
switch (Opcode)
814
{
815
case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
816
817
BufferLength = ACPI_GET8 (ParserState->Aml);
818
ParserState->Aml += 1;
819
break;
820
821
case AML_WORD_OP: /* AML_WORDDATA_ARG */
822
823
BufferLength = ACPI_GET16 (ParserState->Aml);
824
ParserState->Aml += 2;
825
break;
826
827
case AML_DWORD_OP: /* AML_DWORDATA_ARG */
828
829
BufferLength = ACPI_GET32 (ParserState->Aml);
830
ParserState->Aml += 4;
831
break;
832
833
default:
834
835
BufferLength = 0;
836
break;
837
}
838
839
/* Fill in bytelist data */
840
841
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
842
Arg->Named.Value.Size = BufferLength;
843
Arg->Named.Data = ParserState->Aml;
844
}
845
846
/* Skip to End of byte data */
847
848
ParserState->Aml = PkgEnd;
849
}
850
else
851
{
852
Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
853
if (!Arg)
854
{
855
AcpiPsFreeOp (Field);
856
return_PTR (NULL);
857
}
858
859
/* Get the Namestring argument */
860
861
Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
862
}
863
864
/* Link the buffer/namestring to parent (CONNECTION_OP) */
865
866
AcpiPsAppendArg (Field, Arg);
867
break;
868
869
870
default:
871
872
/* Opcode was set in previous switch */
873
break;
874
}
875
876
return_PTR (Field);
877
}
878
879
/*******************************************************************************
880
*
881
* FUNCTION: AcpiPsFreeFieldList
882
*
883
* PARAMETERS: Start - First Op in field list
884
*
885
* RETURN: None.
886
*
887
* DESCRIPTION: Free all Op objects inside a field list.
888
*
889
******************************************************************************/
890
891
static void
892
AcpiPsFreeFieldList (
893
ACPI_PARSE_OBJECT *Start)
894
{
895
ACPI_PARSE_OBJECT *Current = Start;
896
ACPI_PARSE_OBJECT *Next;
897
ACPI_PARSE_OBJECT *Arg;
898
899
while (Current)
900
{
901
Next = Current->Common.Next;
902
903
/* AML_INT_CONNECTION_OP can have a single argument */
904
905
Arg = AcpiPsGetArg (Current, 0);
906
if (Arg)
907
{
908
AcpiPsFreeOp (Arg);
909
}
910
911
AcpiPsFreeOp(Current);
912
Current = Next;
913
}
914
}
915
916
917
/*******************************************************************************
918
*
919
* FUNCTION: AcpiPsGetNextArg
920
*
921
* PARAMETERS: WalkState - Current state
922
* ParserState - Current parser state object
923
* ArgType - The argument type (AML_*_ARG)
924
* ReturnArg - Where the next arg is returned
925
*
926
* RETURN: Status, and an op object containing the next argument.
927
*
928
* DESCRIPTION: Get next argument (including complex list arguments that require
929
* pushing the parser stack)
930
*
931
******************************************************************************/
932
933
ACPI_STATUS
934
AcpiPsGetNextArg (
935
ACPI_WALK_STATE *WalkState,
936
ACPI_PARSE_STATE *ParserState,
937
UINT32 ArgType,
938
ACPI_PARSE_OBJECT **ReturnArg)
939
{
940
ACPI_PARSE_OBJECT *Arg = NULL;
941
ACPI_PARSE_OBJECT *Prev = NULL;
942
ACPI_PARSE_OBJECT *Field;
943
UINT32 Subop;
944
ACPI_STATUS Status = AE_OK;
945
946
947
ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
948
949
950
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
951
"Expected argument type ARGP: %s (%2.2X)\n",
952
AcpiUtGetArgumentTypeName (ArgType), ArgType));
953
954
switch (ArgType)
955
{
956
case ARGP_BYTEDATA:
957
case ARGP_WORDDATA:
958
case ARGP_DWORDDATA:
959
case ARGP_CHARLIST:
960
case ARGP_NAME:
961
case ARGP_NAMESTRING:
962
963
/* Constants, strings, and namestrings are all the same size */
964
965
Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml);
966
if (!Arg)
967
{
968
return_ACPI_STATUS (AE_NO_MEMORY);
969
}
970
971
AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
972
break;
973
974
case ARGP_PKGLENGTH:
975
976
/* Package length, nothing returned */
977
978
ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
979
break;
980
981
case ARGP_FIELDLIST:
982
983
if (ParserState->Aml < ParserState->PkgEnd)
984
{
985
/* Non-empty list */
986
987
while (ParserState->Aml < ParserState->PkgEnd)
988
{
989
Field = AcpiPsGetNextField (ParserState);
990
if (!Field)
991
{
992
if (Arg)
993
{
994
AcpiPsFreeFieldList(Arg);
995
}
996
997
return_ACPI_STATUS (AE_NO_MEMORY);
998
}
999
1000
if (Prev)
1001
{
1002
Prev->Common.Next = Field;
1003
}
1004
else
1005
{
1006
Arg = Field;
1007
}
1008
Prev = Field;
1009
}
1010
1011
/* Skip to End of byte data */
1012
1013
ParserState->Aml = ParserState->PkgEnd;
1014
}
1015
break;
1016
1017
case ARGP_BYTELIST:
1018
1019
if (ParserState->Aml < ParserState->PkgEnd)
1020
{
1021
/* Non-empty list */
1022
1023
Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
1024
ParserState->Aml);
1025
if (!Arg)
1026
{
1027
return_ACPI_STATUS (AE_NO_MEMORY);
1028
}
1029
1030
/* Fill in bytelist data */
1031
1032
Arg->Common.Value.Size = (UINT32)
1033
ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
1034
Arg->Named.Data = ParserState->Aml;
1035
1036
/* Skip to End of byte data */
1037
1038
ParserState->Aml = ParserState->PkgEnd;
1039
}
1040
break;
1041
1042
case ARGP_SIMPLENAME:
1043
case ARGP_NAME_OR_REF:
1044
1045
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1046
"**** SimpleName/NameOrRef: %s (%2.2X)\n",
1047
AcpiUtGetArgumentTypeName (ArgType), ArgType));
1048
1049
Subop = AcpiPsPeekOpcode (ParserState);
1050
if (Subop == 0 ||
1051
AcpiPsIsLeadingChar (Subop) ||
1052
ACPI_IS_ROOT_PREFIX (Subop) ||
1053
ACPI_IS_PARENT_PREFIX (Subop))
1054
{
1055
/* NullName or NameString */
1056
1057
Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
1058
if (!Arg)
1059
{
1060
return_ACPI_STATUS (AE_NO_MEMORY);
1061
}
1062
1063
Status = AcpiPsGetNextNamepath (WalkState, ParserState,
1064
Arg, ACPI_NOT_METHOD_CALL);
1065
if (ACPI_FAILURE(Status))
1066
{
1067
AcpiPsFreeOp (Arg);
1068
return_ACPI_STATUS (Status);
1069
}
1070
}
1071
else
1072
{
1073
/* Single complex argument, nothing returned */
1074
1075
WalkState->ArgCount = 1;
1076
}
1077
break;
1078
1079
case ARGP_TARGET:
1080
case ARGP_SUPERNAME:
1081
1082
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1083
"**** Target/Supername: %s (%2.2X)\n",
1084
AcpiUtGetArgumentTypeName (ArgType), ArgType));
1085
1086
Subop = AcpiPsPeekOpcode (ParserState);
1087
if (Subop == 0 ||
1088
AcpiPsIsLeadingChar (Subop) ||
1089
ACPI_IS_ROOT_PREFIX (Subop) ||
1090
ACPI_IS_PARENT_PREFIX (Subop))
1091
{
1092
/* NULL target (zero). Convert to a NULL namepath */
1093
1094
Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
1095
if (!Arg)
1096
{
1097
return_ACPI_STATUS (AE_NO_MEMORY);
1098
}
1099
1100
Status = AcpiPsGetNextNamepath (WalkState, ParserState,
1101
Arg, ACPI_POSSIBLE_METHOD_CALL);
1102
if (ACPI_FAILURE(Status))
1103
{
1104
AcpiPsFreeOp (Arg);
1105
return_ACPI_STATUS (Status);
1106
}
1107
1108
if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
1109
{
1110
/* Free method call op and corresponding namestring sub-ob */
1111
1112
AcpiPsFreeOp (Arg->Common.Value.Arg);
1113
AcpiPsFreeOp (Arg);
1114
Arg = NULL;
1115
WalkState->ArgCount = 1;
1116
}
1117
}
1118
else
1119
{
1120
/* Single complex argument, nothing returned */
1121
1122
WalkState->ArgCount = 1;
1123
}
1124
break;
1125
1126
case ARGP_DATAOBJ:
1127
case ARGP_TERMARG:
1128
1129
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1130
"**** TermArg/DataObj: %s (%2.2X)\n",
1131
AcpiUtGetArgumentTypeName (ArgType), ArgType));
1132
1133
/* Single complex argument, nothing returned */
1134
1135
WalkState->ArgCount = 1;
1136
break;
1137
1138
case ARGP_DATAOBJLIST:
1139
case ARGP_TERMLIST:
1140
case ARGP_OBJLIST:
1141
1142
if (ParserState->Aml < ParserState->PkgEnd)
1143
{
1144
/* Non-empty list of variable arguments, nothing returned */
1145
1146
WalkState->ArgCount = ACPI_VAR_ARGS;
1147
}
1148
break;
1149
1150
default:
1151
1152
ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
1153
Status = AE_AML_OPERAND_TYPE;
1154
break;
1155
}
1156
1157
*ReturnArg = Arg;
1158
return_ACPI_STATUS (Status);
1159
}
1160
1161