The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/parser/psargs.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 892f577419a1185a3e0830b0adcb8d98


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.