Home | History | Annotate | Line # | Download | only in compiler
dtutils.c revision 1.1.1.11
      1 /******************************************************************************
      2  *
      3  * Module Name: dtutils.c - Utility routines for the data table compiler
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, 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 #include "dtcompiler.h"
     46 #include "actables.h"
     47 
     48 #define _COMPONENT          DT_COMPILER
     49         ACPI_MODULE_NAME    ("dtutils")
     50 
     51 /* Local prototypes */
     52 
     53 static void
     54 DtSum (
     55     DT_SUBTABLE             *Subtable,
     56     void                    *Context,
     57     void                    *ReturnValue);
     58 
     59 
     60 /******************************************************************************
     61  *
     62  * FUNCTION:    DtError
     63  *
     64  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
     65  *              MessageId           - Index into global message buffer
     66  *              Op                  - Parse node where error happened
     67  *              ExtraMessage        - additional error message
     68  *
     69  * RETURN:      None
     70  *
     71  * DESCRIPTION: Common error interface for data table compiler
     72  *
     73  *****************************************************************************/
     74 
     75 void
     76 DtError (
     77     UINT8                   Level,
     78     UINT16                  MessageId,
     79     DT_FIELD                *FieldObject,
     80     char                    *ExtraMessage)
     81 {
     82 
     83     /* Check if user wants to ignore this exception */
     84 
     85     if (AslIsExceptionIgnored (Level, MessageId))
     86     {
     87         return;
     88     }
     89 
     90     if (FieldObject)
     91     {
     92         AslCommonError (Level, MessageId,
     93             FieldObject->Line,
     94             FieldObject->Line,
     95             FieldObject->ByteOffset,
     96             FieldObject->Column,
     97             Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
     98     }
     99     else
    100     {
    101         AslCommonError (Level, MessageId, 0,
    102             0, 0, 0, 0, ExtraMessage);
    103     }
    104 }
    105 
    106 
    107 /******************************************************************************
    108  *
    109  * FUNCTION:    DtNameError
    110  *
    111  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    112  *              MessageId           - Index into global message buffer
    113  *              Op                  - Parse node where error happened
    114  *              ExtraMessage        - additional error message
    115  *
    116  * RETURN:      None
    117  *
    118  * DESCRIPTION: Error interface for named objects
    119  *
    120  *****************************************************************************/
    121 
    122 void
    123 DtNameError (
    124     UINT8                   Level,
    125     UINT16                  MessageId,
    126     DT_FIELD                *FieldObject,
    127     char                    *ExtraMessage)
    128 {
    129 
    130     switch (Level)
    131     {
    132     case ASL_WARNING2:
    133     case ASL_WARNING3:
    134 
    135         if (Gbl_WarningLevel < Level)
    136         {
    137             return;
    138         }
    139         break;
    140 
    141     default:
    142 
    143         break;
    144     }
    145 
    146     if (FieldObject)
    147     {
    148         AslCommonError (Level, MessageId,
    149             FieldObject->Line,
    150             FieldObject->Line,
    151             FieldObject->ByteOffset,
    152             FieldObject->NameColumn,
    153             Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
    154     }
    155     else
    156     {
    157         AslCommonError (Level, MessageId, 0,
    158             0, 0, 0, 0, ExtraMessage);
    159     }
    160 }
    161 
    162 
    163 /*******************************************************************************
    164  *
    165  * FUNCTION:    DtFatal
    166  *
    167  * PARAMETERS:  None
    168  *
    169  * RETURN:      None
    170  *
    171  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
    172  *              compile or I/O errors
    173  *
    174  ******************************************************************************/
    175 
    176 void
    177 DtFatal (
    178     UINT16                  MessageId,
    179     DT_FIELD                *FieldObject,
    180     char                    *ExtraMessage)
    181 {
    182 
    183     DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
    184 
    185 /*
    186  * TBD: remove this entire function, DtFatal
    187  *
    188  * We cannot abort the compiler on error, because we may be compiling a
    189  * list of files. We must move on to the next file.
    190  */
    191 #ifdef __OBSOLETE
    192     CmCleanupAndExit ();
    193     exit (1);
    194 #endif
    195 }
    196 
    197 
    198 /*******************************************************************************
    199  *
    200  * FUNCTION:    DtDoConstant
    201  *
    202  * PARAMETERS:  String              - Only hex constants are supported,
    203  *                                    regardless of whether the 0x prefix
    204  *                                    is used
    205  *
    206  * RETURN:      Converted Integer
    207  *
    208  * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
    209  *
    210  ******************************************************************************/
    211 
    212 UINT64
    213 DtDoConstant (
    214     char                    *String)
    215 {
    216     UINT64                  ConvertedInteger;
    217 
    218 
    219     /*
    220      * TBD: The ImplicitStrtoul64 function does not report overflow
    221      * conditions. The input string is simply truncated. If it is
    222      * desired to report overflow to the table compiler, this should
    223      * somehow be added here. Note: integers that are prefixed with 0x
    224      * or not are both hex integers.
    225      */
    226     ConvertedInteger = AcpiUtImplicitStrtoul64 (String);
    227     return (ConvertedInteger);
    228 }
    229 
    230 /******************************************************************************
    231  *
    232  * FUNCTION:    DtGetFieldValue
    233  *
    234  * PARAMETERS:  Field               - Current field list pointer
    235  *
    236  * RETURN:      Field value
    237  *
    238  * DESCRIPTION: Get field value
    239  *
    240  *****************************************************************************/
    241 
    242 char *
    243 DtGetFieldValue (
    244     DT_FIELD                *Field)
    245 {
    246     if (!Field)
    247     {
    248         return (NULL);
    249     }
    250 
    251     return (Field->Value);
    252 }
    253 
    254 
    255 /******************************************************************************
    256  *
    257  * FUNCTION:    DtGetFieldType
    258  *
    259  * PARAMETERS:  Info                - Data table info
    260  *
    261  * RETURN:      Field type
    262  *
    263  * DESCRIPTION: Get field type
    264  *
    265  *****************************************************************************/
    266 
    267 UINT8
    268 DtGetFieldType (
    269     ACPI_DMTABLE_INFO       *Info)
    270 {
    271     UINT8                   Type;
    272 
    273 
    274     /* DT_FLAG means that this is the start of a block of flag bits */
    275     /* TBD - we can make these a separate opcode later */
    276 
    277     if (Info->Flags & DT_FLAG)
    278     {
    279         return (DT_FIELD_TYPE_FLAGS_INTEGER);
    280     }
    281 
    282     /* Type is based upon the opcode for this field in the info table */
    283 
    284     switch (Info->Opcode)
    285     {
    286     case ACPI_DMT_FLAG0:
    287     case ACPI_DMT_FLAG1:
    288     case ACPI_DMT_FLAG2:
    289     case ACPI_DMT_FLAG3:
    290     case ACPI_DMT_FLAG4:
    291     case ACPI_DMT_FLAG5:
    292     case ACPI_DMT_FLAG6:
    293     case ACPI_DMT_FLAG7:
    294     case ACPI_DMT_FLAGS0:
    295     case ACPI_DMT_FLAGS1:
    296     case ACPI_DMT_FLAGS2:
    297     case ACPI_DMT_FLAGS4:
    298     case ACPI_DMT_FLAGS4_0:
    299     case ACPI_DMT_FLAGS4_4:
    300     case ACPI_DMT_FLAGS4_8:
    301     case ACPI_DMT_FLAGS4_12:
    302     case ACPI_DMT_FLAGS16_16:
    303 
    304         Type = DT_FIELD_TYPE_FLAG;
    305         break;
    306 
    307     case ACPI_DMT_NAME4:
    308     case ACPI_DMT_SIG:
    309     case ACPI_DMT_NAME6:
    310     case ACPI_DMT_NAME8:
    311     case ACPI_DMT_STRING:
    312 
    313         Type = DT_FIELD_TYPE_STRING;
    314         break;
    315 
    316     case ACPI_DMT_BUFFER:
    317     case ACPI_DMT_RAW_BUFFER:
    318     case ACPI_DMT_BUF7:
    319     case ACPI_DMT_BUF10:
    320     case ACPI_DMT_BUF12:
    321     case ACPI_DMT_BUF16:
    322     case ACPI_DMT_BUF128:
    323     case ACPI_DMT_PCI_PATH:
    324 
    325         Type = DT_FIELD_TYPE_BUFFER;
    326         break;
    327 
    328     case ACPI_DMT_GAS:
    329     case ACPI_DMT_HESTNTFY:
    330     case ACPI_DMT_IORTMEM:
    331 
    332         Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
    333         break;
    334 
    335     case ACPI_DMT_UNICODE:
    336 
    337         Type = DT_FIELD_TYPE_UNICODE;
    338         break;
    339 
    340     case ACPI_DMT_UUID:
    341 
    342         Type = DT_FIELD_TYPE_UUID;
    343         break;
    344 
    345     case ACPI_DMT_DEVICE_PATH:
    346 
    347         Type = DT_FIELD_TYPE_DEVICE_PATH;
    348         break;
    349 
    350     case ACPI_DMT_LABEL:
    351 
    352         Type = DT_FIELD_TYPE_LABEL;
    353         break;
    354 
    355     default:
    356 
    357         Type = DT_FIELD_TYPE_INTEGER;
    358         break;
    359     }
    360 
    361     return (Type);
    362 }
    363 
    364 
    365 /******************************************************************************
    366  *
    367  * FUNCTION:    DtGetBufferLength
    368  *
    369  * PARAMETERS:  Buffer              - List of integers,
    370  *                                    for example "10 3A 4F 2E"
    371  *
    372  * RETURN:      Count of integer
    373  *
    374  * DESCRIPTION: Get length of bytes needed to store the integers
    375  *
    376  *****************************************************************************/
    377 
    378 UINT32
    379 DtGetBufferLength (
    380     char                    *Buffer)
    381 {
    382     UINT32                  ByteLength = 0;
    383 
    384 
    385     while (*Buffer)
    386     {
    387         if (*Buffer == ' ')
    388         {
    389             ByteLength++;
    390 
    391             while (*Buffer == ' ')
    392             {
    393                 Buffer++;
    394             }
    395         }
    396 
    397         Buffer++;
    398     }
    399 
    400     return (++ByteLength);
    401 }
    402 
    403 
    404 /******************************************************************************
    405  *
    406  * FUNCTION:    DtGetFieldLength
    407  *
    408  * PARAMETERS:  Field               - Current field
    409  *              Info                - Data table info
    410  *
    411  * RETURN:      Field length
    412  *
    413  * DESCRIPTION: Get length of bytes needed to compile the field
    414  *
    415  * Note: This function must remain in sync with AcpiDmDumpTable.
    416  *
    417  *****************************************************************************/
    418 
    419 UINT32
    420 DtGetFieldLength (
    421     DT_FIELD                *Field,
    422     ACPI_DMTABLE_INFO       *Info)
    423 {
    424     UINT32                  ByteLength = 0;
    425     char                    *Value;
    426 
    427 
    428     /* Length is based upon the opcode for this field in the info table */
    429 
    430     switch (Info->Opcode)
    431     {
    432     case ACPI_DMT_FLAG0:
    433     case ACPI_DMT_FLAG1:
    434     case ACPI_DMT_FLAG2:
    435     case ACPI_DMT_FLAG3:
    436     case ACPI_DMT_FLAG4:
    437     case ACPI_DMT_FLAG5:
    438     case ACPI_DMT_FLAG6:
    439     case ACPI_DMT_FLAG7:
    440     case ACPI_DMT_FLAGS0:
    441     case ACPI_DMT_FLAGS1:
    442     case ACPI_DMT_FLAGS2:
    443     case ACPI_DMT_FLAGS4:
    444     case ACPI_DMT_FLAGS4_0:
    445     case ACPI_DMT_FLAGS4_4:
    446     case ACPI_DMT_FLAGS4_8:
    447     case ACPI_DMT_FLAGS4_12:
    448     case ACPI_DMT_FLAGS16_16:
    449     case ACPI_DMT_LABEL:
    450     case ACPI_DMT_EXTRA_TEXT:
    451 
    452         ByteLength = 0;
    453         break;
    454 
    455     case ACPI_DMT_UINT8:
    456     case ACPI_DMT_CHKSUM:
    457     case ACPI_DMT_SPACEID:
    458     case ACPI_DMT_ACCWIDTH:
    459     case ACPI_DMT_IVRS:
    460     case ACPI_DMT_GTDT:
    461     case ACPI_DMT_MADT:
    462     case ACPI_DMT_PCCT:
    463     case ACPI_DMT_PMTT:
    464     case ACPI_DMT_PPTT:
    465     case ACPI_DMT_SRAT:
    466     case ACPI_DMT_ASF:
    467     case ACPI_DMT_HESTNTYP:
    468     case ACPI_DMT_FADTPM:
    469     case ACPI_DMT_EINJACT:
    470     case ACPI_DMT_EINJINST:
    471     case ACPI_DMT_ERSTACT:
    472     case ACPI_DMT_ERSTINST:
    473     case ACPI_DMT_DMAR_SCOPE:
    474 
    475         ByteLength = 1;
    476         break;
    477 
    478     case ACPI_DMT_UINT16:
    479     case ACPI_DMT_DMAR:
    480     case ACPI_DMT_HEST:
    481     case ACPI_DMT_HMAT:
    482     case ACPI_DMT_NFIT:
    483     case ACPI_DMT_PCI_PATH:
    484 
    485         ByteLength = 2;
    486         break;
    487 
    488     case ACPI_DMT_UINT24:
    489 
    490         ByteLength = 3;
    491         break;
    492 
    493     case ACPI_DMT_UINT32:
    494     case ACPI_DMT_NAME4:
    495     case ACPI_DMT_SIG:
    496     case ACPI_DMT_LPIT:
    497 
    498         ByteLength = 4;
    499         break;
    500 
    501     case ACPI_DMT_UINT40:
    502 
    503         ByteLength = 5;
    504         break;
    505 
    506     case ACPI_DMT_UINT48:
    507     case ACPI_DMT_NAME6:
    508 
    509         ByteLength = 6;
    510         break;
    511 
    512     case ACPI_DMT_UINT56:
    513     case ACPI_DMT_BUF7:
    514 
    515         ByteLength = 7;
    516         break;
    517 
    518     case ACPI_DMT_UINT64:
    519     case ACPI_DMT_NAME8:
    520 
    521         ByteLength = 8;
    522         break;
    523 
    524     case ACPI_DMT_STRING:
    525 
    526         Value = DtGetFieldValue (Field);
    527         if (Value)
    528         {
    529             ByteLength = strlen (Value) + 1;
    530         }
    531         else
    532         {   /* At this point, this is a fatal error */
    533 
    534             sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
    535             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
    536             return (0);
    537         }
    538         break;
    539 
    540     case ACPI_DMT_GAS:
    541 
    542         ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
    543         break;
    544 
    545     case ACPI_DMT_HESTNTFY:
    546 
    547         ByteLength = sizeof (ACPI_HEST_NOTIFY);
    548         break;
    549 
    550     case ACPI_DMT_IORTMEM:
    551 
    552         ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS);
    553         break;
    554 
    555     case ACPI_DMT_BUFFER:
    556     case ACPI_DMT_RAW_BUFFER:
    557 
    558         Value = DtGetFieldValue (Field);
    559         if (Value)
    560         {
    561             ByteLength = DtGetBufferLength (Value);
    562         }
    563         else
    564         {   /* At this point, this is a fatal error */
    565 
    566             sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
    567             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
    568             return (0);
    569         }
    570         break;
    571 
    572     case ACPI_DMT_BUF10:
    573 
    574         ByteLength = 10;
    575         break;
    576 
    577     case ACPI_DMT_BUF12:
    578 
    579         ByteLength = 12;
    580         break;
    581 
    582     case ACPI_DMT_BUF16:
    583     case ACPI_DMT_UUID:
    584 
    585         ByteLength = 16;
    586         break;
    587 
    588     case ACPI_DMT_BUF128:
    589 
    590         ByteLength = 128;
    591         break;
    592 
    593     case ACPI_DMT_UNICODE:
    594 
    595         Value = DtGetFieldValue (Field);
    596 
    597         /* TBD: error if Value is NULL? (as below?) */
    598 
    599         ByteLength = (strlen (Value) + 1) * sizeof(UINT16);
    600         break;
    601 
    602     default:
    603 
    604         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
    605         return (0);
    606     }
    607 
    608     return (ByteLength);
    609 }
    610 
    611 
    612 /******************************************************************************
    613  *
    614  * FUNCTION:    DtSum
    615  *
    616  * PARAMETERS:  DT_WALK_CALLBACK:
    617  *              Subtable            - Subtable
    618  *              Context             - Unused
    619  *              ReturnValue         - Store the checksum of subtable
    620  *
    621  * RETURN:      Status
    622  *
    623  * DESCRIPTION: Get the checksum of subtable
    624  *
    625  *****************************************************************************/
    626 
    627 static void
    628 DtSum (
    629     DT_SUBTABLE             *Subtable,
    630     void                    *Context,
    631     void                    *ReturnValue)
    632 {
    633     UINT8                   Checksum;
    634     UINT8                   *Sum = ReturnValue;
    635 
    636 
    637     Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
    638     *Sum = (UINT8) (*Sum + Checksum);
    639 }
    640 
    641 
    642 /******************************************************************************
    643  *
    644  * FUNCTION:    DtSetTableChecksum
    645  *
    646  * PARAMETERS:  ChecksumPointer     - Where to return the checksum
    647  *
    648  * RETURN:      None
    649  *
    650  * DESCRIPTION: Set checksum of the whole data table into the checksum field
    651  *
    652  *****************************************************************************/
    653 
    654 void
    655 DtSetTableChecksum (
    656     UINT8                   *ChecksumPointer)
    657 {
    658     UINT8                   Checksum = 0;
    659     UINT8                   OldSum;
    660 
    661 
    662     DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
    663 
    664     OldSum = *ChecksumPointer;
    665     Checksum = (UINT8) (Checksum - OldSum);
    666 
    667     /* Compute the final checksum */
    668 
    669     Checksum = (UINT8) (0 - Checksum);
    670     *ChecksumPointer = Checksum;
    671 }
    672 
    673 
    674 /******************************************************************************
    675  *
    676  * FUNCTION:    DtSetTableLength
    677  *
    678  * PARAMETERS:  None
    679  *
    680  * RETURN:      None
    681  *
    682  * DESCRIPTION: Walk the subtables and set all the length fields
    683  *
    684  *****************************************************************************/
    685 
    686 void
    687 DtSetTableLength (
    688     void)
    689 {
    690     DT_SUBTABLE             *ParentTable;
    691     DT_SUBTABLE             *ChildTable;
    692 
    693 
    694     ParentTable = Gbl_RootTable;
    695     ChildTable = NULL;
    696 
    697     if (!ParentTable)
    698     {
    699         return;
    700     }
    701 
    702     DtSetSubtableLength (ParentTable);
    703 
    704     while (1)
    705     {
    706         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
    707         if (ChildTable)
    708         {
    709             if (ChildTable->LengthField)
    710             {
    711                 DtSetSubtableLength (ChildTable);
    712             }
    713 
    714             if (ChildTable->Child)
    715             {
    716                 ParentTable = ChildTable;
    717                 ChildTable = NULL;
    718             }
    719             else
    720             {
    721                 ParentTable->TotalLength += ChildTable->TotalLength;
    722                 if (ParentTable->LengthField)
    723                 {
    724                     DtSetSubtableLength (ParentTable);
    725                 }
    726             }
    727         }
    728         else
    729         {
    730             ChildTable = ParentTable;
    731 
    732             if (ChildTable == Gbl_RootTable)
    733             {
    734                 break;
    735             }
    736 
    737             ParentTable = DtGetParentSubtable (ParentTable);
    738 
    739             ParentTable->TotalLength += ChildTable->TotalLength;
    740             if (ParentTable->LengthField)
    741             {
    742                 DtSetSubtableLength (ParentTable);
    743             }
    744         }
    745     }
    746 }
    747 
    748 
    749 /******************************************************************************
    750  *
    751  * FUNCTION:    DtWalkTableTree
    752  *
    753  * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
    754  *              UserFunction        - Called during the walk
    755  *              Context             - Passed to user function
    756  *              ReturnValue         - The return value of UserFunction
    757  *
    758  * RETURN:      None
    759  *
    760  * DESCRIPTION: Performs a depth-first walk of the subtable tree
    761  *
    762  *****************************************************************************/
    763 
    764 void
    765 DtWalkTableTree (
    766     DT_SUBTABLE             *StartTable,
    767     DT_WALK_CALLBACK        UserFunction,
    768     void                    *Context,
    769     void                    *ReturnValue)
    770 {
    771     DT_SUBTABLE             *ParentTable;
    772     DT_SUBTABLE             *ChildTable;
    773 
    774 
    775     ParentTable = StartTable;
    776     ChildTable = NULL;
    777 
    778     if (!ParentTable)
    779     {
    780         return;
    781     }
    782 
    783     UserFunction (ParentTable, Context, ReturnValue);
    784 
    785     while (1)
    786     {
    787         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
    788         if (ChildTable)
    789         {
    790             UserFunction (ChildTable, Context, ReturnValue);
    791 
    792             if (ChildTable->Child)
    793             {
    794                 ParentTable = ChildTable;
    795                 ChildTable = NULL;
    796             }
    797         }
    798         else
    799         {
    800             ChildTable = ParentTable;
    801             if (ChildTable == Gbl_RootTable)
    802             {
    803                 break;
    804             }
    805 
    806             ParentTable = DtGetParentSubtable (ParentTable);
    807 
    808             if (ChildTable->Peer == StartTable)
    809             {
    810                 break;
    811             }
    812         }
    813     }
    814 }
    815 
    816 
    817 /*******************************************************************************
    818  *
    819  * FUNCTION:    UtSubtableCacheCalloc
    820  *
    821  * PARAMETERS:  None
    822  *
    823  * RETURN:      Pointer to the buffer. Aborts on allocation failure
    824  *
    825  * DESCRIPTION: Allocate a subtable object buffer. Bypass the local
    826  *              dynamic memory manager for performance reasons (This has a
    827  *              major impact on the speed of the compiler.)
    828  *
    829  ******************************************************************************/
    830 
    831 DT_SUBTABLE *
    832 UtSubtableCacheCalloc (
    833     void)
    834 {
    835     ASL_CACHE_INFO          *Cache;
    836 
    837 
    838     if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast)
    839     {
    840         /* Allocate a new buffer */
    841 
    842         Cache = UtLocalCalloc (sizeof (Cache->Next) +
    843             (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE));
    844 
    845         /* Link new cache buffer to head of list */
    846 
    847         Cache->Next = Gbl_SubtableCacheList;
    848         Gbl_SubtableCacheList = Cache;
    849 
    850         /* Setup cache management pointers */
    851 
    852         Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer);
    853         Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE;
    854     }
    855 
    856     Gbl_SubtableCount++;
    857     return (Gbl_SubtableCacheNext++);
    858 }
    859 
    860 
    861 /*******************************************************************************
    862  *
    863  * FUNCTION:    UtFieldCacheCalloc
    864  *
    865  * PARAMETERS:  None
    866  *
    867  * RETURN:      Pointer to the buffer. Aborts on allocation failure
    868  *
    869  * DESCRIPTION: Allocate a field object buffer. Bypass the local
    870  *              dynamic memory manager for performance reasons (This has a
    871  *              major impact on the speed of the compiler.)
    872  *
    873  ******************************************************************************/
    874 
    875 DT_FIELD *
    876 UtFieldCacheCalloc (
    877     void)
    878 {
    879     ASL_CACHE_INFO          *Cache;
    880 
    881 
    882     if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast)
    883     {
    884         /* Allocate a new buffer */
    885 
    886         Cache = UtLocalCalloc (sizeof (Cache->Next) +
    887             (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE));
    888 
    889         /* Link new cache buffer to head of list */
    890 
    891         Cache->Next = Gbl_FieldCacheList;
    892         Gbl_FieldCacheList = Cache;
    893 
    894         /* Setup cache management pointers */
    895 
    896         Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer);
    897         Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE;
    898     }
    899 
    900     Gbl_FieldCount++;
    901     return (Gbl_FieldCacheNext++);
    902 }
    903 
    904 
    905 /*******************************************************************************
    906  *
    907  * FUNCTION:    DtDeleteCaches
    908  *
    909  * PARAMETERS:  None
    910  *
    911  * RETURN:      None
    912  *
    913  * DESCRIPTION: Delete all local cache buffer blocks
    914  *
    915  ******************************************************************************/
    916 
    917 void
    918 DtDeleteCaches (
    919     void)
    920 {
    921     UINT32                  BufferCount;
    922     ASL_CACHE_INFO          *Next;
    923 
    924 
    925     /* Field cache */
    926 
    927     BufferCount = 0;
    928     while (Gbl_FieldCacheList)
    929     {
    930         Next = Gbl_FieldCacheList->Next;
    931         ACPI_FREE (Gbl_FieldCacheList);
    932         Gbl_FieldCacheList = Next;
    933         BufferCount++;
    934     }
    935 
    936     DbgPrint (ASL_DEBUG_OUTPUT,
    937         "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n",
    938         Gbl_FieldCount, ASL_FIELD_CACHE_SIZE,
    939         (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount);
    940 
    941     Gbl_FieldCount = 0;
    942     Gbl_FieldCacheNext = NULL;
    943     Gbl_FieldCacheLast = NULL;
    944 
    945     /* Subtable cache */
    946 
    947     BufferCount = 0;
    948     while (Gbl_SubtableCacheList)
    949     {
    950         Next = Gbl_SubtableCacheList->Next;
    951         ACPI_FREE (Gbl_SubtableCacheList);
    952         Gbl_SubtableCacheList = Next;
    953         BufferCount++;
    954     }
    955 
    956     DbgPrint (ASL_DEBUG_OUTPUT,
    957         "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n",
    958         Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE,
    959         (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount);
    960 
    961     Gbl_SubtableCount = 0;
    962     Gbl_SubtableCacheNext = NULL;
    963     Gbl_SubtableCacheLast = NULL;
    964 }
    965