Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: asllookup- Namespace lookup
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2010, 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.  
  117. #include "aslcompiler.h"
  118. #include "aslcompiler.y.h"
  119.  
  120. #include "acparser.h"
  121. #include "amlcode.h"
  122. #include "acnamesp.h"
  123. #include "acdispat.h"
  124.  
  125.  
  126. #define _COMPONENT          ACPI_COMPILER
  127.         ACPI_MODULE_NAME    ("asllookup")
  128.  
  129. /* Local prototypes */
  130.  
  131. static ACPI_STATUS
  132. LsCompareOneNamespaceObject (
  133.     ACPI_HANDLE             ObjHandle,
  134.     UINT32                  Level,
  135.     void                    *Context,
  136.     void                    **ReturnValue);
  137.  
  138. static ACPI_STATUS
  139. LsDoOneNamespaceObject (
  140.     ACPI_HANDLE             ObjHandle,
  141.     UINT32                  Level,
  142.     void                    *Context,
  143.     void                    **ReturnValue);
  144.  
  145. static BOOLEAN
  146. LkObjectExists (
  147.     char                    *Name);
  148.  
  149. static void
  150. LkCheckFieldRange (
  151.     ACPI_PARSE_OBJECT       *Op,
  152.     UINT32                  RegionBitLength,
  153.     UINT32                  FieldBitOffset,
  154.     UINT32                  FieldBitLength,
  155.     UINT32                  AccessBitWidth);
  156.  
  157. static ACPI_STATUS
  158. LkNamespaceLocateBegin (
  159.     ACPI_PARSE_OBJECT       *Op,
  160.     UINT32                  Level,
  161.     void                    *Context);
  162.  
  163. static ACPI_STATUS
  164. LkNamespaceLocateEnd (
  165.     ACPI_PARSE_OBJECT       *Op,
  166.     UINT32                  Level,
  167.     void                    *Context);
  168.  
  169. static ACPI_STATUS
  170. LkIsObjectUsed (
  171.     ACPI_HANDLE             ObjHandle,
  172.     UINT32                  Level,
  173.     void                    *Context,
  174.     void                    **ReturnValue);
  175.  
  176. static ACPI_STATUS
  177. LsDoOnePathname (
  178.     ACPI_HANDLE             ObjHandle,
  179.     UINT32                  Level,
  180.     void                    *Context,
  181.     void                    **ReturnValue);
  182.  
  183. void
  184. LsSetupNsList (
  185.     void                    *Handle);
  186.  
  187. ACPI_PARSE_OBJECT *
  188. LkGetNameOp (
  189.     ACPI_PARSE_OBJECT       *Op);
  190.  
  191.  
  192. /*******************************************************************************
  193.  *
  194.  * FUNCTION:    LsDoOneNamespaceObject
  195.  *
  196.  * PARAMETERS:  ACPI_WALK_CALLBACK
  197.  *
  198.  * RETURN:      Status
  199.  *
  200.  * DESCRIPTION: Dump a namespace object to the namespace output file.
  201.  *              Called during the walk of the namespace to dump all objects.
  202.  *
  203.  ******************************************************************************/
  204.  
  205. static ACPI_STATUS
  206. LsDoOneNamespaceObject (
  207.     ACPI_HANDLE             ObjHandle,
  208.     UINT32                  Level,
  209.     void                    *Context,
  210.     void                    **ReturnValue)
  211. {
  212.     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  213.     ACPI_OPERAND_OBJECT     *ObjDesc;
  214.     ACPI_PARSE_OBJECT       *Op;
  215.  
  216.  
  217.     Gbl_NumNamespaceObjects++;
  218.  
  219.     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
  220.         Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
  221.         &Node->Name,
  222.         AcpiUtGetTypeName (Node->Type));
  223.  
  224.     Op = Node->Op;
  225.     ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
  226.  
  227.     if (!Op)
  228.     {
  229.         FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
  230.         return (AE_OK);
  231.     }
  232.  
  233.  
  234.     if ((ObjDesc) &&
  235.         (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
  236.     {
  237.         switch (Node->Type)
  238.         {
  239.         case ACPI_TYPE_INTEGER:
  240.  
  241.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  242.                 "       [Initial Value   0x%8.8X%8.8X]",
  243.                 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
  244.             break;
  245.  
  246.  
  247.         case ACPI_TYPE_STRING:
  248.  
  249.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  250.                 "        [Initial Value   \"%s\"]",
  251.                 ObjDesc->String.Pointer);
  252.             break;
  253.  
  254.         default:
  255.             /* Nothing to do for other types */
  256.             break;
  257.         }
  258.  
  259.     }
  260.     else
  261.     {
  262.         switch (Node->Type)
  263.         {
  264.         case ACPI_TYPE_INTEGER:
  265.  
  266.             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
  267.             {
  268.                 Op = Op->Asl.Child;
  269.             }
  270.             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
  271.                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
  272.             {
  273.                 Op = Op->Asl.Next;
  274.             }
  275.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  276.                 "       [Initial Value   0x%8.8X%8.8X]",
  277.                 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
  278.             break;
  279.  
  280.  
  281.         case ACPI_TYPE_STRING:
  282.  
  283.             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
  284.             {
  285.                 Op = Op->Asl.Child;
  286.             }
  287.             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
  288.                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
  289.             {
  290.                 Op = Op->Asl.Next;
  291.             }
  292.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  293.                 "        [Initial Value   \"%s\"]",
  294.                 Op->Asl.Value.String);
  295.             break;
  296.  
  297.  
  298.         case ACPI_TYPE_LOCAL_REGION_FIELD:
  299.  
  300.             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
  301.                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
  302.             {
  303.                 Op = Op->Asl.Child;
  304.             }
  305.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  306.                 "   [Offset 0x%04X   Length 0x%04X bits]",
  307.                 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
  308.             break;
  309.  
  310.  
  311.         case ACPI_TYPE_BUFFER_FIELD:
  312.  
  313.             switch (Op->Asl.ParseOpcode)
  314.             {
  315.             case PARSEOP_CREATEBYTEFIELD:
  316.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
  317.                 break;
  318.  
  319.             case PARSEOP_CREATEDWORDFIELD:
  320.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
  321.                 break;
  322.  
  323.             case PARSEOP_CREATEQWORDFIELD:
  324.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
  325.                 break;
  326.  
  327.             case PARSEOP_CREATEWORDFIELD:
  328.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
  329.                 break;
  330.  
  331.             case PARSEOP_CREATEBITFIELD:
  332.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
  333.                 break;
  334.  
  335.             case PARSEOP_CREATEFIELD:
  336.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
  337.                 break;
  338.  
  339.             default:
  340.                 break;
  341.  
  342.             }
  343.             break;
  344.  
  345.  
  346.         case ACPI_TYPE_PACKAGE:
  347.  
  348.             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
  349.             {
  350.                 Op = Op->Asl.Child;
  351.             }
  352.             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
  353.                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
  354.             {
  355.                 Op = Op->Asl.Next;
  356.             }
  357.             Op = Op->Asl.Child;
  358.  
  359.             if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
  360.                 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
  361.             {
  362.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  363.                     "       [Initial Length  0x%.2X elements]",
  364.                     Op->Asl.Value.Integer);
  365.             }
  366.             break;
  367.  
  368.  
  369.         case ACPI_TYPE_BUFFER:
  370.  
  371.             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
  372.             {
  373.                 Op = Op->Asl.Child;
  374.             }
  375.             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
  376.                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
  377.             {
  378.                 Op = Op->Asl.Next;
  379.             }
  380.             Op = Op->Asl.Child;
  381.  
  382.             if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
  383.             {
  384.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  385.                     "        [Initial Length  0x%.2X bytes]",
  386.                     Op->Asl.Value.Integer);
  387.             }
  388.             break;
  389.  
  390.  
  391.         case ACPI_TYPE_METHOD:
  392.  
  393.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  394.                 "        [Code Length     0x%.4X bytes]",
  395.                 Op->Asl.AmlSubtreeLength);
  396.             break;
  397.  
  398.  
  399.         case ACPI_TYPE_LOCAL_RESOURCE:
  400.  
  401.             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  402.                 "  [Desc Offset     0x%.4X Bytes]", Node->Value);
  403.             break;
  404.  
  405.  
  406.         case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
  407.  
  408.             if (Node->Flags & 0x80)
  409.             {
  410.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  411.                     "   [Field Offset    0x%.4X Bits 0x%.4X Bytes]",
  412.                     Node->Value, Node->Value / 8);
  413.             }
  414.             else
  415.             {
  416.                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
  417.                     "   [Field Offset    0x%.4X Bytes]", Node->Value);
  418.             }
  419.             break;
  420.  
  421.  
  422.         default:
  423.             /* Nothing to do for other types */
  424.             break;
  425.         }
  426.     }
  427.  
  428.     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
  429.     return (AE_OK);
  430. }
  431.  
  432.  
  433. /*******************************************************************************
  434.  *
  435.  * FUNCTION:    LsSetupNsList
  436.  *
  437.  * PARAMETERS:  Handle          - local file handle
  438.  *
  439.  * RETURN:      None
  440.  *
  441.  * DESCRIPTION: Set the namespace output file to the input handle
  442.  *
  443.  ******************************************************************************/
  444.  
  445. void
  446. LsSetupNsList (
  447.     void                    *Handle)
  448. {
  449.  
  450.     Gbl_NsOutputFlag = TRUE;
  451.     Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
  452. }
  453.  
  454.  
  455. /*******************************************************************************
  456.  *
  457.  * FUNCTION:    LsDoOnePathname
  458.  *
  459.  * PARAMETERS:  ACPI_WALK_CALLBACK
  460.  *
  461.  * RETURN:      Status
  462.  *
  463.  * DESCRIPTION: Print the full pathname for a namespace node.
  464.  *
  465.  ******************************************************************************/
  466.  
  467. static ACPI_STATUS
  468. LsDoOnePathname (
  469.     ACPI_HANDLE             ObjHandle,
  470.     UINT32                  Level,
  471.     void                    *Context,
  472.     void                    **ReturnValue)
  473. {
  474.     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  475.     ACPI_STATUS             Status;
  476.     ACPI_BUFFER             TargetPath;
  477.  
  478.  
  479.     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  480.     Status = AcpiNsHandleToPathname (Node, &TargetPath);
  481.     if (ACPI_FAILURE (Status))
  482.     {
  483.         return (Status);
  484.     }
  485.  
  486.     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
  487.     ACPI_FREE (TargetPath.Pointer);
  488.  
  489.     return (AE_OK);
  490. }
  491.  
  492.  
  493. /*******************************************************************************
  494.  *
  495.  * FUNCTION:    LsDisplayNamespace
  496.  *
  497.  * PARAMETERS:  None
  498.  *
  499.  * RETURN:      Status
  500.  *
  501.  * DESCRIPTION: Walk the namespace an display information about each node
  502.  *              in the tree.  Information is written to the optional
  503.  *              namespace output file.
  504.  *
  505.  ******************************************************************************/
  506.  
  507. ACPI_STATUS
  508. LsDisplayNamespace (
  509.     void)
  510. {
  511.     ACPI_STATUS             Status;
  512.  
  513.  
  514.     if (!Gbl_NsOutputFlag)
  515.     {
  516.         return (AE_OK);
  517.     }
  518.  
  519.     Gbl_NumNamespaceObjects = 0;
  520.  
  521.     /* File header */
  522.  
  523.     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
  524.     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
  525.  
  526.     /* Walk entire namespace from the root */
  527.  
  528.     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  529.                 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
  530.                 NULL, NULL);
  531.  
  532.     /* Print the full pathname for each namespace node */
  533.  
  534.     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
  535.  
  536.     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  537.                 ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
  538.                 NULL, NULL);
  539.  
  540.     return (Status);
  541. }
  542.  
  543.  
  544. /*******************************************************************************
  545.  *
  546.  * FUNCTION:    LsCompareOneNamespaceObject
  547.  *
  548.  * PARAMETERS:  ACPI_WALK_CALLBACK
  549.  *
  550.  * RETURN:      Status
  551.  *
  552.  * DESCRIPTION: Compare name of one object.
  553.  *
  554.  ******************************************************************************/
  555.  
  556. static ACPI_STATUS
  557. LsCompareOneNamespaceObject (
  558.     ACPI_HANDLE             ObjHandle,
  559.     UINT32                  Level,
  560.     void                    *Context,
  561.     void                    **ReturnValue)
  562. {
  563.     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  564.  
  565.  
  566.     /* Simply check the name */
  567.  
  568.     if (*((UINT32 *) (Context)) == Node->Name.Integer)
  569.     {
  570.         /* Abort walk if we found one instance */
  571.  
  572.         return (AE_CTRL_TRUE);
  573.     }
  574.  
  575.     return (AE_OK);
  576. }
  577.  
  578.  
  579. /*******************************************************************************
  580.  *
  581.  * FUNCTION:    LkObjectExists
  582.  *
  583.  * PARAMETERS:  Name            - 4 char ACPI name
  584.  *
  585.  * RETURN:      TRUE if name exists in namespace
  586.  *
  587.  * DESCRIPTION: Walk the namespace to find an object
  588.  *
  589.  ******************************************************************************/
  590.  
  591. static BOOLEAN
  592. LkObjectExists (
  593.     char                    *Name)
  594. {
  595.     ACPI_STATUS             Status;
  596.  
  597.  
  598.     /* Walk entire namespace from the supplied root */
  599.  
  600.     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  601.                 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
  602.                 Name, NULL);
  603.     if (Status == AE_CTRL_TRUE)
  604.     {
  605.         /* At least one instance of the name was found */
  606.  
  607.         return (TRUE);
  608.     }
  609.  
  610.     return (FALSE);
  611. }
  612.  
  613.  
  614. /*******************************************************************************
  615.  *
  616.  * FUNCTION:    LkGetNameOp
  617.  *
  618.  * PARAMETERS:  Op              - Current Op
  619.  *
  620.  * RETURN:      NameOp associated with the input op
  621.  *
  622.  * DESCRIPTION: Find the name declaration op associated with the operator
  623.  *
  624.  ******************************************************************************/
  625.  
  626. ACPI_PARSE_OBJECT *
  627. LkGetNameOp (
  628.     ACPI_PARSE_OBJECT       *Op)
  629. {
  630.     const ACPI_OPCODE_INFO  *OpInfo;
  631.     ACPI_PARSE_OBJECT       *NameOp = Op;
  632.  
  633.  
  634.     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
  635.  
  636.  
  637.     /* Get the NamePath from the appropriate place */
  638.  
  639.     if (OpInfo->Flags & AML_NAMED)
  640.     {
  641.         /* For nearly all NAMED operators, the name reference is the first child */
  642.  
  643.         NameOp = Op->Asl.Child;
  644.         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
  645.         {
  646.             /*
  647.              * ALIAS is the only oddball opcode, the name declaration
  648.              * (alias name) is the second operand
  649.              */
  650.             NameOp = Op->Asl.Child->Asl.Next;
  651.         }
  652.     }
  653.     else if (OpInfo->Flags & AML_CREATE)
  654.     {
  655.         /* Name must appear as the last parameter */
  656.  
  657.         NameOp = Op->Asl.Child;
  658.         while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
  659.         {
  660.             NameOp = NameOp->Asl.Next;
  661.         }
  662.     }
  663.  
  664.     return (NameOp);
  665. }
  666.  
  667.  
  668. /*******************************************************************************
  669.  *
  670.  * FUNCTION:    LkIsObjectUsed
  671.  *
  672.  * PARAMETERS:  ACPI_WALK_CALLBACK
  673.  *
  674.  * RETURN:      Status
  675.  *
  676.  * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
  677.  *              We have to be careful, because some types and names are
  678.  *              typically or always unreferenced, we don't want to issue
  679.  *              excessive warnings.
  680.  *
  681.  ******************************************************************************/
  682.  
  683. static ACPI_STATUS
  684. LkIsObjectUsed (
  685.     ACPI_HANDLE             ObjHandle,
  686.     UINT32                  Level,
  687.     void                    *Context,
  688.     void                    **ReturnValue)
  689. {
  690.     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
  691.  
  692.  
  693.     /* Referenced flag is set during the namespace xref */
  694.  
  695.     if (Node->Flags & ANOBJ_IS_REFERENCED)
  696.     {
  697.         return (AE_OK);
  698.     }
  699.  
  700.     /*
  701.      * Ignore names that start with an underscore,
  702.      * these are the reserved ACPI names and are typically not referenced,
  703.      * they are called by the host OS.
  704.      */
  705.     if (Node->Name.Ascii[0] == '_')
  706.     {
  707.         return (AE_OK);
  708.     }
  709.  
  710.     /* There are some types that are typically not referenced, ignore them */
  711.  
  712.     switch (Node->Type)
  713.     {
  714.     case ACPI_TYPE_DEVICE:
  715.     case ACPI_TYPE_PROCESSOR:
  716.     case ACPI_TYPE_POWER:
  717.     case ACPI_TYPE_LOCAL_RESOURCE:
  718.         return (AE_OK);
  719.  
  720.     default:
  721.         break;
  722.     }
  723.  
  724.     /* All others are valid unreferenced namespace objects */
  725.  
  726.     if (Node->Op)
  727.     {
  728.         AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
  729.     }
  730.     return (AE_OK);
  731. }
  732.  
  733.  
  734. /*******************************************************************************
  735.  *
  736.  * FUNCTION:    LkFindUnreferencedObjects
  737.  *
  738.  * PARAMETERS:  None
  739.  *
  740.  * RETURN:      None
  741.  *
  742.  * DESCRIPTION: Namespace walk to find objects that are not referenced in any
  743.  *              way. Must be called after the namespace has been cross
  744.  *              referenced.
  745.  *
  746.  ******************************************************************************/
  747.  
  748. void
  749. LkFindUnreferencedObjects (
  750.     void)
  751. {
  752.  
  753.     /* Walk entire namespace from the supplied root */
  754.  
  755.     (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  756.                 ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
  757.                 NULL, NULL);
  758. }
  759.  
  760.  
  761. /*******************************************************************************
  762.  *
  763.  * FUNCTION:    LkCrossReferenceNamespace
  764.  *
  765.  * PARAMETERS:  None
  766.  *
  767.  * RETURN:      Status
  768.  *
  769.  * DESCRIPTION: Perform a cross reference check of the parse tree against the
  770.  *              namespace.  Every named referenced within the parse tree
  771.  *              should be get resolved with a namespace lookup.  If not, the
  772.  *              original reference in the ASL code is invalid -- i.e., refers
  773.  *              to a non-existent object.
  774.  *
  775.  * NOTE:  The ASL "External" operator causes the name to be inserted into the
  776.  *        namespace so that references to the external name will be resolved
  777.  *        correctly here.
  778.  *
  779.  ******************************************************************************/
  780.  
  781. ACPI_STATUS
  782. LkCrossReferenceNamespace (
  783.     void)
  784. {
  785.     ACPI_WALK_STATE         *WalkState;
  786.  
  787.  
  788.     DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
  789.  
  790.     /*
  791.      * Create a new walk state for use when looking up names
  792.      * within the namespace (Passed as context to the callbacks)
  793.      */
  794.     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
  795.     if (!WalkState)
  796.     {
  797.         return AE_NO_MEMORY;
  798.     }
  799.  
  800.     /* Walk the entire parse tree */
  801.  
  802.     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
  803.                         LkNamespaceLocateEnd, WalkState);
  804.     return AE_OK;
  805. }
  806.  
  807.  
  808. /*******************************************************************************
  809.  *
  810.  * FUNCTION:    LkCheckFieldRange
  811.  *
  812.  * PARAMETERS:  RegionBitLength     - Length of entire parent region
  813.  *              FieldBitOffset      - Start of the field unit (within region)
  814.  *              FieldBitLength      - Entire length of field unit
  815.  *              AccessBitWidth      - Access width of the field unit
  816.  *
  817.  * RETURN:      None
  818.  *
  819.  * DESCRIPTION: Check one field unit to make sure it fits in the parent
  820.  *              op region.
  821.  *
  822.  * Note: AccessBitWidth must be either 8,16,32, or 64
  823.  *
  824.  ******************************************************************************/
  825.  
  826. static void
  827. LkCheckFieldRange (
  828.     ACPI_PARSE_OBJECT       *Op,
  829.     UINT32                  RegionBitLength,
  830.     UINT32                  FieldBitOffset,
  831.     UINT32                  FieldBitLength,
  832.     UINT32                  AccessBitWidth)
  833. {
  834.     UINT32                  FieldEndBitOffset;
  835.  
  836.  
  837.     /*
  838.      * Check each field unit against the region size.  The entire
  839.      * field unit (start offset plus length) must fit within the
  840.      * region.
  841.      */
  842.     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
  843.  
  844.     if (FieldEndBitOffset > RegionBitLength)
  845.     {
  846.         /* Field definition itself is beyond the end-of-region */
  847.  
  848.         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
  849.         return;
  850.     }
  851.  
  852.     /*
  853.      * Now check that the field plus AccessWidth doesn't go beyond
  854.      * the end-of-region.  Assumes AccessBitWidth is a power of 2
  855.      */
  856.     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
  857.  
  858.     if (FieldEndBitOffset > RegionBitLength)
  859.     {
  860.         /* Field definition combined with the access is beyond EOR */
  861.  
  862.         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
  863.     }
  864. }
  865.  
  866. /*******************************************************************************
  867.  *
  868.  * FUNCTION:    LkNamespaceLocateBegin
  869.  *
  870.  * PARAMETERS:  ASL_WALK_CALLBACK
  871.  *
  872.  * RETURN:      Status
  873.  *
  874.  * DESCRIPTION: Descending callback used during cross-reference.  For named
  875.  *              object references, attempt to locate the name in the
  876.  *              namespace.
  877.  *
  878.  * NOTE: ASL references to named fields within resource descriptors are
  879.  *       resolved to integer values here.  Therefore, this step is an
  880.  *       important part of the code generation.  We don't know that the
  881.  *       name refers to a resource descriptor until now.
  882.  *
  883.  ******************************************************************************/
  884.  
  885. static ACPI_STATUS
  886. LkNamespaceLocateBegin (
  887.     ACPI_PARSE_OBJECT       *Op,
  888.     UINT32                  Level,
  889.     void                    *Context)
  890. {
  891.     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
  892.     ACPI_NAMESPACE_NODE     *Node;
  893.     ACPI_STATUS             Status;
  894.     ACPI_OBJECT_TYPE        ObjectType;
  895.     char                    *Path;
  896.     UINT8                   PassedArgs;
  897.     ACPI_PARSE_OBJECT       *NextOp;
  898.     ACPI_PARSE_OBJECT       *OwningOp;
  899.     ACPI_PARSE_OBJECT       *SpaceIdOp;
  900.     UINT32                  MinimumLength;
  901.     UINT32                  Temp;
  902.     const ACPI_OPCODE_INFO  *OpInfo;
  903.     UINT32                  Flags;
  904.  
  905.  
  906.     ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
  907.  
  908.     /*
  909.      * If this node is the actual declaration of a name
  910.      * [such as the XXXX name in "Method (XXXX)"],
  911.      * we are not interested in it here.  We only care about names that are
  912.      * references to other objects within the namespace and the parent objects
  913.      * of name declarations
  914.      */
  915.     if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
  916.     {
  917.         return (AE_OK);
  918.     }
  919.  
  920.     /* We are only interested in opcodes that have an associated name */
  921.  
  922.     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
  923.  
  924.     if ((!(OpInfo->Flags & AML_NAMED)) &&
  925.         (!(OpInfo->Flags & AML_CREATE)) &&
  926.         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
  927.         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
  928.         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
  929.     {
  930.         return (AE_OK);
  931.     }
  932.  
  933.     /*
  934.      * One special case: CondRefOf operator - we don't care if the name exists
  935.      * or not at this point, just ignore it, the point of the operator is to
  936.      * determine if the name exists at runtime.
  937.      */
  938.     if ((Op->Asl.Parent) &&
  939.         (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
  940.     {
  941.         return (AE_OK);
  942.     }
  943.  
  944.     /*
  945.      * We must enable the "search-to-root" for single NameSegs, but
  946.      * we have to be very careful about opening up scopes
  947.      */
  948.     Flags = ACPI_NS_SEARCH_PARENT;
  949.     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
  950.         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
  951.         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
  952.     {
  953.         /*
  954.          * These are name references, do not push the scope stack
  955.          * for them.
  956.          */
  957.         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
  958.     }
  959.  
  960.     /* Get the NamePath from the appropriate place */
  961.  
  962.     if (OpInfo->Flags & AML_NAMED)
  963.     {
  964.         /* For nearly all NAMED operators, the name reference is the first child */
  965.  
  966.         Path = Op->Asl.Child->Asl.Value.String;
  967.         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
  968.         {
  969.             /*
  970.              * ALIAS is the only oddball opcode, the name declaration
  971.              * (alias name) is the second operand
  972.              */
  973.             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
  974.         }
  975.     }
  976.     else if (OpInfo->Flags & AML_CREATE)
  977.     {
  978.         /* Name must appear as the last parameter */
  979.  
  980.         NextOp = Op->Asl.Child;
  981.         while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
  982.         {
  983.             NextOp = NextOp->Asl.Next;
  984.         }
  985.         Path = NextOp->Asl.Value.String;
  986.     }
  987.     else
  988.     {
  989.         Path = Op->Asl.Value.String;
  990.     }
  991.  
  992.     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
  993.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  994.         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
  995.  
  996.     /*
  997.      * Lookup the name in the namespace.  Name must exist at this point, or it
  998.      * is an invalid reference.
  999.      *
  1000.      * The namespace is also used as a lookup table for references to resource
  1001.      * descriptors and the fields within them.
  1002.      */
  1003.     Gbl_NsLookupCount++;
  1004.  
  1005.     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
  1006.                 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
  1007.     if (ACPI_FAILURE (Status))
  1008.     {
  1009.         if (Status == AE_NOT_FOUND)
  1010.         {
  1011.             /*
  1012.              * We didn't find the name reference by path -- we can qualify this
  1013.              * a little better before we print an error message
  1014.              */
  1015.             if (strlen (Path) == ACPI_NAME_SIZE)
  1016.             {
  1017.                 /* A simple, one-segment ACPI name */
  1018.  
  1019.                 if (LkObjectExists (Path))
  1020.                 {
  1021.                     /*
  1022.                      * There exists such a name, but we couldn't get to it
  1023.                      * from this scope
  1024.                      */
  1025.                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
  1026.                         Op->Asl.ExternalName);
  1027.                 }
  1028.                 else
  1029.                 {
  1030.                     /* The name doesn't exist, period */
  1031.  
  1032.                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
  1033.                         Op, Op->Asl.ExternalName);
  1034.                 }
  1035.             }
  1036.             else
  1037.             {
  1038.                 /* Check for a fully qualified path */
  1039.  
  1040.                 if (Path[0] == AML_ROOT_PREFIX)
  1041.                 {
  1042.                     /* Gave full path, the object does not exist */
  1043.  
  1044.                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
  1045.                         Op->Asl.ExternalName);
  1046.                 }
  1047.                 else
  1048.                 {
  1049.                     /*
  1050.                      * We can't tell whether it doesn't exist or just
  1051.                      * can't be reached.
  1052.                      */
  1053.                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
  1054.                         Op->Asl.ExternalName);
  1055.                 }
  1056.             }
  1057.  
  1058.             Status = AE_OK;
  1059.         }
  1060.         return (Status);
  1061.     }
  1062.  
  1063.     /* Check for a reference vs. name declaration */
  1064.  
  1065.     if (!(OpInfo->Flags & AML_NAMED) &&
  1066.         !(OpInfo->Flags & AML_CREATE))
  1067.     {
  1068.         /* This node has been referenced, mark it for reference check */
  1069.  
  1070.         Node->Flags |= ANOBJ_IS_REFERENCED;
  1071.     }
  1072.  
  1073.     /* Attempt to optimize the NamePath */
  1074.  
  1075.     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
  1076.  
  1077.     /*
  1078.      * 1) Dereference an alias (A name reference that is an alias)
  1079.      *    Aliases are not nested, the alias always points to the final object
  1080.      */
  1081.     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
  1082.         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
  1083.     {
  1084.         /* This node points back to the original PARSEOP_ALIAS */
  1085.  
  1086.         NextOp = Node->Op;
  1087.  
  1088.         /* The first child is the alias target op */
  1089.  
  1090.         NextOp = NextOp->Asl.Child;
  1091.  
  1092.         /* That in turn points back to original target alias node */
  1093.  
  1094.         if (NextOp->Asl.Node)
  1095.         {
  1096.             Node = NextOp->Asl.Node;
  1097.         }
  1098.  
  1099.         /* Else - forward reference to alias, will be resolved later */
  1100.     }
  1101.  
  1102.     /* 2) Check for a reference to a resource descriptor */
  1103.  
  1104.     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
  1105.              (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
  1106.     {
  1107.         /*
  1108.          * This was a reference to a field within a resource descriptor.  Extract
  1109.          * the associated field offset (either a bit or byte offset depending on
  1110.          * the field type) and change the named reference into an integer for
  1111.          * AML code generation
  1112.          */
  1113.         Temp = Node->Value;
  1114.         if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
  1115.         {
  1116.             Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
  1117.         }
  1118.  
  1119.         /* Perform BitOffset <--> ByteOffset conversion if necessary */
  1120.  
  1121.         switch (Op->Asl.Parent->Asl.AmlOpcode)
  1122.         {
  1123.         case AML_CREATE_FIELD_OP:
  1124.  
  1125.             /* We allow a Byte offset to Bit Offset conversion for this op */
  1126.  
  1127.             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
  1128.             {
  1129.                 /* Simply multiply byte offset times 8 to get bit offset */
  1130.  
  1131.                 Temp = ACPI_MUL_8 (Temp);
  1132.             }
  1133.             break;
  1134.  
  1135.  
  1136.         case AML_CREATE_BIT_FIELD_OP:
  1137.  
  1138.             /* This op requires a Bit Offset */
  1139.  
  1140.             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
  1141.             {
  1142.                 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
  1143.             }
  1144.             break;
  1145.  
  1146.  
  1147.         case AML_CREATE_BYTE_FIELD_OP:
  1148.         case AML_CREATE_WORD_FIELD_OP:
  1149.         case AML_CREATE_DWORD_FIELD_OP:
  1150.         case AML_CREATE_QWORD_FIELD_OP:
  1151.         case AML_INDEX_OP:
  1152.  
  1153.             /* These Ops require Byte offsets */
  1154.  
  1155.             if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
  1156.             {
  1157.                 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
  1158.             }
  1159.             break;
  1160.  
  1161.  
  1162.         default:
  1163.             /* Nothing to do for other opcodes */
  1164.             break;
  1165.         }
  1166.  
  1167.         /* Now convert this node to an integer whose value is the field offset */
  1168.  
  1169.         Op->Asl.AmlLength       = 0;
  1170.         Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
  1171.         Op->Asl.Value.Integer   = (UINT64) Temp;
  1172.         Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
  1173.  
  1174.         OpcGenerateAmlOpcode (Op);
  1175.     }
  1176.  
  1177.     /* 3) Check for a method invocation */
  1178.  
  1179.     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
  1180.                 (Node->Type == ACPI_TYPE_METHOD) &&
  1181.                 (Op->Asl.Parent) &&
  1182.                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
  1183.  
  1184.                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
  1185.     {
  1186.  
  1187.         /*
  1188.          * A reference to a method within one of these opcodes is not an
  1189.          * invocation of the method, it is simply a reference to the method.
  1190.          */
  1191.         if ((Op->Asl.Parent) &&
  1192.            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
  1193.             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
  1194.             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
  1195.         {
  1196.             return (AE_OK);
  1197.         }
  1198.         /*
  1199.          * There are two types of method invocation:
  1200.          * 1) Invocation with arguments -- the parser recognizes this
  1201.          *    as a METHODCALL.
  1202.          * 2) Invocation with no arguments --the parser cannot determine that
  1203.          *    this is a method invocation, therefore we have to figure it out
  1204.          *    here.
  1205.          */
  1206.         if (Node->Type != ACPI_TYPE_METHOD)
  1207.         {
  1208.             sprintf (MsgBuffer, "%s is a %s",
  1209.                     Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
  1210.  
  1211.             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
  1212.             return (AE_OK);
  1213.         }
  1214.  
  1215.         /* Save the method node in the caller's op */
  1216.  
  1217.         Op->Asl.Node = Node;
  1218.         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
  1219.         {
  1220.             return (AE_OK);
  1221.         }
  1222.  
  1223.         /*
  1224.          * This is a method invocation, with or without arguments.
  1225.          * Count the number of arguments, each appears as a child
  1226.          * under the parent node
  1227.          */
  1228.         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
  1229.         UtSetParseOpName (Op);
  1230.  
  1231.         PassedArgs = 0;
  1232.         NextOp     = Op->Asl.Child;
  1233.  
  1234.         while (NextOp)
  1235.         {
  1236.             PassedArgs++;
  1237.             NextOp = NextOp->Asl.Next;
  1238.         }
  1239.  
  1240.         if (Node->Value != ASL_EXTERNAL_METHOD)
  1241.         {
  1242.             /*
  1243.              * Check the parsed arguments with the number expected by the
  1244.              * method declaration itself
  1245.              */
  1246.             if (PassedArgs != Node->Value)
  1247.             {
  1248.                 sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
  1249.                             Node->Value);
  1250.  
  1251.                 if (PassedArgs < Node->Value)
  1252.                 {
  1253.                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
  1254.                 }
  1255.                 else
  1256.                 {
  1257.                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
  1258.                 }
  1259.             }
  1260.         }
  1261.     }
  1262.  
  1263.     /* 4) Check for an ASL Field definition */
  1264.  
  1265.     else if ((Op->Asl.Parent) &&
  1266.             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
  1267.              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
  1268.     {
  1269.         /*
  1270.          * Offset checking for fields.  If the parent operation region has a
  1271.          * constant length (known at compile time), we can check fields
  1272.          * defined in that region against the region length.  This will catch
  1273.          * fields and field units that cannot possibly fit within the region.
  1274.          *
  1275.          * Note: Index fields do not directly reference an operation region,
  1276.          * thus they are not included in this check.
  1277.          */
  1278.         if (Op == Op->Asl.Parent->Asl.Child)
  1279.         {
  1280.             /*
  1281.              * This is the first child of the field node, which is
  1282.              * the name of the region.  Get the parse node for the
  1283.              * region -- which contains the length of the region.
  1284.              */
  1285.             OwningOp = Node->Op;
  1286.             Op->Asl.Parent->Asl.ExtraValue =
  1287.                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
  1288.  
  1289.             /* Examine the field access width */
  1290.  
  1291.             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
  1292.             {
  1293.             case AML_FIELD_ACCESS_ANY:
  1294.             case AML_FIELD_ACCESS_BYTE:
  1295.             case AML_FIELD_ACCESS_BUFFER:
  1296.             default:
  1297.                 MinimumLength = 1;
  1298.                 break;
  1299.  
  1300.             case AML_FIELD_ACCESS_WORD:
  1301.                 MinimumLength = 2;
  1302.                 break;
  1303.  
  1304.             case AML_FIELD_ACCESS_DWORD:
  1305.                 MinimumLength = 4;
  1306.                 break;
  1307.  
  1308.             case AML_FIELD_ACCESS_QWORD:
  1309.                 MinimumLength = 8;
  1310.                 break;
  1311.             }
  1312.  
  1313.             /*
  1314.              * Is the region at least as big as the access width?
  1315.              * Note: DataTableRegions have 0 length
  1316.              */
  1317.             if (((UINT32) OwningOp->Asl.Value.Integer) &&
  1318.                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
  1319.             {
  1320.                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
  1321.             }
  1322.  
  1323.             /*
  1324.              * Check EC/CMOS/SMBUS fields to make sure that the correct
  1325.              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
  1326.              */
  1327.             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
  1328.             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
  1329.             {
  1330.             case REGION_EC:
  1331.             case REGION_CMOS:
  1332.  
  1333.                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
  1334.                 {
  1335.                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
  1336.                 }
  1337.                 break;
  1338.  
  1339.             case REGION_SMBUS:
  1340.             case REGION_IPMI:
  1341.  
  1342.                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
  1343.                 {
  1344.                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
  1345.                 }
  1346.                 break;
  1347.  
  1348.             default:
  1349.  
  1350.                 /* Nothing to do for other address spaces */
  1351.                 break;
  1352.             }
  1353.         }
  1354.         else
  1355.         {
  1356.             /*
  1357.              * This is one element of the field list.  Check to make sure
  1358.              * that it does not go beyond the end of the parent operation region.
  1359.              *
  1360.              * In the code below:
  1361.              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
  1362.              *    Op->Asl.ExtraValue                  - Field start offset (bits)
  1363.              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
  1364.              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
  1365.              */
  1366.             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
  1367.             {
  1368.                 LkCheckFieldRange (Op,
  1369.                             Op->Asl.Parent->Asl.ExtraValue,
  1370.                             Op->Asl.ExtraValue,
  1371.                             (UINT32) Op->Asl.Child->Asl.Value.Integer,
  1372.                             Op->Asl.Child->Asl.ExtraValue);
  1373.             }
  1374.         }
  1375.     }
  1376.  
  1377.     Op->Asl.Node = Node;
  1378.     return (Status);
  1379. }
  1380.  
  1381.  
  1382. /*******************************************************************************
  1383.  *
  1384.  * FUNCTION:    LkNamespaceLocateEnd
  1385.  *
  1386.  * PARAMETERS:  ASL_WALK_CALLBACK
  1387.  *
  1388.  * RETURN:      Status
  1389.  *
  1390.  * DESCRIPTION: Ascending callback used during cross reference.  We only
  1391.  *              need to worry about scope management here.
  1392.  *
  1393.  ******************************************************************************/
  1394.  
  1395. static ACPI_STATUS
  1396. LkNamespaceLocateEnd (
  1397.     ACPI_PARSE_OBJECT       *Op,
  1398.     UINT32                  Level,
  1399.     void                    *Context)
  1400. {
  1401.     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
  1402.     const ACPI_OPCODE_INFO  *OpInfo;
  1403.  
  1404.  
  1405.     ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
  1406.  
  1407.  
  1408.     /* We are only interested in opcodes that have an associated name */
  1409.  
  1410.     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
  1411.     if (!(OpInfo->Flags & AML_NAMED))
  1412.     {
  1413.         return (AE_OK);
  1414.     }
  1415.  
  1416.     /* Not interested in name references, we did not open a scope for them */
  1417.  
  1418.     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
  1419.         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
  1420.         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
  1421.     {
  1422.         return (AE_OK);
  1423.     }
  1424.  
  1425.     /* Pop the scope stack if necessary */
  1426.  
  1427.     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
  1428.     {
  1429.  
  1430.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  1431.             "%s: Popping scope for Op %p\n",
  1432.             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
  1433.  
  1434.         (void) AcpiDsScopeStackPop (WalkState);
  1435.     }
  1436.  
  1437.     return (AE_OK);
  1438. }
  1439.  
  1440.  
  1441.