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