xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/dtutils.c (revision 987b04d624d6d5e25e3e80d683a4ebe80fe47dcf)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: dtutils.c - Utility routines for the data table compiler
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
82c7d7e3cSchristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3398244dcfSchristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "aslcompiler.h"
4528c506b8Sjruoho #include "actables.h"
4628c506b8Sjruoho 
4728c506b8Sjruoho #define _COMPONENT          DT_COMPILER
4828c506b8Sjruoho         ACPI_MODULE_NAME    ("dtutils")
4928c506b8Sjruoho 
5028c506b8Sjruoho /* Local prototypes */
5128c506b8Sjruoho 
5228c506b8Sjruoho static void
5328c506b8Sjruoho DtSum (
5428c506b8Sjruoho     DT_SUBTABLE             *Subtable,
5528c506b8Sjruoho     void                    *Context,
5628c506b8Sjruoho     void                    *ReturnValue);
5728c506b8Sjruoho 
5828c506b8Sjruoho 
5928c506b8Sjruoho /******************************************************************************
6028c506b8Sjruoho  *
6128c506b8Sjruoho  * FUNCTION:    DtError
6228c506b8Sjruoho  *
6328c506b8Sjruoho  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
6428c506b8Sjruoho  *              MessageId           - Index into global message buffer
6528c506b8Sjruoho  *              Op                  - Parse node where error happened
6628c506b8Sjruoho  *              ExtraMessage        - additional error message
6728c506b8Sjruoho  *
6828c506b8Sjruoho  * RETURN:      None
6928c506b8Sjruoho  *
7028c506b8Sjruoho  * DESCRIPTION: Common error interface for data table compiler
7128c506b8Sjruoho  *
7228c506b8Sjruoho  *****************************************************************************/
7328c506b8Sjruoho 
7428c506b8Sjruoho void
7528c506b8Sjruoho DtError (
7628c506b8Sjruoho     UINT8                   Level,
77414ef032Schristos     UINT16                  MessageId,
7828c506b8Sjruoho     DT_FIELD                *FieldObject,
7928c506b8Sjruoho     char                    *ExtraMessage)
8028c506b8Sjruoho {
81f5b481b3Schristos     UINT32                  Line = 0;
82f5b481b3Schristos 
83f5b481b3Schristos 
84f5b481b3Schristos     /* Field object could be NULL */
85f5b481b3Schristos 
86f5b481b3Schristos     if (FieldObject)
87f5b481b3Schristos     {
88f5b481b3Schristos         Line = FieldObject->Line;
89f5b481b3Schristos     }
9028c506b8Sjruoho 
91ff4a156dSchristos     /* Check if user wants to ignore this exception */
92ff4a156dSchristos 
939ddb8508Schristos     if (AslIsExceptionIgnored (AslGbl_Files[ASL_FILE_INPUT].Filename,
94f5b481b3Schristos         Line, Level, MessageId))
9528c506b8Sjruoho     {
9628c506b8Sjruoho         return;
9728c506b8Sjruoho     }
9828c506b8Sjruoho 
9928c506b8Sjruoho     if (FieldObject)
10028c506b8Sjruoho     {
10128c506b8Sjruoho         AslCommonError (Level, MessageId,
10228c506b8Sjruoho             FieldObject->Line,
10328c506b8Sjruoho             FieldObject->Line,
10428c506b8Sjruoho             FieldObject->ByteOffset,
10528c506b8Sjruoho             FieldObject->Column,
1067efa3256Schristos             AslGbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
10728c506b8Sjruoho     }
10828c506b8Sjruoho     else
10928c506b8Sjruoho     {
11028c506b8Sjruoho         AslCommonError (Level, MessageId, 0,
11128c506b8Sjruoho             0, 0, 0, 0, ExtraMessage);
11228c506b8Sjruoho     }
11328c506b8Sjruoho }
11428c506b8Sjruoho 
11528c506b8Sjruoho 
11628c506b8Sjruoho /******************************************************************************
11728c506b8Sjruoho  *
11828c506b8Sjruoho  * FUNCTION:    DtNameError
11928c506b8Sjruoho  *
12028c506b8Sjruoho  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
12128c506b8Sjruoho  *              MessageId           - Index into global message buffer
12228c506b8Sjruoho  *              Op                  - Parse node where error happened
12328c506b8Sjruoho  *              ExtraMessage        - additional error message
12428c506b8Sjruoho  *
12528c506b8Sjruoho  * RETURN:      None
12628c506b8Sjruoho  *
12728c506b8Sjruoho  * DESCRIPTION: Error interface for named objects
12828c506b8Sjruoho  *
12928c506b8Sjruoho  *****************************************************************************/
13028c506b8Sjruoho 
13128c506b8Sjruoho void
13228c506b8Sjruoho DtNameError (
13328c506b8Sjruoho     UINT8                   Level,
134414ef032Schristos     UINT16                  MessageId,
13528c506b8Sjruoho     DT_FIELD                *FieldObject,
13628c506b8Sjruoho     char                    *ExtraMessage)
13728c506b8Sjruoho {
13828c506b8Sjruoho 
13928c506b8Sjruoho     switch (Level)
14028c506b8Sjruoho     {
14128c506b8Sjruoho     case ASL_WARNING2:
14228c506b8Sjruoho     case ASL_WARNING3:
143ff4a156dSchristos 
1447efa3256Schristos         if (AslGbl_WarningLevel < Level)
14528c506b8Sjruoho         {
14628c506b8Sjruoho             return;
14728c506b8Sjruoho         }
14828c506b8Sjruoho         break;
14928c506b8Sjruoho 
15028c506b8Sjruoho     default:
151ff4a156dSchristos 
15228c506b8Sjruoho         break;
15328c506b8Sjruoho     }
15428c506b8Sjruoho 
15528c506b8Sjruoho     if (FieldObject)
15628c506b8Sjruoho     {
15728c506b8Sjruoho         AslCommonError (Level, MessageId,
15828c506b8Sjruoho             FieldObject->Line,
15928c506b8Sjruoho             FieldObject->Line,
16028c506b8Sjruoho             FieldObject->ByteOffset,
16128c506b8Sjruoho             FieldObject->NameColumn,
1627efa3256Schristos             AslGbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
16328c506b8Sjruoho     }
16428c506b8Sjruoho     else
16528c506b8Sjruoho     {
16628c506b8Sjruoho         AslCommonError (Level, MessageId, 0,
16728c506b8Sjruoho             0, 0, 0, 0, ExtraMessage);
16828c506b8Sjruoho     }
16928c506b8Sjruoho }
17028c506b8Sjruoho 
17128c506b8Sjruoho 
17228c506b8Sjruoho /*******************************************************************************
17328c506b8Sjruoho  *
17428c506b8Sjruoho  * FUNCTION:    DtFatal
17528c506b8Sjruoho  *
17628c506b8Sjruoho  * PARAMETERS:  None
17728c506b8Sjruoho  *
17828c506b8Sjruoho  * RETURN:      None
17928c506b8Sjruoho  *
18028c506b8Sjruoho  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
18128c506b8Sjruoho  *              compile or I/O errors
18228c506b8Sjruoho  *
18328c506b8Sjruoho  ******************************************************************************/
18428c506b8Sjruoho 
18528c506b8Sjruoho void
18628c506b8Sjruoho DtFatal (
187414ef032Schristos     UINT16                  MessageId,
18828c506b8Sjruoho     DT_FIELD                *FieldObject,
18928c506b8Sjruoho     char                    *ExtraMessage)
19028c506b8Sjruoho {
19128c506b8Sjruoho 
19228c506b8Sjruoho     DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
19328c506b8Sjruoho 
194a8e4c046Sjruoho /*
195a8e4c046Sjruoho  * TBD: remove this entire function, DtFatal
196a8e4c046Sjruoho  *
197a8e4c046Sjruoho  * We cannot abort the compiler on error, because we may be compiling a
198a8e4c046Sjruoho  * list of files. We must move on to the next file.
199a8e4c046Sjruoho  */
200a8e4c046Sjruoho #ifdef __OBSOLETE
20128c506b8Sjruoho     CmCleanupAndExit ();
20228c506b8Sjruoho     exit (1);
203a8e4c046Sjruoho #endif
20428c506b8Sjruoho }
20528c506b8Sjruoho 
20628c506b8Sjruoho 
207ae01dbf5Schristos /*******************************************************************************
208ae01dbf5Schristos  *
209ae01dbf5Schristos  * FUNCTION:    DtDoConstant
210ae01dbf5Schristos  *
211ae01dbf5Schristos  * PARAMETERS:  String              - Only hex constants are supported,
212ae01dbf5Schristos  *                                    regardless of whether the 0x prefix
213ae01dbf5Schristos  *                                    is used
214ae01dbf5Schristos  *
215ae01dbf5Schristos  * RETURN:      Converted Integer
216ae01dbf5Schristos  *
217ae01dbf5Schristos  * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
218ae01dbf5Schristos  *
219ae01dbf5Schristos  ******************************************************************************/
220ae01dbf5Schristos 
221ae01dbf5Schristos UINT64
222ae01dbf5Schristos DtDoConstant (
223ae01dbf5Schristos     char                    *String)
224ae01dbf5Schristos {
225ae01dbf5Schristos     UINT64                  ConvertedInteger;
226ae01dbf5Schristos 
227ae01dbf5Schristos 
228ae01dbf5Schristos     /*
229ae01dbf5Schristos      * TBD: The ImplicitStrtoul64 function does not report overflow
230ae01dbf5Schristos      * conditions. The input string is simply truncated. If it is
231ae01dbf5Schristos      * desired to report overflow to the table compiler, this should
232ae01dbf5Schristos      * somehow be added here. Note: integers that are prefixed with 0x
233ae01dbf5Schristos      * or not are both hex integers.
234ae01dbf5Schristos      */
235ae01dbf5Schristos     ConvertedInteger = AcpiUtImplicitStrtoul64 (String);
236ae01dbf5Schristos     return (ConvertedInteger);
237ae01dbf5Schristos }
238ae01dbf5Schristos 
23928c506b8Sjruoho /******************************************************************************
24028c506b8Sjruoho  *
24128c506b8Sjruoho  * FUNCTION:    DtGetFieldValue
24228c506b8Sjruoho  *
24328c506b8Sjruoho  * PARAMETERS:  Field               - Current field list pointer
24428c506b8Sjruoho  *
24528c506b8Sjruoho  * RETURN:      Field value
24628c506b8Sjruoho  *
24728c506b8Sjruoho  * DESCRIPTION: Get field value
24828c506b8Sjruoho  *
24928c506b8Sjruoho  *****************************************************************************/
25028c506b8Sjruoho 
25128c506b8Sjruoho char *
25228c506b8Sjruoho DtGetFieldValue (
253a8e4c046Sjruoho     DT_FIELD                *Field)
25428c506b8Sjruoho {
255a8e4c046Sjruoho     if (!Field)
25628c506b8Sjruoho     {
25728c506b8Sjruoho         return (NULL);
25828c506b8Sjruoho     }
25928c506b8Sjruoho 
260a8e4c046Sjruoho     return (Field->Value);
261a8e4c046Sjruoho }
262a8e4c046Sjruoho 
26328c506b8Sjruoho 
26428c506b8Sjruoho /******************************************************************************
26528c506b8Sjruoho  *
26628c506b8Sjruoho  * FUNCTION:    DtGetFieldType
26728c506b8Sjruoho  *
26828c506b8Sjruoho  * PARAMETERS:  Info                - Data table info
26928c506b8Sjruoho  *
27028c506b8Sjruoho  * RETURN:      Field type
27128c506b8Sjruoho  *
27228c506b8Sjruoho  * DESCRIPTION: Get field type
27328c506b8Sjruoho  *
27428c506b8Sjruoho  *****************************************************************************/
27528c506b8Sjruoho 
27628c506b8Sjruoho UINT8
27728c506b8Sjruoho DtGetFieldType (
27828c506b8Sjruoho     ACPI_DMTABLE_INFO       *Info)
27928c506b8Sjruoho {
28028c506b8Sjruoho     UINT8                   Type;
28128c506b8Sjruoho 
28228c506b8Sjruoho 
28328c506b8Sjruoho     /* DT_FLAG means that this is the start of a block of flag bits */
28428c506b8Sjruoho     /* TBD - we can make these a separate opcode later */
28528c506b8Sjruoho 
28628c506b8Sjruoho     if (Info->Flags & DT_FLAG)
28728c506b8Sjruoho     {
28828c506b8Sjruoho         return (DT_FIELD_TYPE_FLAGS_INTEGER);
28928c506b8Sjruoho     }
29028c506b8Sjruoho 
29128c506b8Sjruoho     /* Type is based upon the opcode for this field in the info table */
29228c506b8Sjruoho 
29328c506b8Sjruoho     switch (Info->Opcode)
29428c506b8Sjruoho     {
29528c506b8Sjruoho     case ACPI_DMT_FLAG0:
29628c506b8Sjruoho     case ACPI_DMT_FLAG1:
29728c506b8Sjruoho     case ACPI_DMT_FLAG2:
29828c506b8Sjruoho     case ACPI_DMT_FLAG3:
29928c506b8Sjruoho     case ACPI_DMT_FLAG4:
30028c506b8Sjruoho     case ACPI_DMT_FLAG5:
30128c506b8Sjruoho     case ACPI_DMT_FLAG6:
30228c506b8Sjruoho     case ACPI_DMT_FLAG7:
30328c506b8Sjruoho     case ACPI_DMT_FLAGS0:
304ff4a156dSchristos     case ACPI_DMT_FLAGS1:
30528c506b8Sjruoho     case ACPI_DMT_FLAGS2:
306bae73670Schristos     case ACPI_DMT_FLAGS8_2:
307ff4a156dSchristos     case ACPI_DMT_FLAGS4:
308ae01dbf5Schristos     case ACPI_DMT_FLAGS4_0:
309ae01dbf5Schristos     case ACPI_DMT_FLAGS4_4:
310ae01dbf5Schristos     case ACPI_DMT_FLAGS4_8:
311ae01dbf5Schristos     case ACPI_DMT_FLAGS4_12:
312ae01dbf5Schristos     case ACPI_DMT_FLAGS16_16:
313ff4a156dSchristos 
31428c506b8Sjruoho         Type = DT_FIELD_TYPE_FLAG;
31528c506b8Sjruoho         break;
31628c506b8Sjruoho 
31728c506b8Sjruoho     case ACPI_DMT_NAME4:
31828c506b8Sjruoho     case ACPI_DMT_SIG:
31928c506b8Sjruoho     case ACPI_DMT_NAME6:
32028c506b8Sjruoho     case ACPI_DMT_NAME8:
32128c506b8Sjruoho     case ACPI_DMT_STRING:
3222546ead2Schristos     case ACPI_DMT_IVRS_UNTERMINATED_STRING:
323ff4a156dSchristos 
32428c506b8Sjruoho         Type = DT_FIELD_TYPE_STRING;
32528c506b8Sjruoho         break;
32628c506b8Sjruoho 
32728c506b8Sjruoho     case ACPI_DMT_BUFFER:
328cb2bd8f0Schristos     case ACPI_DMT_RAW_BUFFER:
329124f4c82Sjruoho     case ACPI_DMT_BUF7:
330ff4a156dSchristos     case ACPI_DMT_BUF10:
33147dc3895Schristos     case ACPI_DMT_BUF12:
33228c506b8Sjruoho     case ACPI_DMT_BUF16:
333a43dcd2aSchristos     case ACPI_DMT_BUF18:
334*987b04d6Schristos     case ACPI_DMT_BUF32:
335*987b04d6Schristos     case ACPI_DMT_BUF112:
336a8e4c046Sjruoho     case ACPI_DMT_BUF128:
33728c506b8Sjruoho     case ACPI_DMT_PCI_PATH:
33898244dcfSchristos     case ACPI_DMT_PMTT_VENDOR:
339ff4a156dSchristos 
340124f4c82Sjruoho         Type = DT_FIELD_TYPE_BUFFER;
34128c506b8Sjruoho         break;
34228c506b8Sjruoho 
34328c506b8Sjruoho     case ACPI_DMT_GAS:
34428c506b8Sjruoho     case ACPI_DMT_HESTNTFY:
3459b9ee194Schristos     case ACPI_DMT_IORTMEM:
346ff4a156dSchristos 
34728c506b8Sjruoho         Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
34828c506b8Sjruoho         break;
34928c506b8Sjruoho 
350124f4c82Sjruoho     case ACPI_DMT_UNICODE:
35186cbec8eSchristos     case ACPI_DMT_WPBT_UNICODE:
352ff4a156dSchristos 
353124f4c82Sjruoho         Type = DT_FIELD_TYPE_UNICODE;
354124f4c82Sjruoho         break;
355124f4c82Sjruoho 
356124f4c82Sjruoho     case ACPI_DMT_UUID:
357ff4a156dSchristos 
358124f4c82Sjruoho         Type = DT_FIELD_TYPE_UUID;
359124f4c82Sjruoho         break;
360124f4c82Sjruoho 
361124f4c82Sjruoho     case ACPI_DMT_DEVICE_PATH:
362ff4a156dSchristos 
363124f4c82Sjruoho         Type = DT_FIELD_TYPE_DEVICE_PATH;
364124f4c82Sjruoho         break;
365124f4c82Sjruoho 
366124f4c82Sjruoho     case ACPI_DMT_LABEL:
367ff4a156dSchristos 
368124f4c82Sjruoho         Type = DT_FIELD_TYPE_LABEL;
369124f4c82Sjruoho         break;
370124f4c82Sjruoho 
37128c506b8Sjruoho     default:
372ff4a156dSchristos 
37328c506b8Sjruoho         Type = DT_FIELD_TYPE_INTEGER;
37428c506b8Sjruoho         break;
37528c506b8Sjruoho     }
37628c506b8Sjruoho 
37728c506b8Sjruoho     return (Type);
37828c506b8Sjruoho }
37928c506b8Sjruoho 
38028c506b8Sjruoho 
38128c506b8Sjruoho /******************************************************************************
38228c506b8Sjruoho  *
38328c506b8Sjruoho  * FUNCTION:    DtGetBufferLength
38428c506b8Sjruoho  *
38528c506b8Sjruoho  * PARAMETERS:  Buffer              - List of integers,
38628c506b8Sjruoho  *                                    for example "10 3A 4F 2E"
38728c506b8Sjruoho  *
38828c506b8Sjruoho  * RETURN:      Count of integer
38928c506b8Sjruoho  *
39028c506b8Sjruoho  * DESCRIPTION: Get length of bytes needed to store the integers
39128c506b8Sjruoho  *
39228c506b8Sjruoho  *****************************************************************************/
39328c506b8Sjruoho 
39428c506b8Sjruoho UINT32
39528c506b8Sjruoho DtGetBufferLength (
39628c506b8Sjruoho     char                    *Buffer)
39728c506b8Sjruoho {
39828c506b8Sjruoho     UINT32                  ByteLength = 0;
39928c506b8Sjruoho 
40028c506b8Sjruoho 
40128c506b8Sjruoho     while (*Buffer)
40228c506b8Sjruoho     {
40328c506b8Sjruoho         if (*Buffer == ' ')
40428c506b8Sjruoho         {
40528c506b8Sjruoho             ByteLength++;
40628c506b8Sjruoho 
40728c506b8Sjruoho             while (*Buffer == ' ')
40828c506b8Sjruoho             {
40928c506b8Sjruoho                 Buffer++;
41028c506b8Sjruoho             }
41128c506b8Sjruoho         }
41228c506b8Sjruoho 
41328c506b8Sjruoho         Buffer++;
41428c506b8Sjruoho     }
41528c506b8Sjruoho 
41628c506b8Sjruoho     return (++ByteLength);
41728c506b8Sjruoho }
41828c506b8Sjruoho 
41928c506b8Sjruoho 
42028c506b8Sjruoho /******************************************************************************
42128c506b8Sjruoho  *
42228c506b8Sjruoho  * FUNCTION:    DtGetFieldLength
42328c506b8Sjruoho  *
424a8e4c046Sjruoho  * PARAMETERS:  Field               - Current field
42528c506b8Sjruoho  *              Info                - Data table info
42628c506b8Sjruoho  *
42728c506b8Sjruoho  * RETURN:      Field length
42828c506b8Sjruoho  *
42928c506b8Sjruoho  * DESCRIPTION: Get length of bytes needed to compile the field
43028c506b8Sjruoho  *
431124f4c82Sjruoho  * Note: This function must remain in sync with AcpiDmDumpTable.
432124f4c82Sjruoho  *
43328c506b8Sjruoho  *****************************************************************************/
43428c506b8Sjruoho 
43528c506b8Sjruoho UINT32
43628c506b8Sjruoho DtGetFieldLength (
43728c506b8Sjruoho     DT_FIELD                *Field,
43828c506b8Sjruoho     ACPI_DMTABLE_INFO       *Info)
43928c506b8Sjruoho {
44028c506b8Sjruoho     UINT32                  ByteLength = 0;
44128c506b8Sjruoho     char                    *Value;
44228c506b8Sjruoho 
44328c506b8Sjruoho 
44428c506b8Sjruoho     /* Length is based upon the opcode for this field in the info table */
44528c506b8Sjruoho 
44628c506b8Sjruoho     switch (Info->Opcode)
44728c506b8Sjruoho     {
44828c506b8Sjruoho     case ACPI_DMT_FLAG0:
44928c506b8Sjruoho     case ACPI_DMT_FLAG1:
45028c506b8Sjruoho     case ACPI_DMT_FLAG2:
45128c506b8Sjruoho     case ACPI_DMT_FLAG3:
45228c506b8Sjruoho     case ACPI_DMT_FLAG4:
45328c506b8Sjruoho     case ACPI_DMT_FLAG5:
45428c506b8Sjruoho     case ACPI_DMT_FLAG6:
45528c506b8Sjruoho     case ACPI_DMT_FLAG7:
45628c506b8Sjruoho     case ACPI_DMT_FLAGS0:
457ff4a156dSchristos     case ACPI_DMT_FLAGS1:
45828c506b8Sjruoho     case ACPI_DMT_FLAGS2:
459bae73670Schristos     case ACPI_DMT_FLAGS8_2:
460ff4a156dSchristos     case ACPI_DMT_FLAGS4:
461ae01dbf5Schristos     case ACPI_DMT_FLAGS4_0:
462ae01dbf5Schristos     case ACPI_DMT_FLAGS4_4:
463ae01dbf5Schristos     case ACPI_DMT_FLAGS4_8:
464ae01dbf5Schristos     case ACPI_DMT_FLAGS4_12:
465ae01dbf5Schristos     case ACPI_DMT_FLAGS16_16:
466124f4c82Sjruoho     case ACPI_DMT_LABEL:
467ff4a156dSchristos     case ACPI_DMT_EXTRA_TEXT:
468ff4a156dSchristos 
46928c506b8Sjruoho         ByteLength = 0;
47028c506b8Sjruoho         break;
47128c506b8Sjruoho 
47228c506b8Sjruoho     case ACPI_DMT_UINT8:
47328c506b8Sjruoho     case ACPI_DMT_CHKSUM:
47428c506b8Sjruoho     case ACPI_DMT_SPACEID:
475124f4c82Sjruoho     case ACPI_DMT_ACCWIDTH:
47698244dcfSchristos     case ACPI_DMT_CEDT:
477124f4c82Sjruoho     case ACPI_DMT_IVRS:
4782546ead2Schristos     case ACPI_DMT_IVRS_DE:
479414ef032Schristos     case ACPI_DMT_GTDT:
48028c506b8Sjruoho     case ACPI_DMT_MADT:
4812c7d7e3cSchristos     case ACPI_DMT_MPAM_LOCATOR:
482ff4a156dSchristos     case ACPI_DMT_PCCT:
483ff4a156dSchristos     case ACPI_DMT_PMTT:
484ae01dbf5Schristos     case ACPI_DMT_PPTT:
4852546ead2Schristos     case ACPI_DMT_RGRT:
48625666a51Schristos     case ACPI_DMT_SDEV:
48728c506b8Sjruoho     case ACPI_DMT_SRAT:
48886cbec8eSchristos     case ACPI_DMT_AEST:
48986cbec8eSchristos     case ACPI_DMT_AEST_RES:
49086cbec8eSchristos     case ACPI_DMT_AEST_XFACE:
49186cbec8eSchristos     case ACPI_DMT_AEST_XRUPT:
49228c506b8Sjruoho     case ACPI_DMT_ASF:
493121a0548Schristos     case ACPI_DMT_CDAT:
49428c506b8Sjruoho     case ACPI_DMT_HESTNTYP:
49528c506b8Sjruoho     case ACPI_DMT_FADTPM:
496124f4c82Sjruoho     case ACPI_DMT_EINJACT:
497124f4c82Sjruoho     case ACPI_DMT_EINJINST:
498124f4c82Sjruoho     case ACPI_DMT_ERSTACT:
499124f4c82Sjruoho     case ACPI_DMT_ERSTINST:
500414ef032Schristos     case ACPI_DMT_DMAR_SCOPE:
50198244dcfSchristos     case ACPI_DMT_VIOT:
502ff4a156dSchristos 
50328c506b8Sjruoho         ByteLength = 1;
50428c506b8Sjruoho         break;
50528c506b8Sjruoho 
5062c7d7e3cSchristos     case ACPI_DMT_ASPT:
50728c506b8Sjruoho     case ACPI_DMT_UINT16:
50828c506b8Sjruoho     case ACPI_DMT_DMAR:
50928c506b8Sjruoho     case ACPI_DMT_HEST:
510ae01dbf5Schristos     case ACPI_DMT_HMAT:
5119b9ee194Schristos     case ACPI_DMT_NFIT:
51228c506b8Sjruoho     case ACPI_DMT_PCI_PATH:
51398244dcfSchristos     case ACPI_DMT_PHAT:
514ff4a156dSchristos 
51528c506b8Sjruoho         ByteLength = 2;
51628c506b8Sjruoho         break;
51728c506b8Sjruoho 
51828c506b8Sjruoho     case ACPI_DMT_UINT24:
519ff4a156dSchristos 
52028c506b8Sjruoho         ByteLength = 3;
52128c506b8Sjruoho         break;
52228c506b8Sjruoho 
52328c506b8Sjruoho     case ACPI_DMT_UINT32:
52486cbec8eSchristos     case ACPI_DMT_AEST_CACHE:
52586cbec8eSchristos     case ACPI_DMT_AEST_GIC:
52628c506b8Sjruoho     case ACPI_DMT_NAME4:
52728c506b8Sjruoho     case ACPI_DMT_SIG:
528414ef032Schristos     case ACPI_DMT_LPIT:
52925666a51Schristos     case ACPI_DMT_TPM2:
530ff4a156dSchristos 
53128c506b8Sjruoho         ByteLength = 4;
53228c506b8Sjruoho         break;
53328c506b8Sjruoho 
534ff4a156dSchristos     case ACPI_DMT_UINT40:
535ff4a156dSchristos 
536ff4a156dSchristos         ByteLength = 5;
537ff4a156dSchristos         break;
538ff4a156dSchristos 
539ff4a156dSchristos     case ACPI_DMT_UINT48:
54028c506b8Sjruoho     case ACPI_DMT_NAME6:
541ff4a156dSchristos 
54228c506b8Sjruoho         ByteLength = 6;
54328c506b8Sjruoho         break;
54428c506b8Sjruoho 
54528c506b8Sjruoho     case ACPI_DMT_UINT56:
546124f4c82Sjruoho     case ACPI_DMT_BUF7:
547ff4a156dSchristos 
54828c506b8Sjruoho         ByteLength = 7;
54928c506b8Sjruoho         break;
55028c506b8Sjruoho 
55128c506b8Sjruoho     case ACPI_DMT_UINT64:
55228c506b8Sjruoho     case ACPI_DMT_NAME8:
553ff4a156dSchristos 
55428c506b8Sjruoho         ByteLength = 8;
55528c506b8Sjruoho         break;
55628c506b8Sjruoho 
55728c506b8Sjruoho     case ACPI_DMT_STRING:
558ff4a156dSchristos 
559a8e4c046Sjruoho         Value = DtGetFieldValue (Field);
560124f4c82Sjruoho         if (Value)
561124f4c82Sjruoho         {
5629b9ee194Schristos             ByteLength = strlen (Value) + 1;
563124f4c82Sjruoho         }
564124f4c82Sjruoho         else
565124f4c82Sjruoho         {   /* At this point, this is a fatal error */
566124f4c82Sjruoho 
5677efa3256Schristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Expected \"%s\"", Info->Name);
5687efa3256Schristos             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, AslGbl_MsgBuffer);
569a8e4c046Sjruoho             return (0);
570124f4c82Sjruoho         }
57128c506b8Sjruoho         break;
57228c506b8Sjruoho 
5732546ead2Schristos     case ACPI_DMT_IVRS_UNTERMINATED_STRING:
5742546ead2Schristos 
5752546ead2Schristos         Value = DtGetFieldValue (Field);
5762546ead2Schristos         if (Value)
5772546ead2Schristos         {
5782546ead2Schristos             ByteLength = strlen (Value);
5792546ead2Schristos         }
5802546ead2Schristos         else
5812546ead2Schristos         {   /* At this point, this is a fatal error */
5822546ead2Schristos 
583a43dcd2aSchristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Expected \"%s\"", Info->Name);
5842546ead2Schristos             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, AslGbl_MsgBuffer);
5852546ead2Schristos             return (0);
5862546ead2Schristos         }
5872546ead2Schristos         break;
5882546ead2Schristos 
58928c506b8Sjruoho     case ACPI_DMT_GAS:
590ff4a156dSchristos 
59128c506b8Sjruoho         ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
59228c506b8Sjruoho         break;
59328c506b8Sjruoho 
59428c506b8Sjruoho     case ACPI_DMT_HESTNTFY:
595ff4a156dSchristos 
59628c506b8Sjruoho         ByteLength = sizeof (ACPI_HEST_NOTIFY);
59728c506b8Sjruoho         break;
59828c506b8Sjruoho 
5999b9ee194Schristos     case ACPI_DMT_IORTMEM:
6009b9ee194Schristos 
6019b9ee194Schristos         ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS);
6029b9ee194Schristos         break;
6039b9ee194Schristos 
60428c506b8Sjruoho     case ACPI_DMT_BUFFER:
605cb2bd8f0Schristos     case ACPI_DMT_RAW_BUFFER:
60698244dcfSchristos     case ACPI_DMT_PMTT_VENDOR:
607ff4a156dSchristos 
608a8e4c046Sjruoho         Value = DtGetFieldValue (Field);
60928c506b8Sjruoho         if (Value)
61028c506b8Sjruoho         {
61128c506b8Sjruoho             ByteLength = DtGetBufferLength (Value);
61228c506b8Sjruoho         }
61328c506b8Sjruoho         else
61428c506b8Sjruoho         {   /* At this point, this is a fatal error */
61528c506b8Sjruoho 
6167efa3256Schristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Expected \"%s\"", Info->Name);
6177efa3256Schristos             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, AslGbl_MsgBuffer);
618a8e4c046Sjruoho             return (0);
61928c506b8Sjruoho         }
62028c506b8Sjruoho         break;
62128c506b8Sjruoho 
622ff4a156dSchristos     case ACPI_DMT_BUF10:
623ff4a156dSchristos 
624ff4a156dSchristos         ByteLength = 10;
625ff4a156dSchristos         break;
626ff4a156dSchristos 
62747dc3895Schristos     case ACPI_DMT_BUF12:
62847dc3895Schristos 
62947dc3895Schristos         ByteLength = 12;
63047dc3895Schristos         break;
63147dc3895Schristos 
63228c506b8Sjruoho     case ACPI_DMT_BUF16:
633124f4c82Sjruoho     case ACPI_DMT_UUID:
634ff4a156dSchristos 
63528c506b8Sjruoho         ByteLength = 16;
63628c506b8Sjruoho         break;
63728c506b8Sjruoho 
638a43dcd2aSchristos     case ACPI_DMT_BUF18:
639a43dcd2aSchristos 
640a43dcd2aSchristos         ByteLength = 18;
641a43dcd2aSchristos         break;
642a43dcd2aSchristos 
643*987b04d6Schristos     case ACPI_DMT_BUF32:
644*987b04d6Schristos 
645*987b04d6Schristos         ByteLength = 32;
646*987b04d6Schristos         break;
647*987b04d6Schristos 
648*987b04d6Schristos     case ACPI_DMT_BUF112:
649*987b04d6Schristos 
650*987b04d6Schristos         ByteLength = 112;
651*987b04d6Schristos         break;
652*987b04d6Schristos 
653a8e4c046Sjruoho     case ACPI_DMT_BUF128:
654ff4a156dSchristos 
655a8e4c046Sjruoho         ByteLength = 128;
656a8e4c046Sjruoho         break;
657a8e4c046Sjruoho 
658124f4c82Sjruoho     case ACPI_DMT_UNICODE:
65986cbec8eSchristos     case ACPI_DMT_WPBT_UNICODE:
660ff4a156dSchristos 
661a8e4c046Sjruoho         Value = DtGetFieldValue (Field);
662124f4c82Sjruoho 
663124f4c82Sjruoho         /* TBD: error if Value is NULL? (as below?) */
664124f4c82Sjruoho 
6659b9ee194Schristos         ByteLength = (strlen (Value) + 1) * sizeof (UINT16);
666124f4c82Sjruoho         break;
667124f4c82Sjruoho 
66828c506b8Sjruoho     default:
669ff4a156dSchristos 
67028c506b8Sjruoho         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
671a8e4c046Sjruoho         return (0);
67228c506b8Sjruoho     }
67328c506b8Sjruoho 
67428c506b8Sjruoho     return (ByteLength);
67528c506b8Sjruoho }
67628c506b8Sjruoho 
67728c506b8Sjruoho 
67828c506b8Sjruoho /******************************************************************************
67928c506b8Sjruoho  *
68028c506b8Sjruoho  * FUNCTION:    DtSum
68128c506b8Sjruoho  *
68228c506b8Sjruoho  * PARAMETERS:  DT_WALK_CALLBACK:
68328c506b8Sjruoho  *              Subtable            - Subtable
68428c506b8Sjruoho  *              Context             - Unused
68528c506b8Sjruoho  *              ReturnValue         - Store the checksum of subtable
68628c506b8Sjruoho  *
68728c506b8Sjruoho  * RETURN:      Status
68828c506b8Sjruoho  *
68928c506b8Sjruoho  * DESCRIPTION: Get the checksum of subtable
69028c506b8Sjruoho  *
69128c506b8Sjruoho  *****************************************************************************/
69228c506b8Sjruoho 
69328c506b8Sjruoho static void
69428c506b8Sjruoho DtSum (
69528c506b8Sjruoho     DT_SUBTABLE             *Subtable,
69628c506b8Sjruoho     void                    *Context,
69728c506b8Sjruoho     void                    *ReturnValue)
69828c506b8Sjruoho {
69928c506b8Sjruoho     UINT8                   Checksum;
70028c506b8Sjruoho     UINT8                   *Sum = ReturnValue;
70128c506b8Sjruoho 
70228c506b8Sjruoho 
703121a0548Schristos     Checksum = AcpiUtChecksum (Subtable->Buffer, Subtable->Length);
70428c506b8Sjruoho     *Sum = (UINT8) (*Sum + Checksum);
70528c506b8Sjruoho }
70628c506b8Sjruoho 
70728c506b8Sjruoho 
70828c506b8Sjruoho /******************************************************************************
70928c506b8Sjruoho  *
71028c506b8Sjruoho  * FUNCTION:    DtSetTableChecksum
71128c506b8Sjruoho  *
71228c506b8Sjruoho  * PARAMETERS:  ChecksumPointer     - Where to return the checksum
71328c506b8Sjruoho  *
71428c506b8Sjruoho  * RETURN:      None
71528c506b8Sjruoho  *
71628c506b8Sjruoho  * DESCRIPTION: Set checksum of the whole data table into the checksum field
71728c506b8Sjruoho  *
71828c506b8Sjruoho  *****************************************************************************/
71928c506b8Sjruoho 
72028c506b8Sjruoho void
72128c506b8Sjruoho DtSetTableChecksum (
72228c506b8Sjruoho     UINT8                   *ChecksumPointer)
72328c506b8Sjruoho {
72428c506b8Sjruoho     UINT8                   Checksum = 0;
72528c506b8Sjruoho     UINT8                   OldSum;
72628c506b8Sjruoho 
72728c506b8Sjruoho 
7287efa3256Schristos     DtWalkTableTree (AslGbl_RootTable, DtSum, NULL, &Checksum);
72928c506b8Sjruoho 
73028c506b8Sjruoho     OldSum = *ChecksumPointer;
73128c506b8Sjruoho     Checksum = (UINT8) (Checksum - OldSum);
73228c506b8Sjruoho 
73328c506b8Sjruoho     /* Compute the final checksum */
73428c506b8Sjruoho 
73528c506b8Sjruoho     Checksum = (UINT8) (0 - Checksum);
73628c506b8Sjruoho     *ChecksumPointer = Checksum;
73728c506b8Sjruoho }
73828c506b8Sjruoho 
73928c506b8Sjruoho 
74028c506b8Sjruoho /******************************************************************************
74128c506b8Sjruoho  *
74228c506b8Sjruoho  * FUNCTION:    DtSetTableLength
74328c506b8Sjruoho  *
74428c506b8Sjruoho  * PARAMETERS:  None
74528c506b8Sjruoho  *
74628c506b8Sjruoho  * RETURN:      None
74728c506b8Sjruoho  *
74828c506b8Sjruoho  * DESCRIPTION: Walk the subtables and set all the length fields
74928c506b8Sjruoho  *
75028c506b8Sjruoho  *****************************************************************************/
75128c506b8Sjruoho 
75228c506b8Sjruoho void
75328c506b8Sjruoho DtSetTableLength (
75428c506b8Sjruoho     void)
75528c506b8Sjruoho {
75628c506b8Sjruoho     DT_SUBTABLE             *ParentTable;
75728c506b8Sjruoho     DT_SUBTABLE             *ChildTable;
75828c506b8Sjruoho 
75928c506b8Sjruoho 
7607efa3256Schristos     ParentTable = AslGbl_RootTable;
76128c506b8Sjruoho     ChildTable = NULL;
76228c506b8Sjruoho 
76328c506b8Sjruoho     if (!ParentTable)
76428c506b8Sjruoho     {
76528c506b8Sjruoho         return;
76628c506b8Sjruoho     }
76728c506b8Sjruoho 
76828c506b8Sjruoho     DtSetSubtableLength (ParentTable);
76928c506b8Sjruoho 
77028c506b8Sjruoho     while (1)
77128c506b8Sjruoho     {
77228c506b8Sjruoho         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
77328c506b8Sjruoho         if (ChildTable)
77428c506b8Sjruoho         {
775124f4c82Sjruoho             if (ChildTable->LengthField)
776124f4c82Sjruoho             {
777124f4c82Sjruoho                 DtSetSubtableLength (ChildTable);
778124f4c82Sjruoho             }
779124f4c82Sjruoho 
78028c506b8Sjruoho             if (ChildTable->Child)
78128c506b8Sjruoho             {
78228c506b8Sjruoho                 ParentTable = ChildTable;
78328c506b8Sjruoho                 ChildTable = NULL;
78428c506b8Sjruoho             }
78528c506b8Sjruoho             else
78628c506b8Sjruoho             {
78728c506b8Sjruoho                 ParentTable->TotalLength += ChildTable->TotalLength;
78828c506b8Sjruoho                 if (ParentTable->LengthField)
78928c506b8Sjruoho                 {
79028c506b8Sjruoho                     DtSetSubtableLength (ParentTable);
79128c506b8Sjruoho                 }
79228c506b8Sjruoho             }
79328c506b8Sjruoho         }
79428c506b8Sjruoho         else
79528c506b8Sjruoho         {
79628c506b8Sjruoho             ChildTable = ParentTable;
79728c506b8Sjruoho 
7987efa3256Schristos             if (ChildTable == AslGbl_RootTable)
79928c506b8Sjruoho             {
80028c506b8Sjruoho                 break;
80128c506b8Sjruoho             }
80228c506b8Sjruoho 
80328c506b8Sjruoho             ParentTable = DtGetParentSubtable (ParentTable);
80428c506b8Sjruoho 
80528c506b8Sjruoho             ParentTable->TotalLength += ChildTable->TotalLength;
80628c506b8Sjruoho             if (ParentTable->LengthField)
80728c506b8Sjruoho             {
80828c506b8Sjruoho                 DtSetSubtableLength (ParentTable);
80928c506b8Sjruoho             }
81028c506b8Sjruoho         }
81128c506b8Sjruoho     }
81228c506b8Sjruoho }
81328c506b8Sjruoho 
81428c506b8Sjruoho 
81528c506b8Sjruoho /******************************************************************************
81628c506b8Sjruoho  *
81728c506b8Sjruoho  * FUNCTION:    DtWalkTableTree
81828c506b8Sjruoho  *
81928c506b8Sjruoho  * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
82028c506b8Sjruoho  *              UserFunction        - Called during the walk
82128c506b8Sjruoho  *              Context             - Passed to user function
82228c506b8Sjruoho  *              ReturnValue         - The return value of UserFunction
82328c506b8Sjruoho  *
82428c506b8Sjruoho  * RETURN:      None
82528c506b8Sjruoho  *
82628c506b8Sjruoho  * DESCRIPTION: Performs a depth-first walk of the subtable tree
82728c506b8Sjruoho  *
82828c506b8Sjruoho  *****************************************************************************/
82928c506b8Sjruoho 
83028c506b8Sjruoho void
83128c506b8Sjruoho DtWalkTableTree (
83228c506b8Sjruoho     DT_SUBTABLE             *StartTable,
83328c506b8Sjruoho     DT_WALK_CALLBACK        UserFunction,
83428c506b8Sjruoho     void                    *Context,
83528c506b8Sjruoho     void                    *ReturnValue)
83628c506b8Sjruoho {
83728c506b8Sjruoho     DT_SUBTABLE             *ParentTable;
83828c506b8Sjruoho     DT_SUBTABLE             *ChildTable;
83928c506b8Sjruoho 
84028c506b8Sjruoho 
84128c506b8Sjruoho     ParentTable = StartTable;
84228c506b8Sjruoho     ChildTable = NULL;
84328c506b8Sjruoho 
84428c506b8Sjruoho     if (!ParentTable)
84528c506b8Sjruoho     {
84628c506b8Sjruoho         return;
84728c506b8Sjruoho     }
84828c506b8Sjruoho 
84928c506b8Sjruoho     UserFunction (ParentTable, Context, ReturnValue);
85028c506b8Sjruoho 
85128c506b8Sjruoho     while (1)
85228c506b8Sjruoho     {
85328c506b8Sjruoho         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
85428c506b8Sjruoho         if (ChildTable)
85528c506b8Sjruoho         {
85628c506b8Sjruoho             UserFunction (ChildTable, Context, ReturnValue);
85728c506b8Sjruoho 
85828c506b8Sjruoho             if (ChildTable->Child)
85928c506b8Sjruoho             {
86028c506b8Sjruoho                 ParentTable = ChildTable;
86128c506b8Sjruoho                 ChildTable = NULL;
86228c506b8Sjruoho             }
86328c506b8Sjruoho         }
86428c506b8Sjruoho         else
86528c506b8Sjruoho         {
86628c506b8Sjruoho             ChildTable = ParentTable;
8677efa3256Schristos             if (ChildTable == AslGbl_RootTable)
86828c506b8Sjruoho             {
86928c506b8Sjruoho                 break;
87028c506b8Sjruoho             }
87128c506b8Sjruoho 
87228c506b8Sjruoho             ParentTable = DtGetParentSubtable (ParentTable);
87328c506b8Sjruoho 
87428c506b8Sjruoho             if (ChildTable->Peer == StartTable)
87528c506b8Sjruoho             {
87628c506b8Sjruoho                 break;
87728c506b8Sjruoho             }
87828c506b8Sjruoho         }
87928c506b8Sjruoho     }
88028c506b8Sjruoho }
881