Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: dtutils.c - Utility routines for the data table compiler
4
 *
5
 *****************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
#define __DTUTILS_C__
117
 
118
#include "aslcompiler.h"
119
#include "dtcompiler.h"
120
#include "actables.h"
121
 
122
#define _COMPONENT          DT_COMPILER
123
        ACPI_MODULE_NAME    ("dtutils")
124
 
125
/* Local prototypes */
126
 
127
static void
128
DtSum (
129
    DT_SUBTABLE             *Subtable,
130
    void                    *Context,
131
    void                    *ReturnValue);
132
 
133
 
134
/******************************************************************************
135
 *
136
 * FUNCTION:    DtError
137
 *
138
 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
139
 *              MessageId           - Index into global message buffer
140
 *              Op                  - Parse node where error happened
141
 *              ExtraMessage        - additional error message
142
 *
143
 * RETURN:      None
144
 *
145
 * DESCRIPTION: Common error interface for data table compiler
146
 *
147
 *****************************************************************************/
148
 
149
void
150
DtError (
151
    UINT8                   Level,
152
    UINT8                   MessageId,
153
    DT_FIELD                *FieldObject,
154
    char                    *ExtraMessage)
155
{
156
 
157
    switch (Level)
158
    {
159
    case ASL_WARNING2:
160
    case ASL_WARNING3:
161
        if (Gbl_WarningLevel < Level)
162
        {
163
            return;
164
        }
165
        break;
166
 
167
    default:
168
        break;
169
    }
170
 
171
    if (FieldObject)
172
    {
173
        AslCommonError (Level, MessageId,
174
            FieldObject->Line,
175
            FieldObject->Line,
176
            FieldObject->ByteOffset,
177
            FieldObject->Column,
178
            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
179
    }
180
    else
181
    {
182
        AslCommonError (Level, MessageId, 0,
183
            0, 0, 0, 0, ExtraMessage);
184
    }
185
}
186
 
187
 
188
/******************************************************************************
189
 *
190
 * FUNCTION:    DtNameError
191
 *
192
 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
193
 *              MessageId           - Index into global message buffer
194
 *              Op                  - Parse node where error happened
195
 *              ExtraMessage        - additional error message
196
 *
197
 * RETURN:      None
198
 *
199
 * DESCRIPTION: Error interface for named objects
200
 *
201
 *****************************************************************************/
202
 
203
void
204
DtNameError (
205
    UINT8                   Level,
206
    UINT8                   MessageId,
207
    DT_FIELD                *FieldObject,
208
    char                    *ExtraMessage)
209
{
210
 
211
    switch (Level)
212
    {
213
    case ASL_WARNING2:
214
    case ASL_WARNING3:
215
        if (Gbl_WarningLevel < Level)
216
        {
217
            return;
218
        }
219
        break;
220
 
221
    default:
222
        break;
223
    }
224
 
225
    if (FieldObject)
226
    {
227
        AslCommonError (Level, MessageId,
228
            FieldObject->Line,
229
            FieldObject->Line,
230
            FieldObject->ByteOffset,
231
            FieldObject->NameColumn,
232
            Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
233
    }
234
    else
235
    {
236
        AslCommonError (Level, MessageId, 0,
237
            0, 0, 0, 0, ExtraMessage);
238
    }
239
}
240
 
241
 
242
/*******************************************************************************
243
 *
244
 * FUNCTION:    DtFatal
245
 *
246
 * PARAMETERS:  None
247
 *
248
 * RETURN:      None
249
 *
250
 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
251
 *              compile or I/O errors
252
 *
253
 ******************************************************************************/
254
 
255
void
256
DtFatal (
257
    UINT8                   MessageId,
258
    DT_FIELD                *FieldObject,
259
    char                    *ExtraMessage)
260
{
261
 
262
    DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
263
 
264
    CmCleanupAndExit ();
265
    exit (1);
266
}
267
 
268
 
269
/******************************************************************************
270
 *
271
 * FUNCTION:    DtStrtoul64
272
 *
273
 * PARAMETERS:  String              - Null terminated string
274
 *              ReturnInteger       - Where the converted integer is returned
275
 *
276
 * RETURN:      Status
277
 *
278
 * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
279
 *              value. Assumes no leading "0x" for the constant.
280
 *
281
 * Portability note: The reason this function exists is because a 64-bit
282
 * sscanf is not available in all environments.
283
 *
284
 *****************************************************************************/
285
 
286
ACPI_STATUS
287
DtStrtoul64 (
288
    char                    *String,
289
    UINT64                  *ReturnInteger)
290
{
291
    char                    *ThisChar = String;
292
    UINT32                  ThisDigit;
293
    UINT64                  ReturnValue = 0;
294
    int                     DigitCount = 0;
295
 
296
 
297
    /* Skip over any white space in the buffer */
298
 
299
    while ((*ThisChar == ' ') || (*ThisChar == '\t'))
300
    {
301
        ThisChar++;
302
    }
303
 
304
    /* Skip leading zeros */
305
 
306
    while ((*ThisChar) == '0')
307
    {
308
        ThisChar++;
309
    }
310
 
311
    /* Convert character-by-character */
312
 
313
    while (*ThisChar)
314
    {
315
        if (ACPI_IS_DIGIT (*ThisChar))
316
        {
317
            /* Convert ASCII 0-9 to Decimal value */
318
 
319
            ThisDigit = ((UINT8) *ThisChar) - '0';
320
        }
321
        else /* Letter */
322
        {
323
            ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
324
            if (!ACPI_IS_XDIGIT ((char) ThisDigit))
325
            {
326
                /* Not A-F */
327
 
328
                return (AE_BAD_CHARACTER);
329
            }
330
 
331
            /* Convert ASCII Hex char (A-F) to value */
332
 
333
            ThisDigit = (ThisDigit - 'A') + 10;
334
        }
335
 
336
        /* Insert the 4-bit hex digit */
337
 
338
        ReturnValue <<= 4;
339
        ReturnValue += ThisDigit;
340
 
341
        ThisChar++;
342
        DigitCount++;
343
        if (DigitCount > 16)
344
        {
345
            /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
346
 
347
            return (AE_LIMIT);
348
        }
349
    }
350
 
351
    *ReturnInteger = ReturnValue;
352
    return (AE_OK);
353
}
354
 
355
 
356
/******************************************************************************
357
 *
358
 * FUNCTION:    DtGetFileSize
359
 *
360
 * PARAMETERS:  Handle              - Open file handler
361
 *
362
 * RETURN:      Current file size
363
 *
364
 * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
365
 *              offset. Seek back to the original location.
366
 *
367
 *****************************************************************************/
368
 
369
UINT32
370
DtGetFileSize (
371
    FILE                    *Handle)
372
{
373
    int                     CurrentOffset;
374
    int                     LastOffset;
375
 
376
 
377
    CurrentOffset = ftell (Handle);
378
    fseek (Handle, 0, SEEK_END);
379
    LastOffset = ftell (Handle);
380
    fseek (Handle, CurrentOffset, SEEK_SET);
381
 
382
    return ((UINT32) LastOffset);
383
}
384
 
385
 
386
/******************************************************************************
387
 *
388
 * FUNCTION:    DtGetFieldValue
389
 *
390
 * PARAMETERS:  Field               - Current field list pointer
391
 *              Name                - Field name
392
 *
393
 * RETURN:      Field value
394
 *
395
 * DESCRIPTION: Get field value
396
 *
397
 *****************************************************************************/
398
 
399
char *
400
DtGetFieldValue (
401
    DT_FIELD                *Field,
402
    char                    *Name)
403
{
404
 
405
    /* Search the field list for the name */
406
 
407
    while (Field)
408
    {
409
        if (!ACPI_STRCMP (Name, Field->Name))
410
        {
411
            return (Field->Value);
412
        }
413
 
414
        Field = Field->Next;
415
    }
416
 
417
    return (NULL);
418
}
419
 
420
 
421
/******************************************************************************
422
 *
423
 * FUNCTION:    DtGetFieldType
424
 *
425
 * PARAMETERS:  Info                - Data table info
426
 *
427
 * RETURN:      Field type
428
 *
429
 * DESCRIPTION: Get field type
430
 *
431
 *****************************************************************************/
432
 
433
UINT8
434
DtGetFieldType (
435
    ACPI_DMTABLE_INFO       *Info)
436
{
437
    UINT8                   Type;
438
 
439
 
440
    /* DT_FLAG means that this is the start of a block of flag bits */
441
    /* TBD - we can make these a separate opcode later */
442
 
443
    if (Info->Flags & DT_FLAG)
444
    {
445
        return (DT_FIELD_TYPE_FLAGS_INTEGER);
446
    }
447
 
448
    /* Type is based upon the opcode for this field in the info table */
449
 
450
    switch (Info->Opcode)
451
    {
452
    case ACPI_DMT_FLAG0:
453
    case ACPI_DMT_FLAG1:
454
    case ACPI_DMT_FLAG2:
455
    case ACPI_DMT_FLAG3:
456
    case ACPI_DMT_FLAG4:
457
    case ACPI_DMT_FLAG5:
458
    case ACPI_DMT_FLAG6:
459
    case ACPI_DMT_FLAG7:
460
    case ACPI_DMT_FLAGS0:
461
    case ACPI_DMT_FLAGS2:
462
        Type = DT_FIELD_TYPE_FLAG;
463
        break;
464
 
465
    case ACPI_DMT_NAME4:
466
    case ACPI_DMT_SIG:
467
    case ACPI_DMT_NAME6:
468
    case ACPI_DMT_NAME8:
469
    case ACPI_DMT_STRING:
470
        Type = DT_FIELD_TYPE_STRING;
471
        break;
472
 
473
    case ACPI_DMT_BUFFER:
474
    case ACPI_DMT_BUF16:
475
        Type = DT_FIELD_TYPE_BUFFER;
476
        break;
477
 
478
    case ACPI_DMT_PCI_PATH:
479
        Type = DT_FIELD_TYPE_PCI_PATH;
480
        break;
481
 
482
    case ACPI_DMT_GAS:
483
    case ACPI_DMT_HESTNTFY:
484
        Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
485
        break;
486
 
487
    default:
488
        Type = DT_FIELD_TYPE_INTEGER;
489
        break;
490
    }
491
 
492
    return (Type);
493
}
494
 
495
 
496
/******************************************************************************
497
 *
498
 * FUNCTION:    DtGetBufferLength
499
 *
500
 * PARAMETERS:  Buffer              - List of integers,
501
 *                                    for example "10 3A 4F 2E"
502
 *
503
 * RETURN:      Count of integer
504
 *
505
 * DESCRIPTION: Get length of bytes needed to store the integers
506
 *
507
 *****************************************************************************/
508
 
509
UINT32
510
DtGetBufferLength (
511
    char                    *Buffer)
512
{
513
    UINT32                  ByteLength = 0;
514
 
515
 
516
    while (*Buffer)
517
    {
518
        if (*Buffer == ' ')
519
        {
520
            ByteLength++;
521
 
522
            while (*Buffer == ' ')
523
            {
524
                Buffer++;
525
            }
526
        }
527
 
528
        Buffer++;
529
    }
530
 
531
    return (++ByteLength);
532
}
533
 
534
 
535
/******************************************************************************
536
 *
537
 * FUNCTION:    DtGetFieldLength
538
 *
539
 * PARAMETERS:  Field               - Current field list pointer
540
 *              Info                - Data table info
541
 *
542
 * RETURN:      Field length
543
 *
544
 * DESCRIPTION: Get length of bytes needed to compile the field
545
 *
546
 *****************************************************************************/
547
 
548
UINT32
549
DtGetFieldLength (
550
    DT_FIELD                *Field,
551
    ACPI_DMTABLE_INFO       *Info)
552
{
553
    UINT32                  ByteLength = 0;
554
    char                    *Value;
555
 
556
 
557
    /* Length is based upon the opcode for this field in the info table */
558
 
559
    switch (Info->Opcode)
560
    {
561
    case ACPI_DMT_FLAG0:
562
    case ACPI_DMT_FLAG1:
563
    case ACPI_DMT_FLAG2:
564
    case ACPI_DMT_FLAG3:
565
    case ACPI_DMT_FLAG4:
566
    case ACPI_DMT_FLAG5:
567
    case ACPI_DMT_FLAG6:
568
    case ACPI_DMT_FLAG7:
569
    case ACPI_DMT_FLAGS0:
570
    case ACPI_DMT_FLAGS2:
571
        ByteLength = 0;
572
        break;
573
 
574
    case ACPI_DMT_UINT8:
575
    case ACPI_DMT_CHKSUM:
576
    case ACPI_DMT_SPACEID:
577
    case ACPI_DMT_MADT:
578
    case ACPI_DMT_SRAT:
579
    case ACPI_DMT_ASF:
580
    case ACPI_DMT_HESTNTYP:
581
    case ACPI_DMT_FADTPM:
582
    case ACPI_DMT_IVRS:
583
        ByteLength = 1;
584
        break;
585
 
586
    case ACPI_DMT_UINT16:
587
    case ACPI_DMT_DMAR:
588
    case ACPI_DMT_HEST:
589
    case ACPI_DMT_PCI_PATH:
590
        ByteLength = 2;
591
        break;
592
 
593
    case ACPI_DMT_UINT24:
594
        ByteLength = 3;
595
        break;
596
 
597
    case ACPI_DMT_UINT32:
598
    case ACPI_DMT_NAME4:
599
    case ACPI_DMT_SIG:
600
        ByteLength = 4;
601
        break;
602
 
603
    case ACPI_DMT_NAME6:
604
        ByteLength = 6;
605
        break;
606
 
607
    case ACPI_DMT_UINT56:
608
        ByteLength = 7;
609
        break;
610
 
611
    case ACPI_DMT_UINT64:
612
    case ACPI_DMT_NAME8:
613
        ByteLength = 8;
614
        break;
615
 
616
    case ACPI_DMT_STRING:
617
        Value = DtGetFieldValue (Field, Info->Name);
618
 
619
        /* TBD: error if Value is NULL? (as below?) */
620
 
621
        ByteLength = ACPI_STRLEN (Value) + 1;
622
        break;
623
 
624
    case ACPI_DMT_GAS:
625
        ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
626
        break;
627
 
628
    case ACPI_DMT_HESTNTFY:
629
        ByteLength = sizeof (ACPI_HEST_NOTIFY);
630
        break;
631
 
632
    case ACPI_DMT_BUFFER:
633
        Value = DtGetFieldValue (Field, Info->Name);
634
        if (Value)
635
        {
636
            ByteLength = DtGetBufferLength (Value);
637
        }
638
        else
639
        {   /* At this point, this is a fatal error */
640
 
641
            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
642
            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
643
        }
644
        break;
645
 
646
    case ACPI_DMT_BUF16:
647
        ByteLength = 16;
648
        break;
649
 
650
    default:
651
        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
652
        break;
653
    }
654
 
655
    return (ByteLength);
656
}
657
 
658
 
659
/******************************************************************************
660
 *
661
 * FUNCTION:    DtSum
662
 *
663
 * PARAMETERS:  DT_WALK_CALLBACK:
664
 *              Subtable            - Subtable
665
 *              Context             - Unused
666
 *              ReturnValue         - Store the checksum of subtable
667
 *
668
 * RETURN:      Status
669
 *
670
 * DESCRIPTION: Get the checksum of subtable
671
 *
672
 *****************************************************************************/
673
 
674
static void
675
DtSum (
676
    DT_SUBTABLE             *Subtable,
677
    void                    *Context,
678
    void                    *ReturnValue)
679
{
680
    UINT8                   Checksum;
681
    UINT8                   *Sum = ReturnValue;
682
 
683
 
684
    Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
685
    *Sum = (UINT8) (*Sum + Checksum);
686
}
687
 
688
 
689
/******************************************************************************
690
 *
691
 * FUNCTION:    DtSetTableChecksum
692
 *
693
 * PARAMETERS:  ChecksumPointer     - Where to return the checksum
694
 *
695
 * RETURN:      None
696
 *
697
 * DESCRIPTION: Set checksum of the whole data table into the checksum field
698
 *
699
 *****************************************************************************/
700
 
701
void
702
DtSetTableChecksum (
703
    UINT8                   *ChecksumPointer)
704
{
705
    UINT8                   Checksum = 0;
706
    UINT8                   OldSum;
707
 
708
 
709
    DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
710
 
711
    OldSum = *ChecksumPointer;
712
    Checksum = (UINT8) (Checksum - OldSum);
713
 
714
    /* Compute the final checksum */
715
 
716
    Checksum = (UINT8) (0 - Checksum);
717
    *ChecksumPointer = Checksum;
718
}
719
 
720
 
721
/******************************************************************************
722
 *
723
 * FUNCTION:    DtSetTableLength
724
 *
725
 * PARAMETERS:  None
726
 *
727
 * RETURN:      None
728
 *
729
 * DESCRIPTION: Walk the subtables and set all the length fields
730
 *
731
 *****************************************************************************/
732
 
733
void
734
DtSetTableLength (
735
    void)
736
{
737
    DT_SUBTABLE             *ParentTable;
738
    DT_SUBTABLE             *ChildTable;
739
 
740
 
741
    ParentTable = Gbl_RootTable;
742
    ChildTable = NULL;
743
 
744
    if (!ParentTable)
745
    {
746
        return;
747
    }
748
 
749
    DtSetSubtableLength (ParentTable);
750
 
751
    while (1)
752
    {
753
        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
754
        if (ChildTable)
755
        {
756
            if (ChildTable->Child)
757
            {
758
                ParentTable = ChildTable;
759
                ChildTable = NULL;
760
            }
761
            else
762
            {
763
                ParentTable->TotalLength += ChildTable->TotalLength;
764
                if (ParentTable->LengthField)
765
                {
766
                    DtSetSubtableLength (ParentTable);
767
                }
768
            }
769
        }
770
        else
771
        {
772
            ChildTable = ParentTable;
773
 
774
            if (ChildTable == Gbl_RootTable)
775
            {
776
                break;
777
            }
778
 
779
            ParentTable = DtGetParentSubtable (ParentTable);
780
 
781
            ParentTable->TotalLength += ChildTable->TotalLength;
782
            if (ParentTable->LengthField)
783
            {
784
                DtSetSubtableLength (ParentTable);
785
            }
786
        }
787
    }
788
}
789
 
790
 
791
/******************************************************************************
792
 *
793
 * FUNCTION:    DtWalkTableTree
794
 *
795
 * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
796
 *              UserFunction        - Called during the walk
797
 *              Context             - Passed to user function
798
 *              ReturnValue         - The return value of UserFunction
799
 *
800
 * RETURN:      None
801
 *
802
 * DESCRIPTION: Performs a depth-first walk of the subtable tree
803
 *
804
 *****************************************************************************/
805
 
806
void
807
DtWalkTableTree (
808
    DT_SUBTABLE             *StartTable,
809
    DT_WALK_CALLBACK        UserFunction,
810
    void                    *Context,
811
    void                    *ReturnValue)
812
{
813
    DT_SUBTABLE             *ParentTable;
814
    DT_SUBTABLE             *ChildTable;
815
 
816
 
817
    ParentTable = StartTable;
818
    ChildTable = NULL;
819
 
820
    if (!ParentTable)
821
    {
822
        return;
823
    }
824
 
825
    UserFunction (ParentTable, Context, ReturnValue);
826
 
827
    while (1)
828
    {
829
        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
830
        if (ChildTable)
831
        {
832
            UserFunction (ChildTable, Context, ReturnValue);
833
 
834
            if (ChildTable->Child)
835
            {
836
                ParentTable = ChildTable;
837
                ChildTable = NULL;
838
            }
839
        }
840
        else
841
        {
842
            ChildTable = ParentTable;
843
            if (ChildTable == Gbl_RootTable)
844
            {
845
                break;
846
            }
847
 
848
            ParentTable = DtGetParentSubtable (ParentTable);
849
 
850
            if (ChildTable->Peer == StartTable)
851
            {
852
                break;
853
            }
854
        }
855
    }
856
}
857
 
858
 
859
/******************************************************************************
860
 *
861
 * FUNCTION:    DtFreeFieldList
862
 *
863
 * PARAMETERS:  None
864
 *
865
 * RETURN:      None
866
 *
867
 * DESCRIPTION: Free the field list
868
 *
869
 *****************************************************************************/
870
 
871
void
872
DtFreeFieldList (
873
    void)
874
{
875
    DT_FIELD                *Field = Gbl_FieldList;
876
    DT_FIELD                *NextField;
877
 
878
 
879
    /* Walk and free entire field list */
880
 
881
    while (Field)
882
    {
883
        NextField = Field->Next; /* Save link */
884
 
885
        if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
886
        {
887
            ACPI_FREE (Field->Name);
888
            ACPI_FREE (Field->Value);
889
        }
890
 
891
        ACPI_FREE (Field);
892
        Field = NextField;
893
    }
894
}