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:
400252279Sjkim    case ACPI_DMT_BUF10:
401208625Sjkim    case ACPI_DMT_BUF16:
402219707Sjkim    case ACPI_DMT_BUF128:
403209734Sjkim    case ACPI_DMT_PCI_PATH:
404250838Sjkim
405208625Sjkim        Type = DT_FIELD_TYPE_BUFFER;
406208625Sjkim        break;
407208625Sjkim
408208625Sjkim    case ACPI_DMT_GAS:
409208625Sjkim    case ACPI_DMT_HESTNTFY:
410250838Sjkim
411208625Sjkim        Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
412208625Sjkim        break;
413208625Sjkim
414217365Sjkim    case ACPI_DMT_UNICODE:
415250838Sjkim
416217365Sjkim        Type = DT_FIELD_TYPE_UNICODE;
417217365Sjkim        break;
418217365Sjkim
419217365Sjkim    case ACPI_DMT_UUID:
420250838Sjkim
421217365Sjkim        Type = DT_FIELD_TYPE_UUID;
422217365Sjkim        break;
423217365Sjkim
424217365Sjkim    case ACPI_DMT_DEVICE_PATH:
425250838Sjkim
426217365Sjkim        Type = DT_FIELD_TYPE_DEVICE_PATH;
427217365Sjkim        break;
428217365Sjkim
429218590Sjkim    case ACPI_DMT_LABEL:
430250838Sjkim
431218590Sjkim        Type = DT_FIELD_TYPE_LABEL;
432218590Sjkim        break;
433218590Sjkim
434208625Sjkim    default:
435250838Sjkim
436208625Sjkim        Type = DT_FIELD_TYPE_INTEGER;
437208625Sjkim        break;
438208625Sjkim    }
439208625Sjkim
440208625Sjkim    return (Type);
441208625Sjkim}
442208625Sjkim
443208625Sjkim
444208625Sjkim/******************************************************************************
445208625Sjkim *
446208625Sjkim * FUNCTION:    DtGetBufferLength
447208625Sjkim *
448208625Sjkim * PARAMETERS:  Buffer              - List of integers,
449208625Sjkim *                                    for example "10 3A 4F 2E"
450208625Sjkim *
451208625Sjkim * RETURN:      Count of integer
452208625Sjkim *
453208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers
454208625Sjkim *
455208625Sjkim *****************************************************************************/
456208625Sjkim
457208625SjkimUINT32
458208625SjkimDtGetBufferLength (
459208625Sjkim    char                    *Buffer)
460208625Sjkim{
461208625Sjkim    UINT32                  ByteLength = 0;
462208625Sjkim
463208625Sjkim
464208625Sjkim    while (*Buffer)
465208625Sjkim    {
466208625Sjkim        if (*Buffer == ' ')
467208625Sjkim        {
468208625Sjkim            ByteLength++;
469208625Sjkim
470208625Sjkim            while (*Buffer == ' ')
471208625Sjkim            {
472208625Sjkim                Buffer++;
473208625Sjkim            }
474208625Sjkim        }
475208625Sjkim
476208625Sjkim        Buffer++;
477208625Sjkim    }
478208625Sjkim
479208625Sjkim    return (++ByteLength);
480208625Sjkim}
481208625Sjkim
482208625Sjkim
483208625Sjkim/******************************************************************************
484208625Sjkim *
485208625Sjkim * FUNCTION:    DtGetFieldLength
486208625Sjkim *
487220663Sjkim * PARAMETERS:  Field               - Current field
488208625Sjkim *              Info                - Data table info
489208625Sjkim *
490208625Sjkim * RETURN:      Field length
491208625Sjkim *
492208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field
493208625Sjkim *
494209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable.
495209734Sjkim *
496208625Sjkim *****************************************************************************/
497208625Sjkim
498208625SjkimUINT32
499208625SjkimDtGetFieldLength (
500208625Sjkim    DT_FIELD                *Field,
501208625Sjkim    ACPI_DMTABLE_INFO       *Info)
502208625Sjkim{
503208625Sjkim    UINT32                  ByteLength = 0;
504208625Sjkim    char                    *Value;
505208625Sjkim
506208625Sjkim
507208625Sjkim    /* Length is based upon the opcode for this field in the info table */
508208625Sjkim
509208625Sjkim    switch (Info->Opcode)
510208625Sjkim    {
511208625Sjkim    case ACPI_DMT_FLAG0:
512208625Sjkim    case ACPI_DMT_FLAG1:
513208625Sjkim    case ACPI_DMT_FLAG2:
514208625Sjkim    case ACPI_DMT_FLAG3:
515208625Sjkim    case ACPI_DMT_FLAG4:
516208625Sjkim    case ACPI_DMT_FLAG5:
517208625Sjkim    case ACPI_DMT_FLAG6:
518208625Sjkim    case ACPI_DMT_FLAG7:
519208625Sjkim    case ACPI_DMT_FLAGS0:
520228110Sjkim    case ACPI_DMT_FLAGS1:
521208625Sjkim    case ACPI_DMT_FLAGS2:
522228110Sjkim    case ACPI_DMT_FLAGS4:
523218590Sjkim    case ACPI_DMT_LABEL:
524228110Sjkim    case ACPI_DMT_EXTRA_TEXT:
525250838Sjkim
526208625Sjkim        ByteLength = 0;
527208625Sjkim        break;
528208625Sjkim
529208625Sjkim    case ACPI_DMT_UINT8:
530208625Sjkim    case ACPI_DMT_CHKSUM:
531208625Sjkim    case ACPI_DMT_SPACEID:
532216471Sjkim    case ACPI_DMT_ACCWIDTH:
533209734Sjkim    case ACPI_DMT_IVRS:
534208625Sjkim    case ACPI_DMT_MADT:
535228110Sjkim    case ACPI_DMT_PMTT:
536208625Sjkim    case ACPI_DMT_SRAT:
537208625Sjkim    case ACPI_DMT_ASF:
538208625Sjkim    case ACPI_DMT_HESTNTYP:
539208625Sjkim    case ACPI_DMT_FADTPM:
540209734Sjkim    case ACPI_DMT_EINJACT:
541209734Sjkim    case ACPI_DMT_EINJINST:
542209734Sjkim    case ACPI_DMT_ERSTACT:
543209734Sjkim    case ACPI_DMT_ERSTINST:
544250838Sjkim
545208625Sjkim        ByteLength = 1;
546208625Sjkim        break;
547208625Sjkim
548208625Sjkim    case ACPI_DMT_UINT16:
549208625Sjkim    case ACPI_DMT_DMAR:
550208625Sjkim    case ACPI_DMT_HEST:
551208625Sjkim    case ACPI_DMT_PCI_PATH:
552250838Sjkim
553208625Sjkim        ByteLength = 2;
554208625Sjkim        break;
555208625Sjkim
556208625Sjkim    case ACPI_DMT_UINT24:
557250838Sjkim
558208625Sjkim        ByteLength = 3;
559208625Sjkim        break;
560208625Sjkim
561208625Sjkim    case ACPI_DMT_UINT32:
562208625Sjkim    case ACPI_DMT_NAME4:
563219707Sjkim    case ACPI_DMT_SLIC:
564208625Sjkim    case ACPI_DMT_SIG:
565250838Sjkim
566208625Sjkim        ByteLength = 4;
567208625Sjkim        break;
568208625Sjkim
569228110Sjkim    case ACPI_DMT_UINT40:
570250838Sjkim
571228110Sjkim        ByteLength = 5;
572228110Sjkim        break;
573228110Sjkim
574228110Sjkim    case ACPI_DMT_UINT48:
575208625Sjkim    case ACPI_DMT_NAME6:
576250838Sjkim
577208625Sjkim        ByteLength = 6;
578208625Sjkim        break;
579208625Sjkim
580208625Sjkim    case ACPI_DMT_UINT56:
581218590Sjkim    case ACPI_DMT_BUF7:
582250838Sjkim
583208625Sjkim        ByteLength = 7;
584208625Sjkim        break;
585208625Sjkim
586208625Sjkim    case ACPI_DMT_UINT64:
587208625Sjkim    case ACPI_DMT_NAME8:
588250838Sjkim
589208625Sjkim        ByteLength = 8;
590208625Sjkim        break;
591208625Sjkim
592208625Sjkim    case ACPI_DMT_STRING:
593250838Sjkim
594220663Sjkim        Value = DtGetFieldValue (Field);
595217365Sjkim        if (Value)
596217365Sjkim        {
597217365Sjkim            ByteLength = ACPI_STRLEN (Value) + 1;
598217365Sjkim        }
599217365Sjkim        else
600217365Sjkim        {   /* At this point, this is a fatal error */
601208625Sjkim
602217365Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
603217365Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
604220663Sjkim            return (0);
605217365Sjkim        }
606208625Sjkim        break;
607208625Sjkim
608208625Sjkim    case ACPI_DMT_GAS:
609250838Sjkim
610208625Sjkim        ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
611208625Sjkim        break;
612208625Sjkim
613208625Sjkim    case ACPI_DMT_HESTNTFY:
614250838Sjkim
615208625Sjkim        ByteLength = sizeof (ACPI_HEST_NOTIFY);
616208625Sjkim        break;
617208625Sjkim
618208625Sjkim    case ACPI_DMT_BUFFER:
619250838Sjkim
620220663Sjkim        Value = DtGetFieldValue (Field);
621208625Sjkim        if (Value)
622208625Sjkim        {
623208625Sjkim            ByteLength = DtGetBufferLength (Value);
624208625Sjkim        }
625208625Sjkim        else
626208625Sjkim        {   /* At this point, this is a fatal error */
627208625Sjkim
628208625Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
629208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
630220663Sjkim            return (0);
631208625Sjkim        }
632208625Sjkim        break;
633208625Sjkim
634252279Sjkim    case ACPI_DMT_BUF10:
635252279Sjkim
636252279Sjkim        ByteLength = 10;
637252279Sjkim        break;
638252279Sjkim
639208625Sjkim    case ACPI_DMT_BUF16:
640217365Sjkim    case ACPI_DMT_UUID:
641250838Sjkim
642208625Sjkim        ByteLength = 16;
643208625Sjkim        break;
644208625Sjkim
645219707Sjkim    case ACPI_DMT_BUF128:
646250838Sjkim
647219707Sjkim        ByteLength = 128;
648219707Sjkim        break;
649219707Sjkim
650217365Sjkim    case ACPI_DMT_UNICODE:
651250838Sjkim
652220663Sjkim        Value = DtGetFieldValue (Field);
653217365Sjkim
654217365Sjkim        /* TBD: error if Value is NULL? (as below?) */
655217365Sjkim
656217365Sjkim        ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
657217365Sjkim        break;
658217365Sjkim
659208625Sjkim    default:
660250838Sjkim
661208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
662220663Sjkim        return (0);
663208625Sjkim    }
664208625Sjkim
665208625Sjkim    return (ByteLength);
666208625Sjkim}
667208625Sjkim
668208625Sjkim
669208625Sjkim/******************************************************************************
670208625Sjkim *
671208625Sjkim * FUNCTION:    DtSum
672208625Sjkim *
673208625Sjkim * PARAMETERS:  DT_WALK_CALLBACK:
674208625Sjkim *              Subtable            - Subtable
675208625Sjkim *              Context             - Unused
676208625Sjkim *              ReturnValue         - Store the checksum of subtable
677208625Sjkim *
678208625Sjkim * RETURN:      Status
679208625Sjkim *
680208625Sjkim * DESCRIPTION: Get the checksum of subtable
681208625Sjkim *
682208625Sjkim *****************************************************************************/
683208625Sjkim
684208625Sjkimstatic void
685208625SjkimDtSum (
686208625Sjkim    DT_SUBTABLE             *Subtable,
687208625Sjkim    void                    *Context,
688208625Sjkim    void                    *ReturnValue)
689208625Sjkim{
690208625Sjkim    UINT8                   Checksum;
691208625Sjkim    UINT8                   *Sum = ReturnValue;
692208625Sjkim
693208625Sjkim
694208625Sjkim    Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
695208625Sjkim    *Sum = (UINT8) (*Sum + Checksum);
696208625Sjkim}
697208625Sjkim
698208625Sjkim
699208625Sjkim/******************************************************************************
700208625Sjkim *
701208625Sjkim * FUNCTION:    DtSetTableChecksum
702208625Sjkim *
703208625Sjkim * PARAMETERS:  ChecksumPointer     - Where to return the checksum
704208625Sjkim *
705208625Sjkim * RETURN:      None
706208625Sjkim *
707208625Sjkim * DESCRIPTION: Set checksum of the whole data table into the checksum field
708208625Sjkim *
709208625Sjkim *****************************************************************************/
710208625Sjkim
711208625Sjkimvoid
712208625SjkimDtSetTableChecksum (
713208625Sjkim    UINT8                   *ChecksumPointer)
714208625Sjkim{
715208625Sjkim    UINT8                   Checksum = 0;
716208625Sjkim    UINT8                   OldSum;
717208625Sjkim
718208625Sjkim
719208625Sjkim    DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
720208625Sjkim
721208625Sjkim    OldSum = *ChecksumPointer;
722208625Sjkim    Checksum = (UINT8) (Checksum - OldSum);
723208625Sjkim
724208625Sjkim    /* Compute the final checksum */
725208625Sjkim
726208625Sjkim    Checksum = (UINT8) (0 - Checksum);
727208625Sjkim    *ChecksumPointer = Checksum;
728208625Sjkim}
729208625Sjkim
730208625Sjkim
731208625Sjkim/******************************************************************************
732208625Sjkim *
733208625Sjkim * FUNCTION:    DtSetTableLength
734208625Sjkim *
735208625Sjkim * PARAMETERS:  None
736208625Sjkim *
737208625Sjkim * RETURN:      None
738208625Sjkim *
739208625Sjkim * DESCRIPTION: Walk the subtables and set all the length fields
740208625Sjkim *
741208625Sjkim *****************************************************************************/
742208625Sjkim
743208625Sjkimvoid
744208625SjkimDtSetTableLength (
745208625Sjkim    void)
746208625Sjkim{
747208625Sjkim    DT_SUBTABLE             *ParentTable;
748208625Sjkim    DT_SUBTABLE             *ChildTable;
749208625Sjkim
750208625Sjkim
751208625Sjkim    ParentTable = Gbl_RootTable;
752208625Sjkim    ChildTable = NULL;
753208625Sjkim
754208625Sjkim    if (!ParentTable)
755208625Sjkim    {
756208625Sjkim        return;
757208625Sjkim    }
758208625Sjkim
759208625Sjkim    DtSetSubtableLength (ParentTable);
760208625Sjkim
761208625Sjkim    while (1)
762208625Sjkim    {
763208625Sjkim        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
764208625Sjkim        if (ChildTable)
765208625Sjkim        {
766209734Sjkim            if (ChildTable->LengthField)
767209734Sjkim            {
768209734Sjkim                DtSetSubtableLength (ChildTable);
769209734Sjkim            }
770209734Sjkim
771208625Sjkim            if (ChildTable->Child)
772208625Sjkim            {
773208625Sjkim                ParentTable = ChildTable;
774208625Sjkim                ChildTable = NULL;
775208625Sjkim            }
776208625Sjkim            else
777208625Sjkim            {
778208625Sjkim                ParentTable->TotalLength += ChildTable->TotalLength;
779208625Sjkim                if (ParentTable->LengthField)
780208625Sjkim                {
781208625Sjkim                    DtSetSubtableLength (ParentTable);
782208625Sjkim                }
783208625Sjkim            }
784208625Sjkim        }
785208625Sjkim        else
786208625Sjkim        {
787208625Sjkim            ChildTable = ParentTable;
788208625Sjkim
789208625Sjkim            if (ChildTable == Gbl_RootTable)
790208625Sjkim            {
791208625Sjkim                break;
792208625Sjkim            }
793208625Sjkim
794208625Sjkim            ParentTable = DtGetParentSubtable (ParentTable);
795208625Sjkim
796208625Sjkim            ParentTable->TotalLength += ChildTable->TotalLength;
797208625Sjkim            if (ParentTable->LengthField)
798208625Sjkim            {
799208625Sjkim                DtSetSubtableLength (ParentTable);
800208625Sjkim            }
801208625Sjkim        }
802208625Sjkim    }
803208625Sjkim}
804208625Sjkim
805208625Sjkim
806208625Sjkim/******************************************************************************
807208625Sjkim *
808208625Sjkim * FUNCTION:    DtWalkTableTree
809208625Sjkim *
810208625Sjkim * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
811208625Sjkim *              UserFunction        - Called during the walk
812208625Sjkim *              Context             - Passed to user function
813208625Sjkim *              ReturnValue         - The return value of UserFunction
814208625Sjkim *
815208625Sjkim * RETURN:      None
816208625Sjkim *
817208625Sjkim * DESCRIPTION: Performs a depth-first walk of the subtable tree
818208625Sjkim *
819208625Sjkim *****************************************************************************/
820208625Sjkim
821208625Sjkimvoid
822208625SjkimDtWalkTableTree (
823208625Sjkim    DT_SUBTABLE             *StartTable,
824208625Sjkim    DT_WALK_CALLBACK        UserFunction,
825208625Sjkim    void                    *Context,
826208625Sjkim    void                    *ReturnValue)
827208625Sjkim{
828208625Sjkim    DT_SUBTABLE             *ParentTable;
829208625Sjkim    DT_SUBTABLE             *ChildTable;
830208625Sjkim
831208625Sjkim
832208625Sjkim    ParentTable = StartTable;
833208625Sjkim    ChildTable = NULL;
834208625Sjkim
835208625Sjkim    if (!ParentTable)
836208625Sjkim    {
837208625Sjkim        return;
838208625Sjkim    }
839208625Sjkim
840208625Sjkim    UserFunction (ParentTable, Context, ReturnValue);
841208625Sjkim
842208625Sjkim    while (1)
843208625Sjkim    {
844208625Sjkim        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
845208625Sjkim        if (ChildTable)
846208625Sjkim        {
847208625Sjkim            UserFunction (ChildTable, Context, ReturnValue);
848208625Sjkim
849208625Sjkim            if (ChildTable->Child)
850208625Sjkim            {
851208625Sjkim                ParentTable = ChildTable;
852208625Sjkim                ChildTable = NULL;
853208625Sjkim            }
854208625Sjkim        }
855208625Sjkim        else
856208625Sjkim        {
857208625Sjkim            ChildTable = ParentTable;
858208625Sjkim            if (ChildTable == Gbl_RootTable)
859208625Sjkim            {
860208625Sjkim                break;
861208625Sjkim            }
862208625Sjkim
863208625Sjkim            ParentTable = DtGetParentSubtable (ParentTable);
864208625Sjkim
865208625Sjkim            if (ChildTable->Peer == StartTable)
866208625Sjkim            {
867208625Sjkim                break;
868208625Sjkim            }
869208625Sjkim        }
870208625Sjkim    }
871208625Sjkim}
872208625Sjkim
873208625Sjkim
874208625Sjkim/******************************************************************************
875208625Sjkim *
876208625Sjkim * FUNCTION:    DtFreeFieldList
877208625Sjkim *
878208625Sjkim * PARAMETERS:  None
879208625Sjkim *
880208625Sjkim * RETURN:      None
881208625Sjkim *
882208625Sjkim * DESCRIPTION: Free the field list
883208625Sjkim *
884208625Sjkim *****************************************************************************/
885208625Sjkim
886208625Sjkimvoid
887208625SjkimDtFreeFieldList (
888208625Sjkim    void)
889208625Sjkim{
890208625Sjkim    DT_FIELD                *Field = Gbl_FieldList;
891208625Sjkim    DT_FIELD                *NextField;
892208625Sjkim
893208625Sjkim
894208625Sjkim    /* Walk and free entire field list */
895208625Sjkim
896208625Sjkim    while (Field)
897208625Sjkim    {
898208625Sjkim        NextField = Field->Next; /* Save link */
899208625Sjkim
900208625Sjkim        if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
901208625Sjkim        {
902208625Sjkim            ACPI_FREE (Field->Name);
903208625Sjkim            ACPI_FREE (Field->Value);
904208625Sjkim        }
905208625Sjkim
906208625Sjkim        ACPI_FREE (Field);
907208625Sjkim        Field = NextField;
908208625Sjkim    }
909208625Sjkim}
910