Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: aslmaputils - Utilities for the resource descriptor/device maps
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2025, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acapps.h"
     47 #include "aslcompiler.h"
     48 #include "aslcompiler.y.h"
     49 #include "acinterp.h"
     50 #include "acnamesp.h"
     51 #include "amlcode.h"
     52 
     53 /* This module used for application-level code only */
     54 
     55 #define _COMPONENT          ACPI_COMPILER
     56         ACPI_MODULE_NAME    ("aslmaputils")
     57 
     58 
     59 /*******************************************************************************
     60  *
     61  * FUNCTION:    MpGetHidFromParseTree
     62  *
     63  * PARAMETERS:  HidNode             - Node for a _HID object
     64  *
     65  * RETURN:      An _HID string value. Automatically converts _HID integers
     66  *              to strings. Never NULL.
     67  *
     68  * DESCRIPTION: Extract a _HID value from the parse tree, not the namespace.
     69  *              Used when a fully initialized namespace is not available.
     70  *
     71  ******************************************************************************/
     72 
     73 char *
     74 MpGetHidFromParseTree (
     75     ACPI_NAMESPACE_NODE     *HidNode)
     76 {
     77     ACPI_PARSE_OBJECT       *Op;
     78     ACPI_PARSE_OBJECT       *Arg;
     79     char                    *HidString;
     80 
     81 
     82     Op = HidNode->Op;
     83     if (!Op)
     84     {
     85         /* Object is not resolved, probably an External */
     86 
     87         return ("Unresolved Symbol - referenced but not defined in this table");
     88     }
     89 
     90     switch (Op->Asl.ParseOpcode)
     91     {
     92     case PARSEOP_NAME:
     93 
     94         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
     95         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
     96 
     97         switch (Arg->Asl.ParseOpcode)
     98         {
     99         case PARSEOP_STRING_LITERAL:
    100 
    101             return (Arg->Asl.Value.String);
    102 
    103         case PARSEOP_INTEGER:
    104 
    105             /* Convert EISAID to a string */
    106 
    107             HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE);
    108             AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer);
    109             return (HidString);
    110 
    111         default:
    112 
    113             return ("UNKNOWN");
    114         }
    115 
    116     default:
    117         return ("-No HID-");
    118     }
    119 }
    120 
    121 
    122 /*******************************************************************************
    123  *
    124  * FUNCTION:    MpGetHidValue
    125  *
    126  * PARAMETERS:  DeviceNode          - Node for parent device
    127  *
    128  * RETURN:      An _HID string value. Automatically converts _HID integers
    129  *              to strings. Never NULL.
    130  *
    131  * DESCRIPTION: Extract _HID value from within a device scope. Does not
    132  *              actually execute a method, just gets the string or integer
    133  *              value for the _HID.
    134  *
    135  ******************************************************************************/
    136 
    137 char *
    138 MpGetHidValue (
    139     ACPI_NAMESPACE_NODE     *DeviceNode)
    140 {
    141     ACPI_NAMESPACE_NODE     *HidNode;
    142     char                    *HidString;
    143     ACPI_STATUS             Status;
    144 
    145 
    146     Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__HID,
    147         ACPI_NS_NO_UPSEARCH, &HidNode);
    148     if (ACPI_FAILURE (Status))
    149     {
    150         goto ErrorExit;
    151     }
    152 
    153     /* If only partial namespace, get the _HID from the parse tree */
    154 
    155     if (!HidNode->Object)
    156     {
    157         return (MpGetHidFromParseTree (HidNode));
    158     }
    159 
    160     /* Handle the different _HID flavors */
    161 
    162     switch (HidNode->Type)
    163     {
    164     case ACPI_TYPE_STRING:
    165 
    166         return (HidNode->Object->String.Pointer);
    167 
    168     case ACPI_TYPE_INTEGER:
    169 
    170         /* Convert EISAID to a string */
    171 
    172         HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE);
    173         AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value);
    174         return (HidString);
    175 
    176     case ACPI_TYPE_METHOD:
    177 
    178         return ("-Method-");
    179 
    180     default:
    181 
    182         FlPrintFile (ASL_FILE_MAP_OUTPUT, "BAD HID TYPE: %u", HidNode->Type);
    183         break;
    184     }
    185 
    186 
    187 ErrorExit:
    188     return ("-No HID-");
    189 }
    190 
    191 
    192 /*******************************************************************************
    193  *
    194  * FUNCTION:    MpGetHidViaNamestring
    195  *
    196  * PARAMETERS:  DeviceName          - Namepath for parent device
    197  *
    198  * RETURN:      _HID string. Never NULL.
    199  *
    200  * DESCRIPTION: Get a _HID value via a device pathname (instead of just simply
    201  *              a device node.)
    202  *
    203  ******************************************************************************/
    204 
    205 char *
    206 MpGetHidViaNamestring (
    207     char                    *DeviceName)
    208 {
    209     ACPI_NAMESPACE_NODE     *DeviceNode;
    210     ACPI_STATUS             Status;
    211 
    212 
    213     Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
    214         &DeviceNode);
    215     if (ACPI_FAILURE (Status))
    216     {
    217         goto ErrorExit;
    218     }
    219 
    220     return (MpGetHidValue (DeviceNode));
    221 
    222 
    223 ErrorExit:
    224     return ("-No HID-");
    225 }
    226 
    227 
    228 /*******************************************************************************
    229  *
    230  * FUNCTION:    MpGetParentDeviceHid
    231  *
    232  * PARAMETERS:  Op                      - Parse Op to be examined
    233  *              TargetNode              - Where the field node is returned
    234  *              ParentDeviceName        - Where the node path is returned
    235  *
    236  * RETURN:      _HID string. Never NULL.
    237  *
    238  * DESCRIPTION: Find the parent Device or Scope Op, get the full pathname to
    239  *              the parent, and get the _HID associated with the parent.
    240  *
    241  ******************************************************************************/
    242 
    243 char *
    244 MpGetParentDeviceHid (
    245     ACPI_PARSE_OBJECT       *Op,
    246     ACPI_NAMESPACE_NODE     **TargetNode,
    247     char                    **ParentDeviceName)
    248 {
    249     ACPI_NAMESPACE_NODE     *DeviceNode;
    250 
    251 
    252     /* Find parent Device() or Scope() Op */
    253 
    254     while (Op &&
    255         (Op->Asl.AmlOpcode != AML_DEVICE_OP) &&
    256         (Op->Asl.AmlOpcode != AML_SCOPE_OP))
    257     {
    258         Op = Op->Asl.Parent;
    259     }
    260 
    261     if (!Op)
    262     {
    263         FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Parent_Device ");
    264         goto ErrorExit;
    265     }
    266 
    267     /* Get the full pathname to the device and the _HID */
    268 
    269     DeviceNode = Op->Asl.Node;
    270     if (!DeviceNode)
    271     {
    272         FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Device_Node ");
    273         goto ErrorExit;
    274     }
    275 
    276     *ParentDeviceName = AcpiNsGetExternalPathname (DeviceNode);
    277     return (MpGetHidValue (DeviceNode));
    278 
    279 
    280 ErrorExit:
    281     return ("-No HID-");
    282 }
    283 
    284 
    285 /*******************************************************************************
    286  *
    287  * FUNCTION:    MpGetDdnValue
    288  *
    289  * PARAMETERS:  DeviceName          - Namepath for parent device
    290  *
    291  * RETURN:      _DDN description string. NULL on failure.
    292  *
    293  * DESCRIPTION: Execute the _DDN method for the device.
    294  *
    295  ******************************************************************************/
    296 
    297 char *
    298 MpGetDdnValue (
    299     char                    *DeviceName)
    300 {
    301     ACPI_NAMESPACE_NODE     *DeviceNode;
    302     ACPI_NAMESPACE_NODE     *DdnNode;
    303     ACPI_STATUS             Status;
    304 
    305 
    306     Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
    307         &DeviceNode);
    308     if (ACPI_FAILURE (Status))
    309     {
    310         goto ErrorExit;
    311     }
    312 
    313     Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__DDN, ACPI_NS_NO_UPSEARCH,
    314         &DdnNode);
    315     if (ACPI_FAILURE (Status))
    316     {
    317         goto ErrorExit;
    318     }
    319 
    320     if ((DdnNode->Type != ACPI_TYPE_STRING) ||
    321         !DdnNode->Object)
    322     {
    323         goto ErrorExit;
    324     }
    325 
    326     return (DdnNode->Object->String.Pointer);
    327 
    328 
    329 ErrorExit:
    330     return (NULL);
    331 }
    332 
    333 
    334 /*******************************************************************************
    335  *
    336  * FUNCTION:    MpGetConnectionInfo
    337  *
    338  * PARAMETERS:  Op                      - Parse Op to be examined
    339  *              PinIndex                - Index into GPIO PinList
    340  *              TargetNode              - Where the field node is returned
    341  *              TargetName              - Where the node path is returned
    342  *
    343  * RETURN:      A substitute _HID string, indicating that the name is actually
    344  *              a field. NULL if the Op does not refer to a Connection.
    345  *
    346  * DESCRIPTION: Get the Field Unit that corresponds to the PinIndex after
    347  *              a Connection() invocation.
    348  *
    349  ******************************************************************************/
    350 
    351 char *
    352 MpGetConnectionInfo (
    353     ACPI_PARSE_OBJECT       *Op,
    354     UINT32                  PinIndex,
    355     ACPI_NAMESPACE_NODE     **TargetNode,
    356     char                    **TargetName)
    357 {
    358     ACPI_PARSE_OBJECT       *NextOp;
    359     UINT32                  i;
    360 
    361 
    362     /*
    363      * Handle Connection() here. Find the next named FieldUnit.
    364      * Note: we look at the ParseOpcode for the compiler, look
    365      * at the AmlOpcode for the disassembler.
    366      */
    367     if ((Op->Asl.AmlOpcode == AML_INT_CONNECTION_OP) ||
    368         (Op->Asl.ParseOpcode == PARSEOP_CONNECTION))
    369     {
    370         /* Find the correct field unit definition */
    371 
    372         NextOp = Op;
    373         for (i = 0; i <= PinIndex;)
    374         {
    375             NextOp = NextOp->Asl.Next;
    376             while (NextOp &&
    377                 (NextOp->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
    378                 (NextOp->Asl.AmlOpcode != AML_INT_NAMEDFIELD_OP))
    379             {
    380                 NextOp = NextOp->Asl.Next;
    381             }
    382 
    383             if (!NextOp)
    384             {
    385                 return ("UNKNOWN");
    386             }
    387 
    388             /* Add length of this field to the current pin index */
    389 
    390             if (NextOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
    391             {
    392                 i += (UINT32) NextOp->Asl.Child->Asl.Value.Integer;
    393             }
    394             else /* AML_INT_NAMEDFIELD_OP */
    395             {
    396                 i += (UINT32) NextOp->Asl.Value.Integer;
    397             }
    398         }
    399 
    400         /* Return the node and pathname for the field unit */
    401 
    402         *TargetNode = NextOp->Asl.Node;
    403         *TargetName = AcpiNsGetExternalPathname (*TargetNode);
    404         return ("-Field-");
    405     }
    406 
    407     return (NULL);
    408 }
    409