Home | History | Annotate | Line # | Download | only in acpiexec
aeinitfile.c revision 1.1.1.11
      1 /******************************************************************************
      2  *
      3  * Module Name: aeinitfile - Support for optional initialization file
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2019, 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 MERCHANTIBILITY 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 
     47 #define _COMPONENT          ACPI_TOOLS
     48         ACPI_MODULE_NAME    ("aeinitfile")
     49 
     50 
     51 /* Local prototypes */
     52 
     53 static void
     54 AeEnterInitFileEntry (
     55     INIT_FILE_ENTRY         InitEntry,
     56     ACPI_WALK_STATE         *WalkState);
     57 
     58 
     59 #define AE_FILE_BUFFER_SIZE     512
     60 
     61 static char                 LineBuffer[AE_FILE_BUFFER_SIZE];
     62 static char                 NameBuffer[AE_FILE_BUFFER_SIZE];
     63 static char                 ValueBuffer[AE_FILE_BUFFER_SIZE];
     64 static FILE                 *InitFile;
     65 
     66 
     67 /******************************************************************************
     68  *
     69  * FUNCTION:    AeOpenInitializationFile
     70  *
     71  * PARAMETERS:  Filename            - Path to the init file
     72  *
     73  * RETURN:      Status
     74  *
     75  * DESCRIPTION: Open the initialization file for the -fi option
     76  *
     77  *****************************************************************************/
     78 
     79 int
     80 AeOpenInitializationFile (
     81     char                    *Filename)
     82 {
     83 
     84     InitFile = fopen (Filename, "r");
     85     if (!InitFile)
     86     {
     87         fprintf (stderr,
     88             "Could not open initialization file: %s\n", Filename);
     89         return (-1);
     90     }
     91 
     92     AcpiOsPrintf ("Opened initialization file [%s]\n", Filename);
     93     return (0);
     94 }
     95 
     96 
     97 /******************************************************************************
     98  *
     99  * FUNCTION:    AeProcessInitFile
    100  *
    101  * PARAMETERS:  None
    102  *
    103  * RETURN:      None
    104  *
    105  * DESCRIPTION: Read the initialization file and perform all namespace
    106  *              initializations. AcpiGbl_InitEntries will be used for region
    107  *              field initialization.
    108  *
    109  * NOTE:        The format of the file is multiple lines, each of format:
    110  *                  <ACPI-pathname> <Integer Value>
    111  *
    112  *****************************************************************************/
    113 
    114 void
    115 AeProcessInitFile(
    116     void)
    117 {
    118     ACPI_WALK_STATE         *WalkState;
    119     UINT64                  idx;
    120     ACPI_STATUS             Status;
    121     char                    *Token;
    122     char                    *ObjectBuffer;
    123     char                    *TempNameBuffer;
    124     ACPI_OBJECT_TYPE        Type;
    125     ACPI_OBJECT             TempObject;
    126 
    127 
    128     if (!InitFile)
    129     {
    130         return;
    131     }
    132 
    133     /* Create needed objects to be reused for each init entry */
    134 
    135     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    136     NameBuffer[0] = '\\';
    137 
    138     while (fgets (LineBuffer, AE_FILE_BUFFER_SIZE, InitFile) != NULL)
    139     {
    140         ++AcpiGbl_InitFileLineCount;
    141     }
    142     rewind (InitFile);
    143 
    144     AcpiGbl_InitEntries =
    145         AcpiOsAllocate (sizeof (INIT_FILE_ENTRY) * AcpiGbl_InitFileLineCount);
    146     for (idx = 0; fgets (LineBuffer, AE_FILE_BUFFER_SIZE, InitFile); ++idx)
    147     {
    148 
    149         TempNameBuffer = AcpiDbGetNextToken (LineBuffer, &Token, &Type);
    150         if (LineBuffer[0] == '\\')
    151         {
    152             strcpy (NameBuffer, TempNameBuffer);
    153         }
    154         else
    155         {
    156             /* Add a root prefix if not present in the string */
    157 
    158             strcpy (NameBuffer + 1, TempNameBuffer);
    159         }
    160 
    161         AcpiGbl_InitEntries[idx].Name =
    162             AcpiOsAllocateZeroed (strnlen (NameBuffer, AE_FILE_BUFFER_SIZE) + 1);
    163 
    164         strcpy (AcpiGbl_InitEntries[idx].Name, NameBuffer);
    165 
    166         ObjectBuffer = AcpiDbGetNextToken (Token, &Token, &Type);
    167 
    168         if (Type == ACPI_TYPE_FIELD_UNIT)
    169         {
    170             Status = AcpiDbConvertToObject (ACPI_TYPE_BUFFER, ObjectBuffer,
    171                 &TempObject);
    172         }
    173         else
    174         {
    175             Status = AcpiDbConvertToObject (Type, ObjectBuffer, &TempObject);
    176         }
    177 
    178         Status = AcpiUtCopyEobjectToIobject (&TempObject,
    179             &AcpiGbl_InitEntries[idx].ObjDesc);
    180 
    181         if (Type == ACPI_TYPE_BUFFER || Type == ACPI_TYPE_FIELD_UNIT)
    182         {
    183             ACPI_FREE (TempObject.Buffer.Pointer);
    184         }
    185 
    186         if (ACPI_FAILURE (Status))
    187         {
    188             AcpiOsPrintf ("%s %s\n", ValueBuffer,
    189                 AcpiFormatException (Status));
    190             goto CleanupAndExit;
    191         }
    192 
    193         /*
    194          * Special case for field units. Field units are dependent on the
    195          * parent region. This parent region has yet to be created so defer the
    196          * initialization until the dispatcher. For all other types, initialize
    197          * the namespace node with the value found in the init file.
    198          */
    199         if (Type != ACPI_TYPE_FIELD_UNIT)
    200         {
    201             AeEnterInitFileEntry (AcpiGbl_InitEntries[idx], WalkState);
    202         }
    203     }
    204 
    205     /* Cleanup */
    206 
    207 CleanupAndExit:
    208     fclose (InitFile);
    209     AcpiDsDeleteWalkState (WalkState);
    210 }
    211 
    212 
    213 /******************************************************************************
    214  *
    215  * FUNCTION:    AeInitFileEntry
    216  *
    217  * PARAMETERS:  InitEntry           - Entry of the init file
    218  *              WalkState           - Used for the Store operation
    219  *
    220  * RETURN:      None
    221  *
    222  * DESCRIPTION: Perform initialization of a single namespace object
    223  *
    224  *              Note: namespace of objects are limited to integers and region
    225  *              fields units of 8 bytes at this time.
    226  *
    227  *****************************************************************************/
    228 
    229 static void
    230 AeEnterInitFileEntry (
    231     INIT_FILE_ENTRY         InitEntry,
    232     ACPI_WALK_STATE         *WalkState)
    233 {
    234     char                    *Pathname = InitEntry.Name;
    235     ACPI_OPERAND_OBJECT     *ObjDesc = InitEntry.ObjDesc;
    236     ACPI_NAMESPACE_NODE     *NewNode;
    237     ACPI_STATUS             Status;
    238 
    239 
    240     Status = AcpiNsLookup (NULL, Pathname, ObjDesc->Common.Type,
    241         ACPI_IMODE_LOAD_PASS2, ACPI_NS_ERROR_IF_FOUND | ACPI_NS_NO_UPSEARCH |
    242         ACPI_NS_EARLY_INIT, NULL, &NewNode);
    243     if (ACPI_FAILURE (Status))
    244     {
    245         ACPI_EXCEPTION ((AE_INFO, Status,
    246             "While creating name from namespace initialization file: %s",
    247             Pathname));
    248         return;
    249     }
    250 
    251     /* Store pointer to value descriptor in the Node */
    252 
    253     Status = AcpiNsAttachObject (NewNode, ObjDesc,
    254          ObjDesc->Common.Type);
    255     if (ACPI_FAILURE (Status))
    256     {
    257         ACPI_EXCEPTION ((AE_INFO, Status,
    258             "While attaching object to node from namespace initialization file: %s",
    259             Pathname));
    260         return;
    261     }
    262 
    263     /* Remove local reference to the object */
    264 
    265     AcpiUtRemoveReference (ObjDesc);
    266 }
    267 
    268 
    269 /******************************************************************************
    270  *
    271  * FUNCTION:    AeLookupInitFileEntry
    272  *
    273  * PARAMETERS:  Pathname            - AML namepath in external format
    274  *              ValueString         - value of the namepath if it exitst
    275  *
    276  * RETURN:      None
    277  *
    278  * DESCRIPTION: Search the init file for a particular name and its value.
    279  *
    280  *****************************************************************************/
    281 
    282 ACPI_STATUS
    283 AeLookupInitFileEntry (
    284     char                    *Pathname,
    285     ACPI_OPERAND_OBJECT     **ObjDesc)
    286 {
    287     UINT32                  i;
    288 
    289     if (!AcpiGbl_InitEntries)
    290     {
    291         return AE_NOT_FOUND;
    292     }
    293 
    294     for (i = 0; i < AcpiGbl_InitFileLineCount; ++i)
    295     {
    296         if (!strcmp(AcpiGbl_InitEntries[i].Name, Pathname))
    297         {
    298             *ObjDesc = AcpiGbl_InitEntries[i].ObjDesc;
    299             return AE_OK;
    300         }
    301     }
    302     return AE_NOT_FOUND;
    303 }
    304