Home | History | Annotate | Line # | Download | only in acpiexec
aeinitfile.c revision 1.1.1.13
      1 /******************************************************************************
      2  *
      3  * Module Name: aeinitfile - Support for optional initialization file
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aecommon.h"
     45 #include "acdispat.h"
     46 #include "acnamesp.h"
     47 
     48 
     49 #define _COMPONENT          ACPI_TOOLS
     50         ACPI_MODULE_NAME    ("aeinitfile")
     51 
     52 
     53 #define AE_FILE_BUFFER_SIZE     512
     54 
     55 static char                 LineBuffer[AE_FILE_BUFFER_SIZE];
     56 static char                 NameBuffer[AE_FILE_BUFFER_SIZE];
     57 static FILE                 *InitFile;
     58 
     59 
     60 /******************************************************************************
     61  *
     62  * FUNCTION:    AeOpenInitializationFile
     63  *
     64  * PARAMETERS:  Filename            - Path to the init file
     65  *
     66  * RETURN:      Status
     67  *
     68  * DESCRIPTION: Open the initialization file for the -fi option
     69  *
     70  *****************************************************************************/
     71 
     72 int
     73 AeOpenInitializationFile (
     74     char                    *Filename)
     75 {
     76 
     77     InitFile = fopen (Filename, "r");
     78     if (!InitFile)
     79     {
     80         fprintf (stderr,
     81             "Could not open initialization file: %s\n", Filename);
     82         return (-1);
     83     }
     84 
     85     AcpiOsPrintf ("Opened initialization file [%s]\n", Filename);
     86     return (0);
     87 }
     88 
     89 
     90 /******************************************************************************
     91  *
     92  * FUNCTION:    AeProcessInitFile
     93  *
     94  * PARAMETERS:  None
     95  *
     96  * RETURN:      None
     97  *
     98  * DESCRIPTION: Read the initialization file and perform all namespace
     99  *              initializations. AcpiGbl_InitEntries will be used for all
    100  *              object initialization.
    101  *
    102  * NOTE:        The format of the file is multiple lines, each of format:
    103  *                  <ACPI-pathname> <New Value>
    104  *
    105  *****************************************************************************/
    106 
    107 ACPI_STATUS
    108 AeProcessInitFile (
    109     void)
    110 {
    111     ACPI_WALK_STATE         *WalkState;
    112     UINT64                  idx;
    113     ACPI_STATUS             Status = AE_OK;
    114     char                    *Token;
    115     char                    *ValueBuffer;
    116     char                    *TempNameBuffer;
    117     ACPI_OBJECT_TYPE        Type;
    118     ACPI_OBJECT             TempObject;
    119 
    120 
    121     if (!InitFile)
    122     {
    123         return (AE_OK);
    124     }
    125 
    126     /* Create needed objects to be reused for each init entry */
    127 
    128     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    129     NameBuffer[0] = '\\';
    130     NameBuffer[1] = 0;
    131 
    132     while (fgets (LineBuffer, AE_FILE_BUFFER_SIZE, InitFile) != NULL)
    133     {
    134         ++AcpiGbl_InitFileLineCount;
    135     }
    136     rewind (InitFile);
    137 
    138     /*
    139      * Allocate and populate the Gbl_InitEntries array
    140      */
    141     AcpiGbl_InitEntries =
    142         AcpiOsAllocateZeroed (sizeof (INIT_FILE_ENTRY) * AcpiGbl_InitFileLineCount);
    143     for (idx = 0; fgets (LineBuffer, AE_FILE_BUFFER_SIZE, InitFile); ++idx)
    144     {
    145         TempNameBuffer = AcpiDbGetNextToken (LineBuffer, &Token, &Type);
    146         if (!TempNameBuffer)
    147         {
    148             AcpiGbl_InitEntries[idx].Name = NULL;
    149             continue;
    150         }
    151 
    152         if (LineBuffer[0] == '\\')
    153         {
    154             strcpy (NameBuffer, TempNameBuffer);
    155         }
    156         else
    157         {
    158             /* Add a root prefix if not present in the string */
    159 
    160             strcpy (NameBuffer + 1, TempNameBuffer);
    161         }
    162 
    163         AcpiNsNormalizePathname (NameBuffer);
    164         AcpiGbl_InitEntries[idx].Name =
    165             AcpiOsAllocateZeroed (strnlen (NameBuffer, AE_FILE_BUFFER_SIZE) + 1);
    166         strcpy (AcpiGbl_InitEntries[idx].Name, NameBuffer);
    167 
    168         ValueBuffer = AcpiDbGetNextToken (Token, &Token, &Type);
    169         if (!ValueBuffer)
    170         {
    171             AcpiGbl_InitEntries[idx].Value = NULL;
    172             continue;
    173         }
    174 
    175         AcpiGbl_InitEntries[idx].Value =
    176             AcpiOsAllocateZeroed (strnlen (ValueBuffer, AE_FILE_BUFFER_SIZE) + 1);
    177         strcpy (AcpiGbl_InitEntries[idx].Value, ValueBuffer);
    178 
    179         if (Type == ACPI_TYPE_FIELD_UNIT)
    180         {
    181             Status = AcpiDbConvertToObject (ACPI_TYPE_BUFFER, ValueBuffer,
    182                 &TempObject);
    183         }
    184         else
    185         {
    186             Status = AcpiDbConvertToObject (Type, ValueBuffer, &TempObject);
    187         }
    188 
    189         if (ACPI_FAILURE (Status))
    190         {
    191             AcpiOsPrintf ("%s[%s]: %s\n", NameBuffer, AcpiUtGetTypeName (Type),
    192                 AcpiFormatException (Status));
    193             goto CleanupAndExit;
    194         }
    195 
    196         Status = AcpiUtCopyEobjectToIobject (&TempObject,
    197             &AcpiGbl_InitEntries[idx].ObjDesc);
    198 
    199         /* Cleanup the external object created by DbConvertToObject above */
    200 
    201         if (ACPI_SUCCESS (Status))
    202         {
    203             if (Type == ACPI_TYPE_BUFFER || Type == ACPI_TYPE_FIELD_UNIT)
    204             {
    205                 ACPI_FREE (TempObject.Buffer.Pointer);
    206             }
    207             else if (Type == ACPI_TYPE_PACKAGE)
    208             {
    209                 AcpiDbDeleteObjects (1, &TempObject);
    210             }
    211         }
    212         else
    213         {
    214             AcpiOsPrintf ("%s[%s]: %s\n", NameBuffer, AcpiUtGetTypeName (Type),
    215                 AcpiFormatException (Status));
    216             goto CleanupAndExit;
    217         }
    218 
    219         /*
    220          * Initialize the namespace node with the value found in the init file.
    221          */
    222         AcpiOsPrintf ("Namespace object init from file: %16s, Value \"%s\", Type %s\n",
    223             AcpiGbl_InitEntries[idx].Name, AcpiGbl_InitEntries[idx].Value, AcpiUtGetTypeName (Type));
    224     }
    225 
    226     /* Cleanup */
    227 
    228 CleanupAndExit:
    229     fclose (InitFile);
    230     AcpiDsDeleteWalkState (WalkState);
    231     return (Status);
    232 }
    233 
    234 
    235 /******************************************************************************
    236  *
    237  * FUNCTION:    AeLookupInitFileEntry
    238  *
    239  * PARAMETERS:  Pathname            - AML namepath in external format
    240  *              ObjDesc             - Where the object is returned if it exists
    241  *
    242  * RETURN:      Status. AE_OK if a match was found
    243  *
    244  * DESCRIPTION: Search the init file for a particular name and its value.
    245  *
    246  *****************************************************************************/
    247 
    248 ACPI_STATUS
    249 AeLookupInitFileEntry (
    250     char                    *Pathname,
    251     ACPI_OPERAND_OBJECT     **ObjDesc)
    252 {
    253     UINT32                  i;
    254 
    255     ACPI_FUNCTION_TRACE (AeLookupInitFileEntry);
    256 
    257     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Lookup: %s\n", Pathname));
    258 
    259     if (!AcpiGbl_InitEntries)
    260     {
    261         return (AE_NOT_FOUND);
    262     }
    263 
    264     AcpiNsNormalizePathname (Pathname);
    265 
    266     for (i = 0; i < AcpiGbl_InitFileLineCount; ++i)
    267     {
    268         if (AcpiGbl_InitEntries[i].Name &&
    269             !strcmp (AcpiGbl_InitEntries[i].Name, Pathname))
    270         {
    271             *ObjDesc = AcpiGbl_InitEntries[i].ObjDesc;
    272             AcpiGbl_InitEntries[i].IsUsed = TRUE;
    273             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Found match: %s, %p\n", Pathname, *ObjDesc));
    274             return_ACPI_STATUS (AE_OK);
    275         }
    276     }
    277 
    278     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "No match found: %s\n", Pathname));
    279     return_ACPI_STATUS (AE_NOT_FOUND);
    280 }
    281 
    282 
    283 /******************************************************************************
    284  *
    285  * FUNCTION:    AeDisplayUnusedInitFileItems
    286  *
    287  * PARAMETERS:  None
    288  *
    289  * RETURN:      None
    290  *
    291  * DESCRIPTION: Display all init file items that have not been referenced
    292  *              (i.e., items that have not been found in the namespace).
    293  *
    294  *****************************************************************************/
    295 
    296 void
    297 AeDisplayUnusedInitFileItems (
    298     void)
    299 {
    300     UINT32                  i;
    301 
    302 
    303     if (!AcpiGbl_InitEntries)
    304     {
    305         return;
    306     }
    307 
    308     for (i = 0; i < AcpiGbl_InitFileLineCount; ++i)
    309     {
    310         if (AcpiGbl_InitEntries[i].Name &&
    311             !AcpiGbl_InitEntries[i].IsUsed)
    312         {
    313             AcpiOsPrintf ("Init file entry not found in namespace "
    314                 "(or is a non-data type): %s\n",
    315                 AcpiGbl_InitEntries[i].Name);
    316         }
    317     }
    318 }
    319 
    320 
    321 /******************************************************************************
    322  *
    323  * FUNCTION:    AeDeleteInitFileList
    324  *
    325  * PARAMETERS:  None
    326  *
    327  * RETURN:      None
    328  *
    329  * DESCRIPTION: Delete the global namespace initialization file data
    330  *
    331  *****************************************************************************/
    332 
    333 void
    334 AeDeleteInitFileList (
    335     void)
    336 {
    337     UINT32                  i;
    338 
    339 
    340     if (!AcpiGbl_InitEntries)
    341     {
    342         return;
    343     }
    344 
    345     for (i = 0; i < AcpiGbl_InitFileLineCount; ++i)
    346     {
    347 
    348         if ((AcpiGbl_InitEntries[i].ObjDesc) && (AcpiGbl_InitEntries[i].Value))
    349         {
    350             /* Remove one reference on the object (and all subobjects) */
    351 
    352             AcpiUtRemoveReference (AcpiGbl_InitEntries[i].ObjDesc);
    353         }
    354     }
    355 
    356     AcpiOsFree (AcpiGbl_InitEntries);
    357 }
    358