dtutils.c revision 216471
1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtutils.c - Utility routines for the data table compiler
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7208625Sjkim/******************************************************************************
8208625Sjkim *
9208625Sjkim * 1. Copyright Notice
10208625Sjkim *
11208625Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12208625Sjkim * All rights reserved.
13208625Sjkim *
14208625Sjkim * 2. License
15208625Sjkim *
16208625Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17208625Sjkim * rights.  You may have additional license terms from the party that provided
18208625Sjkim * you this software, covering your right to use that party's intellectual
19208625Sjkim * property rights.
20208625Sjkim *
21208625Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22208625Sjkim * copy of the source code appearing in this file ("Covered Code") an
23208625Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24208625Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25208625Sjkim * make derivatives, distribute, use and display any portion of the Covered
26208625Sjkim * Code in any form, with the right to sublicense such rights; and
27208625Sjkim *
28208625Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29208625Sjkim * license (with the right to sublicense), under only those claims of Intel
30208625Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31208625Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32208625Sjkim * solely to the minimum extent necessary to exercise the above copyright
33208625Sjkim * license, and in no event shall the patent license extend to any additions
34208625Sjkim * to or modifications of the Original Intel Code.  No other license or right
35208625Sjkim * is granted directly or by implication, estoppel or otherwise;
36208625Sjkim *
37208625Sjkim * The above copyright and patent license is granted only if the following
38208625Sjkim * conditions are met:
39208625Sjkim *
40208625Sjkim * 3. Conditions
41208625Sjkim *
42208625Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43208625Sjkim * Redistribution of source code of any substantial portion of the Covered
44208625Sjkim * Code or modification with rights to further distribute source must include
45208625Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46208625Sjkim * and the following Disclaimer and Export Compliance provision.  In addition,
47208625Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48208625Sjkim * contain a file documenting the changes Licensee made to create that Covered
49208625Sjkim * Code and the date of any change.  Licensee must include in that file the
50208625Sjkim * documentation of any changes made by any predecessor Licensee.  Licensee
51208625Sjkim * must include a prominent statement that the modification is derived,
52208625Sjkim * directly or indirectly, from Original Intel Code.
53208625Sjkim *
54208625Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55208625Sjkim * Redistribution of source code of any substantial portion of the Covered
56208625Sjkim * Code or modification without rights to further distribute source must
57208625Sjkim * include the following Disclaimer and Export Compliance provision in the
58208625Sjkim * documentation and/or other materials provided with distribution.  In
59208625Sjkim * addition, Licensee may not authorize further sublicense of source of any
60208625Sjkim * portion of the Covered Code, and must include terms to the effect that the
61208625Sjkim * license from Licensee to its licensee is limited to the intellectual
62208625Sjkim * property embodied in the software Licensee provides to its licensee, and
63208625Sjkim * not to intellectual property embodied in modifications its licensee may
64208625Sjkim * make.
65208625Sjkim *
66208625Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67208625Sjkim * substantial portion of the Covered Code or modification must reproduce the
68208625Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69208625Sjkim * provision in the documentation and/or other materials provided with the
70208625Sjkim * distribution.
71208625Sjkim *
72208625Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73208625Sjkim * Intel Code.
74208625Sjkim *
75208625Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76208625Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77208625Sjkim * other dealings in products derived from or relating to the Covered Code
78208625Sjkim * without prior written authorization from Intel.
79208625Sjkim *
80208625Sjkim * 4. Disclaimer and Export Compliance
81208625Sjkim *
82208625Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83208625Sjkim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84208625Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85208625Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86208625Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87208625Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88208625Sjkim * PARTICULAR PURPOSE.
89208625Sjkim *
90208625Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91208625Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92208625Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93208625Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94208625Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95208625Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96208625Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97208625Sjkim * LIMITED REMEDY.
98208625Sjkim *
99208625Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100208625Sjkim * software or system incorporating such software without first obtaining any
101208625Sjkim * required license or other approval from the U. S. Department of Commerce or
102208625Sjkim * any other agency or department of the United States Government.  In the
103208625Sjkim * event Licensee exports any such software from the United States or
104208625Sjkim * re-exports any such software from a foreign destination, Licensee shall
105208625Sjkim * ensure that the distribution and export/re-export of the software is in
106208625Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107208625Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108208625Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109208625Sjkim * software, or service, directly or indirectly, to any country for which the
110208625Sjkim * United States government or any agency thereof requires an export license,
111208625Sjkim * other governmental approval, or letter of assurance, without first obtaining
112208625Sjkim * such license, approval or letter.
113208625Sjkim *
114208625Sjkim *****************************************************************************/
115208625Sjkim
116208625Sjkim#define __DTUTILS_C__
117208625Sjkim
118209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
119209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
120209746Sjkim#include <contrib/dev/acpica/include/actables.h>
121208625Sjkim
122208625Sjkim#define _COMPONENT          DT_COMPILER
123208625Sjkim        ACPI_MODULE_NAME    ("dtutils")
124208625Sjkim
125208625Sjkim/* Local prototypes */
126208625Sjkim
127208625Sjkimstatic void
128208625SjkimDtSum (
129208625Sjkim    DT_SUBTABLE             *Subtable,
130208625Sjkim    void                    *Context,
131208625Sjkim    void                    *ReturnValue);
132208625Sjkim
133208625Sjkim
134208625Sjkim/******************************************************************************
135208625Sjkim *
136208625Sjkim * FUNCTION:    DtError
137208625Sjkim *
138208625Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
139208625Sjkim *              MessageId           - Index into global message buffer
140208625Sjkim *              Op                  - Parse node where error happened
141208625Sjkim *              ExtraMessage        - additional error message
142208625Sjkim *
143208625Sjkim * RETURN:      None
144208625Sjkim *
145208625Sjkim * DESCRIPTION: Common error interface for data table compiler
146208625Sjkim *
147208625Sjkim *****************************************************************************/
148208625Sjkim
149208625Sjkimvoid
150208625SjkimDtError (
151208625Sjkim    UINT8                   Level,
152208625Sjkim    UINT8                   MessageId,
153208625Sjkim    DT_FIELD                *FieldObject,
154208625Sjkim    char                    *ExtraMessage)
155208625Sjkim{
156208625Sjkim
157208625Sjkim    switch (Level)
158208625Sjkim    {
159208625Sjkim    case ASL_WARNING2:
160208625Sjkim    case ASL_WARNING3:
161208625Sjkim        if (Gbl_WarningLevel < Level)
162208625Sjkim        {
163208625Sjkim            return;
164208625Sjkim        }
165208625Sjkim        break;
166208625Sjkim
167208625Sjkim    default:
168208625Sjkim        break;
169208625Sjkim    }
170208625Sjkim
171208625Sjkim    if (FieldObject)
172208625Sjkim    {
173208625Sjkim        AslCommonError (Level, MessageId,
174208625Sjkim            FieldObject->Line,
175208625Sjkim            FieldObject->Line,
176208625Sjkim            FieldObject->ByteOffset,
177208625Sjkim            FieldObject->Column,
178208625Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
179208625Sjkim    }
180208625Sjkim    else
181208625Sjkim    {
182208625Sjkim        AslCommonError (Level, MessageId, 0,
183208625Sjkim            0, 0, 0, 0, ExtraMessage);
184208625Sjkim    }
185208625Sjkim}
186208625Sjkim
187208625Sjkim
188208625Sjkim/******************************************************************************
189208625Sjkim *
190208625Sjkim * FUNCTION:    DtNameError
191208625Sjkim *
192208625Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
193208625Sjkim *              MessageId           - Index into global message buffer
194208625Sjkim *              Op                  - Parse node where error happened
195208625Sjkim *              ExtraMessage        - additional error message
196208625Sjkim *
197208625Sjkim * RETURN:      None
198208625Sjkim *
199208625Sjkim * DESCRIPTION: Error interface for named objects
200208625Sjkim *
201208625Sjkim *****************************************************************************/
202208625Sjkim
203208625Sjkimvoid
204208625SjkimDtNameError (
205208625Sjkim    UINT8                   Level,
206208625Sjkim    UINT8                   MessageId,
207208625Sjkim    DT_FIELD                *FieldObject,
208208625Sjkim    char                    *ExtraMessage)
209208625Sjkim{
210208625Sjkim
211208625Sjkim    switch (Level)
212208625Sjkim    {
213208625Sjkim    case ASL_WARNING2:
214208625Sjkim    case ASL_WARNING3:
215208625Sjkim        if (Gbl_WarningLevel < Level)
216208625Sjkim        {
217208625Sjkim            return;
218208625Sjkim        }
219208625Sjkim        break;
220208625Sjkim
221208625Sjkim    default:
222208625Sjkim        break;
223208625Sjkim    }
224208625Sjkim
225208625Sjkim    if (FieldObject)
226208625Sjkim    {
227208625Sjkim        AslCommonError (Level, MessageId,
228208625Sjkim            FieldObject->Line,
229208625Sjkim            FieldObject->Line,
230208625Sjkim            FieldObject->ByteOffset,
231208625Sjkim            FieldObject->NameColumn,
232208625Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
233208625Sjkim    }
234208625Sjkim    else
235208625Sjkim    {
236208625Sjkim        AslCommonError (Level, MessageId, 0,
237208625Sjkim            0, 0, 0, 0, ExtraMessage);
238208625Sjkim    }
239208625Sjkim}
240208625Sjkim
241208625Sjkim
242208625Sjkim/*******************************************************************************
243208625Sjkim *
244208625Sjkim * FUNCTION:    DtFatal
245208625Sjkim *
246208625Sjkim * PARAMETERS:  None
247208625Sjkim *
248208625Sjkim * RETURN:      None
249208625Sjkim *
250208625Sjkim * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
251208625Sjkim *              compile or I/O errors
252208625Sjkim *
253208625Sjkim ******************************************************************************/
254208625Sjkim
255208625Sjkimvoid
256208625SjkimDtFatal (
257208625Sjkim    UINT8                   MessageId,
258208625Sjkim    DT_FIELD                *FieldObject,
259208625Sjkim    char                    *ExtraMessage)
260208625Sjkim{
261208625Sjkim
262208625Sjkim    DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
263208625Sjkim
264208625Sjkim    CmCleanupAndExit ();
265208625Sjkim    exit (1);
266208625Sjkim}
267208625Sjkim
268208625Sjkim
269208625Sjkim/******************************************************************************
270208625Sjkim *
271208625Sjkim * FUNCTION:    DtStrtoul64
272208625Sjkim *
273208625Sjkim * PARAMETERS:  String              - Null terminated string
274208625Sjkim *              ReturnInteger       - Where the converted integer is returned
275208625Sjkim *
276208625Sjkim * RETURN:      Status
277208625Sjkim *
278208625Sjkim * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
279208625Sjkim *              value. Assumes no leading "0x" for the constant.
280208625Sjkim *
281208625Sjkim * Portability note: The reason this function exists is because a 64-bit
282208625Sjkim * sscanf is not available in all environments.
283208625Sjkim *
284208625Sjkim *****************************************************************************/
285208625Sjkim
286208625SjkimACPI_STATUS
287208625SjkimDtStrtoul64 (
288208625Sjkim    char                    *String,
289208625Sjkim    UINT64                  *ReturnInteger)
290208625Sjkim{
291208625Sjkim    char                    *ThisChar = String;
292208625Sjkim    UINT32                  ThisDigit;
293208625Sjkim    UINT64                  ReturnValue = 0;
294208625Sjkim    int                     DigitCount = 0;
295208625Sjkim
296208625Sjkim
297208625Sjkim    /* Skip over any white space in the buffer */
298208625Sjkim
299208625Sjkim    while ((*ThisChar == ' ') || (*ThisChar == '\t'))
300208625Sjkim    {
301208625Sjkim        ThisChar++;
302208625Sjkim    }
303208625Sjkim
304208625Sjkim    /* Skip leading zeros */
305208625Sjkim
306208625Sjkim    while ((*ThisChar) == '0')
307208625Sjkim    {
308208625Sjkim        ThisChar++;
309208625Sjkim    }
310208625Sjkim
311208625Sjkim    /* Convert character-by-character */
312208625Sjkim
313208625Sjkim    while (*ThisChar)
314208625Sjkim    {
315208625Sjkim        if (ACPI_IS_DIGIT (*ThisChar))
316208625Sjkim        {
317208625Sjkim            /* Convert ASCII 0-9 to Decimal value */
318208625Sjkim
319208625Sjkim            ThisDigit = ((UINT8) *ThisChar) - '0';
320208625Sjkim        }
321208625Sjkim        else /* Letter */
322208625Sjkim        {
323208625Sjkim            ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
324208625Sjkim            if (!ACPI_IS_XDIGIT ((char) ThisDigit))
325208625Sjkim            {
326208625Sjkim                /* Not A-F */
327208625Sjkim
328208625Sjkim                return (AE_BAD_CHARACTER);
329208625Sjkim            }
330208625Sjkim
331208625Sjkim            /* Convert ASCII Hex char (A-F) to value */
332208625Sjkim
333208625Sjkim            ThisDigit = (ThisDigit - 'A') + 10;
334208625Sjkim        }
335208625Sjkim
336208625Sjkim        /* Insert the 4-bit hex digit */
337208625Sjkim
338208625Sjkim        ReturnValue <<= 4;
339208625Sjkim        ReturnValue += ThisDigit;
340208625Sjkim
341208625Sjkim        ThisChar++;
342208625Sjkim        DigitCount++;
343208625Sjkim        if (DigitCount > 16)
344208625Sjkim        {
345208625Sjkim            /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
346208625Sjkim
347208625Sjkim            return (AE_LIMIT);
348208625Sjkim        }
349208625Sjkim    }
350208625Sjkim
351208625Sjkim    *ReturnInteger = ReturnValue;
352208625Sjkim    return (AE_OK);
353208625Sjkim}
354208625Sjkim
355208625Sjkim
356208625Sjkim/******************************************************************************
357208625Sjkim *
358208625Sjkim * FUNCTION:    DtGetFileSize
359208625Sjkim *
360208625Sjkim * PARAMETERS:  Handle              - Open file handler
361208625Sjkim *
362208625Sjkim * RETURN:      Current file size
363208625Sjkim *
364208625Sjkim * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
365208625Sjkim *              offset. Seek back to the original location.
366208625Sjkim *
367208625Sjkim *****************************************************************************/
368208625Sjkim
369208625SjkimUINT32
370208625SjkimDtGetFileSize (
371208625Sjkim    FILE                    *Handle)
372208625Sjkim{
373208625Sjkim    int                     CurrentOffset;
374208625Sjkim    int                     LastOffset;
375208625Sjkim
376208625Sjkim
377208625Sjkim    CurrentOffset = ftell (Handle);
378208625Sjkim    fseek (Handle, 0, SEEK_END);
379208625Sjkim    LastOffset = ftell (Handle);
380208625Sjkim    fseek (Handle, CurrentOffset, SEEK_SET);
381208625Sjkim
382208625Sjkim    return ((UINT32) LastOffset);
383208625Sjkim}
384208625Sjkim
385208625Sjkim
386208625Sjkim/******************************************************************************
387208625Sjkim *
388208625Sjkim * FUNCTION:    DtGetFieldValue
389208625Sjkim *
390208625Sjkim * PARAMETERS:  Field               - Current field list pointer
391208625Sjkim *              Name                - Field name
392208625Sjkim *
393208625Sjkim * RETURN:      Field value
394208625Sjkim *
395208625Sjkim * DESCRIPTION: Get field value
396208625Sjkim *
397208625Sjkim *****************************************************************************/
398208625Sjkim
399208625Sjkimchar *
400208625SjkimDtGetFieldValue (
401208625Sjkim    DT_FIELD                *Field,
402208625Sjkim    char                    *Name)
403208625Sjkim{
404208625Sjkim
405208625Sjkim    /* Search the field list for the name */
406208625Sjkim
407208625Sjkim    while (Field)
408208625Sjkim    {
409208625Sjkim        if (!ACPI_STRCMP (Name, Field->Name))
410208625Sjkim        {
411208625Sjkim            return (Field->Value);
412208625Sjkim        }
413208625Sjkim
414208625Sjkim        Field = Field->Next;
415208625Sjkim    }
416208625Sjkim
417208625Sjkim    return (NULL);
418208625Sjkim}
419208625Sjkim
420208625Sjkim
421208625Sjkim/******************************************************************************
422208625Sjkim *
423208625Sjkim * FUNCTION:    DtGetFieldType
424208625Sjkim *
425208625Sjkim * PARAMETERS:  Info                - Data table info
426208625Sjkim *
427208625Sjkim * RETURN:      Field type
428208625Sjkim *
429208625Sjkim * DESCRIPTION: Get field type
430208625Sjkim *
431208625Sjkim *****************************************************************************/
432208625Sjkim
433208625SjkimUINT8
434208625SjkimDtGetFieldType (
435208625Sjkim    ACPI_DMTABLE_INFO       *Info)
436208625Sjkim{
437208625Sjkim    UINT8                   Type;
438208625Sjkim
439208625Sjkim
440208625Sjkim    /* DT_FLAG means that this is the start of a block of flag bits */
441208625Sjkim    /* TBD - we can make these a separate opcode later */
442208625Sjkim
443208625Sjkim    if (Info->Flags & DT_FLAG)
444208625Sjkim    {
445208625Sjkim        return (DT_FIELD_TYPE_FLAGS_INTEGER);
446208625Sjkim    }
447208625Sjkim
448208625Sjkim    /* Type is based upon the opcode for this field in the info table */
449208625Sjkim
450208625Sjkim    switch (Info->Opcode)
451208625Sjkim    {
452208625Sjkim    case ACPI_DMT_FLAG0:
453208625Sjkim    case ACPI_DMT_FLAG1:
454208625Sjkim    case ACPI_DMT_FLAG2:
455208625Sjkim    case ACPI_DMT_FLAG3:
456208625Sjkim    case ACPI_DMT_FLAG4:
457208625Sjkim    case ACPI_DMT_FLAG5:
458208625Sjkim    case ACPI_DMT_FLAG6:
459208625Sjkim    case ACPI_DMT_FLAG7:
460208625Sjkim    case ACPI_DMT_FLAGS0:
461208625Sjkim    case ACPI_DMT_FLAGS2:
462208625Sjkim        Type = DT_FIELD_TYPE_FLAG;
463208625Sjkim        break;
464208625Sjkim
465208625Sjkim    case ACPI_DMT_NAME4:
466208625Sjkim    case ACPI_DMT_SIG:
467208625Sjkim    case ACPI_DMT_NAME6:
468208625Sjkim    case ACPI_DMT_NAME8:
469208625Sjkim    case ACPI_DMT_STRING:
470208625Sjkim        Type = DT_FIELD_TYPE_STRING;
471208625Sjkim        break;
472208625Sjkim
473208625Sjkim    case ACPI_DMT_BUFFER:
474208625Sjkim    case ACPI_DMT_BUF16:
475209734Sjkim    case ACPI_DMT_PCI_PATH:
476208625Sjkim        Type = DT_FIELD_TYPE_BUFFER;
477208625Sjkim        break;
478208625Sjkim
479208625Sjkim    case ACPI_DMT_GAS:
480208625Sjkim    case ACPI_DMT_HESTNTFY:
481208625Sjkim        Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
482208625Sjkim        break;
483208625Sjkim
484208625Sjkim    default:
485208625Sjkim        Type = DT_FIELD_TYPE_INTEGER;
486208625Sjkim        break;
487208625Sjkim    }
488208625Sjkim
489208625Sjkim    return (Type);
490208625Sjkim}
491208625Sjkim
492208625Sjkim
493208625Sjkim/******************************************************************************
494208625Sjkim *
495208625Sjkim * FUNCTION:    DtGetBufferLength
496208625Sjkim *
497208625Sjkim * PARAMETERS:  Buffer              - List of integers,
498208625Sjkim *                                    for example "10 3A 4F 2E"
499208625Sjkim *
500208625Sjkim * RETURN:      Count of integer
501208625Sjkim *
502208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers
503208625Sjkim *
504208625Sjkim *****************************************************************************/
505208625Sjkim
506208625SjkimUINT32
507208625SjkimDtGetBufferLength (
508208625Sjkim    char                    *Buffer)
509208625Sjkim{
510208625Sjkim    UINT32                  ByteLength = 0;
511208625Sjkim
512208625Sjkim
513208625Sjkim    while (*Buffer)
514208625Sjkim    {
515208625Sjkim        if (*Buffer == ' ')
516208625Sjkim        {
517208625Sjkim            ByteLength++;
518208625Sjkim
519208625Sjkim            while (*Buffer == ' ')
520208625Sjkim            {
521208625Sjkim                Buffer++;
522208625Sjkim            }
523208625Sjkim        }
524208625Sjkim
525208625Sjkim        Buffer++;
526208625Sjkim    }
527208625Sjkim
528208625Sjkim    return (++ByteLength);
529208625Sjkim}
530208625Sjkim
531208625Sjkim
532208625Sjkim/******************************************************************************
533208625Sjkim *
534208625Sjkim * FUNCTION:    DtGetFieldLength
535208625Sjkim *
536208625Sjkim * PARAMETERS:  Field               - Current field list pointer
537208625Sjkim *              Info                - Data table info
538208625Sjkim *
539208625Sjkim * RETURN:      Field length
540208625Sjkim *
541208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field
542208625Sjkim *
543209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable.
544209734Sjkim *
545208625Sjkim *****************************************************************************/
546208625Sjkim
547208625SjkimUINT32
548208625SjkimDtGetFieldLength (
549208625Sjkim    DT_FIELD                *Field,
550208625Sjkim    ACPI_DMTABLE_INFO       *Info)
551208625Sjkim{
552208625Sjkim    UINT32                  ByteLength = 0;
553208625Sjkim    char                    *Value;
554208625Sjkim
555208625Sjkim
556208625Sjkim    /* Length is based upon the opcode for this field in the info table */
557208625Sjkim
558208625Sjkim    switch (Info->Opcode)
559208625Sjkim    {
560208625Sjkim    case ACPI_DMT_FLAG0:
561208625Sjkim    case ACPI_DMT_FLAG1:
562208625Sjkim    case ACPI_DMT_FLAG2:
563208625Sjkim    case ACPI_DMT_FLAG3:
564208625Sjkim    case ACPI_DMT_FLAG4:
565208625Sjkim    case ACPI_DMT_FLAG5:
566208625Sjkim    case ACPI_DMT_FLAG6:
567208625Sjkim    case ACPI_DMT_FLAG7:
568208625Sjkim    case ACPI_DMT_FLAGS0:
569208625Sjkim    case ACPI_DMT_FLAGS2:
570208625Sjkim        ByteLength = 0;
571208625Sjkim        break;
572208625Sjkim
573208625Sjkim    case ACPI_DMT_UINT8:
574208625Sjkim    case ACPI_DMT_CHKSUM:
575208625Sjkim    case ACPI_DMT_SPACEID:
576216471Sjkim    case ACPI_DMT_ACCWIDTH:
577209734Sjkim    case ACPI_DMT_IVRS:
578208625Sjkim    case ACPI_DMT_MADT:
579208625Sjkim    case ACPI_DMT_SRAT:
580208625Sjkim    case ACPI_DMT_ASF:
581208625Sjkim    case ACPI_DMT_HESTNTYP:
582208625Sjkim    case ACPI_DMT_FADTPM:
583209734Sjkim    case ACPI_DMT_EINJACT:
584209734Sjkim    case ACPI_DMT_EINJINST:
585209734Sjkim    case ACPI_DMT_ERSTACT:
586209734Sjkim    case ACPI_DMT_ERSTINST:
587208625Sjkim        ByteLength = 1;
588208625Sjkim        break;
589208625Sjkim
590208625Sjkim    case ACPI_DMT_UINT16:
591208625Sjkim    case ACPI_DMT_DMAR:
592208625Sjkim    case ACPI_DMT_HEST:
593208625Sjkim    case ACPI_DMT_PCI_PATH:
594208625Sjkim        ByteLength = 2;
595208625Sjkim        break;
596208625Sjkim
597208625Sjkim    case ACPI_DMT_UINT24:
598208625Sjkim        ByteLength = 3;
599208625Sjkim        break;
600208625Sjkim
601208625Sjkim    case ACPI_DMT_UINT32:
602208625Sjkim    case ACPI_DMT_NAME4:
603208625Sjkim    case ACPI_DMT_SIG:
604208625Sjkim        ByteLength = 4;
605208625Sjkim        break;
606208625Sjkim
607208625Sjkim    case ACPI_DMT_NAME6:
608208625Sjkim        ByteLength = 6;
609208625Sjkim        break;
610208625Sjkim
611208625Sjkim    case ACPI_DMT_UINT56:
612208625Sjkim        ByteLength = 7;
613208625Sjkim        break;
614208625Sjkim
615208625Sjkim    case ACPI_DMT_UINT64:
616208625Sjkim    case ACPI_DMT_NAME8:
617208625Sjkim        ByteLength = 8;
618208625Sjkim        break;
619208625Sjkim
620208625Sjkim    case ACPI_DMT_STRING:
621208625Sjkim        Value = DtGetFieldValue (Field, Info->Name);
622208625Sjkim
623208625Sjkim        /* TBD: error if Value is NULL? (as below?) */
624208625Sjkim
625208625Sjkim        ByteLength = ACPI_STRLEN (Value) + 1;
626208625Sjkim        break;
627208625Sjkim
628208625Sjkim    case ACPI_DMT_GAS:
629208625Sjkim        ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
630208625Sjkim        break;
631208625Sjkim
632208625Sjkim    case ACPI_DMT_HESTNTFY:
633208625Sjkim        ByteLength = sizeof (ACPI_HEST_NOTIFY);
634208625Sjkim        break;
635208625Sjkim
636208625Sjkim    case ACPI_DMT_BUFFER:
637208625Sjkim        Value = DtGetFieldValue (Field, Info->Name);
638208625Sjkim        if (Value)
639208625Sjkim        {
640208625Sjkim            ByteLength = DtGetBufferLength (Value);
641208625Sjkim        }
642208625Sjkim        else
643208625Sjkim        {   /* At this point, this is a fatal error */
644208625Sjkim
645208625Sjkim            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
646208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
647208625Sjkim        }
648208625Sjkim        break;
649208625Sjkim
650208625Sjkim    case ACPI_DMT_BUF16:
651208625Sjkim        ByteLength = 16;
652208625Sjkim        break;
653208625Sjkim
654208625Sjkim    default:
655208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
656208625Sjkim        break;
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