Home | History | Annotate | Line # | Download | only in compiler
dtsubtable.c revision 1.1.1.13
      1 /******************************************************************************
      2  *
      3  * Module Name: dtsubtable.c - handling of subtables within ACPI tables
      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 "aslcompiler.h"
     45 
     46 #define _COMPONENT          DT_COMPILER
     47         ACPI_MODULE_NAME    ("dtsubtable")
     48 
     49 
     50 /******************************************************************************
     51  *
     52  * FUNCTION:    DtCreateSubtable
     53  *
     54  * PARAMETERS:  Buffer              - Input buffer
     55  *              Length              - Buffer length
     56  *              RetSubtable         - Returned newly created subtable
     57  *
     58  * RETURN:      None
     59  *
     60  * DESCRIPTION: Create a subtable that is not listed with ACPI_DMTABLE_INFO
     61  *              For example, FACS has 24 bytes reserved at the end
     62  *              and it's not listed at AcpiDmTableInfoFacs
     63  *
     64  *****************************************************************************/
     65 
     66 void
     67 DtCreateSubtable (
     68     UINT8                   *Buffer,
     69     UINT32                  Length,
     70     DT_SUBTABLE             **RetSubtable)
     71 {
     72     DT_SUBTABLE             *Subtable;
     73     char                    *String;
     74 
     75 
     76     Subtable = UtSubtableCacheCalloc ();
     77 
     78     /* Create a new buffer for the subtable data */
     79 
     80     String = UtLocalCacheCalloc (Length);
     81     Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
     82     memcpy (Subtable->Buffer, Buffer, Length);
     83 
     84     Subtable->Length = Length;
     85     Subtable->TotalLength = Length;
     86 
     87     *RetSubtable = Subtable;
     88 }
     89 
     90 
     91 /******************************************************************************
     92  *
     93  * FUNCTION:    DtInsertSubtable
     94  *
     95  * PARAMETERS:  ParentTable         - The Parent of the new subtable
     96  *              Subtable            - The new subtable to insert
     97  *
     98  * RETURN:      None
     99  *
    100  * DESCRIPTION: Insert the new subtable to the parent table
    101  *
    102  *****************************************************************************/
    103 
    104 void
    105 DtInsertSubtable (
    106     DT_SUBTABLE             *ParentTable,
    107     DT_SUBTABLE             *Subtable)
    108 {
    109     DT_SUBTABLE             *ChildTable;
    110 
    111 
    112     Subtable->Peer = NULL;
    113     Subtable->Parent = ParentTable;
    114     Subtable->Depth = ParentTable->Depth + 1;
    115 
    116     /* Link the new entry into the child list */
    117 
    118     if (!ParentTable->Child)
    119     {
    120         ParentTable->Child = Subtable;
    121     }
    122     else
    123     {
    124         /* Walk to the end of the child list */
    125 
    126         ChildTable = ParentTable->Child;
    127         while (ChildTable->Peer)
    128         {
    129             ChildTable = ChildTable->Peer;
    130         }
    131 
    132         /* Add new subtable at the end of the child list */
    133 
    134         ChildTable->Peer = Subtable;
    135     }
    136 }
    137 
    138 
    139 /******************************************************************************
    140  *
    141  * FUNCTION:    DtPushSubtable
    142  *
    143  * PARAMETERS:  Subtable            - Subtable to push
    144  *
    145  * RETURN:      None
    146  *
    147  * DESCRIPTION: Push a subtable onto a subtable stack
    148  *
    149  *****************************************************************************/
    150 
    151 void
    152 DtPushSubtable (
    153     DT_SUBTABLE             *Subtable)
    154 {
    155 
    156     Subtable->StackTop = AslGbl_SubtableStack;
    157     AslGbl_SubtableStack = Subtable;
    158 }
    159 
    160 
    161 /******************************************************************************
    162  *
    163  * FUNCTION:    DtPopSubtable
    164  *
    165  * PARAMETERS:  None
    166  *
    167  * RETURN:      None
    168  *
    169  * DESCRIPTION: Pop a subtable from a subtable stack. Uses global SubtableStack
    170  *
    171  *****************************************************************************/
    172 
    173 void
    174 DtPopSubtable (
    175     void)
    176 {
    177     DT_SUBTABLE             *Subtable;
    178 
    179 
    180     Subtable = AslGbl_SubtableStack;
    181 
    182     if (Subtable)
    183     {
    184         AslGbl_SubtableStack = Subtable->StackTop;
    185     }
    186 }
    187 
    188 
    189 /******************************************************************************
    190  *
    191  * FUNCTION:    DtPeekSubtable
    192  *
    193  * PARAMETERS:  None
    194  *
    195  * RETURN:      The subtable on top of stack
    196  *
    197  * DESCRIPTION: Get the subtable on top of stack
    198  *
    199  *****************************************************************************/
    200 
    201 DT_SUBTABLE *
    202 DtPeekSubtable (
    203     void)
    204 {
    205 
    206     return (AslGbl_SubtableStack);
    207 }
    208 
    209 
    210 /******************************************************************************
    211  *
    212  * FUNCTION:    DtGetNextSubtable
    213  *
    214  * PARAMETERS:  ParentTable         - Parent table whose children we are
    215  *                                    getting
    216  *              ChildTable          - Previous child that was found.
    217  *                                    The NEXT child will be returned
    218  *
    219  * RETURN:      Pointer to the NEXT child or NULL if none is found.
    220  *
    221  * DESCRIPTION: Return the next peer subtable within the tree.
    222  *
    223  *****************************************************************************/
    224 
    225 DT_SUBTABLE *
    226 DtGetNextSubtable (
    227     DT_SUBTABLE             *ParentTable,
    228     DT_SUBTABLE             *ChildTable)
    229 {
    230     ACPI_FUNCTION_ENTRY ();
    231 
    232 
    233     if (!ChildTable)
    234     {
    235         /* It's really the parent's _scope_ that we want */
    236 
    237         return (ParentTable->Child);
    238     }
    239 
    240     /* Otherwise just return the next peer (NULL if at end-of-list) */
    241 
    242     return (ChildTable->Peer);
    243 }
    244 
    245 
    246 /******************************************************************************
    247  *
    248  * FUNCTION:    DtGetParentSubtable
    249  *
    250  * PARAMETERS:  Subtable            - Current subtable
    251  *
    252  * RETURN:      Parent of the given subtable
    253  *
    254  * DESCRIPTION: Get the parent of the given subtable in the tree
    255  *
    256  *****************************************************************************/
    257 
    258 DT_SUBTABLE *
    259 DtGetParentSubtable (
    260     DT_SUBTABLE             *Subtable)
    261 {
    262 
    263     if (!Subtable)
    264     {
    265         return (NULL);
    266     }
    267 
    268     return (Subtable->Parent);
    269 }
    270 
    271 
    272 /******************************************************************************
    273  *
    274  * FUNCTION:    DtGetSubtableLength
    275  *
    276  * PARAMETERS:  Field               - Current field list pointer
    277  *              Info                - Data table info
    278  *
    279  * RETURN:      Subtable length
    280  *
    281  * DESCRIPTION: Get length of bytes needed to compile the subtable
    282  *
    283  *****************************************************************************/
    284 
    285 UINT32
    286 DtGetSubtableLength (
    287     DT_FIELD                *Field,
    288     ACPI_DMTABLE_INFO       *Info)
    289 {
    290     UINT32                  ByteLength = 0;
    291     UINT8                   Step;
    292     UINT8                   i;
    293 
    294 
    295     /* Walk entire Info table; Null name terminates */
    296 
    297     for (; Info->Name; Info++)
    298     {
    299         if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
    300         {
    301             continue;
    302         }
    303 
    304         if (!Field)
    305         {
    306             goto Error;
    307         }
    308 
    309         ByteLength += DtGetFieldLength (Field, Info);
    310 
    311         switch (Info->Opcode)
    312         {
    313         case ACPI_DMT_GAS:
    314 
    315             Step = 5;
    316             break;
    317 
    318         case ACPI_DMT_HESTNTFY:
    319 
    320             Step = 9;
    321             break;
    322 
    323         case ACPI_DMT_IORTMEM:
    324 
    325             Step = 10;
    326             break;
    327 
    328         default:
    329 
    330             Step = 1;
    331             break;
    332         }
    333 
    334         for (i = 0; i < Step; i++)
    335         {
    336             if (!Field)
    337             {
    338                 goto Error;
    339             }
    340 
    341             Field = Field->Next;
    342         }
    343     }
    344 
    345     return (ByteLength);
    346 
    347 Error:
    348     if (!Field)
    349     {
    350         sprintf (AslGbl_MsgBuffer, "Found NULL field - Field name \"%s\" needed",
    351             Info->Name);
    352         DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, AslGbl_MsgBuffer);
    353     }
    354 
    355     return (ASL_EOF);
    356 }
    357 
    358 
    359 /******************************************************************************
    360  *
    361  * FUNCTION:    DtSetSubtableLength
    362  *
    363  * PARAMETERS:  Subtable            - Subtable
    364  *
    365  * RETURN:      None
    366  *
    367  * DESCRIPTION: Set length of the subtable into its length field
    368  *
    369  *****************************************************************************/
    370 
    371 void
    372 DtSetSubtableLength (
    373     DT_SUBTABLE             *Subtable)
    374 {
    375 
    376     if (!Subtable->LengthField)
    377     {
    378         return;
    379     }
    380 
    381     memcpy (Subtable->LengthField, &Subtable->TotalLength,
    382         Subtable->SizeOfLengthField);
    383 }
    384