dtutils.c revision 250838
1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtutils.c - Utility routines for the data table compiler
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9208625Sjkim * All rights reserved.
10208625Sjkim *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25208625Sjkim *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29208625Sjkim *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43208625Sjkim
44208625Sjkim#define __DTUTILS_C__
45208625Sjkim
46209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
48209746Sjkim#include <contrib/dev/acpica/include/actables.h>
49208625Sjkim
50208625Sjkim#define _COMPONENT          DT_COMPILER
51208625Sjkim        ACPI_MODULE_NAME    ("dtutils")
52208625Sjkim
53208625Sjkim/* Local prototypes */
54208625Sjkim
55208625Sjkimstatic void
56208625SjkimDtSum (
57208625Sjkim    DT_SUBTABLE             *Subtable,
58208625Sjkim    void                    *Context,
59208625Sjkim    void                    *ReturnValue);
60208625Sjkim
61208625Sjkim
62208625Sjkim/******************************************************************************
63208625Sjkim *
64208625Sjkim * FUNCTION:    DtError
65208625Sjkim *
66208625Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
67208625Sjkim *              MessageId           - Index into global message buffer
68208625Sjkim *              Op                  - Parse node where error happened
69208625Sjkim *              ExtraMessage        - additional error message
70208625Sjkim *
71208625Sjkim * RETURN:      None
72208625Sjkim *
73208625Sjkim * DESCRIPTION: Common error interface for data table compiler
74208625Sjkim *
75208625Sjkim *****************************************************************************/
76208625Sjkim
77208625Sjkimvoid
78208625SjkimDtError (
79208625Sjkim    UINT8                   Level,
80208625Sjkim    UINT8                   MessageId,
81208625Sjkim    DT_FIELD                *FieldObject,
82208625Sjkim    char                    *ExtraMessage)
83208625Sjkim{
84208625Sjkim
85250838Sjkim    /* Check if user wants to ignore this exception */
86250838Sjkim
87250838Sjkim    if (AslIsExceptionDisabled (Level, MessageId))
88208625Sjkim    {
89250838Sjkim        return;
90208625Sjkim    }
91208625Sjkim
92208625Sjkim    if (FieldObject)
93208625Sjkim    {
94208625Sjkim        AslCommonError (Level, MessageId,
95208625Sjkim            FieldObject->Line,
96208625Sjkim            FieldObject->Line,
97208625Sjkim            FieldObject->ByteOffset,
98208625Sjkim            FieldObject->Column,
99208625Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
100208625Sjkim    }
101208625Sjkim    else
102208625Sjkim    {
103208625Sjkim        AslCommonError (Level, MessageId, 0,
104208625Sjkim            0, 0, 0, 0, ExtraMessage);
105208625Sjkim    }
106208625Sjkim}
107208625Sjkim
108208625Sjkim
109208625Sjkim/******************************************************************************
110208625Sjkim *
111208625Sjkim * FUNCTION:    DtNameError
112208625Sjkim *
113208625Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
114208625Sjkim *              MessageId           - Index into global message buffer
115208625Sjkim *              Op                  - Parse node where error happened
116208625Sjkim *              ExtraMessage        - additional error message
117208625Sjkim *
118208625Sjkim * RETURN:      None
119208625Sjkim *
120208625Sjkim * DESCRIPTION: Error interface for named objects
121208625Sjkim *
122208625Sjkim *****************************************************************************/
123208625Sjkim
124208625Sjkimvoid
125208625SjkimDtNameError (
126208625Sjkim    UINT8                   Level,
127208625Sjkim    UINT8                   MessageId,
128208625Sjkim    DT_FIELD                *FieldObject,
129208625Sjkim    char                    *ExtraMessage)
130208625Sjkim{
131208625Sjkim
132208625Sjkim    switch (Level)
133208625Sjkim    {
134208625Sjkim    case ASL_WARNING2:
135208625Sjkim    case ASL_WARNING3:
136250838Sjkim
137208625Sjkim        if (Gbl_WarningLevel < Level)
138208625Sjkim        {
139208625Sjkim            return;
140208625Sjkim        }
141208625Sjkim        break;
142208625Sjkim
143208625Sjkim    default:
144250838Sjkim
145208625Sjkim        break;
146208625Sjkim    }
147208625Sjkim
148208625Sjkim    if (FieldObject)
149208625Sjkim    {
150208625Sjkim        AslCommonError (Level, MessageId,
151208625Sjkim            FieldObject->Line,
152208625Sjkim            FieldObject->Line,
153208625Sjkim            FieldObject->ByteOffset,
154208625Sjkim            FieldObject->NameColumn,
155208625Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
156208625Sjkim    }
157208625Sjkim    else
158208625Sjkim    {
159208625Sjkim        AslCommonError (Level, MessageId, 0,
160208625Sjkim            0, 0, 0, 0, ExtraMessage);
161208625Sjkim    }
162208625Sjkim}
163208625Sjkim
164208625Sjkim
165208625Sjkim/*******************************************************************************
166208625Sjkim *
167208625Sjkim * FUNCTION:    DtFatal
168208625Sjkim *
169208625Sjkim * PARAMETERS:  None
170208625Sjkim *
171208625Sjkim * RETURN:      None
172208625Sjkim *
173208625Sjkim * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
174208625Sjkim *              compile or I/O errors
175208625Sjkim *
176208625Sjkim ******************************************************************************/
177208625Sjkim
178208625Sjkimvoid
179208625SjkimDtFatal (
180208625Sjkim    UINT8                   MessageId,
181208625Sjkim    DT_FIELD                *FieldObject,
182208625Sjkim    char                    *ExtraMessage)
183208625Sjkim{
184208625Sjkim
185208625Sjkim    DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
186208625Sjkim
187220663Sjkim/*
188220663Sjkim * TBD: remove this entire function, DtFatal
189220663Sjkim *
190220663Sjkim * We cannot abort the compiler on error, because we may be compiling a
191220663Sjkim * list of files. We must move on to the next file.
192220663Sjkim */
193220663Sjkim#ifdef __OBSOLETE
194208625Sjkim    CmCleanupAndExit ();
195208625Sjkim    exit (1);
196220663Sjkim#endif
197208625Sjkim}
198208625Sjkim
199208625Sjkim
200208625Sjkim/******************************************************************************
201208625Sjkim *
202208625Sjkim * FUNCTION:    DtStrtoul64
203208625Sjkim *
204208625Sjkim * PARAMETERS:  String              - Null terminated string
205208625Sjkim *              ReturnInteger       - Where the converted integer is returned
206208625Sjkim *
207208625Sjkim * RETURN:      Status
208208625Sjkim *
209208625Sjkim * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
210208625Sjkim *              value. Assumes no leading "0x" for the constant.
211208625Sjkim *
212208625Sjkim * Portability note: The reason this function exists is because a 64-bit
213208625Sjkim * sscanf is not available in all environments.
214208625Sjkim *
215208625Sjkim *****************************************************************************/
216208625Sjkim
217208625SjkimACPI_STATUS
218208625SjkimDtStrtoul64 (
219208625Sjkim    char                    *String,
220208625Sjkim    UINT64                  *ReturnInteger)
221208625Sjkim{
222208625Sjkim    char                    *ThisChar = String;
223208625Sjkim    UINT32                  ThisDigit;
224208625Sjkim    UINT64                  ReturnValue = 0;
225208625Sjkim    int                     DigitCount = 0;
226208625Sjkim
227208625Sjkim
228208625Sjkim    /* Skip over any white space in the buffer */
229208625Sjkim
230208625Sjkim    while ((*ThisChar == ' ') || (*ThisChar == '\t'))
231208625Sjkim    {
232208625Sjkim        ThisChar++;
233208625Sjkim    }
234208625Sjkim
235208625Sjkim    /* Skip leading zeros */
236208625Sjkim
237208625Sjkim    while ((*ThisChar) == '0')
238208625Sjkim    {
239208625Sjkim        ThisChar++;
240208625Sjkim    }
241208625Sjkim
242208625Sjkim    /* Convert character-by-character */
243208625Sjkim
244208625Sjkim    while (*ThisChar)
245208625Sjkim    {
246208625Sjkim        if (ACPI_IS_DIGIT (*ThisChar))
247208625Sjkim        {
248208625Sjkim            /* Convert ASCII 0-9 to Decimal value */
249208625Sjkim
250208625Sjkim            ThisDigit = ((UINT8) *ThisChar) - '0';
251208625Sjkim        }
252208625Sjkim        else /* Letter */
253208625Sjkim        {
254208625Sjkim            ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
255208625Sjkim            if (!ACPI_IS_XDIGIT ((char) ThisDigit))
256208625Sjkim            {
257208625Sjkim                /* Not A-F */
258208625Sjkim
259208625Sjkim                return (AE_BAD_CHARACTER);
260208625Sjkim            }
261208625Sjkim
262208625Sjkim            /* Convert ASCII Hex char (A-F) to value */
263208625Sjkim
264208625Sjkim            ThisDigit = (ThisDigit - 'A') + 10;
265208625Sjkim        }
266208625Sjkim
267208625Sjkim        /* Insert the 4-bit hex digit */
268208625Sjkim
269208625Sjkim        ReturnValue <<= 4;
270208625Sjkim        ReturnValue += ThisDigit;
271208625Sjkim
272208625Sjkim        ThisChar++;
273208625Sjkim        DigitCount++;
274208625Sjkim        if (DigitCount > 16)
275208625Sjkim        {
276208625Sjkim            /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
277208625Sjkim
278208625Sjkim            return (AE_LIMIT);
279208625Sjkim        }
280208625Sjkim    }
281208625Sjkim
282208625Sjkim    *ReturnInteger = ReturnValue;
283208625Sjkim    return (AE_OK);
284208625Sjkim}
285208625Sjkim
286208625Sjkim
287208625Sjkim/******************************************************************************
288208625Sjkim *
289208625Sjkim * FUNCTION:    DtGetFileSize
290208625Sjkim *
291208625Sjkim * PARAMETERS:  Handle              - Open file handler
292208625Sjkim *
293208625Sjkim * RETURN:      Current file size
294208625Sjkim *
295208625Sjkim * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
296208625Sjkim *              offset. Seek back to the original location.
297208625Sjkim *
298208625Sjkim *****************************************************************************/
299208625Sjkim
300208625SjkimUINT32
301208625SjkimDtGetFileSize (
302208625Sjkim    FILE                    *Handle)
303208625Sjkim{
304208625Sjkim    int                     CurrentOffset;
305208625Sjkim    int                     LastOffset;
306208625Sjkim
307208625Sjkim
308208625Sjkim    CurrentOffset = ftell (Handle);
309208625Sjkim    fseek (Handle, 0, SEEK_END);
310208625Sjkim    LastOffset = ftell (Handle);
311208625Sjkim    fseek (Handle, CurrentOffset, SEEK_SET);
312208625Sjkim
313208625Sjkim    return ((UINT32) LastOffset);
314208625Sjkim}
315208625Sjkim
316208625Sjkim
317208625Sjkim/******************************************************************************
318208625Sjkim *
319208625Sjkim * FUNCTION:    DtGetFieldValue
320208625Sjkim *
321208625Sjkim * PARAMETERS:  Field               - Current field list pointer
322208625Sjkim *
323208625Sjkim * RETURN:      Field value
324208625Sjkim *
325208625Sjkim * DESCRIPTION: Get field value
326208625Sjkim *
327208625Sjkim *****************************************************************************/
328208625Sjkim
329208625Sjkimchar *
330208625SjkimDtGetFieldValue (
331220663Sjkim    DT_FIELD                *Field)
332208625Sjkim{
333220663Sjkim    if (!Field)
334208625Sjkim    {
335220663Sjkim        return (NULL);
336208625Sjkim    }
337208625Sjkim
338220663Sjkim    return (Field->Value);
339208625Sjkim}
340208625Sjkim
341208625Sjkim
342208625Sjkim/******************************************************************************
343208625Sjkim *
344208625Sjkim * FUNCTION:    DtGetFieldType
345208625Sjkim *
346208625Sjkim * PARAMETERS:  Info                - Data table info
347208625Sjkim *
348208625Sjkim * RETURN:      Field type
349208625Sjkim *
350208625Sjkim * DESCRIPTION: Get field type
351208625Sjkim *
352208625Sjkim *****************************************************************************/
353208625Sjkim
354208625SjkimUINT8
355208625SjkimDtGetFieldType (
356208625Sjkim    ACPI_DMTABLE_INFO       *Info)
357208625Sjkim{
358208625Sjkim    UINT8                   Type;
359208625Sjkim
360208625Sjkim
361208625Sjkim    /* DT_FLAG means that this is the start of a block of flag bits */
362208625Sjkim    /* TBD - we can make these a separate opcode later */
363208625Sjkim
364208625Sjkim    if (Info->Flags & DT_FLAG)
365208625Sjkim    {
366208625Sjkim        return (DT_FIELD_TYPE_FLAGS_INTEGER);
367208625Sjkim    }
368208625Sjkim
369208625Sjkim    /* Type is based upon the opcode for this field in the info table */
370208625Sjkim
371208625Sjkim    switch (Info->Opcode)
372208625Sjkim    {
373208625Sjkim    case ACPI_DMT_FLAG0:
374208625Sjkim    case ACPI_DMT_FLAG1:
375208625Sjkim    case ACPI_DMT_FLAG2:
376208625Sjkim    case ACPI_DMT_FLAG3:
377208625Sjkim    case ACPI_DMT_FLAG4:
378208625Sjkim    case ACPI_DMT_FLAG5:
379208625Sjkim    case ACPI_DMT_FLAG6:
380208625Sjkim    case ACPI_DMT_FLAG7:
381208625Sjkim    case ACPI_DMT_FLAGS0:
382228110Sjkim    case ACPI_DMT_FLAGS1:
383208625Sjkim    case ACPI_DMT_FLAGS2:
384228110Sjkim    case ACPI_DMT_FLAGS4:
385250838Sjkim
386208625Sjkim        Type = DT_FIELD_TYPE_FLAG;
387208625Sjkim        break;
388208625Sjkim
389208625Sjkim    case ACPI_DMT_NAME4:
390208625Sjkim    case ACPI_DMT_SIG:
391208625Sjkim    case ACPI_DMT_NAME6:
392208625Sjkim    case ACPI_DMT_NAME8:
393208625Sjkim    case ACPI_DMT_STRING:
394250838Sjkim
395208625Sjkim        Type = DT_FIELD_TYPE_STRING;
396208625Sjkim        break;
397208625Sjkim
398208625Sjkim    case ACPI_DMT_BUFFER:
399218590Sjkim    case ACPI_DMT_BUF7:
400208625Sjkim    case ACPI_DMT_BUF16:
401219707Sjkim    case ACPI_DMT_BUF128:
402209734Sjkim    case ACPI_DMT_PCI_PATH:
403250838Sjkim
404208625Sjkim        Type = DT_FIELD_TYPE_BUFFER;
405208625Sjkim        break;
406208625Sjkim
407208625Sjkim    case ACPI_DMT_GAS:
408208625Sjkim    case ACPI_DMT_HESTNTFY:
409250838Sjkim
410208625Sjkim        Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
411208625Sjkim        break;
412208625Sjkim
413217365Sjkim    case ACPI_DMT_UNICODE:
414250838Sjkim
415217365Sjkim        Type = DT_FIELD_TYPE_UNICODE;
416217365Sjkim        break;
417217365Sjkim
418217365Sjkim    case ACPI_DMT_UUID:
419250838Sjkim
420217365Sjkim        Type = DT_FIELD_TYPE_UUID;
421217365Sjkim        break;
422217365Sjkim
423217365Sjkim    case ACPI_DMT_DEVICE_PATH:
424250838Sjkim
425217365Sjkim        Type = DT_FIELD_TYPE_DEVICE_PATH;
426217365Sjkim        break;
427217365Sjkim
428218590Sjkim    case ACPI_DMT_LABEL:
429250838Sjkim
430218590Sjkim        Type = DT_FIELD_TYPE_LABEL;
431218590Sjkim        break;
432218590Sjkim
433208625Sjkim    default:
434250838Sjkim
435208625Sjkim        Type = DT_FIELD_TYPE_INTEGER;
436208625Sjkim        break;
437208625Sjkim    }
438208625Sjkim
439208625Sjkim    return (Type);
440208625Sjkim}
441208625Sjkim
442208625Sjkim
443208625Sjkim/******************************************************************************
444208625Sjkim *
445208625Sjkim * FUNCTION:    DtGetBufferLength
446208625Sjkim *
447208625Sjkim * PARAMETERS:  Buffer              - List of integers,
448208625Sjkim *                                    for example "10 3A 4F 2E"
449208625Sjkim *
450208625Sjkim * RETURN:      Count of integer
451208625Sjkim *
452208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers
453208625Sjkim *
454208625Sjkim *****************************************************************************/
455208625Sjkim
456208625SjkimUINT32
457208625SjkimDtGetBufferLength (
458208625Sjkim    char                    *Buffer)
459208625Sjkim{
460208625Sjkim    UINT32                  ByteLength = 0;
461208625Sjkim
462208625Sjkim
463208625Sjkim    while (*Buffer)
464208625Sjkim    {
465208625Sjkim        if (*Buffer == ' ')
466208625Sjkim        {
467208625Sjkim            ByteLength++;
468208625Sjkim
469208625Sjkim            while (*Buffer == ' ')
470208625Sjkim            {
471208625Sjkim                Buffer++;
472208625Sjkim            }
473208625Sjkim        }
474208625Sjkim
475208625Sjkim        Buffer++;
476208625Sjkim    }
477208625Sjkim
478208625Sjkim    return (++ByteLength);
479208625Sjkim}
480208625Sjkim
481208625Sjkim
482208625Sjkim/******************************************************************************
483208625Sjkim *
484208625Sjkim * FUNCTION:    DtGetFieldLength
485208625Sjkim *
486220663Sjkim * PARAMETERS:  Field               - Current field
487208625Sjkim *              Info                - Data table info
488208625Sjkim *
489208625Sjkim * RETURN:      Field length
490208625Sjkim *
491208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field
492208625Sjkim *
493209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable.
494209734Sjkim *
495208625Sjkim *****************************************************************************/
496208625Sjkim
497208625SjkimUINT32
498208625SjkimDtGetFieldLength (
499208625Sjkim    DT_FIELD                *Field,
500208625Sjkim    ACPI_DMTABLE_INFO       *Info)
501208625Sjkim{
502208625Sjkim    UINT32                  ByteLength = 0;
503208625Sjkim    char                    *Value;
504208625Sjkim
505208625Sjkim
506208625Sjkim    /* Length is based upon the opcode for this field in the info table */
507208625Sjkim
508208625Sjkim    switch (Info->Opcode)
509208625Sjkim    {
510208625Sjkim    case ACPI_DMT_FLAG0:
511208625Sjkim    case ACPI_DMT_FLAG1:
512208625Sjkim    case ACPI_DMT_FLAG2:
513208625Sjkim    case ACPI_DMT_FLAG3:
514208625Sjkim    case ACPI_DMT_FLAG4:
515208625Sjkim    case ACPI_DMT_FLAG5:
516208625Sjkim    case ACPI_DMT_FLAG6:
517208625Sjkim    case ACPI_DMT_FLAG7:
518208625Sjkim    case ACPI_DMT_FLAGS0:
519228110Sjkim    case ACPI_DMT_FLAGS1:
520208625Sjkim    case ACPI_DMT_FLAGS2:
521228110Sjkim    case ACPI_DMT_FLAGS4:
522218590Sjkim    case ACPI_DMT_LABEL:
523228110Sjkim    case ACPI_DMT_EXTRA_TEXT:
524250838Sjkim
525208625Sjkim        ByteLength = 0;
526208625Sjkim        break;
527208625Sjkim
528208625Sjkim    case ACPI_DMT_UINT8:
529208625Sjkim    case ACPI_DMT_CHKSUM:
530208625Sjkim    case ACPI_DMT_SPACEID:
531216471Sjkim    case ACPI_DMT_ACCWIDTH:
532209734Sjkim    case ACPI_DMT_IVRS:
533208625Sjkim    case ACPI_DMT_MADT:
534228110Sjkim    case ACPI_DMT_PMTT:
535208625Sjkim    case ACPI_DMT_SRAT:
536208625Sjkim    case ACPI_DMT_ASF:
537208625Sjkim    case ACPI_DMT_HESTNTYP:
538208625Sjkim    case ACPI_DMT_FADTPM:
539209734Sjkim    case ACPI_DMT_EINJACT:
540209734Sjkim    case ACPI_DMT_EINJINST:
541209734Sjkim    case ACPI_DMT_ERSTACT:
542209734Sjkim    case ACPI_DMT_ERSTINST:
543250838Sjkim
544208625Sjkim        ByteLength = 1;
545208625Sjkim        break;
546208625Sjkim
547208625Sjkim    case ACPI_DMT_UINT16:
548208625Sjkim    case ACPI_DMT_DMAR:
549208625Sjkim    case ACPI_DMT_HEST:
550208625Sjkim    case ACPI_DMT_PCI_PATH:
551250838Sjkim
552208625Sjkim        ByteLength = 2;
553208625Sjkim        break;
554208625Sjkim
555208625Sjkim    case ACPI_DMT_UINT24:
556250838Sjkim
557208625Sjkim        ByteLength = 3;
558208625Sjkim        break;
559208625Sjkim
560208625Sjkim    case ACPI_DMT_UINT32:
561208625Sjkim    case ACPI_DMT_NAME4:
562219707Sjkim    case ACPI_DMT_SLIC:
563208625Sjkim    case ACPI_DMT_SIG:
564250838Sjkim
565208625Sjkim        ByteLength = 4;
566208625Sjkim        break;
567208625Sjkim
568228110Sjkim    case ACPI_DMT_UINT40:
569250838Sjkim
570228110Sjkim        ByteLength = 5;
571228110Sjkim        break;
572228110Sjkim
573228110Sjkim    case ACPI_DMT_UINT48:
574208625Sjkim    case ACPI_DMT_NAME6:
575250838Sjkim
576208625Sjkim        ByteLength = 6;
577208625Sjkim        break;
578208625Sjkim
579208625Sjkim    case ACPI_DMT_UINT56:
580218590Sjkim    case ACPI_DMT_BUF7:
581250838Sjkim
582208625Sjkim        ByteLength = 7;
583208625Sjkim        break;
584208625Sjkim
585208625Sjkim    case ACPI_DMT_UINT64:
586208625Sjkim    case ACPI_DMT_NAME8:
587250838Sjkim
588208625Sjkim        ByteLength = 8;
589208625Sjkim        break;
590208625Sjkim
591208625Sjkim    case ACPI_DMT_STRING:
592250838Sjkim
593220663Sjkim        Value = DtGetFieldValue (Field);
594217365Sjkim        if (Value)
595217365Sjkim        {
596217365Sjkim            ByteLength = ACPI_STRLEN (Value) + 1;
597217365Sjkim        }
598217365Sjkim        else
599217365Sjkim        {   /* At this point, this is a fatal error */
600208625Sjkim
601217365Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
602217365Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
603220663Sjkim            return (0);
604217365Sjkim        }
605208625Sjkim        break;
606208625Sjkim
607208625Sjkim    case ACPI_DMT_GAS:
608250838Sjkim
609208625Sjkim        ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
610208625Sjkim        break;
611208625Sjkim
612208625Sjkim    case ACPI_DMT_HESTNTFY:
613250838Sjkim
614208625Sjkim        ByteLength = sizeof (ACPI_HEST_NOTIFY);
615208625Sjkim        break;
616208625Sjkim
617208625Sjkim    case ACPI_DMT_BUFFER:
618250838Sjkim
619220663Sjkim        Value = DtGetFieldValue (Field);
620208625Sjkim        if (Value)
621208625Sjkim        {
622208625Sjkim            ByteLength = DtGetBufferLength (Value);
623208625Sjkim        }
624208625Sjkim        else
625208625Sjkim        {   /* At this point, this is a fatal error */
626208625Sjkim
627208625Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
628208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
629220663Sjkim            return (0);
630208625Sjkim        }
631208625Sjkim        break;
632208625Sjkim
633208625Sjkim    case ACPI_DMT_BUF16:
634217365Sjkim    case ACPI_DMT_UUID:
635250838Sjkim
636208625Sjkim        ByteLength = 16;
637208625Sjkim        break;
638208625Sjkim
639219707Sjkim    case ACPI_DMT_BUF128:
640250838Sjkim
641219707Sjkim        ByteLength = 128;
642219707Sjkim        break;
643219707Sjkim
644217365Sjkim    case ACPI_DMT_UNICODE:
645250838Sjkim
646220663Sjkim        Value = DtGetFieldValue (Field);
647217365Sjkim
648217365Sjkim        /* TBD: error if Value is NULL? (as below?) */
649217365Sjkim
650217365Sjkim        ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
651217365Sjkim        break;
652217365Sjkim
653208625Sjkim    default:
654250838Sjkim
655208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
656220663Sjkim        return (0);
657208625Sjkim    }
658208625Sjkim
659208625Sjkim    return (ByteLength);
660208625Sjkim}
661208625Sjkim
662208625Sjkim
663208625Sjkim/******************************************************************************
664208625Sjkim *
665208625Sjkim * FUNCTION:    DtSum
666208625Sjkim *
667208625Sjkim * PARAMETERS:  DT_WALK_CALLBACK:
668208625Sjkim *              Subtable            - Subtable
669208625Sjkim *              Context             - Unused
670208625Sjkim *              ReturnValue         - Store the checksum of subtable
671208625Sjkim *
672208625Sjkim * RETURN:      Status
673208625Sjkim *
674208625Sjkim * DESCRIPTION: Get the checksum of subtable
675208625Sjkim *
676208625Sjkim *****************************************************************************/
677208625Sjkim
678208625Sjkimstatic void
679208625SjkimDtSum (
680208625Sjkim    DT_SUBTABLE             *Subtable,
681208625Sjkim    void                    *Context,
682208625Sjkim    void                    *ReturnValue)
683208625Sjkim{
684208625Sjkim    UINT8                   Checksum;
685208625Sjkim    UINT8                   *Sum = ReturnValue;
686208625Sjkim
687208625Sjkim
688208625Sjkim    Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
689208625Sjkim    *Sum = (UINT8) (*Sum + Checksum);
690208625Sjkim}
691208625Sjkim
692208625Sjkim
693208625Sjkim/******************************************************************************
694208625Sjkim *
695208625Sjkim * FUNCTION:    DtSetTableChecksum
696208625Sjkim *
697208625Sjkim * PARAMETERS:  ChecksumPointer     - Where to return the checksum
698208625Sjkim *
699208625Sjkim * RETURN:      None
700208625Sjkim *
701208625Sjkim * DESCRIPTION: Set checksum of the whole data table into the checksum field
702208625Sjkim *
703208625Sjkim *****************************************************************************/
704208625Sjkim
705208625Sjkimvoid
706208625SjkimDtSetTableChecksum (
707208625Sjkim    UINT8                   *ChecksumPointer)
708208625Sjkim{
709208625Sjkim    UINT8                   Checksum = 0;
710208625Sjkim    UINT8                   OldSum;
711208625Sjkim
712208625Sjkim
713208625Sjkim    DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
714208625Sjkim
715208625Sjkim    OldSum = *ChecksumPointer;
716208625Sjkim    Checksum = (UINT8) (Checksum - OldSum);
717208625Sjkim
718208625Sjkim    /* Compute the final checksum */
719208625Sjkim
720208625Sjkim    Checksum = (UINT8) (0 - Checksum);
721208625Sjkim    *ChecksumPointer = Checksum;
722208625Sjkim}
723208625Sjkim
724208625Sjkim
725208625Sjkim/******************************************************************************
726208625Sjkim *
727208625Sjkim * FUNCTION:    DtSetTableLength
728208625Sjkim *
729208625Sjkim * PARAMETERS:  None
730208625Sjkim *
731208625Sjkim * RETURN:      None
732208625Sjkim *
733208625Sjkim * DESCRIPTION: Walk the subtables and set all the length fields
734208625Sjkim *
735208625Sjkim *****************************************************************************/
736208625Sjkim
737208625Sjkimvoid
738208625SjkimDtSetTableLength (
739208625Sjkim    void)
740208625Sjkim{
741208625Sjkim    DT_SUBTABLE             *ParentTable;
742208625Sjkim    DT_SUBTABLE             *ChildTable;
743208625Sjkim
744208625Sjkim
745208625Sjkim    ParentTable = Gbl_RootTable;
746208625Sjkim    ChildTable = NULL;
747208625Sjkim
748208625Sjkim    if (!ParentTable)
749208625Sjkim    {
750208625Sjkim        return;
751208625Sjkim    }
752208625Sjkim
753208625Sjkim    DtSetSubtableLength (ParentTable);
754208625Sjkim
755208625Sjkim    while (1)
756208625Sjkim    {
757208625Sjkim        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
758208625Sjkim        if (ChildTable)
759208625Sjkim        {
760209734Sjkim            if (ChildTable->LengthField)
761209734Sjkim            {
762209734Sjkim                DtSetSubtableLength (ChildTable);
763209734Sjkim            }
764209734Sjkim
765208625Sjkim            if (ChildTable->Child)
766208625Sjkim            {
767208625Sjkim                ParentTable = ChildTable;
768208625Sjkim                ChildTable = NULL;
769208625Sjkim            }
770208625Sjkim            else
771208625Sjkim            {
772208625Sjkim                ParentTable->TotalLength += ChildTable->TotalLength;
773208625Sjkim                if (ParentTable->LengthField)
774208625Sjkim                {
775208625Sjkim                    DtSetSubtableLength (ParentTable);
776208625Sjkim                }
777208625Sjkim            }
778208625Sjkim        }
779208625Sjkim        else
780208625Sjkim        {
781208625Sjkim            ChildTable = ParentTable;
782208625Sjkim
783208625Sjkim            if (ChildTable == Gbl_RootTable)
784208625Sjkim            {
785208625Sjkim                break;
786208625Sjkim            }
787208625Sjkim
788208625Sjkim            ParentTable = DtGetParentSubtable (ParentTable);
789208625Sjkim
790208625Sjkim            ParentTable->TotalLength += ChildTable->TotalLength;
791208625Sjkim            if (ParentTable->LengthField)
792208625Sjkim            {
793208625Sjkim                DtSetSubtableLength (ParentTable);
794208625Sjkim            }
795208625Sjkim        }
796208625Sjkim    }
797208625Sjkim}
798208625Sjkim
799208625Sjkim
800208625Sjkim/******************************************************************************
801208625Sjkim *
802208625Sjkim * FUNCTION:    DtWalkTableTree
803208625Sjkim *
804208625Sjkim * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
805208625Sjkim *              UserFunction        - Called during the walk
806208625Sjkim *              Context             - Passed to user function
807208625Sjkim *              ReturnValue         - The return value of UserFunction
808208625Sjkim *
809208625Sjkim * RETURN:      None
810208625Sjkim *
811208625Sjkim * DESCRIPTION: Performs a depth-first walk of the subtable tree
812208625Sjkim *
813208625Sjkim *****************************************************************************/
814208625Sjkim
815208625Sjkimvoid
816208625SjkimDtWalkTableTree (
817208625Sjkim    DT_SUBTABLE             *StartTable,
818208625Sjkim    DT_WALK_CALLBACK        UserFunction,
819208625Sjkim    void                    *Context,
820208625Sjkim    void                    *ReturnValue)
821208625Sjkim{
822208625Sjkim    DT_SUBTABLE             *ParentTable;
823208625Sjkim    DT_SUBTABLE             *ChildTable;
824208625Sjkim
825208625Sjkim
826208625Sjkim    ParentTable = StartTable;
827208625Sjkim    ChildTable = NULL;
828208625Sjkim
829208625Sjkim    if (!ParentTable)
830208625Sjkim    {
831208625Sjkim        return;
832208625Sjkim    }
833208625Sjkim
834208625Sjkim    UserFunction (ParentTable, Context, ReturnValue);
835208625Sjkim
836208625Sjkim    while (1)
837208625Sjkim    {
838208625Sjkim        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
839208625Sjkim        if (ChildTable)
840208625Sjkim        {
841208625Sjkim            UserFunction (ChildTable, Context, ReturnValue);
842208625Sjkim
843208625Sjkim            if (ChildTable->Child)
844208625Sjkim            {
845208625Sjkim                ParentTable = ChildTable;
846208625Sjkim                ChildTable = NULL;
847208625Sjkim            }
848208625Sjkim        }
849208625Sjkim        else
850208625Sjkim        {
851208625Sjkim            ChildTable = ParentTable;
852208625Sjkim            if (ChildTable == Gbl_RootTable)
853208625Sjkim            {
854208625Sjkim                break;
855208625Sjkim            }
856208625Sjkim
857208625Sjkim            ParentTable = DtGetParentSubtable (ParentTable);
858208625Sjkim
859208625Sjkim            if (ChildTable->Peer == StartTable)
860208625Sjkim            {
861208625Sjkim                break;
862208625Sjkim            }
863208625Sjkim        }
864208625Sjkim    }
865208625Sjkim}
866208625Sjkim
867208625Sjkim
868208625Sjkim/******************************************************************************
869208625Sjkim *
870208625Sjkim * FUNCTION:    DtFreeFieldList
871208625Sjkim *
872208625Sjkim * PARAMETERS:  None
873208625Sjkim *
874208625Sjkim * RETURN:      None
875208625Sjkim *
876208625Sjkim * DESCRIPTION: Free the field list
877208625Sjkim *
878208625Sjkim *****************************************************************************/
879208625Sjkim
880208625Sjkimvoid
881208625SjkimDtFreeFieldList (
882208625Sjkim    void)
883208625Sjkim{
884208625Sjkim    DT_FIELD                *Field = Gbl_FieldList;
885208625Sjkim    DT_FIELD                *NextField;
886208625Sjkim
887208625Sjkim
888208625Sjkim    /* Walk and free entire field list */
889208625Sjkim
890208625Sjkim    while (Field)
891208625Sjkim    {
892208625Sjkim        NextField = Field->Next; /* Save link */
893208625Sjkim
894208625Sjkim        if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
895208625Sjkim        {
896208625Sjkim            ACPI_FREE (Field->Name);
897208625Sjkim            ACPI_FREE (Field->Value);
898208625Sjkim        }
899208625Sjkim
900208625Sjkim        ACPI_FREE (Field);
901208625Sjkim        Field = NextField;
902208625Sjkim    }
903208625Sjkim}
904