dtutils.c revision 245582
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
85208625Sjkim    switch (Level)
86208625Sjkim    {
87208625Sjkim    case ASL_WARNING2:
88208625Sjkim    case ASL_WARNING3:
89208625Sjkim        if (Gbl_WarningLevel < Level)
90208625Sjkim        {
91208625Sjkim            return;
92208625Sjkim        }
93208625Sjkim        break;
94208625Sjkim
95208625Sjkim    default:
96208625Sjkim        break;
97208625Sjkim    }
98208625Sjkim
99208625Sjkim    if (FieldObject)
100208625Sjkim    {
101208625Sjkim        AslCommonError (Level, MessageId,
102208625Sjkim            FieldObject->Line,
103208625Sjkim            FieldObject->Line,
104208625Sjkim            FieldObject->ByteOffset,
105208625Sjkim            FieldObject->Column,
106208625Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
107208625Sjkim    }
108208625Sjkim    else
109208625Sjkim    {
110208625Sjkim        AslCommonError (Level, MessageId, 0,
111208625Sjkim            0, 0, 0, 0, ExtraMessage);
112208625Sjkim    }
113208625Sjkim}
114208625Sjkim
115208625Sjkim
116208625Sjkim/******************************************************************************
117208625Sjkim *
118208625Sjkim * FUNCTION:    DtNameError
119208625Sjkim *
120208625Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
121208625Sjkim *              MessageId           - Index into global message buffer
122208625Sjkim *              Op                  - Parse node where error happened
123208625Sjkim *              ExtraMessage        - additional error message
124208625Sjkim *
125208625Sjkim * RETURN:      None
126208625Sjkim *
127208625Sjkim * DESCRIPTION: Error interface for named objects
128208625Sjkim *
129208625Sjkim *****************************************************************************/
130208625Sjkim
131208625Sjkimvoid
132208625SjkimDtNameError (
133208625Sjkim    UINT8                   Level,
134208625Sjkim    UINT8                   MessageId,
135208625Sjkim    DT_FIELD                *FieldObject,
136208625Sjkim    char                    *ExtraMessage)
137208625Sjkim{
138208625Sjkim
139208625Sjkim    switch (Level)
140208625Sjkim    {
141208625Sjkim    case ASL_WARNING2:
142208625Sjkim    case ASL_WARNING3:
143208625Sjkim        if (Gbl_WarningLevel < Level)
144208625Sjkim        {
145208625Sjkim            return;
146208625Sjkim        }
147208625Sjkim        break;
148208625Sjkim
149208625Sjkim    default:
150208625Sjkim        break;
151208625Sjkim    }
152208625Sjkim
153208625Sjkim    if (FieldObject)
154208625Sjkim    {
155208625Sjkim        AslCommonError (Level, MessageId,
156208625Sjkim            FieldObject->Line,
157208625Sjkim            FieldObject->Line,
158208625Sjkim            FieldObject->ByteOffset,
159208625Sjkim            FieldObject->NameColumn,
160208625Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
161208625Sjkim    }
162208625Sjkim    else
163208625Sjkim    {
164208625Sjkim        AslCommonError (Level, MessageId, 0,
165208625Sjkim            0, 0, 0, 0, ExtraMessage);
166208625Sjkim    }
167208625Sjkim}
168208625Sjkim
169208625Sjkim
170208625Sjkim/*******************************************************************************
171208625Sjkim *
172208625Sjkim * FUNCTION:    DtFatal
173208625Sjkim *
174208625Sjkim * PARAMETERS:  None
175208625Sjkim *
176208625Sjkim * RETURN:      None
177208625Sjkim *
178208625Sjkim * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
179208625Sjkim *              compile or I/O errors
180208625Sjkim *
181208625Sjkim ******************************************************************************/
182208625Sjkim
183208625Sjkimvoid
184208625SjkimDtFatal (
185208625Sjkim    UINT8                   MessageId,
186208625Sjkim    DT_FIELD                *FieldObject,
187208625Sjkim    char                    *ExtraMessage)
188208625Sjkim{
189208625Sjkim
190208625Sjkim    DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
191208625Sjkim
192220663Sjkim/*
193220663Sjkim * TBD: remove this entire function, DtFatal
194220663Sjkim *
195220663Sjkim * We cannot abort the compiler on error, because we may be compiling a
196220663Sjkim * list of files. We must move on to the next file.
197220663Sjkim */
198220663Sjkim#ifdef __OBSOLETE
199208625Sjkim    CmCleanupAndExit ();
200208625Sjkim    exit (1);
201220663Sjkim#endif
202208625Sjkim}
203208625Sjkim
204208625Sjkim
205208625Sjkim/******************************************************************************
206208625Sjkim *
207208625Sjkim * FUNCTION:    DtStrtoul64
208208625Sjkim *
209208625Sjkim * PARAMETERS:  String              - Null terminated string
210208625Sjkim *              ReturnInteger       - Where the converted integer is returned
211208625Sjkim *
212208625Sjkim * RETURN:      Status
213208625Sjkim *
214208625Sjkim * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
215208625Sjkim *              value. Assumes no leading "0x" for the constant.
216208625Sjkim *
217208625Sjkim * Portability note: The reason this function exists is because a 64-bit
218208625Sjkim * sscanf is not available in all environments.
219208625Sjkim *
220208625Sjkim *****************************************************************************/
221208625Sjkim
222208625SjkimACPI_STATUS
223208625SjkimDtStrtoul64 (
224208625Sjkim    char                    *String,
225208625Sjkim    UINT64                  *ReturnInteger)
226208625Sjkim{
227208625Sjkim    char                    *ThisChar = String;
228208625Sjkim    UINT32                  ThisDigit;
229208625Sjkim    UINT64                  ReturnValue = 0;
230208625Sjkim    int                     DigitCount = 0;
231208625Sjkim
232208625Sjkim
233208625Sjkim    /* Skip over any white space in the buffer */
234208625Sjkim
235208625Sjkim    while ((*ThisChar == ' ') || (*ThisChar == '\t'))
236208625Sjkim    {
237208625Sjkim        ThisChar++;
238208625Sjkim    }
239208625Sjkim
240208625Sjkim    /* Skip leading zeros */
241208625Sjkim
242208625Sjkim    while ((*ThisChar) == '0')
243208625Sjkim    {
244208625Sjkim        ThisChar++;
245208625Sjkim    }
246208625Sjkim
247208625Sjkim    /* Convert character-by-character */
248208625Sjkim
249208625Sjkim    while (*ThisChar)
250208625Sjkim    {
251208625Sjkim        if (ACPI_IS_DIGIT (*ThisChar))
252208625Sjkim        {
253208625Sjkim            /* Convert ASCII 0-9 to Decimal value */
254208625Sjkim
255208625Sjkim            ThisDigit = ((UINT8) *ThisChar) - '0';
256208625Sjkim        }
257208625Sjkim        else /* Letter */
258208625Sjkim        {
259208625Sjkim            ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
260208625Sjkim            if (!ACPI_IS_XDIGIT ((char) ThisDigit))
261208625Sjkim            {
262208625Sjkim                /* Not A-F */
263208625Sjkim
264208625Sjkim                return (AE_BAD_CHARACTER);
265208625Sjkim            }
266208625Sjkim
267208625Sjkim            /* Convert ASCII Hex char (A-F) to value */
268208625Sjkim
269208625Sjkim            ThisDigit = (ThisDigit - 'A') + 10;
270208625Sjkim        }
271208625Sjkim
272208625Sjkim        /* Insert the 4-bit hex digit */
273208625Sjkim
274208625Sjkim        ReturnValue <<= 4;
275208625Sjkim        ReturnValue += ThisDigit;
276208625Sjkim
277208625Sjkim        ThisChar++;
278208625Sjkim        DigitCount++;
279208625Sjkim        if (DigitCount > 16)
280208625Sjkim        {
281208625Sjkim            /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
282208625Sjkim
283208625Sjkim            return (AE_LIMIT);
284208625Sjkim        }
285208625Sjkim    }
286208625Sjkim
287208625Sjkim    *ReturnInteger = ReturnValue;
288208625Sjkim    return (AE_OK);
289208625Sjkim}
290208625Sjkim
291208625Sjkim
292208625Sjkim/******************************************************************************
293208625Sjkim *
294208625Sjkim * FUNCTION:    DtGetFileSize
295208625Sjkim *
296208625Sjkim * PARAMETERS:  Handle              - Open file handler
297208625Sjkim *
298208625Sjkim * RETURN:      Current file size
299208625Sjkim *
300208625Sjkim * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
301208625Sjkim *              offset. Seek back to the original location.
302208625Sjkim *
303208625Sjkim *****************************************************************************/
304208625Sjkim
305208625SjkimUINT32
306208625SjkimDtGetFileSize (
307208625Sjkim    FILE                    *Handle)
308208625Sjkim{
309208625Sjkim    int                     CurrentOffset;
310208625Sjkim    int                     LastOffset;
311208625Sjkim
312208625Sjkim
313208625Sjkim    CurrentOffset = ftell (Handle);
314208625Sjkim    fseek (Handle, 0, SEEK_END);
315208625Sjkim    LastOffset = ftell (Handle);
316208625Sjkim    fseek (Handle, CurrentOffset, SEEK_SET);
317208625Sjkim
318208625Sjkim    return ((UINT32) LastOffset);
319208625Sjkim}
320208625Sjkim
321208625Sjkim
322208625Sjkim/******************************************************************************
323208625Sjkim *
324208625Sjkim * FUNCTION:    DtGetFieldValue
325208625Sjkim *
326208625Sjkim * PARAMETERS:  Field               - Current field list pointer
327208625Sjkim *
328208625Sjkim * RETURN:      Field value
329208625Sjkim *
330208625Sjkim * DESCRIPTION: Get field value
331208625Sjkim *
332208625Sjkim *****************************************************************************/
333208625Sjkim
334208625Sjkimchar *
335208625SjkimDtGetFieldValue (
336220663Sjkim    DT_FIELD                *Field)
337208625Sjkim{
338220663Sjkim    if (!Field)
339208625Sjkim    {
340220663Sjkim        return (NULL);
341208625Sjkim    }
342208625Sjkim
343220663Sjkim    return (Field->Value);
344208625Sjkim}
345208625Sjkim
346208625Sjkim
347208625Sjkim/******************************************************************************
348208625Sjkim *
349208625Sjkim * FUNCTION:    DtGetFieldType
350208625Sjkim *
351208625Sjkim * PARAMETERS:  Info                - Data table info
352208625Sjkim *
353208625Sjkim * RETURN:      Field type
354208625Sjkim *
355208625Sjkim * DESCRIPTION: Get field type
356208625Sjkim *
357208625Sjkim *****************************************************************************/
358208625Sjkim
359208625SjkimUINT8
360208625SjkimDtGetFieldType (
361208625Sjkim    ACPI_DMTABLE_INFO       *Info)
362208625Sjkim{
363208625Sjkim    UINT8                   Type;
364208625Sjkim
365208625Sjkim
366208625Sjkim    /* DT_FLAG means that this is the start of a block of flag bits */
367208625Sjkim    /* TBD - we can make these a separate opcode later */
368208625Sjkim
369208625Sjkim    if (Info->Flags & DT_FLAG)
370208625Sjkim    {
371208625Sjkim        return (DT_FIELD_TYPE_FLAGS_INTEGER);
372208625Sjkim    }
373208625Sjkim
374208625Sjkim    /* Type is based upon the opcode for this field in the info table */
375208625Sjkim
376208625Sjkim    switch (Info->Opcode)
377208625Sjkim    {
378208625Sjkim    case ACPI_DMT_FLAG0:
379208625Sjkim    case ACPI_DMT_FLAG1:
380208625Sjkim    case ACPI_DMT_FLAG2:
381208625Sjkim    case ACPI_DMT_FLAG3:
382208625Sjkim    case ACPI_DMT_FLAG4:
383208625Sjkim    case ACPI_DMT_FLAG5:
384208625Sjkim    case ACPI_DMT_FLAG6:
385208625Sjkim    case ACPI_DMT_FLAG7:
386208625Sjkim    case ACPI_DMT_FLAGS0:
387228110Sjkim    case ACPI_DMT_FLAGS1:
388208625Sjkim    case ACPI_DMT_FLAGS2:
389228110Sjkim    case ACPI_DMT_FLAGS4:
390208625Sjkim        Type = DT_FIELD_TYPE_FLAG;
391208625Sjkim        break;
392208625Sjkim
393208625Sjkim    case ACPI_DMT_NAME4:
394208625Sjkim    case ACPI_DMT_SIG:
395208625Sjkim    case ACPI_DMT_NAME6:
396208625Sjkim    case ACPI_DMT_NAME8:
397208625Sjkim    case ACPI_DMT_STRING:
398208625Sjkim        Type = DT_FIELD_TYPE_STRING;
399208625Sjkim        break;
400208625Sjkim
401208625Sjkim    case ACPI_DMT_BUFFER:
402218590Sjkim    case ACPI_DMT_BUF7:
403208625Sjkim    case ACPI_DMT_BUF16:
404219707Sjkim    case ACPI_DMT_BUF128:
405209734Sjkim    case ACPI_DMT_PCI_PATH:
406208625Sjkim        Type = DT_FIELD_TYPE_BUFFER;
407208625Sjkim        break;
408208625Sjkim
409208625Sjkim    case ACPI_DMT_GAS:
410208625Sjkim    case ACPI_DMT_HESTNTFY:
411208625Sjkim        Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
412208625Sjkim        break;
413208625Sjkim
414217365Sjkim    case ACPI_DMT_UNICODE:
415217365Sjkim        Type = DT_FIELD_TYPE_UNICODE;
416217365Sjkim        break;
417217365Sjkim
418217365Sjkim    case ACPI_DMT_UUID:
419217365Sjkim        Type = DT_FIELD_TYPE_UUID;
420217365Sjkim        break;
421217365Sjkim
422217365Sjkim    case ACPI_DMT_DEVICE_PATH:
423217365Sjkim        Type = DT_FIELD_TYPE_DEVICE_PATH;
424217365Sjkim        break;
425217365Sjkim
426218590Sjkim    case ACPI_DMT_LABEL:
427218590Sjkim        Type = DT_FIELD_TYPE_LABEL;
428218590Sjkim        break;
429218590Sjkim
430208625Sjkim    default:
431208625Sjkim        Type = DT_FIELD_TYPE_INTEGER;
432208625Sjkim        break;
433208625Sjkim    }
434208625Sjkim
435208625Sjkim    return (Type);
436208625Sjkim}
437208625Sjkim
438208625Sjkim
439208625Sjkim/******************************************************************************
440208625Sjkim *
441208625Sjkim * FUNCTION:    DtGetBufferLength
442208625Sjkim *
443208625Sjkim * PARAMETERS:  Buffer              - List of integers,
444208625Sjkim *                                    for example "10 3A 4F 2E"
445208625Sjkim *
446208625Sjkim * RETURN:      Count of integer
447208625Sjkim *
448208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers
449208625Sjkim *
450208625Sjkim *****************************************************************************/
451208625Sjkim
452208625SjkimUINT32
453208625SjkimDtGetBufferLength (
454208625Sjkim    char                    *Buffer)
455208625Sjkim{
456208625Sjkim    UINT32                  ByteLength = 0;
457208625Sjkim
458208625Sjkim
459208625Sjkim    while (*Buffer)
460208625Sjkim    {
461208625Sjkim        if (*Buffer == ' ')
462208625Sjkim        {
463208625Sjkim            ByteLength++;
464208625Sjkim
465208625Sjkim            while (*Buffer == ' ')
466208625Sjkim            {
467208625Sjkim                Buffer++;
468208625Sjkim            }
469208625Sjkim        }
470208625Sjkim
471208625Sjkim        Buffer++;
472208625Sjkim    }
473208625Sjkim
474208625Sjkim    return (++ByteLength);
475208625Sjkim}
476208625Sjkim
477208625Sjkim
478208625Sjkim/******************************************************************************
479208625Sjkim *
480208625Sjkim * FUNCTION:    DtGetFieldLength
481208625Sjkim *
482220663Sjkim * PARAMETERS:  Field               - Current field
483208625Sjkim *              Info                - Data table info
484208625Sjkim *
485208625Sjkim * RETURN:      Field length
486208625Sjkim *
487208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field
488208625Sjkim *
489209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable.
490209734Sjkim *
491208625Sjkim *****************************************************************************/
492208625Sjkim
493208625SjkimUINT32
494208625SjkimDtGetFieldLength (
495208625Sjkim    DT_FIELD                *Field,
496208625Sjkim    ACPI_DMTABLE_INFO       *Info)
497208625Sjkim{
498208625Sjkim    UINT32                  ByteLength = 0;
499208625Sjkim    char                    *Value;
500208625Sjkim
501208625Sjkim
502208625Sjkim    /* Length is based upon the opcode for this field in the info table */
503208625Sjkim
504208625Sjkim    switch (Info->Opcode)
505208625Sjkim    {
506208625Sjkim    case ACPI_DMT_FLAG0:
507208625Sjkim    case ACPI_DMT_FLAG1:
508208625Sjkim    case ACPI_DMT_FLAG2:
509208625Sjkim    case ACPI_DMT_FLAG3:
510208625Sjkim    case ACPI_DMT_FLAG4:
511208625Sjkim    case ACPI_DMT_FLAG5:
512208625Sjkim    case ACPI_DMT_FLAG6:
513208625Sjkim    case ACPI_DMT_FLAG7:
514208625Sjkim    case ACPI_DMT_FLAGS0:
515228110Sjkim    case ACPI_DMT_FLAGS1:
516208625Sjkim    case ACPI_DMT_FLAGS2:
517228110Sjkim    case ACPI_DMT_FLAGS4:
518218590Sjkim    case ACPI_DMT_LABEL:
519228110Sjkim    case ACPI_DMT_EXTRA_TEXT:
520208625Sjkim        ByteLength = 0;
521208625Sjkim        break;
522208625Sjkim
523208625Sjkim    case ACPI_DMT_UINT8:
524208625Sjkim    case ACPI_DMT_CHKSUM:
525208625Sjkim    case ACPI_DMT_SPACEID:
526216471Sjkim    case ACPI_DMT_ACCWIDTH:
527209734Sjkim    case ACPI_DMT_IVRS:
528208625Sjkim    case ACPI_DMT_MADT:
529228110Sjkim    case ACPI_DMT_PMTT:
530208625Sjkim    case ACPI_DMT_SRAT:
531208625Sjkim    case ACPI_DMT_ASF:
532208625Sjkim    case ACPI_DMT_HESTNTYP:
533208625Sjkim    case ACPI_DMT_FADTPM:
534209734Sjkim    case ACPI_DMT_EINJACT:
535209734Sjkim    case ACPI_DMT_EINJINST:
536209734Sjkim    case ACPI_DMT_ERSTACT:
537209734Sjkim    case ACPI_DMT_ERSTINST:
538208625Sjkim        ByteLength = 1;
539208625Sjkim        break;
540208625Sjkim
541208625Sjkim    case ACPI_DMT_UINT16:
542208625Sjkim    case ACPI_DMT_DMAR:
543208625Sjkim    case ACPI_DMT_HEST:
544208625Sjkim    case ACPI_DMT_PCI_PATH:
545208625Sjkim        ByteLength = 2;
546208625Sjkim        break;
547208625Sjkim
548208625Sjkim    case ACPI_DMT_UINT24:
549208625Sjkim        ByteLength = 3;
550208625Sjkim        break;
551208625Sjkim
552208625Sjkim    case ACPI_DMT_UINT32:
553208625Sjkim    case ACPI_DMT_NAME4:
554219707Sjkim    case ACPI_DMT_SLIC:
555208625Sjkim    case ACPI_DMT_SIG:
556208625Sjkim        ByteLength = 4;
557208625Sjkim        break;
558208625Sjkim
559228110Sjkim    case ACPI_DMT_UINT40:
560228110Sjkim        ByteLength = 5;
561228110Sjkim        break;
562228110Sjkim
563228110Sjkim    case ACPI_DMT_UINT48:
564208625Sjkim    case ACPI_DMT_NAME6:
565208625Sjkim        ByteLength = 6;
566208625Sjkim        break;
567208625Sjkim
568208625Sjkim    case ACPI_DMT_UINT56:
569218590Sjkim    case ACPI_DMT_BUF7:
570208625Sjkim        ByteLength = 7;
571208625Sjkim        break;
572208625Sjkim
573208625Sjkim    case ACPI_DMT_UINT64:
574208625Sjkim    case ACPI_DMT_NAME8:
575208625Sjkim        ByteLength = 8;
576208625Sjkim        break;
577208625Sjkim
578208625Sjkim    case ACPI_DMT_STRING:
579220663Sjkim        Value = DtGetFieldValue (Field);
580217365Sjkim        if (Value)
581217365Sjkim        {
582217365Sjkim            ByteLength = ACPI_STRLEN (Value) + 1;
583217365Sjkim        }
584217365Sjkim        else
585217365Sjkim        {   /* At this point, this is a fatal error */
586208625Sjkim
587217365Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
588217365Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
589220663Sjkim            return (0);
590217365Sjkim        }
591208625Sjkim        break;
592208625Sjkim
593208625Sjkim    case ACPI_DMT_GAS:
594208625Sjkim        ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
595208625Sjkim        break;
596208625Sjkim
597208625Sjkim    case ACPI_DMT_HESTNTFY:
598208625Sjkim        ByteLength = sizeof (ACPI_HEST_NOTIFY);
599208625Sjkim        break;
600208625Sjkim
601208625Sjkim    case ACPI_DMT_BUFFER:
602220663Sjkim        Value = DtGetFieldValue (Field);
603208625Sjkim        if (Value)
604208625Sjkim        {
605208625Sjkim            ByteLength = DtGetBufferLength (Value);
606208625Sjkim        }
607208625Sjkim        else
608208625Sjkim        {   /* At this point, this is a fatal error */
609208625Sjkim
610208625Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
611208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
612220663Sjkim            return (0);
613208625Sjkim        }
614208625Sjkim        break;
615208625Sjkim
616208625Sjkim    case ACPI_DMT_BUF16:
617217365Sjkim    case ACPI_DMT_UUID:
618208625Sjkim        ByteLength = 16;
619208625Sjkim        break;
620208625Sjkim
621219707Sjkim    case ACPI_DMT_BUF128:
622219707Sjkim        ByteLength = 128;
623219707Sjkim        break;
624219707Sjkim
625217365Sjkim    case ACPI_DMT_UNICODE:
626220663Sjkim        Value = DtGetFieldValue (Field);
627217365Sjkim
628217365Sjkim        /* TBD: error if Value is NULL? (as below?) */
629217365Sjkim
630217365Sjkim        ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
631217365Sjkim        break;
632217365Sjkim
633208625Sjkim    default:
634208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
635220663Sjkim        return (0);
636208625Sjkim    }
637208625Sjkim
638208625Sjkim    return (ByteLength);
639208625Sjkim}
640208625Sjkim
641208625Sjkim
642208625Sjkim/******************************************************************************
643208625Sjkim *
644208625Sjkim * FUNCTION:    DtSum
645208625Sjkim *
646208625Sjkim * PARAMETERS:  DT_WALK_CALLBACK:
647208625Sjkim *              Subtable            - Subtable
648208625Sjkim *              Context             - Unused
649208625Sjkim *              ReturnValue         - Store the checksum of subtable
650208625Sjkim *
651208625Sjkim * RETURN:      Status
652208625Sjkim *
653208625Sjkim * DESCRIPTION: Get the checksum of subtable
654208625Sjkim *
655208625Sjkim *****************************************************************************/
656208625Sjkim
657208625Sjkimstatic void
658208625SjkimDtSum (
659208625Sjkim    DT_SUBTABLE             *Subtable,
660208625Sjkim    void                    *Context,
661208625Sjkim    void                    *ReturnValue)
662208625Sjkim{
663208625Sjkim    UINT8                   Checksum;
664208625Sjkim    UINT8                   *Sum = ReturnValue;
665208625Sjkim
666208625Sjkim
667208625Sjkim    Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
668208625Sjkim    *Sum = (UINT8) (*Sum + Checksum);
669208625Sjkim}
670208625Sjkim
671208625Sjkim
672208625Sjkim/******************************************************************************
673208625Sjkim *
674208625Sjkim * FUNCTION:    DtSetTableChecksum
675208625Sjkim *
676208625Sjkim * PARAMETERS:  ChecksumPointer     - Where to return the checksum
677208625Sjkim *
678208625Sjkim * RETURN:      None
679208625Sjkim *
680208625Sjkim * DESCRIPTION: Set checksum of the whole data table into the checksum field
681208625Sjkim *
682208625Sjkim *****************************************************************************/
683208625Sjkim
684208625Sjkimvoid
685208625SjkimDtSetTableChecksum (
686208625Sjkim    UINT8                   *ChecksumPointer)
687208625Sjkim{
688208625Sjkim    UINT8                   Checksum = 0;
689208625Sjkim    UINT8                   OldSum;
690208625Sjkim
691208625Sjkim
692208625Sjkim    DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
693208625Sjkim
694208625Sjkim    OldSum = *ChecksumPointer;
695208625Sjkim    Checksum = (UINT8) (Checksum - OldSum);
696208625Sjkim
697208625Sjkim    /* Compute the final checksum */
698208625Sjkim
699208625Sjkim    Checksum = (UINT8) (0 - Checksum);
700208625Sjkim    *ChecksumPointer = Checksum;
701208625Sjkim}
702208625Sjkim
703208625Sjkim
704208625Sjkim/******************************************************************************
705208625Sjkim *
706208625Sjkim * FUNCTION:    DtSetTableLength
707208625Sjkim *
708208625Sjkim * PARAMETERS:  None
709208625Sjkim *
710208625Sjkim * RETURN:      None
711208625Sjkim *
712208625Sjkim * DESCRIPTION: Walk the subtables and set all the length fields
713208625Sjkim *
714208625Sjkim *****************************************************************************/
715208625Sjkim
716208625Sjkimvoid
717208625SjkimDtSetTableLength (
718208625Sjkim    void)
719208625Sjkim{
720208625Sjkim    DT_SUBTABLE             *ParentTable;
721208625Sjkim    DT_SUBTABLE             *ChildTable;
722208625Sjkim
723208625Sjkim
724208625Sjkim    ParentTable = Gbl_RootTable;
725208625Sjkim    ChildTable = NULL;
726208625Sjkim
727208625Sjkim    if (!ParentTable)
728208625Sjkim    {
729208625Sjkim        return;
730208625Sjkim    }
731208625Sjkim
732208625Sjkim    DtSetSubtableLength (ParentTable);
733208625Sjkim
734208625Sjkim    while (1)
735208625Sjkim    {
736208625Sjkim        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
737208625Sjkim        if (ChildTable)
738208625Sjkim        {
739209734Sjkim            if (ChildTable->LengthField)
740209734Sjkim            {
741209734Sjkim                DtSetSubtableLength (ChildTable);
742209734Sjkim            }
743209734Sjkim
744208625Sjkim            if (ChildTable->Child)
745208625Sjkim            {
746208625Sjkim                ParentTable = ChildTable;
747208625Sjkim                ChildTable = NULL;
748208625Sjkim            }
749208625Sjkim            else
750208625Sjkim            {
751208625Sjkim                ParentTable->TotalLength += ChildTable->TotalLength;
752208625Sjkim                if (ParentTable->LengthField)
753208625Sjkim                {
754208625Sjkim                    DtSetSubtableLength (ParentTable);
755208625Sjkim                }
756208625Sjkim            }
757208625Sjkim        }
758208625Sjkim        else
759208625Sjkim        {
760208625Sjkim            ChildTable = ParentTable;
761208625Sjkim
762208625Sjkim            if (ChildTable == Gbl_RootTable)
763208625Sjkim            {
764208625Sjkim                break;
765208625Sjkim            }
766208625Sjkim
767208625Sjkim            ParentTable = DtGetParentSubtable (ParentTable);
768208625Sjkim
769208625Sjkim            ParentTable->TotalLength += ChildTable->TotalLength;
770208625Sjkim            if (ParentTable->LengthField)
771208625Sjkim            {
772208625Sjkim                DtSetSubtableLength (ParentTable);
773208625Sjkim            }
774208625Sjkim        }
775208625Sjkim    }
776208625Sjkim}
777208625Sjkim
778208625Sjkim
779208625Sjkim/******************************************************************************
780208625Sjkim *
781208625Sjkim * FUNCTION:    DtWalkTableTree
782208625Sjkim *
783208625Sjkim * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
784208625Sjkim *              UserFunction        - Called during the walk
785208625Sjkim *              Context             - Passed to user function
786208625Sjkim *              ReturnValue         - The return value of UserFunction
787208625Sjkim *
788208625Sjkim * RETURN:      None
789208625Sjkim *
790208625Sjkim * DESCRIPTION: Performs a depth-first walk of the subtable tree
791208625Sjkim *
792208625Sjkim *****************************************************************************/
793208625Sjkim
794208625Sjkimvoid
795208625SjkimDtWalkTableTree (
796208625Sjkim    DT_SUBTABLE             *StartTable,
797208625Sjkim    DT_WALK_CALLBACK        UserFunction,
798208625Sjkim    void                    *Context,
799208625Sjkim    void                    *ReturnValue)
800208625Sjkim{
801208625Sjkim    DT_SUBTABLE             *ParentTable;
802208625Sjkim    DT_SUBTABLE             *ChildTable;
803208625Sjkim
804208625Sjkim
805208625Sjkim    ParentTable = StartTable;
806208625Sjkim    ChildTable = NULL;
807208625Sjkim
808208625Sjkim    if (!ParentTable)
809208625Sjkim    {
810208625Sjkim        return;
811208625Sjkim    }
812208625Sjkim
813208625Sjkim    UserFunction (ParentTable, Context, ReturnValue);
814208625Sjkim
815208625Sjkim    while (1)
816208625Sjkim    {
817208625Sjkim        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
818208625Sjkim        if (ChildTable)
819208625Sjkim        {
820208625Sjkim            UserFunction (ChildTable, Context, ReturnValue);
821208625Sjkim
822208625Sjkim            if (ChildTable->Child)
823208625Sjkim            {
824208625Sjkim                ParentTable = ChildTable;
825208625Sjkim                ChildTable = NULL;
826208625Sjkim            }
827208625Sjkim        }
828208625Sjkim        else
829208625Sjkim        {
830208625Sjkim            ChildTable = ParentTable;
831208625Sjkim            if (ChildTable == Gbl_RootTable)
832208625Sjkim            {
833208625Sjkim                break;
834208625Sjkim            }
835208625Sjkim
836208625Sjkim            ParentTable = DtGetParentSubtable (ParentTable);
837208625Sjkim
838208625Sjkim            if (ChildTable->Peer == StartTable)
839208625Sjkim            {
840208625Sjkim                break;
841208625Sjkim            }
842208625Sjkim        }
843208625Sjkim    }
844208625Sjkim}
845208625Sjkim
846208625Sjkim
847208625Sjkim/******************************************************************************
848208625Sjkim *
849208625Sjkim * FUNCTION:    DtFreeFieldList
850208625Sjkim *
851208625Sjkim * PARAMETERS:  None
852208625Sjkim *
853208625Sjkim * RETURN:      None
854208625Sjkim *
855208625Sjkim * DESCRIPTION: Free the field list
856208625Sjkim *
857208625Sjkim *****************************************************************************/
858208625Sjkim
859208625Sjkimvoid
860208625SjkimDtFreeFieldList (
861208625Sjkim    void)
862208625Sjkim{
863208625Sjkim    DT_FIELD                *Field = Gbl_FieldList;
864208625Sjkim    DT_FIELD                *NextField;
865208625Sjkim
866208625Sjkim
867208625Sjkim    /* Walk and free entire field list */
868208625Sjkim
869208625Sjkim    while (Field)
870208625Sjkim    {
871208625Sjkim        NextField = Field->Next; /* Save link */
872208625Sjkim
873208625Sjkim        if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
874208625Sjkim        {
875208625Sjkim            ACPI_FREE (Field->Name);
876208625Sjkim            ACPI_FREE (Field->Value);
877208625Sjkim        }
878208625Sjkim
879208625Sjkim        ACPI_FREE (Field);
880208625Sjkim        Field = NextField;
881208625Sjkim    }
882208625Sjkim}
883