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/compiler/aslanalyze.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: aslanalyze.c - Support functions for parse tree walks
    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/compiler/aslcompiler.h>
  153 #include "aslcompiler.y.h"
  154 #include <contrib/dev/acpica/include/acnamesp.h>
  155 #include <string.h>
  156 
  157 
  158 #define _COMPONENT          ACPI_COMPILER
  159         ACPI_MODULE_NAME    ("aslanalyze")
  160 
  161 
  162 /* Local Prototypes */
  163 
  164 static ACPI_STATUS
  165 ApDeviceSubtreeWalk (
  166     ACPI_PARSE_OBJECT       *Op,
  167     UINT32                  Level,
  168     void                    *Context);
  169 
  170 
  171 /*******************************************************************************
  172  *
  173  * FUNCTION:    AnIsInternalMethod
  174  *
  175  * PARAMETERS:  Op                  - Current op
  176  *
  177  * RETURN:      Boolean
  178  *
  179  * DESCRIPTION: Check for an internal control method.
  180  *
  181  ******************************************************************************/
  182 
  183 BOOLEAN
  184 AnIsInternalMethod (
  185     ACPI_PARSE_OBJECT       *Op)
  186 {
  187 
  188     if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) ||
  189         (!strcmp (Op->Asl.ExternalName, "_OSI")))
  190     {
  191         return (TRUE);
  192     }
  193 
  194     return (FALSE);
  195 }
  196 
  197 
  198 /*******************************************************************************
  199  *
  200  * FUNCTION:    AnGetInternalMethodReturnType
  201  *
  202  * PARAMETERS:  Op                  - Current op
  203  *
  204  * RETURN:      Btype
  205  *
  206  * DESCRIPTION: Get the return type of an internal method
  207  *
  208  ******************************************************************************/
  209 
  210 UINT32
  211 AnGetInternalMethodReturnType (
  212     ACPI_PARSE_OBJECT       *Op)
  213 {
  214 
  215     if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) ||
  216         (!strcmp (Op->Asl.ExternalName, "_OSI")))
  217     {
  218         return (ACPI_BTYPE_STRING);
  219     }
  220 
  221     return (0);
  222 }
  223 
  224 
  225 /*******************************************************************************
  226  *
  227  * FUNCTION:    AnCheckId
  228  *
  229  * PARAMETERS:  Op                  - Current parse op
  230  *              Type                - HID or CID
  231  *
  232  * RETURN:      None
  233  *
  234  * DESCRIPTION: Perform various checks on _HID and _CID strings. Only limited
  235  *              checks can be performed on _CID strings.
  236  *
  237  ******************************************************************************/
  238 
  239 void
  240 AnCheckId (
  241     ACPI_PARSE_OBJECT       *Op,
  242     ACPI_NAME               Type)
  243 {
  244     UINT32                  i;
  245     ACPI_SIZE               Length;
  246 
  247 
  248     /* Only care about string versions of _HID/_CID (integers are legal) */
  249 
  250     if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
  251     {
  252         return;
  253     }
  254 
  255     /* For both _HID and _CID, the string must be non-null */
  256 
  257     Length = strlen (Op->Asl.Value.String);
  258     if (!Length)
  259     {
  260         AslError (ASL_ERROR, ASL_MSG_NULL_STRING, Op, NULL);
  261         return;
  262     }
  263 
  264     /*
  265      * One of the things we want to catch here is the use of a leading
  266      * asterisk in the string -- an odd construct that certain platform
  267      * manufacturers are fond of. Technically, a leading asterisk is OK
  268      * for _CID, but a valid use of this has not been seen.
  269      */
  270     if (*Op->Asl.Value.String == '*')
  271     {
  272         AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK,
  273             Op, Op->Asl.Value.String);
  274         return;
  275     }
  276 
  277     /* _CID strings are bus-specific, no more checks can be performed */
  278 
  279     if (Type == ASL_TYPE_CID)
  280     {
  281         return;
  282     }
  283 
  284     /* For _HID, all characters must be alphanumeric */
  285 
  286     for (i = 0; Op->Asl.Value.String[i]; i++)
  287     {
  288         if (!isalnum ((int) Op->Asl.Value.String[i]))
  289         {
  290             AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
  291                 Op, Op->Asl.Value.String);
  292             return;
  293         }
  294     }
  295 
  296     /*
  297      * _HID String must be one of these forms:
  298      *
  299      * "AAA####"    A is an uppercase letter and # is a hex digit
  300      * "ACPI####"   # is a hex digit
  301      * "NNNN####"   N is an uppercase letter or decimal digit (0-9)
  302      *              # is a hex digit (ACPI 5.0)
  303      */
  304     if ((Length < 7) || (Length > 8))
  305     {
  306         AslError (ASL_ERROR, ASL_MSG_HID_LENGTH,
  307             Op, Op->Asl.Value.String);
  308         return;
  309     }
  310 
  311     /* _HID Length is valid (7 or 8), now check prefix (first 3 or 4 chars) */
  312 
  313     if (Length == 7)
  314     {
  315         /* AAA####: Ensure the alphabetic prefix is all uppercase */
  316 
  317         for (i = 0; i < 3; i++)
  318         {
  319             if (!isupper ((int) Op->Asl.Value.String[i]))
  320             {
  321                 AslError (ASL_ERROR, ASL_MSG_UPPER_CASE,
  322                     Op, &Op->Asl.Value.String[i]);
  323                 return;
  324             }
  325         }
  326     }
  327     else /* Length == 8 */
  328     {
  329         /*
  330          * ACPI#### or NNNN####:
  331          * Ensure the prefix contains only uppercase alpha or decimal digits
  332          */
  333         for (i = 0; i < 4; i++)
  334         {
  335             if (!isupper ((int) Op->Asl.Value.String[i]) &&
  336                 !isdigit ((int) Op->Asl.Value.String[i]))
  337             {
  338                 AslError (ASL_ERROR, ASL_MSG_HID_PREFIX,
  339                     Op, &Op->Asl.Value.String[i]);
  340                 return;
  341             }
  342         }
  343     }
  344 
  345     /* Remaining characters (suffix) must be hex digits */
  346 
  347     for (; i < Length; i++)
  348     {
  349         if (!isxdigit ((int) Op->Asl.Value.String[i]))
  350         {
  351             AslError (ASL_ERROR, ASL_MSG_HID_SUFFIX,
  352                 Op, &Op->Asl.Value.String[i]);
  353             break;
  354         }
  355     }
  356 }
  357 
  358 
  359 /*******************************************************************************
  360  *
  361  * FUNCTION:    AnLastStatementIsReturn
  362  *
  363  * PARAMETERS:  Op                  - A method parse node
  364  *
  365  * RETURN:      TRUE if last statement is an ASL RETURN. False otherwise
  366  *
  367  * DESCRIPTION: Walk down the list of top level statements within a method
  368  *              to find the last one. Check if that last statement is in
  369  *              fact a RETURN statement.
  370  *
  371  ******************************************************************************/
  372 
  373 BOOLEAN
  374 AnLastStatementIsReturn (
  375     ACPI_PARSE_OBJECT       *Op)
  376 {
  377     ACPI_PARSE_OBJECT       *Next;
  378 
  379 
  380     /* Check if last statement is a return */
  381 
  382     Next = ASL_GET_CHILD_NODE (Op);
  383     while (Next)
  384     {
  385         if ((!Next->Asl.Next) &&
  386             (Next->Asl.ParseOpcode == PARSEOP_RETURN))
  387         {
  388             return (TRUE);
  389         }
  390 
  391         Next = ASL_GET_PEER_NODE (Next);
  392     }
  393 
  394     return (FALSE);
  395 }
  396 
  397 
  398 /*******************************************************************************
  399  *
  400  * FUNCTION:    AnCheckMethodReturnValue
  401  *
  402  * PARAMETERS:  Op                  - Parent
  403  *              OpInfo              - Parent info
  404  *              ArgOp               - Method invocation op
  405  *              RequiredBtypes      - What caller requires
  406  *              ThisNodeBtype       - What this node returns (if anything)
  407  *
  408  * RETURN:      None
  409  *
  410  * DESCRIPTION: Check a method invocation for 1) A return value and if it does
  411  *              in fact return a value, 2) check the type of the return value.
  412  *
  413  ******************************************************************************/
  414 
  415 void
  416 AnCheckMethodReturnValue (
  417     ACPI_PARSE_OBJECT       *Op,
  418     const ACPI_OPCODE_INFO  *OpInfo,
  419     ACPI_PARSE_OBJECT       *ArgOp,
  420     UINT32                  RequiredBtypes,
  421     UINT32                  ThisNodeBtype)
  422 {
  423     ACPI_PARSE_OBJECT       *OwningOp;
  424     ACPI_NAMESPACE_NODE     *Node;
  425     char                    *ExternalPath;
  426 
  427 
  428     Node = ArgOp->Asl.Node;
  429 
  430     if (!Node)
  431     {
  432         /* No error message, this can happen and is OK */
  433 
  434         return;
  435     }
  436 
  437     /* Examine the parent op of this method */
  438 
  439     OwningOp = Node->Op;
  440     ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
  441 
  442     if (OwningOp->Asl.CompileFlags & OP_METHOD_NO_RETVAL)
  443     {
  444         /* Method NEVER returns a value */
  445 
  446         AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, ExternalPath);
  447     }
  448     else if (OwningOp->Asl.CompileFlags & OP_METHOD_SOME_NO_RETVAL)
  449     {
  450         /* Method SOMETIMES returns a value, SOMETIMES not */
  451 
  452         AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, ExternalPath);
  453     }
  454     else if (!(ThisNodeBtype & RequiredBtypes))
  455     {
  456         /* Method returns a value, but the type is wrong */
  457 
  458         AnFormatBtype (AslGbl_StringBuffer, ThisNodeBtype);
  459         AnFormatBtype (AslGbl_StringBuffer2, RequiredBtypes);
  460 
  461         /*
  462          * The case where the method does not return any value at all
  463          * was already handled in the namespace cross reference
  464          * -- Only issue an error if the method in fact returns a value,
  465          * but it is of the wrong type
  466          */
  467         if (ThisNodeBtype != 0)
  468         {
  469             sprintf (AslGbl_MsgBuffer,
  470                 "Method returns [%s], %s operator requires [%s]",
  471                 AslGbl_StringBuffer, OpInfo->Name, AslGbl_StringBuffer2);
  472 
  473             AslError (ASL_WARNING, ASL_MSG_INVALID_TYPE, ArgOp, AslGbl_MsgBuffer);
  474         }
  475     }
  476 
  477     if (ExternalPath)
  478     {
  479         ACPI_FREE (ExternalPath);
  480     }
  481 }
  482 
  483 
  484 /*******************************************************************************
  485  *
  486  * FUNCTION:    AnIsResultUsed
  487  *
  488  * PARAMETERS:  Op                  - Parent op for the operator
  489  *
  490  * RETURN:      TRUE if result from this operation is actually consumed
  491  *
  492  * DESCRIPTION: Determine if the function result value from an operator is
  493  *              used.
  494  *
  495  ******************************************************************************/
  496 
  497 BOOLEAN
  498 AnIsResultUsed (
  499     ACPI_PARSE_OBJECT       *Op)
  500 {
  501     ACPI_PARSE_OBJECT       *Parent;
  502 
  503 
  504     switch (Op->Asl.ParseOpcode)
  505     {
  506     case PARSEOP_INCREMENT:
  507     case PARSEOP_DECREMENT:
  508 
  509         /* These are standalone operators, no return value */
  510 
  511         return (TRUE);
  512 
  513     default:
  514 
  515         break;
  516     }
  517 
  518     /* Examine parent to determine if the return value is used */
  519 
  520     Parent = Op->Asl.Parent;
  521     switch (Parent->Asl.ParseOpcode)
  522     {
  523     /* If/While - check if the operator is the predicate */
  524 
  525     case PARSEOP_IF:
  526     case PARSEOP_WHILE:
  527 
  528         /* First child is the predicate */
  529 
  530         if (Parent->Asl.Child == Op)
  531         {
  532             return (TRUE);
  533         }
  534 
  535         return (FALSE);
  536 
  537     /* Not used if one of these is the parent */
  538 
  539     case PARSEOP_METHOD:
  540     case PARSEOP_DEFINITION_BLOCK:
  541     case PARSEOP_ELSE:
  542 
  543         return (FALSE);
  544 
  545     default:
  546 
  547         /* Any other type of parent means that the result is used */
  548 
  549         return (TRUE);
  550     }
  551 }
  552 
  553 
  554 /*******************************************************************************
  555  *
  556  * FUNCTION:    ApCheckForGpeNameConflict
  557  *
  558  * PARAMETERS:  Op                  - Current parse op
  559  *
  560  * RETURN:      None
  561  *
  562  * DESCRIPTION: Check for a conflict between GPE names within this scope.
  563  *              Conflict means two GPE names with the same GPE number, but
  564  *              different types -- such as _L1C and _E1C.
  565  *
  566  ******************************************************************************/
  567 
  568 void
  569 ApCheckForGpeNameConflict (
  570     ACPI_PARSE_OBJECT       *Op)
  571 {
  572     ACPI_PARSE_OBJECT       *NextOp;
  573     UINT32                  GpeNumber;
  574     char                    Name[ACPI_NAMESEG_SIZE + 1];
  575     char                    Target[ACPI_NAMESEG_SIZE];
  576 
  577 
  578     /* Need a null-terminated string version of NameSeg */
  579 
  580     ACPI_MOVE_32_TO_32 (Name, Op->Asl.NameSeg);
  581     Name[ACPI_NAMESEG_SIZE] = 0;
  582 
  583     /*
  584      * For a GPE method:
  585      * 1st char must be underscore
  586      * 2nd char must be L or E
  587      * 3rd/4th chars must be a hex number
  588      */
  589     if ((Name[0] != '_') ||
  590        ((Name[1] != 'L') && (Name[1] != 'E')))
  591     {
  592         return;
  593     }
  594 
  595     /* Verify 3rd/4th chars are a valid hex value */
  596 
  597     GpeNumber = strtoul (&Name[2], NULL, 16);
  598     if (GpeNumber == ACPI_UINT32_MAX)
  599     {
  600         return;
  601     }
  602 
  603     /*
  604      * We are now sure we have an _Lxx or _Exx.
  605      * Create the target name that would cause collision (Flip E/L)
  606      */
  607     ACPI_MOVE_32_TO_32 (Target, Name);
  608 
  609     /* Inject opposite letter ("L" versus "E") */
  610 
  611     if (Name[1] == 'L')
  612     {
  613         Target[1] = 'E';
  614     }
  615     else /* Name[1] == 'E' */
  616     {
  617         Target[1] = 'L';
  618     }
  619 
  620     /* Search all peers (objects within this scope) for target match */
  621 
  622     NextOp = Op->Asl.Next;
  623     while (NextOp)
  624     {
  625         /*
  626          * We mostly care about methods, but check Name() constructs also,
  627          * even though they will get another error for not being a method.
  628          * All GPE names must be defined as control methods.
  629          */
  630         if ((NextOp->Asl.ParseOpcode == PARSEOP_METHOD) ||
  631             (NextOp->Asl.ParseOpcode == PARSEOP_NAME))
  632         {
  633             if (ACPI_COMPARE_NAMESEG (Target, NextOp->Asl.NameSeg))
  634             {
  635                 /* Found both _Exy and _Lxy in the same scope, error */
  636 
  637                 AslError (ASL_ERROR, ASL_MSG_GPE_NAME_CONFLICT, NextOp,
  638                     Name);
  639                 return;
  640             }
  641         }
  642 
  643         NextOp = NextOp->Asl.Next;
  644     }
  645 
  646     /* OK, no conflict found */
  647 
  648     return;
  649 }
  650 
  651 
  652 /*******************************************************************************
  653  *
  654  * FUNCTION:    ApCheckRegMethod
  655  *
  656  * PARAMETERS:  Op                  - Current parse op
  657  *
  658  * RETURN:      None
  659  *
  660  * DESCRIPTION: Ensure that a _REG method has a corresponding Operation
  661  *              Region declaration within the same scope. Note: _REG is defined
  662  *              to have two arguments and must therefore be defined as a
  663  *              control method.
  664  *
  665  ******************************************************************************/
  666 
  667 void
  668 ApCheckRegMethod (
  669     ACPI_PARSE_OBJECT       *Op)
  670 {
  671     ACPI_PARSE_OBJECT       *Next;
  672     ACPI_PARSE_OBJECT       *Parent;
  673 
  674 
  675     /* We are only interested in _REG methods */
  676 
  677     if (!ACPI_COMPARE_NAMESEG (METHOD_NAME__REG, &Op->Asl.NameSeg))
  678     {
  679         return;
  680     }
  681 
  682     /* Get the start of the current scope */
  683 
  684     Parent = Op->Asl.Parent;
  685     Next = Parent->Asl.Child;
  686 
  687     /* Search entire scope for an operation region declaration */
  688 
  689     while (Next)
  690     {
  691         if (Next->Asl.ParseOpcode == PARSEOP_OPERATIONREGION)
  692         {
  693             return; /* Found region, OK */
  694         }
  695 
  696         Next = Next->Asl.Next;
  697     }
  698 
  699     /* No region found, issue warning */
  700 
  701     AslError (ASL_WARNING, ASL_MSG_NO_REGION, Op, NULL);
  702 }
  703 
  704 
  705 /*******************************************************************************
  706  *
  707  * FUNCTION:    ApFindNameInDeviceTree
  708  *
  709  * PARAMETERS:  Name                - Name to search for
  710  *              Op                  - Current parse op
  711  *
  712  * RETURN:      TRUE if name found in the same scope as Op.
  713  *
  714  * DESCRIPTION: Determine if a name appears in the same scope as Op, as either
  715  *              a Method() or a Name(). "Same scope" can mean under an If or
  716  *              Else statement.
  717  *
  718  * NOTE: Detects _HID/_ADR in this type of construct (legal in ACPI 6.1+)
  719  *
  720  * Scope (\_SB.PCI0)
  721  * {
  722  *     Device (I2C0)
  723  *     {
  724  *         If (SMD0 != 4) {
  725  *             Name (_HID, "INT3442")
  726  *         } Else {
  727  *             Name (_ADR, 0x400)
  728  *         }
  729  *     }
  730  * }
  731  ******************************************************************************/
  732 
  733 BOOLEAN
  734 ApFindNameInDeviceTree (
  735     char                    *Name,
  736     ACPI_PARSE_OBJECT       *Op)
  737 {
  738     ACPI_STATUS             Status;
  739 
  740 
  741     Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD,
  742         ApDeviceSubtreeWalk, NULL, Name);
  743 
  744     if (Status == AE_CTRL_TRUE)
  745     {
  746         return (TRUE);  /* Found a match */
  747     }
  748 
  749     return (FALSE);
  750 }
  751 
  752 
  753 /* Callback function for interface above */
  754 
  755 static ACPI_STATUS
  756 ApDeviceSubtreeWalk (
  757     ACPI_PARSE_OBJECT       *Op,
  758     UINT32                  Level,
  759     void                    *Context)
  760 {
  761     char                    *Name = ACPI_CAST_PTR (char, Context);
  762 
  763 
  764     switch (Op->Asl.ParseOpcode)
  765     {
  766     case PARSEOP_DEVICE:
  767 
  768         /* Level 0 is the starting device, ignore it */
  769 
  770         if (Level > 0)
  771         {
  772             /* Ignore sub-devices */
  773 
  774             return (AE_CTRL_DEPTH);
  775         }
  776         break;
  777 
  778     case PARSEOP_NAME:
  779     case PARSEOP_METHOD:
  780 
  781         /* These are what we are looking for */
  782 
  783         if (ACPI_COMPARE_NAMESEG (Name, Op->Asl.NameSeg))
  784         {
  785             return (AE_CTRL_TRUE);
  786         }
  787         return (AE_CTRL_DEPTH);
  788 
  789     case PARSEOP_SCOPE:
  790     case PARSEOP_FIELD:
  791     case PARSEOP_OPERATIONREGION:
  792 
  793         /*
  794          * We want to ignore these, because either they can be large
  795          * subtrees or open a scope to somewhere else.
  796          */
  797         return (AE_CTRL_DEPTH);
  798 
  799     default:
  800         break;
  801     }
  802 
  803     return (AE_OK);
  804 }
  805 
  806 
  807 /*******************************************************************************
  808  *
  809  * FUNCTION:    ApFindNameInScope
  810  *
  811  * PARAMETERS:  Name                - Name to search for
  812  *              Op                  - Current parse op
  813  *
  814  * RETURN:      TRUE if name found in the same scope as Op.
  815  *
  816  * DESCRIPTION: Determine if a name appears in the same scope as Op, as either
  817  *              a Method() or a Name().
  818  *
  819  ******************************************************************************/
  820 
  821 BOOLEAN
  822 ApFindNameInScope (
  823     char                    *Name,
  824     ACPI_PARSE_OBJECT       *Op)
  825 {
  826     ACPI_PARSE_OBJECT       *Next;
  827     ACPI_PARSE_OBJECT       *Parent;
  828 
  829 
  830     /* Get the start of the current scope */
  831 
  832     Parent = Op->Asl.Parent;
  833     Next = Parent->Asl.Child;
  834 
  835     /* Search entire scope for a match to the name */
  836 
  837     while (Next)
  838     {
  839         if ((Next->Asl.ParseOpcode == PARSEOP_METHOD) ||
  840             (Next->Asl.ParseOpcode == PARSEOP_NAME))
  841         {
  842             if (ACPI_COMPARE_NAMESEG (Name, Next->Asl.NameSeg))
  843             {
  844                 return (TRUE);
  845             }
  846         }
  847 
  848         Next = Next->Asl.Next;
  849     }
  850 
  851     return (FALSE);
  852 }

Cache object: 8c41ae60ebd684ac26e0951da0460f0d


[ 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.