Home | History | Annotate | Line # | Download | only in compiler
dtutils.c revision 1.3.2.2
      1 /******************************************************************************
      2  *
      3  * Module Name: dtutils.c - Utility routines for the data table compiler
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, 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 (AslIsExceptionDisabled (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:    DtStrtoul64
    201  *
    202  * PARAMETERS:  String              - Null terminated string
    203  *              ReturnInteger       - Where the converted integer is returned
    204  *
    205  * RETURN:      Status
    206  *
    207  * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
    208  *              value. Assumes no leading "0x" for the constant.
    209  *
    210  * Portability note: The reason this function exists is because a 64-bit
    211  * sscanf is not available in all environments.
    212  *
    213  *****************************************************************************/
    214 
    215 ACPI_STATUS
    216 DtStrtoul64 (
    217     char                    *String,
    218     UINT64                  *ReturnInteger)
    219 {
    220     char                    *ThisChar = String;
    221     UINT32                  ThisDigit;
    222     UINT64                  ReturnValue = 0;
    223     int                     DigitCount = 0;
    224 
    225 
    226     /* Skip over any white space in the buffer */
    227 
    228     while ((*ThisChar == ' ') || (*ThisChar == '\t'))
    229     {
    230         ThisChar++;
    231     }
    232 
    233     /* Skip leading zeros */
    234 
    235     while ((*ThisChar) == '0')
    236     {
    237         ThisChar++;
    238     }
    239 
    240     /* Convert character-by-character */
    241 
    242     while (*ThisChar)
    243     {
    244         if (isdigit ((int) *ThisChar))
    245         {
    246             /* Convert ASCII 0-9 to Decimal value */
    247 
    248             ThisDigit = ((UINT8) *ThisChar) - '0';
    249         }
    250         else /* Letter */
    251         {
    252             ThisDigit = (UINT32) toupper ((int) *ThisChar);
    253             if (!isxdigit ((int) ThisDigit))
    254             {
    255                 /* Not A-F */
    256 
    257                 return (AE_BAD_CHARACTER);
    258             }
    259 
    260             /* Convert ASCII Hex char (A-F) to value */
    261 
    262             ThisDigit = (ThisDigit - 'A') + 10;
    263         }
    264 
    265         /* Insert the 4-bit hex digit */
    266 
    267         ReturnValue <<= 4;
    268         ReturnValue += ThisDigit;
    269 
    270         ThisChar++;
    271         DigitCount++;
    272         if (DigitCount > 16)
    273         {
    274             /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
    275 
    276             return (AE_LIMIT);
    277         }
    278     }
    279 
    280     *ReturnInteger = ReturnValue;
    281     return (AE_OK);
    282 }
    283 
    284 
    285 /******************************************************************************
    286  *
    287  * FUNCTION:    DtGetFieldValue
    288  *
    289  * PARAMETERS:  Field               - Current field list pointer
    290  *
    291  * RETURN:      Field value
    292  *
    293  * DESCRIPTION: Get field value
    294  *
    295  *****************************************************************************/
    296 
    297 char *
    298 DtGetFieldValue (
    299     DT_FIELD                *Field)
    300 {
    301     if (!Field)
    302     {
    303         return (NULL);
    304     }
    305 
    306     return (Field->Value);
    307 }
    308 
    309 
    310 /******************************************************************************
    311  *
    312  * FUNCTION:    DtGetFieldType
    313  *
    314  * PARAMETERS:  Info                - Data table info
    315  *
    316  * RETURN:      Field type
    317  *
    318  * DESCRIPTION: Get field type
    319  *
    320  *****************************************************************************/
    321 
    322 UINT8
    323 DtGetFieldType (
    324     ACPI_DMTABLE_INFO       *Info)
    325 {
    326     UINT8                   Type;
    327 
    328 
    329     /* DT_FLAG means that this is the start of a block of flag bits */
    330     /* TBD - we can make these a separate opcode later */
    331 
    332     if (Info->Flags & DT_FLAG)
    333     {
    334         return (DT_FIELD_TYPE_FLAGS_INTEGER);
    335     }
    336 
    337     /* Type is based upon the opcode for this field in the info table */
    338 
    339     switch (Info->Opcode)
    340     {
    341     case ACPI_DMT_FLAG0:
    342     case ACPI_DMT_FLAG1:
    343     case ACPI_DMT_FLAG2:
    344     case ACPI_DMT_FLAG3:
    345     case ACPI_DMT_FLAG4:
    346     case ACPI_DMT_FLAG5:
    347     case ACPI_DMT_FLAG6:
    348     case ACPI_DMT_FLAG7:
    349     case ACPI_DMT_FLAGS0:
    350     case ACPI_DMT_FLAGS1:
    351     case ACPI_DMT_FLAGS2:
    352     case ACPI_DMT_FLAGS4:
    353 
    354         Type = DT_FIELD_TYPE_FLAG;
    355         break;
    356 
    357     case ACPI_DMT_NAME4:
    358     case ACPI_DMT_SIG:
    359     case ACPI_DMT_NAME6:
    360     case ACPI_DMT_NAME8:
    361     case ACPI_DMT_STRING:
    362 
    363         Type = DT_FIELD_TYPE_STRING;
    364         break;
    365 
    366     case ACPI_DMT_BUFFER:
    367     case ACPI_DMT_RAW_BUFFER:
    368     case ACPI_DMT_BUF7:
    369     case ACPI_DMT_BUF10:
    370     case ACPI_DMT_BUF16:
    371     case ACPI_DMT_BUF128:
    372     case ACPI_DMT_PCI_PATH:
    373 
    374         Type = DT_FIELD_TYPE_BUFFER;
    375         break;
    376 
    377     case ACPI_DMT_GAS:
    378     case ACPI_DMT_HESTNTFY:
    379     case ACPI_DMT_IORTMEM:
    380 
    381         Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
    382         break;
    383 
    384     case ACPI_DMT_UNICODE:
    385 
    386         Type = DT_FIELD_TYPE_UNICODE;
    387         break;
    388 
    389     case ACPI_DMT_UUID:
    390 
    391         Type = DT_FIELD_TYPE_UUID;
    392         break;
    393 
    394     case ACPI_DMT_DEVICE_PATH:
    395 
    396         Type = DT_FIELD_TYPE_DEVICE_PATH;
    397         break;
    398 
    399     case ACPI_DMT_LABEL:
    400 
    401         Type = DT_FIELD_TYPE_LABEL;
    402         break;
    403 
    404     default:
    405 
    406         Type = DT_FIELD_TYPE_INTEGER;
    407         break;
    408     }
    409 
    410     return (Type);
    411 }
    412 
    413 
    414 /******************************************************************************
    415  *
    416  * FUNCTION:    DtGetBufferLength
    417  *
    418  * PARAMETERS:  Buffer              - List of integers,
    419  *                                    for example "10 3A 4F 2E"
    420  *
    421  * RETURN:      Count of integer
    422  *
    423  * DESCRIPTION: Get length of bytes needed to store the integers
    424  *
    425  *****************************************************************************/
    426 
    427 UINT32
    428 DtGetBufferLength (
    429     char                    *Buffer)
    430 {
    431     UINT32                  ByteLength = 0;
    432 
    433 
    434     while (*Buffer)
    435     {
    436         if (*Buffer == ' ')
    437         {
    438             ByteLength++;
    439 
    440             while (*Buffer == ' ')
    441             {
    442                 Buffer++;
    443             }
    444         }
    445 
    446         Buffer++;
    447     }
    448 
    449     return (++ByteLength);
    450 }
    451 
    452 
    453 /******************************************************************************
    454  *
    455  * FUNCTION:    DtGetFieldLength
    456  *
    457  * PARAMETERS:  Field               - Current field
    458  *              Info                - Data table info
    459  *
    460  * RETURN:      Field length
    461  *
    462  * DESCRIPTION: Get length of bytes needed to compile the field
    463  *
    464  * Note: This function must remain in sync with AcpiDmDumpTable.
    465  *
    466  *****************************************************************************/
    467 
    468 UINT32
    469 DtGetFieldLength (
    470     DT_FIELD                *Field,
    471     ACPI_DMTABLE_INFO       *Info)
    472 {
    473     UINT32                  ByteLength = 0;
    474     char                    *Value;
    475 
    476 
    477     /* Length is based upon the opcode for this field in the info table */
    478 
    479     switch (Info->Opcode)
    480     {
    481     case ACPI_DMT_FLAG0:
    482     case ACPI_DMT_FLAG1:
    483     case ACPI_DMT_FLAG2:
    484     case ACPI_DMT_FLAG3:
    485     case ACPI_DMT_FLAG4:
    486     case ACPI_DMT_FLAG5:
    487     case ACPI_DMT_FLAG6:
    488     case ACPI_DMT_FLAG7:
    489     case ACPI_DMT_FLAGS0:
    490     case ACPI_DMT_FLAGS1:
    491     case ACPI_DMT_FLAGS2:
    492     case ACPI_DMT_FLAGS4:
    493     case ACPI_DMT_LABEL:
    494     case ACPI_DMT_EXTRA_TEXT:
    495 
    496         ByteLength = 0;
    497         break;
    498 
    499     case ACPI_DMT_UINT8:
    500     case ACPI_DMT_CHKSUM:
    501     case ACPI_DMT_SPACEID:
    502     case ACPI_DMT_ACCWIDTH:
    503     case ACPI_DMT_IVRS:
    504     case ACPI_DMT_GTDT:
    505     case ACPI_DMT_MADT:
    506     case ACPI_DMT_PCCT:
    507     case ACPI_DMT_PMTT:
    508     case ACPI_DMT_SRAT:
    509     case ACPI_DMT_ASF:
    510     case ACPI_DMT_HESTNTYP:
    511     case ACPI_DMT_FADTPM:
    512     case ACPI_DMT_EINJACT:
    513     case ACPI_DMT_EINJINST:
    514     case ACPI_DMT_ERSTACT:
    515     case ACPI_DMT_ERSTINST:
    516     case ACPI_DMT_DMAR_SCOPE:
    517 
    518         ByteLength = 1;
    519         break;
    520 
    521     case ACPI_DMT_UINT16:
    522     case ACPI_DMT_DMAR:
    523     case ACPI_DMT_HEST:
    524     case ACPI_DMT_NFIT:
    525     case ACPI_DMT_PCI_PATH:
    526 
    527         ByteLength = 2;
    528         break;
    529 
    530     case ACPI_DMT_UINT24:
    531 
    532         ByteLength = 3;
    533         break;
    534 
    535     case ACPI_DMT_UINT32:
    536     case ACPI_DMT_NAME4:
    537     case ACPI_DMT_SIG:
    538     case ACPI_DMT_LPIT:
    539 
    540         ByteLength = 4;
    541         break;
    542 
    543     case ACPI_DMT_UINT40:
    544 
    545         ByteLength = 5;
    546         break;
    547 
    548     case ACPI_DMT_UINT48:
    549     case ACPI_DMT_NAME6:
    550 
    551         ByteLength = 6;
    552         break;
    553 
    554     case ACPI_DMT_UINT56:
    555     case ACPI_DMT_BUF7:
    556 
    557         ByteLength = 7;
    558         break;
    559 
    560     case ACPI_DMT_UINT64:
    561     case ACPI_DMT_NAME8:
    562 
    563         ByteLength = 8;
    564         break;
    565 
    566     case ACPI_DMT_STRING:
    567 
    568         Value = DtGetFieldValue (Field);
    569         if (Value)
    570         {
    571             ByteLength = strlen (Value) + 1;
    572         }
    573         else
    574         {   /* At this point, this is a fatal error */
    575 
    576             snprintf (MsgBuffer, sizeof(MsgBuffer), "Expected \"%s\"", Info->Name);
    577             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
    578             return (0);
    579         }
    580         break;
    581 
    582     case ACPI_DMT_GAS:
    583 
    584         ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
    585         break;
    586 
    587     case ACPI_DMT_HESTNTFY:
    588 
    589         ByteLength = sizeof (ACPI_HEST_NOTIFY);
    590         break;
    591 
    592     case ACPI_DMT_IORTMEM:
    593 
    594         ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS);
    595         break;
    596 
    597     case ACPI_DMT_BUFFER:
    598     case ACPI_DMT_RAW_BUFFER:
    599 
    600         Value = DtGetFieldValue (Field);
    601         if (Value)
    602         {
    603             ByteLength = DtGetBufferLength (Value);
    604         }
    605         else
    606         {   /* At this point, this is a fatal error */
    607 
    608             snprintf (MsgBuffer, sizeof(MsgBuffer), "Expected \"%s\"", Info->Name);
    609             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
    610             return (0);
    611         }
    612         break;
    613 
    614     case ACPI_DMT_BUF10:
    615 
    616         ByteLength = 10;
    617         break;
    618 
    619     case ACPI_DMT_BUF16:
    620     case ACPI_DMT_UUID:
    621 
    622         ByteLength = 16;
    623         break;
    624 
    625     case ACPI_DMT_BUF128:
    626 
    627         ByteLength = 128;
    628         break;
    629 
    630     case ACPI_DMT_UNICODE:
    631 
    632         Value = DtGetFieldValue (Field);
    633 
    634         /* TBD: error if Value is NULL? (as below?) */
    635 
    636         ByteLength = (strlen (Value) + 1) * sizeof(UINT16);
    637         break;
    638 
    639     default:
    640 
    641         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
    642         return (0);
    643     }
    644 
    645     return (ByteLength);
    646 }
    647 
    648 
    649 /******************************************************************************
    650  *
    651  * FUNCTION:    DtSum
    652  *
    653  * PARAMETERS:  DT_WALK_CALLBACK:
    654  *              Subtable            - Subtable
    655  *              Context             - Unused
    656  *              ReturnValue         - Store the checksum of subtable
    657  *
    658  * RETURN:      Status
    659  *
    660  * DESCRIPTION: Get the checksum of subtable
    661  *
    662  *****************************************************************************/
    663 
    664 static void
    665 DtSum (
    666     DT_SUBTABLE             *Subtable,
    667     void                    *Context,
    668     void                    *ReturnValue)
    669 {
    670     UINT8                   Checksum;
    671     UINT8                   *Sum = ReturnValue;
    672 
    673 
    674     Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
    675     *Sum = (UINT8) (*Sum + Checksum);
    676 }
    677 
    678 
    679 /******************************************************************************
    680  *
    681  * FUNCTION:    DtSetTableChecksum
    682  *
    683  * PARAMETERS:  ChecksumPointer     - Where to return the checksum
    684  *
    685  * RETURN:      None
    686  *
    687  * DESCRIPTION: Set checksum of the whole data table into the checksum field
    688  *
    689  *****************************************************************************/
    690 
    691 void
    692 DtSetTableChecksum (
    693     UINT8                   *ChecksumPointer)
    694 {
    695     UINT8                   Checksum = 0;
    696     UINT8                   OldSum;
    697 
    698 
    699     DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
    700 
    701     OldSum = *ChecksumPointer;
    702     Checksum = (UINT8) (Checksum - OldSum);
    703 
    704     /* Compute the final checksum */
    705 
    706     Checksum = (UINT8) (0 - Checksum);
    707     *ChecksumPointer = Checksum;
    708 }
    709 
    710 
    711 /******************************************************************************
    712  *
    713  * FUNCTION:    DtSetTableLength
    714  *
    715  * PARAMETERS:  None
    716  *
    717  * RETURN:      None
    718  *
    719  * DESCRIPTION: Walk the subtables and set all the length fields
    720  *
    721  *****************************************************************************/
    722 
    723 void
    724 DtSetTableLength (
    725     void)
    726 {
    727     DT_SUBTABLE             *ParentTable;
    728     DT_SUBTABLE             *ChildTable;
    729 
    730 
    731     ParentTable = Gbl_RootTable;
    732     ChildTable = NULL;
    733 
    734     if (!ParentTable)
    735     {
    736         return;
    737     }
    738 
    739     DtSetSubtableLength (ParentTable);
    740 
    741     while (1)
    742     {
    743         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
    744         if (ChildTable)
    745         {
    746             if (ChildTable->LengthField)
    747             {
    748                 DtSetSubtableLength (ChildTable);
    749             }
    750 
    751             if (ChildTable->Child)
    752             {
    753                 ParentTable = ChildTable;
    754                 ChildTable = NULL;
    755             }
    756             else
    757             {
    758                 ParentTable->TotalLength += ChildTable->TotalLength;
    759                 if (ParentTable->LengthField)
    760                 {
    761                     DtSetSubtableLength (ParentTable);
    762                 }
    763             }
    764         }
    765         else
    766         {
    767             ChildTable = ParentTable;
    768 
    769             if (ChildTable == Gbl_RootTable)
    770             {
    771                 break;
    772             }
    773 
    774             ParentTable = DtGetParentSubtable (ParentTable);
    775 
    776             ParentTable->TotalLength += ChildTable->TotalLength;
    777             if (ParentTable->LengthField)
    778             {
    779                 DtSetSubtableLength (ParentTable);
    780             }
    781         }
    782     }
    783 }
    784 
    785 
    786 /******************************************************************************
    787  *
    788  * FUNCTION:    DtWalkTableTree
    789  *
    790  * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
    791  *              UserFunction        - Called during the walk
    792  *              Context             - Passed to user function
    793  *              ReturnValue         - The return value of UserFunction
    794  *
    795  * RETURN:      None
    796  *
    797  * DESCRIPTION: Performs a depth-first walk of the subtable tree
    798  *
    799  *****************************************************************************/
    800 
    801 void
    802 DtWalkTableTree (
    803     DT_SUBTABLE             *StartTable,
    804     DT_WALK_CALLBACK        UserFunction,
    805     void                    *Context,
    806     void                    *ReturnValue)
    807 {
    808     DT_SUBTABLE             *ParentTable;
    809     DT_SUBTABLE             *ChildTable;
    810 
    811 
    812     ParentTable = StartTable;
    813     ChildTable = NULL;
    814 
    815     if (!ParentTable)
    816     {
    817         return;
    818     }
    819 
    820     UserFunction (ParentTable, Context, ReturnValue);
    821 
    822     while (1)
    823     {
    824         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
    825         if (ChildTable)
    826         {
    827             UserFunction (ChildTable, Context, ReturnValue);
    828 
    829             if (ChildTable->Child)
    830             {
    831                 ParentTable = ChildTable;
    832                 ChildTable = NULL;
    833             }
    834         }
    835         else
    836         {
    837             ChildTable = ParentTable;
    838             if (ChildTable == Gbl_RootTable)
    839             {
    840                 break;
    841             }
    842 
    843             ParentTable = DtGetParentSubtable (ParentTable);
    844 
    845             if (ChildTable->Peer == StartTable)
    846             {
    847                 break;
    848             }
    849         }
    850     }
    851 }
    852 
    853 
    854 /*******************************************************************************
    855  *
    856  * FUNCTION:    UtSubtableCacheCalloc
    857  *
    858  * PARAMETERS:  None
    859  *
    860  * RETURN:      Pointer to the buffer. Aborts on allocation failure
    861  *
    862  * DESCRIPTION: Allocate a subtable object buffer. Bypass the local
    863  *              dynamic memory manager for performance reasons (This has a
    864  *              major impact on the speed of the compiler.)
    865  *
    866  ******************************************************************************/
    867 
    868 DT_SUBTABLE *
    869 UtSubtableCacheCalloc (
    870     void)
    871 {
    872     ASL_CACHE_INFO          *Cache;
    873 
    874 
    875     if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast)
    876     {
    877         /* Allocate a new buffer */
    878 
    879         Cache = UtLocalCalloc (sizeof (Cache->Next) +
    880             (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE));
    881 
    882         /* Link new cache buffer to head of list */
    883 
    884         Cache->Next = Gbl_SubtableCacheList;
    885         Gbl_SubtableCacheList = Cache;
    886 
    887         /* Setup cache management pointers */
    888 
    889         Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer);
    890         Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE;
    891     }
    892 
    893     Gbl_SubtableCount++;
    894     return (Gbl_SubtableCacheNext++);
    895 }
    896 
    897 
    898 /*******************************************************************************
    899  *
    900  * FUNCTION:    UtFieldCacheCalloc
    901  *
    902  * PARAMETERS:  None
    903  *
    904  * RETURN:      Pointer to the buffer. Aborts on allocation failure
    905  *
    906  * DESCRIPTION: Allocate a field object buffer. Bypass the local
    907  *              dynamic memory manager for performance reasons (This has a
    908  *              major impact on the speed of the compiler.)
    909  *
    910  ******************************************************************************/
    911 
    912 DT_FIELD *
    913 UtFieldCacheCalloc (
    914     void)
    915 {
    916     ASL_CACHE_INFO          *Cache;
    917 
    918 
    919     if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast)
    920     {
    921         /* Allocate a new buffer */
    922 
    923         Cache = UtLocalCalloc (sizeof (Cache->Next) +
    924             (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE));
    925 
    926         /* Link new cache buffer to head of list */
    927 
    928         Cache->Next = Gbl_FieldCacheList;
    929         Gbl_FieldCacheList = Cache;
    930 
    931         /* Setup cache management pointers */
    932 
    933         Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer);
    934         Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE;
    935     }
    936 
    937     Gbl_FieldCount++;
    938     return (Gbl_FieldCacheNext++);
    939 }
    940 
    941 
    942 /*******************************************************************************
    943  *
    944  * FUNCTION:    DtDeleteCaches
    945  *
    946  * PARAMETERS:  None
    947  *
    948  * RETURN:      None
    949  *
    950  * DESCRIPTION: Delete all local cache buffer blocks
    951  *
    952  ******************************************************************************/
    953 
    954 void
    955 DtDeleteCaches (
    956     void)
    957 {
    958     UINT32                  BufferCount;
    959     ASL_CACHE_INFO          *Next;
    960 
    961 
    962     /* Field cache */
    963 
    964     BufferCount = 0;
    965     while (Gbl_FieldCacheList)
    966     {
    967         Next = Gbl_FieldCacheList->Next;
    968         ACPI_FREE (Gbl_FieldCacheList);
    969         Gbl_FieldCacheList = Next;
    970         BufferCount++;
    971     }
    972 
    973     DbgPrint (ASL_DEBUG_OUTPUT,
    974         "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n",
    975         Gbl_FieldCount, ASL_FIELD_CACHE_SIZE,
    976         (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount);
    977 
    978     Gbl_FieldCount = 0;
    979     Gbl_FieldCacheNext = NULL;
    980     Gbl_FieldCacheLast = NULL;
    981 
    982     /* Subtable cache */
    983 
    984     BufferCount = 0;
    985     while (Gbl_SubtableCacheList)
    986     {
    987         Next = Gbl_SubtableCacheList->Next;
    988         ACPI_FREE (Gbl_SubtableCacheList);
    989         Gbl_SubtableCacheList = Next;
    990         BufferCount++;
    991     }
    992 
    993     DbgPrint (ASL_DEBUG_OUTPUT,
    994         "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n",
    995         Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE,
    996         (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount);
    997 
    998     Gbl_SubtableCount = 0;
    999     Gbl_SubtableCacheNext = NULL;
   1000     Gbl_SubtableCacheLast = NULL;
   1001 }
   1002