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