Home | History | Annotate | Line # | Download | only in common
dmextern.c revision 1.1.1.16
      1       1.1    jruoho /******************************************************************************
      2       1.1    jruoho  *
      3       1.1    jruoho  * Module Name: dmextern - Support for External() ASL statements
      4       1.1    jruoho  *
      5       1.1    jruoho  *****************************************************************************/
      6       1.1    jruoho 
      7   1.1.1.2    jruoho /*
      8  1.1.1.16  christos  * Copyright (C) 2000 - 2020, Intel Corp.
      9       1.1    jruoho  * All rights reserved.
     10       1.1    jruoho  *
     11   1.1.1.2    jruoho  * Redistribution and use in source and binary forms, with or without
     12   1.1.1.2    jruoho  * modification, are permitted provided that the following conditions
     13   1.1.1.2    jruoho  * are met:
     14   1.1.1.2    jruoho  * 1. Redistributions of source code must retain the above copyright
     15   1.1.1.2    jruoho  *    notice, this list of conditions, and the following disclaimer,
     16   1.1.1.2    jruoho  *    without modification.
     17   1.1.1.2    jruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18   1.1.1.2    jruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
     19   1.1.1.2    jruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
     20   1.1.1.2    jruoho  *    including a substantially similar Disclaimer requirement for further
     21   1.1.1.2    jruoho  *    binary redistribution.
     22   1.1.1.2    jruoho  * 3. Neither the names of the above-listed copyright holders nor the names
     23   1.1.1.2    jruoho  *    of any contributors may be used to endorse or promote products derived
     24   1.1.1.2    jruoho  *    from this software without specific prior written permission.
     25   1.1.1.2    jruoho  *
     26   1.1.1.2    jruoho  * Alternatively, this software may be distributed under the terms of the
     27   1.1.1.2    jruoho  * GNU General Public License ("GPL") version 2 as published by the Free
     28   1.1.1.2    jruoho  * Software Foundation.
     29   1.1.1.2    jruoho  *
     30   1.1.1.2    jruoho  * NO WARRANTY
     31   1.1.1.2    jruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32   1.1.1.2    jruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33   1.1.1.2    jruoho  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34   1.1.1.2    jruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35   1.1.1.2    jruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36   1.1.1.2    jruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37   1.1.1.2    jruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38   1.1.1.2    jruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39   1.1.1.2    jruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40   1.1.1.2    jruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41   1.1.1.2    jruoho  * POSSIBILITY OF SUCH DAMAGES.
     42   1.1.1.2    jruoho  */
     43       1.1    jruoho 
     44       1.1    jruoho #include "acpi.h"
     45       1.1    jruoho #include "accommon.h"
     46       1.1    jruoho #include "amlcode.h"
     47       1.1    jruoho #include "acnamesp.h"
     48       1.1    jruoho #include "acdisasm.h"
     49   1.1.1.3  christos #include "aslcompiler.h"
     50   1.1.1.3  christos #include <stdio.h>
     51   1.1.1.3  christos #include <errno.h>
     52       1.1    jruoho 
     53       1.1    jruoho 
     54       1.1    jruoho /*
     55       1.1    jruoho  * This module is used for application-level code (iASL disassembler) only.
     56       1.1    jruoho  *
     57       1.1    jruoho  * It contains the code to create and emit any necessary External() ASL
     58       1.1    jruoho  * statements for the module being disassembled.
     59       1.1    jruoho  */
     60       1.1    jruoho #define _COMPONENT          ACPI_CA_DISASSEMBLER
     61       1.1    jruoho         ACPI_MODULE_NAME    ("dmextern")
     62       1.1    jruoho 
     63       1.1    jruoho 
     64       1.1    jruoho /*
     65       1.1    jruoho  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
     66       1.1    jruoho  * ObjectTypeKeyword. Used to generate typed external declarations
     67       1.1    jruoho  */
     68       1.1    jruoho static const char           *AcpiGbl_DmTypeNames[] =
     69       1.1    jruoho {
     70   1.1.1.4  christos     /* 00 */ ", UnknownObj",        /* Type ANY */
     71       1.1    jruoho     /* 01 */ ", IntObj",
     72       1.1    jruoho     /* 02 */ ", StrObj",
     73       1.1    jruoho     /* 03 */ ", BuffObj",
     74       1.1    jruoho     /* 04 */ ", PkgObj",
     75       1.1    jruoho     /* 05 */ ", FieldUnitObj",
     76       1.1    jruoho     /* 06 */ ", DeviceObj",
     77       1.1    jruoho     /* 07 */ ", EventObj",
     78       1.1    jruoho     /* 08 */ ", MethodObj",
     79       1.1    jruoho     /* 09 */ ", MutexObj",
     80       1.1    jruoho     /* 10 */ ", OpRegionObj",
     81       1.1    jruoho     /* 11 */ ", PowerResObj",
     82       1.1    jruoho     /* 12 */ ", ProcessorObj",
     83       1.1    jruoho     /* 13 */ ", ThermalZoneObj",
     84       1.1    jruoho     /* 14 */ ", BuffFieldObj",
     85       1.1    jruoho     /* 15 */ ", DDBHandleObj",
     86       1.1    jruoho     /* 16 */ "",                    /* Debug object */
     87       1.1    jruoho     /* 17 */ ", FieldUnitObj",
     88       1.1    jruoho     /* 18 */ ", FieldUnitObj",
     89       1.1    jruoho     /* 19 */ ", FieldUnitObj"
     90       1.1    jruoho };
     91       1.1    jruoho 
     92   1.1.1.3  christos #define METHOD_SEPARATORS           " \t,()\n"
     93   1.1.1.3  christos 
     94  1.1.1.11  christos static const char          *ExternalConflictMessage =
     95  1.1.1.11  christos     "    // Conflicts with a later declaration";
     96  1.1.1.11  christos 
     97       1.1    jruoho 
     98       1.1    jruoho /* Local prototypes */
     99       1.1    jruoho 
    100       1.1    jruoho static const char *
    101       1.1    jruoho AcpiDmGetObjectTypeName (
    102       1.1    jruoho     ACPI_OBJECT_TYPE        Type);
    103       1.1    jruoho 
    104       1.1    jruoho static char *
    105       1.1    jruoho AcpiDmNormalizeParentPrefix (
    106       1.1    jruoho     ACPI_PARSE_OBJECT       *Op,
    107       1.1    jruoho     char                    *Path);
    108       1.1    jruoho 
    109  1.1.1.11  christos static ACPI_STATUS
    110  1.1.1.11  christos AcpiDmGetExternalAndInternalPath (
    111  1.1.1.11  christos     ACPI_NAMESPACE_NODE     *Node,
    112  1.1.1.11  christos     char                    **ExternalPath,
    113  1.1.1.11  christos     char                    **InternalPath);
    114  1.1.1.11  christos 
    115  1.1.1.11  christos static ACPI_STATUS
    116  1.1.1.11  christos AcpiDmRemoveRootPrefix (
    117  1.1.1.11  christos     char                    **Path);
    118  1.1.1.11  christos 
    119   1.1.1.3  christos static void
    120   1.1.1.3  christos AcpiDmAddPathToExternalList (
    121   1.1.1.3  christos     char                    *Path,
    122   1.1.1.3  christos     UINT8                   Type,
    123   1.1.1.3  christos     UINT32                  Value,
    124   1.1.1.3  christos     UINT16                  Flags);
    125   1.1.1.3  christos 
    126   1.1.1.3  christos static ACPI_STATUS
    127   1.1.1.3  christos AcpiDmCreateNewExternal (
    128   1.1.1.3  christos     char                    *ExternalPath,
    129   1.1.1.3  christos     char                    *InternalPath,
    130   1.1.1.3  christos     UINT8                   Type,
    131   1.1.1.3  christos     UINT32                  Value,
    132   1.1.1.3  christos     UINT16                  Flags);
    133   1.1.1.3  christos 
    134  1.1.1.11  christos static void
    135  1.1.1.11  christos AcpiDmCheckForExternalConflict (
    136  1.1.1.11  christos     char                    *Path);
    137  1.1.1.11  christos 
    138  1.1.1.11  christos static ACPI_STATUS
    139  1.1.1.11  christos AcpiDmResolveExternal (
    140  1.1.1.11  christos     char                    *Path,
    141  1.1.1.11  christos     UINT8                   Type,
    142  1.1.1.11  christos     ACPI_NAMESPACE_NODE     **Node);
    143  1.1.1.11  christos 
    144  1.1.1.11  christos 
    145  1.1.1.11  christos static void
    146  1.1.1.11  christos AcpiDmConflictingDeclaration (
    147  1.1.1.11  christos     char                    *Path);
    148  1.1.1.11  christos 
    149       1.1    jruoho 
    150       1.1    jruoho /*******************************************************************************
    151       1.1    jruoho  *
    152       1.1    jruoho  * FUNCTION:    AcpiDmGetObjectTypeName
    153       1.1    jruoho  *
    154       1.1    jruoho  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
    155       1.1    jruoho  *
    156       1.1    jruoho  * RETURN:      Pointer to a string
    157       1.1    jruoho  *
    158       1.1    jruoho  * DESCRIPTION: Map an object type to the ASL object type string.
    159       1.1    jruoho  *
    160       1.1    jruoho  ******************************************************************************/
    161       1.1    jruoho 
    162       1.1    jruoho static const char *
    163       1.1    jruoho AcpiDmGetObjectTypeName (
    164       1.1    jruoho     ACPI_OBJECT_TYPE        Type)
    165       1.1    jruoho {
    166       1.1    jruoho 
    167       1.1    jruoho     if (Type == ACPI_TYPE_LOCAL_SCOPE)
    168       1.1    jruoho     {
    169       1.1    jruoho         Type = ACPI_TYPE_DEVICE;
    170       1.1    jruoho     }
    171       1.1    jruoho     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
    172       1.1    jruoho     {
    173       1.1    jruoho         return ("");
    174       1.1    jruoho     }
    175       1.1    jruoho 
    176       1.1    jruoho     return (AcpiGbl_DmTypeNames[Type]);
    177       1.1    jruoho }
    178       1.1    jruoho 
    179       1.1    jruoho 
    180       1.1    jruoho /*******************************************************************************
    181       1.1    jruoho  *
    182       1.1    jruoho  * FUNCTION:    AcpiDmNormalizeParentPrefix
    183       1.1    jruoho  *
    184       1.1    jruoho  * PARAMETERS:  Op                  - Parse op
    185       1.1    jruoho  *              Path                - Path with parent prefix
    186       1.1    jruoho  *
    187       1.1    jruoho  * RETURN:      The full pathname to the object (from the namespace root)
    188       1.1    jruoho  *
    189       1.1    jruoho  * DESCRIPTION: Returns the full pathname of a path with parent prefix
    190       1.1    jruoho  *              The caller must free the fullpath returned.
    191       1.1    jruoho  *
    192       1.1    jruoho  ******************************************************************************/
    193       1.1    jruoho 
    194       1.1    jruoho static char *
    195       1.1    jruoho AcpiDmNormalizeParentPrefix (
    196       1.1    jruoho     ACPI_PARSE_OBJECT       *Op,
    197       1.1    jruoho     char                    *Path)
    198       1.1    jruoho {
    199       1.1    jruoho     ACPI_NAMESPACE_NODE     *Node;
    200       1.1    jruoho     char                    *Fullpath;
    201       1.1    jruoho     char                    *ParentPath;
    202       1.1    jruoho     ACPI_SIZE               Length;
    203   1.1.1.3  christos     UINT32                  Index = 0;
    204       1.1    jruoho 
    205       1.1    jruoho 
    206   1.1.1.3  christos     if (!Op)
    207   1.1.1.3  christos     {
    208   1.1.1.3  christos         return (NULL);
    209   1.1.1.3  christos     }
    210   1.1.1.3  christos 
    211   1.1.1.3  christos     /* Search upwards in the parse tree until we reach the next namespace node */
    212       1.1    jruoho 
    213   1.1.1.3  christos     Op = Op->Common.Parent;
    214       1.1    jruoho     while (Op)
    215       1.1    jruoho     {
    216       1.1    jruoho         if (Op->Common.Node)
    217       1.1    jruoho         {
    218       1.1    jruoho             break;
    219       1.1    jruoho         }
    220       1.1    jruoho 
    221       1.1    jruoho         Op = Op->Common.Parent;
    222       1.1    jruoho     }
    223       1.1    jruoho 
    224       1.1    jruoho     if (!Op)
    225       1.1    jruoho     {
    226       1.1    jruoho         return (NULL);
    227       1.1    jruoho     }
    228       1.1    jruoho 
    229       1.1    jruoho     /*
    230       1.1    jruoho      * Find the actual parent node for the reference:
    231       1.1    jruoho      * Remove all carat prefixes from the input path.
    232       1.1    jruoho      * There may be multiple parent prefixes (For example, ^^^M000)
    233       1.1    jruoho      */
    234       1.1    jruoho     Node = Op->Common.Node;
    235       1.1    jruoho     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
    236       1.1    jruoho     {
    237       1.1    jruoho         Node = Node->Parent;
    238       1.1    jruoho         Path++;
    239       1.1    jruoho     }
    240       1.1    jruoho 
    241       1.1    jruoho     if (!Node)
    242       1.1    jruoho     {
    243       1.1    jruoho         return (NULL);
    244       1.1    jruoho     }
    245       1.1    jruoho 
    246       1.1    jruoho     /* Get the full pathname for the parent node */
    247       1.1    jruoho 
    248       1.1    jruoho     ParentPath = AcpiNsGetExternalPathname (Node);
    249       1.1    jruoho     if (!ParentPath)
    250       1.1    jruoho     {
    251       1.1    jruoho         return (NULL);
    252       1.1    jruoho     }
    253       1.1    jruoho 
    254   1.1.1.6  christos     Length = (strlen (ParentPath) + strlen (Path) + 1);
    255       1.1    jruoho     if (ParentPath[1])
    256       1.1    jruoho     {
    257       1.1    jruoho         /*
    258       1.1    jruoho          * If ParentPath is not just a simple '\', increment the length
    259       1.1    jruoho          * for the required dot separator (ParentPath.Path)
    260       1.1    jruoho          */
    261       1.1    jruoho         Length++;
    262   1.1.1.3  christos 
    263   1.1.1.3  christos         /* For External() statements, we do not want a leading '\' */
    264   1.1.1.3  christos 
    265   1.1.1.3  christos         if (*ParentPath == AML_ROOT_PREFIX)
    266   1.1.1.3  christos         {
    267   1.1.1.3  christos             Index = 1;
    268   1.1.1.3  christos         }
    269       1.1    jruoho     }
    270       1.1    jruoho 
    271       1.1    jruoho     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
    272       1.1    jruoho     if (!Fullpath)
    273       1.1    jruoho     {
    274       1.1    jruoho         goto Cleanup;
    275       1.1    jruoho     }
    276       1.1    jruoho 
    277       1.1    jruoho     /*
    278       1.1    jruoho      * Concatenate parent fullpath and path. For example,
    279       1.1    jruoho      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
    280       1.1    jruoho      *
    281       1.1    jruoho      * Copy the parent path
    282       1.1    jruoho      */
    283   1.1.1.6  christos     strcpy (Fullpath, &ParentPath[Index]);
    284       1.1    jruoho 
    285   1.1.1.3  christos     /*
    286   1.1.1.3  christos      * Add dot separator
    287   1.1.1.3  christos      * (don't need dot if parent fullpath is a single backslash)
    288   1.1.1.3  christos      */
    289       1.1    jruoho     if (ParentPath[1])
    290       1.1    jruoho     {
    291   1.1.1.6  christos         strcat (Fullpath, ".");
    292       1.1    jruoho     }
    293       1.1    jruoho 
    294       1.1    jruoho     /* Copy child path (carat parent prefix(es) were skipped above) */
    295       1.1    jruoho 
    296   1.1.1.6  christos     strcat (Fullpath, Path);
    297       1.1    jruoho 
    298       1.1    jruoho Cleanup:
    299       1.1    jruoho     ACPI_FREE (ParentPath);
    300       1.1    jruoho     return (Fullpath);
    301       1.1    jruoho }
    302       1.1    jruoho 
    303       1.1    jruoho 
    304       1.1    jruoho /*******************************************************************************
    305       1.1    jruoho  *
    306   1.1.1.2    jruoho  * FUNCTION:    AcpiDmAddToExternalFileList
    307   1.1.1.2    jruoho  *
    308   1.1.1.2    jruoho  * PARAMETERS:  PathList            - Single path or list separated by comma
    309   1.1.1.2    jruoho  *
    310   1.1.1.2    jruoho  * RETURN:      None
    311   1.1.1.2    jruoho  *
    312   1.1.1.2    jruoho  * DESCRIPTION: Add external files to global list
    313   1.1.1.2    jruoho  *
    314   1.1.1.2    jruoho  ******************************************************************************/
    315   1.1.1.2    jruoho 
    316   1.1.1.2    jruoho ACPI_STATUS
    317   1.1.1.2    jruoho AcpiDmAddToExternalFileList (
    318   1.1.1.3  christos     char                    *Pathname)
    319   1.1.1.2    jruoho {
    320   1.1.1.2    jruoho     ACPI_EXTERNAL_FILE      *ExternalFile;
    321   1.1.1.3  christos     char                    *LocalPathname;
    322   1.1.1.2    jruoho 
    323   1.1.1.2    jruoho 
    324   1.1.1.3  christos     if (!Pathname)
    325   1.1.1.2    jruoho     {
    326   1.1.1.2    jruoho         return (AE_OK);
    327   1.1.1.2    jruoho     }
    328   1.1.1.2    jruoho 
    329   1.1.1.3  christos     LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
    330   1.1.1.3  christos     if (!LocalPathname)
    331   1.1.1.2    jruoho     {
    332   1.1.1.3  christos         return (AE_NO_MEMORY);
    333   1.1.1.3  christos     }
    334   1.1.1.2    jruoho 
    335   1.1.1.3  christos     ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
    336   1.1.1.3  christos     if (!ExternalFile)
    337   1.1.1.3  christos     {
    338   1.1.1.3  christos         ACPI_FREE (LocalPathname);
    339   1.1.1.3  christos         return (AE_NO_MEMORY);
    340   1.1.1.3  christos     }
    341   1.1.1.2    jruoho 
    342   1.1.1.3  christos     /* Take a copy of the file pathname */
    343   1.1.1.2    jruoho 
    344   1.1.1.3  christos     strcpy (LocalPathname, Pathname);
    345   1.1.1.3  christos     ExternalFile->Path = LocalPathname;
    346   1.1.1.2    jruoho 
    347   1.1.1.3  christos     if (AcpiGbl_ExternalFileList)
    348   1.1.1.3  christos     {
    349   1.1.1.3  christos         ExternalFile->Next = AcpiGbl_ExternalFileList;
    350   1.1.1.2    jruoho     }
    351   1.1.1.2    jruoho 
    352   1.1.1.3  christos     AcpiGbl_ExternalFileList = ExternalFile;
    353   1.1.1.2    jruoho     return (AE_OK);
    354   1.1.1.2    jruoho }
    355   1.1.1.2    jruoho 
    356   1.1.1.2    jruoho 
    357   1.1.1.2    jruoho /*******************************************************************************
    358   1.1.1.2    jruoho  *
    359   1.1.1.2    jruoho  * FUNCTION:    AcpiDmClearExternalFileList
    360   1.1.1.2    jruoho  *
    361   1.1.1.2    jruoho  * PARAMETERS:  None
    362   1.1.1.2    jruoho  *
    363   1.1.1.2    jruoho  * RETURN:      None
    364   1.1.1.2    jruoho  *
    365   1.1.1.2    jruoho  * DESCRIPTION: Clear the external file list
    366   1.1.1.2    jruoho  *
    367   1.1.1.2    jruoho  ******************************************************************************/
    368   1.1.1.2    jruoho 
    369   1.1.1.2    jruoho void
    370   1.1.1.2    jruoho AcpiDmClearExternalFileList (
    371   1.1.1.2    jruoho     void)
    372   1.1.1.2    jruoho {
    373   1.1.1.2    jruoho     ACPI_EXTERNAL_FILE      *NextExternal;
    374   1.1.1.2    jruoho 
    375   1.1.1.2    jruoho 
    376   1.1.1.2    jruoho     while (AcpiGbl_ExternalFileList)
    377   1.1.1.2    jruoho     {
    378   1.1.1.2    jruoho         NextExternal = AcpiGbl_ExternalFileList->Next;
    379   1.1.1.2    jruoho         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
    380   1.1.1.2    jruoho         ACPI_FREE (AcpiGbl_ExternalFileList);
    381   1.1.1.2    jruoho         AcpiGbl_ExternalFileList = NextExternal;
    382   1.1.1.2    jruoho     }
    383   1.1.1.2    jruoho }
    384   1.1.1.2    jruoho 
    385   1.1.1.2    jruoho 
    386   1.1.1.2    jruoho /*******************************************************************************
    387   1.1.1.2    jruoho  *
    388   1.1.1.3  christos  * FUNCTION:    AcpiDmGetExternalsFromFile
    389   1.1.1.3  christos  *
    390   1.1.1.3  christos  * PARAMETERS:  None
    391   1.1.1.3  christos  *
    392   1.1.1.3  christos  * RETURN:      None
    393   1.1.1.3  christos  *
    394   1.1.1.3  christos  * DESCRIPTION: Process the optional external reference file.
    395   1.1.1.3  christos  *
    396   1.1.1.3  christos  * Each line in the file should be of the form:
    397   1.1.1.3  christos  *      External (<Method namepath>, MethodObj, <ArgCount>)
    398   1.1.1.3  christos  *
    399   1.1.1.3  christos  * Example:
    400   1.1.1.3  christos  *      External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
    401   1.1.1.3  christos  *
    402   1.1.1.3  christos  ******************************************************************************/
    403   1.1.1.3  christos 
    404   1.1.1.3  christos void
    405   1.1.1.3  christos AcpiDmGetExternalsFromFile (
    406   1.1.1.3  christos     void)
    407   1.1.1.3  christos {
    408   1.1.1.3  christos     FILE                    *ExternalRefFile;
    409   1.1.1.3  christos     char                    *Token;
    410   1.1.1.3  christos     char                    *MethodName;
    411   1.1.1.3  christos     UINT32                  ArgCount;
    412   1.1.1.3  christos     UINT32                  ImportCount = 0;
    413   1.1.1.3  christos 
    414   1.1.1.3  christos 
    415  1.1.1.14  christos     if (!AslGbl_ExternalRefFilename)
    416   1.1.1.3  christos     {
    417   1.1.1.3  christos         return;
    418   1.1.1.3  christos     }
    419   1.1.1.3  christos 
    420   1.1.1.3  christos     /* Open the file */
    421   1.1.1.3  christos 
    422  1.1.1.14  christos     ExternalRefFile = fopen (AslGbl_ExternalRefFilename, "r");
    423   1.1.1.3  christos     if (!ExternalRefFile)
    424   1.1.1.3  christos     {
    425   1.1.1.3  christos         fprintf (stderr, "Could not open external reference file \"%s\"\n",
    426  1.1.1.14  christos             AslGbl_ExternalRefFilename);
    427   1.1.1.4  christos         AslAbort ();
    428   1.1.1.3  christos         return;
    429   1.1.1.3  christos     }
    430   1.1.1.3  christos 
    431   1.1.1.3  christos     /* Each line defines a method */
    432   1.1.1.3  christos 
    433  1.1.1.14  christos     while (fgets (AslGbl_StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))
    434   1.1.1.3  christos     {
    435  1.1.1.14  christos         Token = strtok (AslGbl_StringBuffer, METHOD_SEPARATORS);   /* "External" */
    436   1.1.1.4  christos         if (!Token)
    437   1.1.1.4  christos         {
    438   1.1.1.4  christos             continue;
    439   1.1.1.4  christos         }
    440   1.1.1.7  christos 
    441   1.1.1.4  christos         if (strcmp (Token, "External"))
    442   1.1.1.4  christos         {
    443   1.1.1.4  christos             continue;
    444   1.1.1.4  christos         }
    445   1.1.1.3  christos 
    446   1.1.1.3  christos         MethodName = strtok (NULL, METHOD_SEPARATORS);      /* Method namepath */
    447   1.1.1.4  christos         if (!MethodName)
    448   1.1.1.4  christos         {
    449   1.1.1.4  christos             continue;
    450   1.1.1.4  christos         }
    451   1.1.1.3  christos 
    452   1.1.1.3  christos         Token = strtok (NULL, METHOD_SEPARATORS);           /* "MethodObj" */
    453   1.1.1.4  christos         if (!Token)
    454   1.1.1.4  christos         {
    455   1.1.1.4  christos             continue;
    456   1.1.1.4  christos         }
    457   1.1.1.4  christos 
    458   1.1.1.4  christos         if (strcmp (Token, "MethodObj"))
    459   1.1.1.4  christos         {
    460   1.1.1.4  christos             continue;
    461   1.1.1.4  christos         }
    462   1.1.1.3  christos 
    463   1.1.1.3  christos         Token = strtok (NULL, METHOD_SEPARATORS);           /* Arg count */
    464   1.1.1.4  christos         if (!Token)
    465   1.1.1.4  christos         {
    466   1.1.1.4  christos             continue;
    467   1.1.1.4  christos         }
    468   1.1.1.3  christos 
    469   1.1.1.3  christos         /* Convert arg count string to an integer */
    470   1.1.1.3  christos 
    471   1.1.1.3  christos         errno = 0;
    472   1.1.1.3  christos         ArgCount = strtoul (Token, NULL, 0);
    473   1.1.1.3  christos         if (errno)
    474   1.1.1.3  christos         {
    475   1.1.1.3  christos             fprintf (stderr, "Invalid argument count (%s)\n", Token);
    476   1.1.1.3  christos             continue;
    477   1.1.1.3  christos         }
    478   1.1.1.7  christos 
    479   1.1.1.3  christos         if (ArgCount > 7)
    480   1.1.1.3  christos         {
    481   1.1.1.3  christos             fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
    482   1.1.1.3  christos             continue;
    483   1.1.1.3  christos         }
    484   1.1.1.3  christos 
    485   1.1.1.3  christos         /* Add this external to the global list */
    486   1.1.1.3  christos 
    487   1.1.1.3  christos         AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
    488  1.1.1.14  christos             AslGbl_ExternalRefFilename, ArgCount, MethodName);
    489   1.1.1.3  christos 
    490   1.1.1.3  christos         AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
    491   1.1.1.3  christos             ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
    492   1.1.1.3  christos         ImportCount++;
    493   1.1.1.3  christos     }
    494   1.1.1.3  christos 
    495   1.1.1.3  christos     if (!ImportCount)
    496   1.1.1.3  christos     {
    497   1.1.1.7  christos         fprintf (stderr,
    498   1.1.1.7  christos             "Did not find any external methods in reference file \"%s\"\n",
    499  1.1.1.14  christos             AslGbl_ExternalRefFilename);
    500   1.1.1.3  christos     }
    501   1.1.1.3  christos     else
    502   1.1.1.3  christos     {
    503   1.1.1.3  christos         /* Add the external(s) to the namespace */
    504   1.1.1.3  christos 
    505  1.1.1.11  christos         AcpiDmAddExternalListToNamespace ();
    506   1.1.1.3  christos 
    507   1.1.1.3  christos         AcpiOsPrintf ("%s: Imported %u external method definitions\n",
    508  1.1.1.14  christos             AslGbl_ExternalRefFilename, ImportCount);
    509   1.1.1.3  christos     }
    510   1.1.1.3  christos 
    511   1.1.1.3  christos     fclose (ExternalRefFile);
    512   1.1.1.3  christos }
    513   1.1.1.3  christos 
    514   1.1.1.3  christos 
    515   1.1.1.3  christos /*******************************************************************************
    516   1.1.1.3  christos  *
    517   1.1.1.3  christos  * FUNCTION:    AcpiDmAddOpToExternalList
    518       1.1    jruoho  *
    519       1.1    jruoho  * PARAMETERS:  Op                  - Current parser Op
    520       1.1    jruoho  *              Path                - Internal (AML) path to the object
    521       1.1    jruoho  *              Type                - ACPI object type to be added
    522       1.1    jruoho  *              Value               - Arg count if adding a Method object
    523   1.1.1.3  christos  *              Flags               - To be passed to the external object
    524       1.1    jruoho  *
    525       1.1    jruoho  * RETURN:      None
    526       1.1    jruoho  *
    527       1.1    jruoho  * DESCRIPTION: Insert a new name into the global list of Externals which
    528       1.1    jruoho  *              will in turn be later emitted as an External() declaration
    529       1.1    jruoho  *              in the disassembled output.
    530       1.1    jruoho  *
    531   1.1.1.3  christos  *              This function handles the most common case where the referenced
    532   1.1.1.3  christos  *              name is simply not found in the constructed namespace.
    533   1.1.1.3  christos  *
    534       1.1    jruoho  ******************************************************************************/
    535       1.1    jruoho 
    536       1.1    jruoho void
    537   1.1.1.3  christos AcpiDmAddOpToExternalList (
    538       1.1    jruoho     ACPI_PARSE_OBJECT       *Op,
    539       1.1    jruoho     char                    *Path,
    540       1.1    jruoho     UINT8                   Type,
    541   1.1.1.3  christos     UINT32                  Value,
    542   1.1.1.3  christos     UINT16                  Flags)
    543       1.1    jruoho {
    544       1.1    jruoho     char                    *ExternalPath;
    545   1.1.1.3  christos     char                    *InternalPath = Path;
    546   1.1.1.3  christos     char                    *Temp;
    547       1.1    jruoho     ACPI_STATUS             Status;
    548       1.1    jruoho 
    549       1.1    jruoho 
    550   1.1.1.3  christos     ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
    551   1.1.1.3  christos 
    552   1.1.1.3  christos 
    553       1.1    jruoho     if (!Path)
    554       1.1    jruoho     {
    555   1.1.1.3  christos         return_VOID;
    556   1.1.1.3  christos     }
    557   1.1.1.3  christos 
    558   1.1.1.3  christos     /* Remove a root backslash if present */
    559   1.1.1.3  christos 
    560   1.1.1.3  christos     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
    561   1.1.1.3  christos     {
    562   1.1.1.3  christos         Path++;
    563       1.1    jruoho     }
    564       1.1    jruoho 
    565   1.1.1.3  christos     /* Externalize the pathname */
    566       1.1    jruoho 
    567       1.1    jruoho     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
    568   1.1.1.3  christos         NULL, &ExternalPath);
    569       1.1    jruoho     if (ACPI_FAILURE (Status))
    570       1.1    jruoho     {
    571   1.1.1.3  christos         return_VOID;
    572       1.1    jruoho     }
    573       1.1    jruoho 
    574   1.1.1.3  christos     /*
    575   1.1.1.3  christos      * Get the full pathname from the root if "Path" has one or more
    576   1.1.1.3  christos      * parent prefixes (^). Note: path will not contain a leading '\'.
    577   1.1.1.3  christos      */
    578       1.1    jruoho     if (*Path == (UINT8) AML_PARENT_PREFIX)
    579       1.1    jruoho     {
    580   1.1.1.3  christos         Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
    581   1.1.1.3  christos 
    582   1.1.1.3  christos         /* Set new external path */
    583   1.1.1.3  christos 
    584   1.1.1.3  christos         ACPI_FREE (ExternalPath);
    585   1.1.1.3  christos         ExternalPath = Temp;
    586   1.1.1.3  christos         if (!Temp)
    587       1.1    jruoho         {
    588   1.1.1.3  christos             return_VOID;
    589   1.1.1.3  christos         }
    590   1.1.1.3  christos 
    591   1.1.1.3  christos         /* Create the new internal pathname */
    592       1.1    jruoho 
    593   1.1.1.3  christos         Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
    594   1.1.1.3  christos         Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
    595   1.1.1.3  christos         if (ACPI_FAILURE (Status))
    596   1.1.1.3  christos         {
    597       1.1    jruoho             ACPI_FREE (ExternalPath);
    598   1.1.1.3  christos             return_VOID;
    599   1.1.1.3  christos         }
    600   1.1.1.3  christos     }
    601   1.1.1.3  christos 
    602   1.1.1.3  christos     /* Create the new External() declaration node */
    603   1.1.1.3  christos 
    604   1.1.1.3  christos     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
    605   1.1.1.3  christos         Type, Value, Flags);
    606   1.1.1.3  christos     if (ACPI_FAILURE (Status))
    607   1.1.1.3  christos     {
    608   1.1.1.3  christos         ACPI_FREE (ExternalPath);
    609   1.1.1.3  christos         if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
    610   1.1.1.3  christos         {
    611   1.1.1.3  christos             ACPI_FREE (InternalPath);
    612       1.1    jruoho         }
    613       1.1    jruoho     }
    614       1.1    jruoho 
    615   1.1.1.3  christos     return_VOID;
    616   1.1.1.3  christos }
    617   1.1.1.3  christos 
    618   1.1.1.3  christos 
    619   1.1.1.3  christos /*******************************************************************************
    620   1.1.1.3  christos  *
    621  1.1.1.11  christos  * FUNCTION:    AcpiDmGetExternalAndInternalPath
    622  1.1.1.11  christos  *
    623  1.1.1.11  christos  * PARAMETERS:  Node                - Namespace node for object to be added
    624  1.1.1.11  christos  *              ExternalPath        - Will contain the external path of the node
    625  1.1.1.11  christos  *              InternalPath        - Will contain the internal path of the node
    626  1.1.1.11  christos  *
    627  1.1.1.11  christos  * RETURN:      None
    628  1.1.1.11  christos  *
    629  1.1.1.11  christos  * DESCRIPTION: Get the External and Internal path from the given node.
    630  1.1.1.11  christos  *
    631  1.1.1.11  christos  ******************************************************************************/
    632  1.1.1.11  christos 
    633  1.1.1.11  christos static ACPI_STATUS
    634  1.1.1.11  christos AcpiDmGetExternalAndInternalPath (
    635  1.1.1.11  christos     ACPI_NAMESPACE_NODE     *Node,
    636  1.1.1.11  christos     char                    **ExternalPath,
    637  1.1.1.11  christos     char                    **InternalPath)
    638  1.1.1.11  christos {
    639  1.1.1.11  christos     ACPI_STATUS             Status;
    640  1.1.1.11  christos 
    641  1.1.1.11  christos 
    642  1.1.1.11  christos     if (!Node)
    643  1.1.1.11  christos     {
    644  1.1.1.11  christos         return (AE_BAD_PARAMETER);
    645  1.1.1.11  christos     }
    646  1.1.1.11  christos 
    647  1.1.1.11  christos     /* Get the full external and internal pathnames to the node */
    648  1.1.1.11  christos 
    649  1.1.1.11  christos     *ExternalPath = AcpiNsGetExternalPathname (Node);
    650  1.1.1.11  christos     if (!*ExternalPath)
    651  1.1.1.11  christos     {
    652  1.1.1.11  christos         return (AE_BAD_PATHNAME);
    653  1.1.1.11  christos     }
    654  1.1.1.11  christos 
    655  1.1.1.11  christos     Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
    656  1.1.1.11  christos     if (ACPI_FAILURE (Status))
    657  1.1.1.11  christos     {
    658  1.1.1.11  christos         ACPI_FREE (*ExternalPath);
    659  1.1.1.11  christos         return (Status);
    660  1.1.1.11  christos     }
    661  1.1.1.11  christos 
    662  1.1.1.11  christos     return (AE_OK);
    663  1.1.1.11  christos }
    664  1.1.1.11  christos 
    665  1.1.1.11  christos 
    666  1.1.1.11  christos /*******************************************************************************
    667  1.1.1.11  christos  *
    668  1.1.1.11  christos  * FUNCTION:    AcpiDmRemoveRootPrefix
    669  1.1.1.11  christos  *
    670  1.1.1.11  christos  * PARAMETERS:  Path                - Remove Root prefix from this Path
    671  1.1.1.11  christos  *
    672  1.1.1.11  christos  * RETURN:      None
    673  1.1.1.11  christos  *
    674  1.1.1.11  christos  * DESCRIPTION: Remove the root prefix character '\' from Path.
    675  1.1.1.11  christos  *
    676  1.1.1.11  christos  ******************************************************************************/
    677  1.1.1.11  christos 
    678  1.1.1.11  christos static ACPI_STATUS
    679  1.1.1.11  christos AcpiDmRemoveRootPrefix (
    680  1.1.1.11  christos     char                    **Path)
    681  1.1.1.11  christos {
    682  1.1.1.11  christos     char                    *InputPath = *Path;
    683  1.1.1.11  christos 
    684  1.1.1.11  christos 
    685  1.1.1.11  christos     if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
    686  1.1.1.11  christos     {
    687  1.1.1.11  christos         if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
    688  1.1.1.11  christos         {
    689  1.1.1.11  christos             return (AE_ERROR);
    690  1.1.1.11  christos         }
    691  1.1.1.11  christos 
    692  1.1.1.11  christos         *Path = InputPath;
    693  1.1.1.11  christos     }
    694  1.1.1.11  christos 
    695  1.1.1.11  christos     return (AE_OK);
    696  1.1.1.11  christos }
    697  1.1.1.11  christos 
    698  1.1.1.11  christos 
    699  1.1.1.11  christos /*******************************************************************************
    700  1.1.1.11  christos  *
    701   1.1.1.3  christos  * FUNCTION:    AcpiDmAddNodeToExternalList
    702   1.1.1.3  christos  *
    703   1.1.1.3  christos  * PARAMETERS:  Node                - Namespace node for object to be added
    704   1.1.1.3  christos  *              Type                - ACPI object type to be added
    705   1.1.1.3  christos  *              Value               - Arg count if adding a Method object
    706   1.1.1.3  christos  *              Flags               - To be passed to the external object
    707   1.1.1.3  christos  *
    708   1.1.1.3  christos  * RETURN:      None
    709   1.1.1.3  christos  *
    710   1.1.1.3  christos  * DESCRIPTION: Insert a new name into the global list of Externals which
    711   1.1.1.3  christos  *              will in turn be later emitted as an External() declaration
    712   1.1.1.3  christos  *              in the disassembled output.
    713   1.1.1.3  christos  *
    714   1.1.1.3  christos  *              This function handles the case where the referenced name has
    715   1.1.1.3  christos  *              been found in the namespace, but the name originated in a
    716   1.1.1.3  christos  *              table other than the one that is being disassembled (such
    717   1.1.1.3  christos  *              as a table that is added via the iASL -e option).
    718   1.1.1.3  christos  *
    719   1.1.1.3  christos  ******************************************************************************/
    720   1.1.1.3  christos 
    721   1.1.1.3  christos void
    722   1.1.1.3  christos AcpiDmAddNodeToExternalList (
    723   1.1.1.3  christos     ACPI_NAMESPACE_NODE     *Node,
    724   1.1.1.3  christos     UINT8                   Type,
    725   1.1.1.3  christos     UINT32                  Value,
    726   1.1.1.3  christos     UINT16                  Flags)
    727   1.1.1.3  christos {
    728   1.1.1.3  christos     char                    *ExternalPath;
    729   1.1.1.3  christos     char                    *InternalPath;
    730   1.1.1.3  christos     ACPI_STATUS             Status;
    731   1.1.1.3  christos 
    732   1.1.1.3  christos 
    733   1.1.1.3  christos     ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
    734   1.1.1.3  christos 
    735   1.1.1.3  christos     /* Get the full external and internal pathnames to the node */
    736   1.1.1.3  christos 
    737  1.1.1.11  christos     Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
    738   1.1.1.3  christos     if (ACPI_FAILURE (Status))
    739   1.1.1.3  christos     {
    740   1.1.1.3  christos         return_VOID;
    741   1.1.1.3  christos     }
    742   1.1.1.3  christos 
    743   1.1.1.3  christos     /* Remove the root backslash */
    744   1.1.1.3  christos 
    745  1.1.1.11  christos     Status = AcpiDmRemoveRootPrefix (&ExternalPath);
    746  1.1.1.11  christos     if (ACPI_FAILURE (Status))
    747   1.1.1.3  christos     {
    748   1.1.1.3  christos         ACPI_FREE (ExternalPath);
    749  1.1.1.11  christos         ACPI_FREE (InternalPath);
    750  1.1.1.11  christos         return_VOID;
    751   1.1.1.3  christos     }
    752   1.1.1.3  christos 
    753   1.1.1.3  christos     /* Create the new External() declaration node */
    754   1.1.1.3  christos 
    755   1.1.1.3  christos     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
    756   1.1.1.3  christos         Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
    757   1.1.1.3  christos     if (ACPI_FAILURE (Status))
    758   1.1.1.3  christos     {
    759   1.1.1.3  christos         ACPI_FREE (ExternalPath);
    760   1.1.1.3  christos         ACPI_FREE (InternalPath);
    761   1.1.1.3  christos     }
    762   1.1.1.3  christos 
    763   1.1.1.3  christos     return_VOID;
    764   1.1.1.3  christos }
    765   1.1.1.3  christos 
    766   1.1.1.3  christos 
    767   1.1.1.3  christos /*******************************************************************************
    768   1.1.1.3  christos  *
    769   1.1.1.3  christos  * FUNCTION:    AcpiDmAddPathToExternalList
    770   1.1.1.3  christos  *
    771   1.1.1.3  christos  * PARAMETERS:  Path                - External name of the object to be added
    772   1.1.1.3  christos  *              Type                - ACPI object type to be added
    773   1.1.1.3  christos  *              Value               - Arg count if adding a Method object
    774   1.1.1.3  christos  *              Flags               - To be passed to the external object
    775   1.1.1.3  christos  *
    776   1.1.1.3  christos  * RETURN:      None
    777   1.1.1.3  christos  *
    778   1.1.1.3  christos  * DESCRIPTION: Insert a new name into the global list of Externals which
    779   1.1.1.3  christos  *              will in turn be later emitted as an External() declaration
    780   1.1.1.3  christos  *              in the disassembled output.
    781   1.1.1.3  christos  *
    782   1.1.1.3  christos  *              This function currently is used to add externals via a
    783   1.1.1.3  christos  *              reference file (via the -fe iASL option).
    784   1.1.1.3  christos  *
    785   1.1.1.3  christos  ******************************************************************************/
    786   1.1.1.3  christos 
    787   1.1.1.3  christos static void
    788   1.1.1.3  christos AcpiDmAddPathToExternalList (
    789   1.1.1.3  christos     char                    *Path,
    790   1.1.1.3  christos     UINT8                   Type,
    791   1.1.1.3  christos     UINT32                  Value,
    792   1.1.1.3  christos     UINT16                  Flags)
    793   1.1.1.3  christos {
    794   1.1.1.3  christos     char                    *InternalPath;
    795   1.1.1.3  christos     char                    *ExternalPath;
    796   1.1.1.3  christos     ACPI_STATUS             Status;
    797   1.1.1.3  christos 
    798   1.1.1.3  christos 
    799   1.1.1.3  christos     ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
    800   1.1.1.3  christos 
    801   1.1.1.3  christos 
    802   1.1.1.3  christos     if (!Path)
    803   1.1.1.3  christos     {
    804   1.1.1.3  christos         return_VOID;
    805   1.1.1.3  christos     }
    806   1.1.1.3  christos 
    807   1.1.1.3  christos     /* Remove a root backslash if present */
    808   1.1.1.3  christos 
    809   1.1.1.3  christos     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
    810   1.1.1.3  christos     {
    811   1.1.1.3  christos         Path++;
    812   1.1.1.3  christos     }
    813   1.1.1.3  christos 
    814   1.1.1.3  christos     /* Create the internal and external pathnames */
    815   1.1.1.3  christos 
    816   1.1.1.3  christos     Status = AcpiNsInternalizeName (Path, &InternalPath);
    817   1.1.1.3  christos     if (ACPI_FAILURE (Status))
    818   1.1.1.3  christos     {
    819   1.1.1.3  christos         return_VOID;
    820   1.1.1.3  christos     }
    821   1.1.1.3  christos 
    822   1.1.1.3  christos     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
    823   1.1.1.3  christos         NULL, &ExternalPath);
    824   1.1.1.3  christos     if (ACPI_FAILURE (Status))
    825   1.1.1.3  christos     {
    826   1.1.1.3  christos         ACPI_FREE (InternalPath);
    827   1.1.1.3  christos         return_VOID;
    828   1.1.1.3  christos     }
    829   1.1.1.3  christos 
    830   1.1.1.3  christos     /* Create the new External() declaration node */
    831   1.1.1.3  christos 
    832   1.1.1.3  christos     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
    833   1.1.1.3  christos         Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
    834   1.1.1.3  christos     if (ACPI_FAILURE (Status))
    835   1.1.1.3  christos     {
    836   1.1.1.3  christos         ACPI_FREE (ExternalPath);
    837   1.1.1.3  christos         ACPI_FREE (InternalPath);
    838   1.1.1.3  christos     }
    839   1.1.1.3  christos 
    840   1.1.1.3  christos     return_VOID;
    841   1.1.1.3  christos }
    842   1.1.1.3  christos 
    843   1.1.1.3  christos 
    844   1.1.1.3  christos /*******************************************************************************
    845   1.1.1.3  christos  *
    846   1.1.1.3  christos  * FUNCTION:    AcpiDmCreateNewExternal
    847   1.1.1.3  christos  *
    848   1.1.1.3  christos  * PARAMETERS:  ExternalPath        - External path to the object
    849   1.1.1.3  christos  *              InternalPath        - Internal (AML) path to the object
    850   1.1.1.3  christos  *              Type                - ACPI object type to be added
    851   1.1.1.3  christos  *              Value               - Arg count if adding a Method object
    852   1.1.1.3  christos  *              Flags               - To be passed to the external object
    853   1.1.1.3  christos  *
    854   1.1.1.3  christos  * RETURN:      Status
    855   1.1.1.3  christos  *
    856   1.1.1.3  christos  * DESCRIPTION: Common low-level function to insert a new name into the global
    857   1.1.1.3  christos  *              list of Externals which will in turn be later emitted as
    858   1.1.1.3  christos  *              External() declarations in the disassembled output.
    859   1.1.1.3  christos  *
    860   1.1.1.3  christos  *              Note: The external name should not include a root prefix
    861   1.1.1.3  christos  *              (backslash). We do not want External() statements to contain
    862   1.1.1.3  christos  *              a leading '\', as this prevents duplicate external statements
    863   1.1.1.3  christos  *              of the form:
    864   1.1.1.3  christos  *
    865   1.1.1.3  christos  *                  External (\ABCD)
    866   1.1.1.3  christos  *                  External (ABCD)
    867   1.1.1.3  christos  *
    868   1.1.1.3  christos  *              This would cause a compile time error when the disassembled
    869   1.1.1.3  christos  *              output file is recompiled.
    870   1.1.1.3  christos  *
    871   1.1.1.3  christos  *              There are two cases that are handled here. For both, we emit
    872   1.1.1.3  christos  *              an External() statement:
    873   1.1.1.3  christos  *              1) The name was simply not found in the namespace.
    874   1.1.1.3  christos  *              2) The name was found, but it originated in a table other than
    875   1.1.1.3  christos  *              the table that is being disassembled.
    876   1.1.1.3  christos  *
    877   1.1.1.3  christos  ******************************************************************************/
    878   1.1.1.3  christos 
    879   1.1.1.3  christos static ACPI_STATUS
    880   1.1.1.3  christos AcpiDmCreateNewExternal (
    881   1.1.1.3  christos     char                    *ExternalPath,
    882   1.1.1.3  christos     char                    *InternalPath,
    883   1.1.1.3  christos     UINT8                   Type,
    884   1.1.1.3  christos     UINT32                  Value,
    885   1.1.1.3  christos     UINT16                  Flags)
    886   1.1.1.3  christos {
    887   1.1.1.3  christos     ACPI_EXTERNAL_LIST      *NewExternal;
    888   1.1.1.3  christos     ACPI_EXTERNAL_LIST      *NextExternal;
    889   1.1.1.3  christos     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
    890   1.1.1.3  christos 
    891   1.1.1.3  christos 
    892   1.1.1.3  christos     ACPI_FUNCTION_TRACE (DmCreateNewExternal);
    893   1.1.1.3  christos 
    894   1.1.1.3  christos 
    895       1.1    jruoho     /* Check all existing externals to ensure no duplicates */
    896       1.1    jruoho 
    897       1.1    jruoho     NextExternal = AcpiGbl_ExternalList;
    898       1.1    jruoho     while (NextExternal)
    899       1.1    jruoho     {
    900   1.1.1.8  christos         /* Check for duplicates */
    901   1.1.1.8  christos 
    902   1.1.1.6  christos         if (!strcmp (ExternalPath, NextExternal->Path))
    903       1.1    jruoho         {
    904   1.1.1.8  christos             /*
    905   1.1.1.8  christos              * If this external came from an External() opcode, we are
    906   1.1.1.8  christos              * finished with this one. (No need to check any further).
    907   1.1.1.8  christos              */
    908   1.1.1.8  christos             if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
    909       1.1    jruoho             {
    910   1.1.1.8  christos                 return_ACPI_STATUS (AE_ALREADY_EXISTS);
    911       1.1    jruoho             }
    912       1.1    jruoho 
    913       1.1    jruoho             /* Allow upgrade of type from ANY */
    914       1.1    jruoho 
    915   1.1.1.8  christos             else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
    916   1.1.1.8  christos                 (Type != ACPI_TYPE_ANY))
    917       1.1    jruoho             {
    918       1.1    jruoho                 NextExternal->Type = Type;
    919   1.1.1.8  christos             }
    920   1.1.1.8  christos 
    921   1.1.1.8  christos             /* Update the argument count as necessary */
    922   1.1.1.8  christos 
    923   1.1.1.8  christos             if (Value < NextExternal->Value)
    924   1.1.1.8  christos             {
    925       1.1    jruoho                 NextExternal->Value = Value;
    926       1.1    jruoho             }
    927       1.1    jruoho 
    928   1.1.1.8  christos             /* Update flags. */
    929   1.1.1.8  christos 
    930   1.1.1.8  christos             NextExternal->Flags |= Flags;
    931   1.1.1.8  christos             NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
    932   1.1.1.8  christos 
    933   1.1.1.3  christos             return_ACPI_STATUS (AE_ALREADY_EXISTS);
    934       1.1    jruoho         }
    935       1.1    jruoho 
    936       1.1    jruoho         NextExternal = NextExternal->Next;
    937       1.1    jruoho     }
    938       1.1    jruoho 
    939       1.1    jruoho     /* Allocate and init a new External() descriptor */
    940       1.1    jruoho 
    941       1.1    jruoho     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
    942       1.1    jruoho     if (!NewExternal)
    943       1.1    jruoho     {
    944   1.1.1.3  christos         return_ACPI_STATUS (AE_NO_MEMORY);
    945       1.1    jruoho     }
    946       1.1    jruoho 
    947   1.1.1.3  christos     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
    948   1.1.1.3  christos         "Adding external reference node (%s) type [%s]\n",
    949   1.1.1.3  christos         ExternalPath, AcpiUtGetTypeName (Type)));
    950   1.1.1.3  christos 
    951   1.1.1.3  christos     NewExternal->Flags = Flags;
    952   1.1.1.3  christos     NewExternal->Value = Value;
    953       1.1    jruoho     NewExternal->Path = ExternalPath;
    954       1.1    jruoho     NewExternal->Type = Type;
    955   1.1.1.6  christos     NewExternal->Length = (UINT16) strlen (ExternalPath);
    956   1.1.1.3  christos     NewExternal->InternalPath = InternalPath;
    957       1.1    jruoho 
    958   1.1.1.3  christos     /* Link the new descriptor into the global list, alphabetically ordered */
    959       1.1    jruoho 
    960       1.1    jruoho     NextExternal = AcpiGbl_ExternalList;
    961       1.1    jruoho     while (NextExternal)
    962       1.1    jruoho     {
    963   1.1.1.3  christos         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
    964       1.1    jruoho         {
    965       1.1    jruoho             if (PrevExternal)
    966       1.1    jruoho             {
    967       1.1    jruoho                 PrevExternal->Next = NewExternal;
    968       1.1    jruoho             }
    969       1.1    jruoho             else
    970       1.1    jruoho             {
    971       1.1    jruoho                 AcpiGbl_ExternalList = NewExternal;
    972       1.1    jruoho             }
    973       1.1    jruoho 
    974       1.1    jruoho             NewExternal->Next = NextExternal;
    975   1.1.1.3  christos             return_ACPI_STATUS (AE_OK);
    976       1.1    jruoho         }
    977       1.1    jruoho 
    978       1.1    jruoho         PrevExternal = NextExternal;
    979       1.1    jruoho         NextExternal = NextExternal->Next;
    980       1.1    jruoho     }
    981       1.1    jruoho 
    982       1.1    jruoho     if (PrevExternal)
    983       1.1    jruoho     {
    984       1.1    jruoho         PrevExternal->Next = NewExternal;
    985       1.1    jruoho     }
    986       1.1    jruoho     else
    987       1.1    jruoho     {
    988       1.1    jruoho         AcpiGbl_ExternalList = NewExternal;
    989       1.1    jruoho     }
    990   1.1.1.3  christos 
    991   1.1.1.3  christos     return_ACPI_STATUS (AE_OK);
    992       1.1    jruoho }
    993       1.1    jruoho 
    994       1.1    jruoho 
    995       1.1    jruoho /*******************************************************************************
    996       1.1    jruoho  *
    997  1.1.1.11  christos  * FUNCTION:    AcpiDmResolveExternal
    998       1.1    jruoho  *
    999  1.1.1.11  christos  * PARAMETERS:  Path               - Path of the external
   1000  1.1.1.11  christos  *              Type               - Type of the external
   1001  1.1.1.11  christos  *              Node               - Input node for AcpiNsLookup
   1002  1.1.1.11  christos  *
   1003  1.1.1.11  christos  * RETURN:      Status
   1004  1.1.1.11  christos  *
   1005  1.1.1.11  christos  * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
   1006  1.1.1.11  christos  *              If the returned node is an external and has the same type
   1007  1.1.1.11  christos  *              we assume that it was either an existing external or a
   1008  1.1.1.11  christos  *
   1009  1.1.1.11  christos  ******************************************************************************/
   1010  1.1.1.11  christos 
   1011  1.1.1.11  christos static ACPI_STATUS
   1012  1.1.1.11  christos AcpiDmResolveExternal (
   1013  1.1.1.11  christos     char                    *Path,
   1014  1.1.1.11  christos     UINT8                   Type,
   1015  1.1.1.11  christos     ACPI_NAMESPACE_NODE     **Node)
   1016  1.1.1.11  christos {
   1017  1.1.1.11  christos     ACPI_STATUS             Status;
   1018  1.1.1.11  christos 
   1019  1.1.1.11  christos 
   1020  1.1.1.11  christos     Status = AcpiNsLookup (NULL, Path, Type,
   1021  1.1.1.11  christos         ACPI_IMODE_LOAD_PASS1,
   1022  1.1.1.11  christos         ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
   1023  1.1.1.11  christos         NULL, Node);
   1024  1.1.1.11  christos 
   1025  1.1.1.11  christos     if (!Node)
   1026  1.1.1.11  christos     {
   1027  1.1.1.11  christos         ACPI_EXCEPTION ((AE_INFO, Status,
   1028  1.1.1.11  christos             "while adding external to namespace [%s]", Path));
   1029  1.1.1.11  christos     }
   1030  1.1.1.11  christos 
   1031  1.1.1.11  christos     /* Note the asl code "external(a) external(a)" is acceptable ASL */
   1032  1.1.1.11  christos 
   1033  1.1.1.11  christos     else if ((*Node)->Type == Type &&
   1034  1.1.1.11  christos         (*Node)->Flags & ANOBJ_IS_EXTERNAL)
   1035  1.1.1.11  christos     {
   1036  1.1.1.11  christos         return (AE_OK);
   1037  1.1.1.11  christos     }
   1038  1.1.1.11  christos     else
   1039  1.1.1.11  christos     {
   1040  1.1.1.11  christos         ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
   1041  1.1.1.11  christos             "[%s] has conflicting declarations", Path));
   1042  1.1.1.11  christos     }
   1043  1.1.1.11  christos 
   1044  1.1.1.11  christos     return (AE_ERROR);
   1045  1.1.1.11  christos }
   1046  1.1.1.11  christos 
   1047  1.1.1.11  christos 
   1048  1.1.1.11  christos /*******************************************************************************
   1049  1.1.1.11  christos  *
   1050  1.1.1.11  christos  * FUNCTION:    AcpiDmCreateSubobjectForExternal
   1051  1.1.1.11  christos  *
   1052  1.1.1.11  christos  * PARAMETERS:  Type                  - Type of the external
   1053  1.1.1.11  christos  *              Node                  - Namespace node from AcpiNsLookup
   1054  1.1.1.11  christos  *              ParamCount            - Value to be used for Method
   1055       1.1    jruoho  *
   1056       1.1    jruoho  * RETURN:      None
   1057       1.1    jruoho  *
   1058  1.1.1.11  christos  * DESCRIPTION: Add one external to the namespace. Allows external to be
   1059       1.1    jruoho  *              "resolved".
   1060       1.1    jruoho  *
   1061       1.1    jruoho  ******************************************************************************/
   1062       1.1    jruoho 
   1063       1.1    jruoho void
   1064  1.1.1.11  christos AcpiDmCreateSubobjectForExternal (
   1065  1.1.1.11  christos     UINT8                   Type,
   1066  1.1.1.11  christos     ACPI_NAMESPACE_NODE     **Node,
   1067  1.1.1.11  christos     UINT32                  ParamCount)
   1068       1.1    jruoho {
   1069   1.1.1.3  christos     ACPI_OPERAND_OBJECT     *ObjDesc;
   1070       1.1    jruoho 
   1071       1.1    jruoho 
   1072  1.1.1.11  christos     switch (Type)
   1073       1.1    jruoho     {
   1074  1.1.1.11  christos     case ACPI_TYPE_METHOD:
   1075       1.1    jruoho 
   1076  1.1.1.11  christos         /* For methods, we need to save the argument count */
   1077       1.1    jruoho 
   1078  1.1.1.11  christos         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
   1079  1.1.1.11  christos         ObjDesc->Method.ParamCount = (UINT8) ParamCount;
   1080  1.1.1.11  christos         (*Node)->Object = ObjDesc;
   1081  1.1.1.11  christos         break;
   1082   1.1.1.3  christos 
   1083  1.1.1.11  christos     case ACPI_TYPE_REGION:
   1084   1.1.1.3  christos 
   1085  1.1.1.11  christos         /* Regions require a region sub-object */
   1086       1.1    jruoho 
   1087  1.1.1.11  christos         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
   1088  1.1.1.11  christos         ObjDesc->Region.Node = *Node;
   1089  1.1.1.11  christos         (*Node)->Object = ObjDesc;
   1090  1.1.1.11  christos         break;
   1091   1.1.1.3  christos 
   1092  1.1.1.11  christos     default:
   1093   1.1.1.3  christos 
   1094  1.1.1.11  christos         break;
   1095  1.1.1.11  christos     }
   1096  1.1.1.11  christos }
   1097   1.1.1.3  christos 
   1098   1.1.1.3  christos 
   1099  1.1.1.11  christos /*******************************************************************************
   1100  1.1.1.11  christos  *
   1101  1.1.1.11  christos  * FUNCTION:    AcpiDmAddOneExternalToNamespace
   1102  1.1.1.11  christos  *
   1103  1.1.1.11  christos  * PARAMETERS:  Path                   - External parse object
   1104  1.1.1.11  christos  *              Type                   - Type of parse object
   1105  1.1.1.11  christos  *              ParamCount             - External method parameter count
   1106  1.1.1.11  christos  *
   1107  1.1.1.11  christos  * RETURN:      None
   1108  1.1.1.11  christos  *
   1109  1.1.1.11  christos  * DESCRIPTION: Add one external to the namespace by resolvign the external
   1110  1.1.1.11  christos  *              (by performing a namespace lookup) and annotating the resulting
   1111  1.1.1.15  christos  *              namespace node with the appropriate information if the type
   1112  1.1.1.11  christos  *              is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
   1113  1.1.1.11  christos  *
   1114  1.1.1.11  christos  ******************************************************************************/
   1115  1.1.1.11  christos 
   1116  1.1.1.11  christos void
   1117  1.1.1.11  christos AcpiDmAddOneExternalToNamespace (
   1118  1.1.1.11  christos     char                    *Path,
   1119  1.1.1.11  christos     UINT8                   Type,
   1120  1.1.1.11  christos     UINT32                  ParamCount)
   1121  1.1.1.11  christos {
   1122  1.1.1.11  christos     ACPI_STATUS             Status;
   1123  1.1.1.11  christos     ACPI_NAMESPACE_NODE     *Node;
   1124   1.1.1.3  christos 
   1125       1.1    jruoho 
   1126  1.1.1.11  christos     Status = AcpiDmResolveExternal (Path, Type, &Node);
   1127  1.1.1.11  christos 
   1128  1.1.1.11  christos     if (ACPI_FAILURE (Status))
   1129  1.1.1.11  christos     {
   1130  1.1.1.11  christos         return;
   1131  1.1.1.11  christos     }
   1132  1.1.1.11  christos 
   1133  1.1.1.11  christos     AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
   1134  1.1.1.11  christos 
   1135  1.1.1.11  christos }
   1136  1.1.1.11  christos 
   1137  1.1.1.11  christos 
   1138  1.1.1.11  christos /*******************************************************************************
   1139  1.1.1.11  christos  *
   1140  1.1.1.11  christos  * FUNCTION:    AcpiDmAddExternalListToNamespace
   1141  1.1.1.11  christos  *
   1142  1.1.1.11  christos  * PARAMETERS:  None
   1143  1.1.1.11  christos  *
   1144  1.1.1.11  christos  * RETURN:      None
   1145  1.1.1.11  christos  *
   1146  1.1.1.11  christos  * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
   1147  1.1.1.11  christos  *              Allows externals to be "resolved".
   1148  1.1.1.11  christos  *
   1149  1.1.1.11  christos  ******************************************************************************/
   1150  1.1.1.11  christos 
   1151  1.1.1.11  christos void
   1152  1.1.1.11  christos AcpiDmAddExternalListToNamespace (
   1153  1.1.1.11  christos     void)
   1154  1.1.1.11  christos {
   1155  1.1.1.11  christos     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
   1156  1.1.1.11  christos 
   1157  1.1.1.11  christos 
   1158  1.1.1.11  christos     while (External)
   1159  1.1.1.11  christos     {
   1160  1.1.1.11  christos         AcpiDmAddOneExternalToNamespace (External->InternalPath,
   1161  1.1.1.11  christos             External->Type, External->Value);
   1162       1.1    jruoho         External = External->Next;
   1163       1.1    jruoho     }
   1164       1.1    jruoho }
   1165       1.1    jruoho 
   1166       1.1    jruoho 
   1167       1.1    jruoho /*******************************************************************************
   1168       1.1    jruoho  *
   1169  1.1.1.11  christos  * FUNCTION:    AcpiDmGetUnresolvedExternalMethodCount
   1170       1.1    jruoho  *
   1171       1.1    jruoho  * PARAMETERS:  None
   1172       1.1    jruoho  *
   1173  1.1.1.11  christos  * RETURN:      The number of unresolved control method externals in the
   1174  1.1.1.11  christos  *              external list
   1175       1.1    jruoho  *
   1176  1.1.1.11  christos  * DESCRIPTION: Return the number of unresolved external methods that have been
   1177  1.1.1.11  christos  *              generated. If any unresolved control method externals have been
   1178  1.1.1.11  christos  *              found, we must re-parse the entire definition block with the new
   1179  1.1.1.11  christos  *              information (number of arguments for the methods.)
   1180  1.1.1.11  christos  *              This is limitation of AML, we don't know the number of arguments
   1181  1.1.1.11  christos  *              from the control method invocation itself.
   1182  1.1.1.11  christos  *
   1183  1.1.1.11  christos  *              Note: resolved external control methods are external control
   1184  1.1.1.11  christos  *              methods encoded with the AML_EXTERNAL_OP bytecode within the
   1185  1.1.1.11  christos  *              AML being disassembled.
   1186       1.1    jruoho  *
   1187       1.1    jruoho  ******************************************************************************/
   1188       1.1    jruoho 
   1189       1.1    jruoho UINT32
   1190  1.1.1.11  christos AcpiDmGetUnresolvedExternalMethodCount (
   1191       1.1    jruoho     void)
   1192       1.1    jruoho {
   1193       1.1    jruoho     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
   1194       1.1    jruoho     UINT32                  Count = 0;
   1195       1.1    jruoho 
   1196       1.1    jruoho 
   1197       1.1    jruoho     while (External)
   1198       1.1    jruoho     {
   1199  1.1.1.11  christos         if (External->Type == ACPI_TYPE_METHOD &&
   1200  1.1.1.11  christos             !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
   1201       1.1    jruoho         {
   1202       1.1    jruoho             Count++;
   1203       1.1    jruoho         }
   1204       1.1    jruoho 
   1205       1.1    jruoho         External = External->Next;
   1206       1.1    jruoho     }
   1207       1.1    jruoho 
   1208       1.1    jruoho     return (Count);
   1209       1.1    jruoho }
   1210       1.1    jruoho 
   1211       1.1    jruoho 
   1212       1.1    jruoho /*******************************************************************************
   1213       1.1    jruoho  *
   1214       1.1    jruoho  * FUNCTION:    AcpiDmClearExternalList
   1215       1.1    jruoho  *
   1216       1.1    jruoho  * PARAMETERS:  None
   1217       1.1    jruoho  *
   1218       1.1    jruoho  * RETURN:      None
   1219       1.1    jruoho  *
   1220       1.1    jruoho  * DESCRIPTION: Free the entire External info list
   1221       1.1    jruoho  *
   1222       1.1    jruoho  ******************************************************************************/
   1223       1.1    jruoho 
   1224       1.1    jruoho void
   1225       1.1    jruoho AcpiDmClearExternalList (
   1226       1.1    jruoho     void)
   1227       1.1    jruoho {
   1228       1.1    jruoho     ACPI_EXTERNAL_LIST      *NextExternal;
   1229       1.1    jruoho 
   1230       1.1    jruoho 
   1231       1.1    jruoho     while (AcpiGbl_ExternalList)
   1232       1.1    jruoho     {
   1233       1.1    jruoho         NextExternal = AcpiGbl_ExternalList->Next;
   1234       1.1    jruoho         ACPI_FREE (AcpiGbl_ExternalList->Path);
   1235       1.1    jruoho         ACPI_FREE (AcpiGbl_ExternalList);
   1236       1.1    jruoho         AcpiGbl_ExternalList = NextExternal;
   1237       1.1    jruoho     }
   1238       1.1    jruoho }
   1239       1.1    jruoho 
   1240       1.1    jruoho 
   1241       1.1    jruoho /*******************************************************************************
   1242       1.1    jruoho  *
   1243       1.1    jruoho  * FUNCTION:    AcpiDmEmitExternals
   1244       1.1    jruoho  *
   1245       1.1    jruoho  * PARAMETERS:  None
   1246       1.1    jruoho  *
   1247       1.1    jruoho  * RETURN:      None
   1248       1.1    jruoho  *
   1249       1.1    jruoho  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
   1250       1.1    jruoho  *              the global external info list.
   1251       1.1    jruoho  *
   1252       1.1    jruoho  ******************************************************************************/
   1253       1.1    jruoho 
   1254       1.1    jruoho void
   1255       1.1    jruoho AcpiDmEmitExternals (
   1256       1.1    jruoho     void)
   1257       1.1    jruoho {
   1258       1.1    jruoho     ACPI_EXTERNAL_LIST      *NextExternal;
   1259       1.1    jruoho 
   1260       1.1    jruoho 
   1261       1.1    jruoho     if (!AcpiGbl_ExternalList)
   1262       1.1    jruoho     {
   1263       1.1    jruoho         return;
   1264       1.1    jruoho     }
   1265       1.1    jruoho 
   1266       1.1    jruoho     /*
   1267   1.1.1.3  christos      * Determine the number of control methods in the external list, and
   1268   1.1.1.3  christos      * also how many of those externals were resolved via the namespace.
   1269       1.1    jruoho      */
   1270   1.1.1.3  christos     NextExternal = AcpiGbl_ExternalList;
   1271   1.1.1.3  christos     while (NextExternal)
   1272       1.1    jruoho     {
   1273   1.1.1.3  christos         if (NextExternal->Type == ACPI_TYPE_METHOD)
   1274   1.1.1.3  christos         {
   1275   1.1.1.3  christos             AcpiGbl_NumExternalMethods++;
   1276   1.1.1.3  christos             if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
   1277   1.1.1.3  christos             {
   1278   1.1.1.3  christos                 AcpiGbl_ResolvedExternalMethods++;
   1279   1.1.1.3  christos             }
   1280   1.1.1.3  christos         }
   1281   1.1.1.3  christos 
   1282   1.1.1.3  christos         NextExternal = NextExternal->Next;
   1283   1.1.1.3  christos     }
   1284       1.1    jruoho 
   1285   1.1.1.3  christos     /* Check if any control methods were unresolved */
   1286   1.1.1.3  christos 
   1287   1.1.1.3  christos     AcpiDmUnresolvedWarning (1);
   1288   1.1.1.3  christos 
   1289  1.1.1.14  christos     if (AslGbl_ExternalRefFilename)
   1290   1.1.1.3  christos     {
   1291   1.1.1.3  christos         AcpiOsPrintf (
   1292   1.1.1.8  christos             "    /*\n     * External declarations were imported from\n"
   1293   1.1.1.8  christos             "     * a reference file -- %s\n     */\n\n",
   1294  1.1.1.14  christos             AslGbl_ExternalRefFilename);
   1295   1.1.1.3  christos     }
   1296   1.1.1.3  christos 
   1297   1.1.1.3  christos     /*
   1298   1.1.1.8  christos      * Walk and emit the list of externals found during the AML parsing
   1299   1.1.1.3  christos      */
   1300   1.1.1.3  christos     while (AcpiGbl_ExternalList)
   1301   1.1.1.3  christos     {
   1302   1.1.1.3  christos         if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
   1303   1.1.1.3  christos         {
   1304   1.1.1.8  christos             AcpiOsPrintf ("    External (%s%s)",
   1305   1.1.1.3  christos                 AcpiGbl_ExternalList->Path,
   1306   1.1.1.3  christos                 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
   1307   1.1.1.3  christos 
   1308   1.1.1.8  christos             /* Check for "unresolved" method reference */
   1309   1.1.1.3  christos 
   1310   1.1.1.8  christos             if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
   1311   1.1.1.8  christos                 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
   1312   1.1.1.3  christos             {
   1313   1.1.1.8  christos                 AcpiOsPrintf ("    // Warning: Unknown method, "
   1314   1.1.1.8  christos                     "guessing %u arguments",
   1315   1.1.1.3  christos                     AcpiGbl_ExternalList->Value);
   1316   1.1.1.3  christos             }
   1317   1.1.1.8  christos 
   1318   1.1.1.8  christos             /* Check for external from a external references file */
   1319   1.1.1.8  christos 
   1320   1.1.1.8  christos             else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
   1321   1.1.1.8  christos             {
   1322   1.1.1.8  christos                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
   1323   1.1.1.8  christos                 {
   1324   1.1.1.8  christos                     AcpiOsPrintf ("    // %u Arguments",
   1325   1.1.1.8  christos                         AcpiGbl_ExternalList->Value);
   1326   1.1.1.8  christos                 }
   1327   1.1.1.8  christos 
   1328   1.1.1.8  christos                 AcpiOsPrintf ("    // From external reference file");
   1329   1.1.1.8  christos             }
   1330   1.1.1.8  christos 
   1331   1.1.1.8  christos             /* This is the normal external case */
   1332   1.1.1.8  christos 
   1333   1.1.1.3  christos             else
   1334   1.1.1.3  christos             {
   1335   1.1.1.8  christos                 /* For methods, add a comment with the number of arguments */
   1336   1.1.1.8  christos 
   1337   1.1.1.8  christos                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
   1338   1.1.1.8  christos                 {
   1339   1.1.1.8  christos                     AcpiOsPrintf ("    // %u Arguments",
   1340   1.1.1.8  christos                         AcpiGbl_ExternalList->Value);
   1341   1.1.1.8  christos                 }
   1342   1.1.1.3  christos             }
   1343   1.1.1.8  christos 
   1344  1.1.1.11  christos             if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
   1345  1.1.1.11  christos             {
   1346  1.1.1.11  christos                 AcpiOsPrintf ("%s", ExternalConflictMessage);
   1347  1.1.1.11  christos                 AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
   1348  1.1.1.11  christos             }
   1349   1.1.1.8  christos             AcpiOsPrintf ("\n");
   1350       1.1    jruoho         }
   1351       1.1    jruoho 
   1352       1.1    jruoho         /* Free this external info block and move on to next external */
   1353       1.1    jruoho 
   1354       1.1    jruoho         NextExternal = AcpiGbl_ExternalList->Next;
   1355   1.1.1.3  christos         if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
   1356       1.1    jruoho         {
   1357       1.1    jruoho             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
   1358       1.1    jruoho         }
   1359       1.1    jruoho 
   1360       1.1    jruoho         ACPI_FREE (AcpiGbl_ExternalList->Path);
   1361       1.1    jruoho         ACPI_FREE (AcpiGbl_ExternalList);
   1362       1.1    jruoho         AcpiGbl_ExternalList = NextExternal;
   1363       1.1    jruoho     }
   1364       1.1    jruoho 
   1365       1.1    jruoho     AcpiOsPrintf ("\n");
   1366       1.1    jruoho }
   1367       1.1    jruoho 
   1368   1.1.1.3  christos 
   1369   1.1.1.3  christos /*******************************************************************************
   1370   1.1.1.3  christos  *
   1371  1.1.1.11  christos  * FUNCTION:    AcpiDmMarkExternalConflict
   1372  1.1.1.11  christos  *
   1373  1.1.1.11  christos  * PARAMETERS:  Path          - Namepath to search
   1374  1.1.1.11  christos  *
   1375  1.1.1.11  christos  * RETURN:      ExternalList
   1376  1.1.1.11  christos  *
   1377  1.1.1.11  christos  * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
   1378  1.1.1.11  christos  *
   1379  1.1.1.11  christos  ******************************************************************************/
   1380  1.1.1.11  christos 
   1381  1.1.1.11  christos void
   1382  1.1.1.11  christos AcpiDmMarkExternalConflict (
   1383  1.1.1.11  christos     ACPI_NAMESPACE_NODE     *Node)
   1384  1.1.1.11  christos {
   1385  1.1.1.11  christos     ACPI_EXTERNAL_LIST      *ExternalList = AcpiGbl_ExternalList;
   1386  1.1.1.11  christos     char                    *ExternalPath;
   1387  1.1.1.11  christos     char                    *InternalPath;
   1388  1.1.1.11  christos     char                    *Temp;
   1389  1.1.1.11  christos     ACPI_STATUS             Status;
   1390  1.1.1.11  christos 
   1391  1.1.1.11  christos 
   1392  1.1.1.11  christos     ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
   1393  1.1.1.11  christos 
   1394  1.1.1.11  christos 
   1395  1.1.1.11  christos     if (Node->Flags & ANOBJ_IS_EXTERNAL)
   1396  1.1.1.11  christos     {
   1397  1.1.1.11  christos         return_VOID;
   1398  1.1.1.11  christos     }
   1399  1.1.1.11  christos 
   1400  1.1.1.11  christos     /* Get the full external and internal pathnames to the node */
   1401  1.1.1.11  christos 
   1402  1.1.1.11  christos     Status = AcpiDmGetExternalAndInternalPath (Node,
   1403  1.1.1.11  christos         &ExternalPath, &InternalPath);
   1404  1.1.1.11  christos     if (ACPI_FAILURE (Status))
   1405  1.1.1.11  christos     {
   1406  1.1.1.11  christos         return_VOID;
   1407  1.1.1.11  christos     }
   1408  1.1.1.11  christos 
   1409  1.1.1.11  christos     /* Remove the root backslash */
   1410  1.1.1.11  christos 
   1411  1.1.1.11  christos     Status = AcpiDmRemoveRootPrefix (&InternalPath);
   1412  1.1.1.11  christos     if (ACPI_FAILURE (Status))
   1413  1.1.1.11  christos     {
   1414  1.1.1.11  christos         ACPI_FREE (InternalPath);
   1415  1.1.1.11  christos         ACPI_FREE (ExternalPath);
   1416  1.1.1.11  christos         return_VOID;
   1417  1.1.1.11  christos     }
   1418  1.1.1.11  christos 
   1419  1.1.1.11  christos     while (ExternalList)
   1420  1.1.1.11  christos     {
   1421  1.1.1.11  christos         Temp = ExternalList->InternalPath;
   1422  1.1.1.11  christos         if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) &&
   1423  1.1.1.11  christos             (ExternalList->InternalPath[1]))
   1424  1.1.1.11  christos         {
   1425  1.1.1.11  christos             Temp++;
   1426  1.1.1.11  christos         }
   1427  1.1.1.11  christos 
   1428  1.1.1.11  christos         if (!strcmp (ExternalList->InternalPath, InternalPath))
   1429  1.1.1.11  christos         {
   1430  1.1.1.11  christos             ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
   1431  1.1.1.11  christos         }
   1432  1.1.1.11  christos         ExternalList = ExternalList->Next;
   1433  1.1.1.11  christos     }
   1434  1.1.1.11  christos 
   1435  1.1.1.11  christos     ACPI_FREE (InternalPath);
   1436  1.1.1.11  christos     ACPI_FREE (ExternalPath);
   1437  1.1.1.11  christos 
   1438  1.1.1.11  christos     return_VOID;
   1439  1.1.1.11  christos }
   1440  1.1.1.11  christos 
   1441  1.1.1.11  christos 
   1442  1.1.1.11  christos /*******************************************************************************
   1443  1.1.1.11  christos  *
   1444  1.1.1.11  christos  * FUNCTION:    AcpiDmConflictingDeclaration
   1445  1.1.1.11  christos  *
   1446  1.1.1.11  christos  * PARAMETERS:  Path                - Path with conflicting declaration
   1447  1.1.1.11  christos  *
   1448  1.1.1.11  christos  * RETURN:      None
   1449  1.1.1.11  christos  *
   1450  1.1.1.11  christos  * DESCRIPTION: Emit a warning when printing conflicting ASL external
   1451  1.1.1.11  christos  *              declarations.
   1452  1.1.1.11  christos  *
   1453  1.1.1.11  christos  ******************************************************************************/
   1454  1.1.1.11  christos 
   1455  1.1.1.11  christos static void
   1456  1.1.1.11  christos AcpiDmConflictingDeclaration (
   1457  1.1.1.11  christos     char                    *Path)
   1458  1.1.1.11  christos {
   1459  1.1.1.11  christos     fprintf (stderr,
   1460  1.1.1.11  christos         " Warning - Emitting ASL code \"External (%s)\"\n"
   1461  1.1.1.11  christos         "           This is a conflicting declaration with some "
   1462  1.1.1.11  christos         "other declaration within the ASL code.\n"
   1463  1.1.1.11  christos         "           This external declaration may need to be "
   1464  1.1.1.11  christos         "deleted in order to recompile the dsl file.\n\n",
   1465  1.1.1.11  christos         Path);
   1466  1.1.1.11  christos }
   1467  1.1.1.11  christos 
   1468  1.1.1.11  christos 
   1469  1.1.1.11  christos /*******************************************************************************
   1470  1.1.1.11  christos  *
   1471  1.1.1.10  christos  * FUNCTION:    AcpiDmEmitExternal
   1472  1.1.1.10  christos  *
   1473  1.1.1.10  christos  * PARAMETERS:  Op                  External Parse Object
   1474  1.1.1.10  christos  *
   1475  1.1.1.10  christos  * RETURN:      None
   1476  1.1.1.10  christos  *
   1477  1.1.1.10  christos  * DESCRIPTION: Emit an External() ASL statement for the current External
   1478  1.1.1.11  christos  *              parse object. Note: External Ops are named types so the
   1479  1.1.1.11  christos  *              namepath is contained within NameOp->Name.Path.
   1480  1.1.1.10  christos  *
   1481  1.1.1.10  christos  ******************************************************************************/
   1482  1.1.1.10  christos 
   1483  1.1.1.10  christos void
   1484  1.1.1.10  christos AcpiDmEmitExternal (
   1485  1.1.1.10  christos     ACPI_PARSE_OBJECT       *NameOp,
   1486  1.1.1.10  christos     ACPI_PARSE_OBJECT       *TypeOp)
   1487  1.1.1.10  christos {
   1488  1.1.1.10  christos     AcpiOsPrintf ("External (");
   1489  1.1.1.11  christos     AcpiDmNamestring (NameOp->Named.Path);
   1490  1.1.1.11  christos     AcpiOsPrintf ("%s)",
   1491  1.1.1.10  christos         AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
   1492  1.1.1.11  christos     AcpiDmCheckForExternalConflict (NameOp->Named.Path);
   1493  1.1.1.11  christos     AcpiOsPrintf ("\n");
   1494  1.1.1.10  christos }
   1495  1.1.1.10  christos 
   1496  1.1.1.10  christos 
   1497  1.1.1.10  christos /*******************************************************************************
   1498  1.1.1.10  christos  *
   1499  1.1.1.11  christos  * FUNCTION:    AcpiDmCheckForExternalConflict
   1500  1.1.1.11  christos  *
   1501  1.1.1.11  christos  * PARAMETERS:  Path                - Path to check
   1502  1.1.1.11  christos  *
   1503  1.1.1.11  christos  * RETURN:      None
   1504  1.1.1.11  christos  *
   1505  1.1.1.11  christos  * DESCRIPTION: Search the External List to see if the input Path has a
   1506  1.1.1.11  christos  *              conflicting declaration.
   1507  1.1.1.11  christos  *
   1508  1.1.1.11  christos  ******************************************************************************/
   1509  1.1.1.11  christos 
   1510  1.1.1.11  christos static void
   1511  1.1.1.11  christos AcpiDmCheckForExternalConflict (
   1512  1.1.1.11  christos     char                    *Path)
   1513  1.1.1.11  christos {
   1514  1.1.1.11  christos     ACPI_EXTERNAL_LIST      *ExternalList = AcpiGbl_ExternalList;
   1515  1.1.1.11  christos     char                    *ListItemPath;
   1516  1.1.1.11  christos     char                    *InputPath;
   1517  1.1.1.11  christos 
   1518  1.1.1.11  christos 
   1519  1.1.1.11  christos     if (!Path)
   1520  1.1.1.11  christos     {
   1521  1.1.1.11  christos         return;
   1522  1.1.1.11  christos     }
   1523  1.1.1.11  christos 
   1524  1.1.1.11  christos     /* Move past the root prefix '\' */
   1525  1.1.1.11  christos 
   1526  1.1.1.11  christos     InputPath = Path;
   1527  1.1.1.11  christos     if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
   1528  1.1.1.11  christos     {
   1529  1.1.1.11  christos         InputPath++;
   1530  1.1.1.11  christos     }
   1531  1.1.1.11  christos 
   1532  1.1.1.11  christos     while (ExternalList)
   1533  1.1.1.11  christos     {
   1534  1.1.1.11  christos         ListItemPath = ExternalList->Path;
   1535  1.1.1.11  christos         if (ListItemPath)
   1536  1.1.1.11  christos         {
   1537  1.1.1.11  christos             /* Move past the root prefix '\' */
   1538  1.1.1.11  christos 
   1539  1.1.1.11  christos             if ((*ListItemPath == AML_ROOT_PREFIX) &&
   1540  1.1.1.11  christos                 ListItemPath[1])
   1541  1.1.1.11  christos             {
   1542  1.1.1.11  christos                 ListItemPath++;
   1543  1.1.1.11  christos             }
   1544  1.1.1.11  christos 
   1545  1.1.1.11  christos             if (!strcmp (ListItemPath, InputPath) &&
   1546  1.1.1.11  christos                 (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
   1547  1.1.1.11  christos             {
   1548  1.1.1.11  christos                 AcpiOsPrintf ("%s", ExternalConflictMessage);
   1549  1.1.1.11  christos                 AcpiDmConflictingDeclaration (Path);
   1550  1.1.1.11  christos 
   1551  1.1.1.11  christos                 return;
   1552  1.1.1.11  christos             }
   1553  1.1.1.11  christos         }
   1554  1.1.1.11  christos         ExternalList = ExternalList->Next;
   1555  1.1.1.11  christos     }
   1556  1.1.1.11  christos }
   1557  1.1.1.11  christos /*******************************************************************************
   1558  1.1.1.11  christos  *
   1559   1.1.1.3  christos  * FUNCTION:    AcpiDmUnresolvedWarning
   1560   1.1.1.3  christos  *
   1561   1.1.1.3  christos  * PARAMETERS:  Type                - Where to output the warning.
   1562   1.1.1.3  christos  *                                    0 means write to stderr
   1563   1.1.1.3  christos  *                                    1 means write to AcpiOsPrintf
   1564   1.1.1.3  christos  *
   1565   1.1.1.3  christos  * RETURN:      None
   1566   1.1.1.3  christos  *
   1567   1.1.1.3  christos  * DESCRIPTION: Issue warning message if there are unresolved external control
   1568   1.1.1.3  christos  *              methods within the disassembly.
   1569   1.1.1.3  christos  *
   1570   1.1.1.3  christos  ******************************************************************************/
   1571   1.1.1.3  christos 
   1572  1.1.1.11  christos /*
   1573   1.1.1.3  christos Summary of the external control method problem:
   1574   1.1.1.3  christos 
   1575   1.1.1.3  christos When the -e option is used with disassembly, the various SSDTs are simply
   1576   1.1.1.3  christos loaded into a global namespace for the disassembler to use in order to
   1577   1.1.1.3  christos resolve control method references (invocations).
   1578   1.1.1.3  christos 
   1579   1.1.1.3  christos The disassembler tracks any such references, and will emit an External()
   1580   1.1.1.3  christos statement for these types of methods, with the proper number of arguments .
   1581   1.1.1.3  christos 
   1582   1.1.1.3  christos Without the SSDTs, the AML does not contain enough information to properly
   1583   1.1.1.3  christos disassemble the control method invocation -- because the disassembler does
   1584   1.1.1.3  christos not know how many arguments to parse.
   1585   1.1.1.3  christos 
   1586   1.1.1.3  christos An example: Assume we have two control methods. ABCD has one argument, and
   1587   1.1.1.3  christos EFGH has zero arguments. Further, we have two additional control methods
   1588   1.1.1.3  christos that invoke ABCD and EFGH, named T1 and T2:
   1589   1.1.1.3  christos 
   1590   1.1.1.3  christos     Method (ABCD, 1)
   1591   1.1.1.3  christos     {
   1592   1.1.1.3  christos     }
   1593   1.1.1.3  christos     Method (EFGH, 0)
   1594   1.1.1.3  christos     {
   1595   1.1.1.3  christos     }
   1596   1.1.1.3  christos     Method (T1)
   1597   1.1.1.3  christos     {
   1598   1.1.1.3  christos         ABCD (Add (2, 7, Local0))
   1599   1.1.1.3  christos     }
   1600   1.1.1.3  christos     Method (T2)
   1601   1.1.1.3  christos     {
   1602   1.1.1.3  christos         EFGH ()
   1603   1.1.1.3  christos         Add (2, 7, Local0)
   1604   1.1.1.3  christos     }
   1605   1.1.1.3  christos 
   1606   1.1.1.3  christos Here is the AML code that is generated for T1 and T2:
   1607   1.1.1.3  christos 
   1608   1.1.1.3  christos      185:      Method (T1)
   1609   1.1.1.3  christos 
   1610   1.1.1.3  christos 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
   1611   1.1.1.3  christos 
   1612   1.1.1.3  christos      186:      {
   1613   1.1.1.3  christos      187:          ABCD (Add (2, 7, Local0))
   1614   1.1.1.3  christos 
   1615   1.1.1.3  christos 00000353:  41 42 43 44 ............    "ABCD"
   1616   1.1.1.3  christos 00000357:  72 0A 02 0A 07 60 ......    "r....`"
   1617   1.1.1.3  christos 
   1618   1.1.1.3  christos      188:      }
   1619   1.1.1.3  christos 
   1620   1.1.1.3  christos      190:      Method (T2)
   1621   1.1.1.3  christos 
   1622   1.1.1.3  christos 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
   1623   1.1.1.3  christos 
   1624   1.1.1.3  christos      191:      {
   1625   1.1.1.3  christos      192:          EFGH ()
   1626   1.1.1.3  christos 
   1627   1.1.1.3  christos 00000364:  45 46 47 48 ............    "EFGH"
   1628   1.1.1.3  christos 
   1629   1.1.1.3  christos      193:          Add (2, 7, Local0)
   1630   1.1.1.3  christos 
   1631   1.1.1.3  christos 00000368:  72 0A 02 0A 07 60 ......    "r....`"
   1632   1.1.1.3  christos      194:      }
   1633   1.1.1.3  christos 
   1634   1.1.1.3  christos Note that the AML code for T1 and T2 is essentially identical. When
   1635   1.1.1.3  christos disassembling this code, the methods ABCD and EFGH must be known to the
   1636   1.1.1.3  christos disassembler, otherwise it does not know how to handle the method invocations.
   1637   1.1.1.3  christos 
   1638   1.1.1.3  christos In other words, if ABCD and EFGH are actually external control methods
   1639   1.1.1.3  christos appearing in an SSDT, the disassembler does not know what to do unless
   1640   1.1.1.3  christos the owning SSDT has been loaded via the -e option.
   1641  1.1.1.11  christos */
   1642   1.1.1.3  christos 
   1643   1.1.1.8  christos static char             ExternalWarningPart1[600];
   1644   1.1.1.8  christos static char             ExternalWarningPart2[400];
   1645   1.1.1.8  christos static char             ExternalWarningPart3[400];
   1646   1.1.1.8  christos static char             ExternalWarningPart4[200];
   1647   1.1.1.8  christos 
   1648   1.1.1.3  christos void
   1649   1.1.1.3  christos AcpiDmUnresolvedWarning (
   1650   1.1.1.3  christos     UINT8                   Type)
   1651   1.1.1.3  christos {
   1652   1.1.1.8  christos     char                    *Format;
   1653   1.1.1.8  christos     char                    Pad[] = "     *";
   1654   1.1.1.8  christos     char                    NoPad[] = "";
   1655   1.1.1.8  christos 
   1656   1.1.1.3  christos 
   1657   1.1.1.3  christos     if (!AcpiGbl_NumExternalMethods)
   1658   1.1.1.3  christos     {
   1659   1.1.1.3  christos         return;
   1660   1.1.1.3  christos     }
   1661   1.1.1.3  christos 
   1662   1.1.1.8  christos     if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
   1663   1.1.1.8  christos     {
   1664   1.1.1.8  christos         return;
   1665   1.1.1.8  christos     }
   1666   1.1.1.8  christos 
   1667   1.1.1.8  christos     Format = Type ? Pad : NoPad;
   1668   1.1.1.8  christos 
   1669   1.1.1.8  christos     sprintf (ExternalWarningPart1,
   1670   1.1.1.8  christos         "%s iASL Warning: There %s %u external control method%s found during\n"
   1671   1.1.1.8  christos         "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
   1672   1.1.1.8  christos         "%s ACPI tables may be required to properly disassemble the code. This\n"
   1673   1.1.1.8  christos         "%s resulting disassembler output file may not compile because the\n"
   1674   1.1.1.8  christos         "%s disassembler did not know how many arguments to assign to the\n"
   1675   1.1.1.8  christos         "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
   1676   1.1.1.8  christos         "%s runtime and may or may not be available via the host OS.\n",
   1677   1.1.1.8  christos         Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
   1678   1.1.1.8  christos         AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
   1679   1.1.1.8  christos         Format, AcpiGbl_ResolvedExternalMethods,
   1680   1.1.1.8  christos         (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
   1681   1.1.1.8  christos         (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
   1682   1.1.1.8  christos         Format, Format, Format, Format, Format);
   1683   1.1.1.8  christos 
   1684   1.1.1.8  christos     sprintf (ExternalWarningPart2,
   1685   1.1.1.8  christos         "%s To specify the tables needed to resolve external control method\n"
   1686   1.1.1.8  christos         "%s references, the -e option can be used to specify the filenames.\n"
   1687   1.1.1.8  christos         "%s Example iASL invocations:\n"
   1688   1.1.1.8  christos         "%s     iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
   1689   1.1.1.8  christos         "%s     iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
   1690   1.1.1.8  christos         "%s     iasl -e ssdt*.aml -d dsdt.aml\n",
   1691   1.1.1.8  christos         Format, Format, Format, Format, Format, Format);
   1692   1.1.1.8  christos 
   1693   1.1.1.8  christos     sprintf (ExternalWarningPart3,
   1694   1.1.1.8  christos         "%s In addition, the -fe option can be used to specify a file containing\n"
   1695   1.1.1.8  christos         "%s control method external declarations with the associated method\n"
   1696   1.1.1.8  christos         "%s argument counts. Each line of the file must be of the form:\n"
   1697   1.1.1.8  christos         "%s     External (<method pathname>, MethodObj, <argument count>)\n"
   1698   1.1.1.8  christos         "%s Invocation:\n"
   1699   1.1.1.8  christos         "%s     iasl -fe refs.txt -d dsdt.aml\n",
   1700   1.1.1.8  christos         Format, Format, Format, Format, Format, Format);
   1701   1.1.1.8  christos 
   1702   1.1.1.8  christos     sprintf (ExternalWarningPart4,
   1703   1.1.1.8  christos         "%s The following methods were unresolved and many not compile properly\n"
   1704   1.1.1.8  christos         "%s because the disassembler had to guess at the number of arguments\n"
   1705   1.1.1.8  christos         "%s required for each:\n",
   1706   1.1.1.8  christos         Format, Format, Format);
   1707   1.1.1.8  christos 
   1708   1.1.1.3  christos     if (Type)
   1709   1.1.1.3  christos     {
   1710   1.1.1.3  christos         if (!AcpiGbl_ExternalFileList)
   1711   1.1.1.3  christos         {
   1712   1.1.1.3  christos             /* The -e option was not specified */
   1713   1.1.1.3  christos 
   1714   1.1.1.8  christos            AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     *\n%s     */\n",
   1715   1.1.1.8  christos                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
   1716   1.1.1.8  christos                ExternalWarningPart4);
   1717   1.1.1.3  christos         }
   1718   1.1.1.8  christos         else
   1719   1.1.1.3  christos         {
   1720   1.1.1.3  christos             /* The -e option was specified, but there are still some unresolved externals */
   1721   1.1.1.3  christos 
   1722   1.1.1.8  christos             AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     */\n",
   1723   1.1.1.8  christos                ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
   1724   1.1.1.3  christos         }
   1725   1.1.1.3  christos     }
   1726   1.1.1.3  christos     else
   1727   1.1.1.3  christos     {
   1728   1.1.1.3  christos         if (!AcpiGbl_ExternalFileList)
   1729   1.1.1.3  christos         {
   1730   1.1.1.3  christos             /* The -e option was not specified */
   1731   1.1.1.3  christos 
   1732   1.1.1.8  christos             fprintf (stderr, "\n%s\n%s\n%s\n",
   1733   1.1.1.8  christos                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
   1734   1.1.1.3  christos         }
   1735   1.1.1.8  christos         else
   1736   1.1.1.3  christos         {
   1737   1.1.1.3  christos             /* The -e option was specified, but there are still some unresolved externals */
   1738   1.1.1.3  christos 
   1739   1.1.1.8  christos             fprintf (stderr, "\n%s\n%s\n",
   1740   1.1.1.8  christos                ExternalWarningPart1, ExternalWarningPart3);
   1741   1.1.1.3  christos         }
   1742   1.1.1.3  christos     }
   1743   1.1.1.3  christos }
   1744