Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | 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
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 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
 
2216 Serge 264
/*
265
 * TBD: remove this entire function, DtFatal
266
 *
267
 * We cannot abort the compiler on error, because we may be compiling a
268
 * list of files. We must move on to the next file.
269
 */
270
#ifdef __OBSOLETE
1498 serge 271
    CmCleanupAndExit ();
272
    exit (1);
2216 Serge 273
#endif
1498 serge 274
}
275
 
276
 
277
/******************************************************************************
278
 *
279
 * FUNCTION:    DtStrtoul64
280
 *
281
 * PARAMETERS:  String              - Null terminated string
282
 *              ReturnInteger       - Where the converted integer is returned
283
 *
284
 * RETURN:      Status
285
 *
286
 * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
287
 *              value. Assumes no leading "0x" for the constant.
288
 *
289
 * Portability note: The reason this function exists is because a 64-bit
290
 * sscanf is not available in all environments.
291
 *
292
 *****************************************************************************/
293
 
294
ACPI_STATUS
295
DtStrtoul64 (
296
    char                    *String,
297
    UINT64                  *ReturnInteger)
298
{
299
    char                    *ThisChar = String;
300
    UINT32                  ThisDigit;
301
    UINT64                  ReturnValue = 0;
302
    int                     DigitCount = 0;
303
 
304
 
305
    /* Skip over any white space in the buffer */
306
 
307
    while ((*ThisChar == ' ') || (*ThisChar == '\t'))
308
    {
309
        ThisChar++;
310
    }
311
 
312
    /* Skip leading zeros */
313
 
314
    while ((*ThisChar) == '0')
315
    {
316
        ThisChar++;
317
    }
318
 
319
    /* Convert character-by-character */
320
 
321
    while (*ThisChar)
322
    {
323
        if (ACPI_IS_DIGIT (*ThisChar))
324
        {
325
            /* Convert ASCII 0-9 to Decimal value */
326
 
327
            ThisDigit = ((UINT8) *ThisChar) - '0';
328
        }
329
        else /* Letter */
330
        {
331
            ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
332
            if (!ACPI_IS_XDIGIT ((char) ThisDigit))
333
            {
334
                /* Not A-F */
335
 
336
                return (AE_BAD_CHARACTER);
337
            }
338
 
339
            /* Convert ASCII Hex char (A-F) to value */
340
 
341
            ThisDigit = (ThisDigit - 'A') + 10;
342
        }
343
 
344
        /* Insert the 4-bit hex digit */
345
 
346
        ReturnValue <<= 4;
347
        ReturnValue += ThisDigit;
348
 
349
        ThisChar++;
350
        DigitCount++;
351
        if (DigitCount > 16)
352
        {
353
            /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
354
 
355
            return (AE_LIMIT);
356
        }
357
    }
358
 
359
    *ReturnInteger = ReturnValue;
360
    return (AE_OK);
361
}
362
 
363
 
364
/******************************************************************************
365
 *
366
 * FUNCTION:    DtGetFileSize
367
 *
368
 * PARAMETERS:  Handle              - Open file handler
369
 *
370
 * RETURN:      Current file size
371
 *
372
 * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
373
 *              offset. Seek back to the original location.
374
 *
375
 *****************************************************************************/
376
 
377
UINT32
378
DtGetFileSize (
379
    FILE                    *Handle)
380
{
381
    int                     CurrentOffset;
382
    int                     LastOffset;
383
 
384
 
385
    CurrentOffset = ftell (Handle);
386
    fseek (Handle, 0, SEEK_END);
387
    LastOffset = ftell (Handle);
388
    fseek (Handle, CurrentOffset, SEEK_SET);
389
 
390
    return ((UINT32) LastOffset);
391
}
392
 
393
 
394
/******************************************************************************
395
 *
396
 * FUNCTION:    DtGetFieldValue
397
 *
398
 * PARAMETERS:  Field               - Current field list pointer
399
 *
400
 * RETURN:      Field value
401
 *
402
 * DESCRIPTION: Get field value
403
 *
404
 *****************************************************************************/
405
 
406
char *
407
DtGetFieldValue (
2216 Serge 408
    DT_FIELD                *Field)
1498 serge 409
{
2216 Serge 410
    if (!Field)
1498 serge 411
    {
2216 Serge 412
        return (NULL);
1498 serge 413
    }
414
 
2216 Serge 415
    return (Field->Value);
1498 serge 416
}
417
 
418
 
419
/******************************************************************************
420
 *
421
 * FUNCTION:    DtGetFieldType
422
 *
423
 * PARAMETERS:  Info                - Data table info
424
 *
425
 * RETURN:      Field type
426
 *
427
 * DESCRIPTION: Get field type
428
 *
429
 *****************************************************************************/
430
 
431
UINT8
432
DtGetFieldType (
433
    ACPI_DMTABLE_INFO       *Info)
434
{
435
    UINT8                   Type;
436
 
437
 
438
    /* DT_FLAG means that this is the start of a block of flag bits */
439
    /* TBD - we can make these a separate opcode later */
440
 
441
    if (Info->Flags & DT_FLAG)
442
    {
443
        return (DT_FIELD_TYPE_FLAGS_INTEGER);
444
    }
445
 
446
    /* Type is based upon the opcode for this field in the info table */
447
 
448
    switch (Info->Opcode)
449
    {
450
    case ACPI_DMT_FLAG0:
451
    case ACPI_DMT_FLAG1:
452
    case ACPI_DMT_FLAG2:
453
    case ACPI_DMT_FLAG3:
454
    case ACPI_DMT_FLAG4:
455
    case ACPI_DMT_FLAG5:
456
    case ACPI_DMT_FLAG6:
457
    case ACPI_DMT_FLAG7:
458
    case ACPI_DMT_FLAGS0:
459
    case ACPI_DMT_FLAGS2:
460
        Type = DT_FIELD_TYPE_FLAG;
461
        break;
462
 
463
    case ACPI_DMT_NAME4:
464
    case ACPI_DMT_SIG:
465
    case ACPI_DMT_NAME6:
466
    case ACPI_DMT_NAME8:
467
    case ACPI_DMT_STRING:
468
        Type = DT_FIELD_TYPE_STRING;
469
        break;
470
 
471
    case ACPI_DMT_BUFFER:
2216 Serge 472
    case ACPI_DMT_BUF7:
1498 serge 473
    case ACPI_DMT_BUF16:
2216 Serge 474
    case ACPI_DMT_BUF128:
475
    case ACPI_DMT_PCI_PATH:
1498 serge 476
        Type = DT_FIELD_TYPE_BUFFER;
477
        break;
478
 
479
    case ACPI_DMT_GAS:
480
    case ACPI_DMT_HESTNTFY:
481
        Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
482
        break;
483
 
2216 Serge 484
    case ACPI_DMT_UNICODE:
485
        Type = DT_FIELD_TYPE_UNICODE;
486
        break;
487
 
488
    case ACPI_DMT_UUID:
489
        Type = DT_FIELD_TYPE_UUID;
490
        break;
491
 
492
    case ACPI_DMT_DEVICE_PATH:
493
        Type = DT_FIELD_TYPE_DEVICE_PATH;
494
        break;
495
 
496
    case ACPI_DMT_LABEL:
497
        Type = DT_FIELD_TYPE_LABEL;
498
        break;
499
 
1498 serge 500
    default:
501
        Type = DT_FIELD_TYPE_INTEGER;
502
        break;
503
    }
504
 
505
    return (Type);
506
}
507
 
508
 
509
/******************************************************************************
510
 *
511
 * FUNCTION:    DtGetBufferLength
512
 *
513
 * PARAMETERS:  Buffer              - List of integers,
514
 *                                    for example "10 3A 4F 2E"
515
 *
516
 * RETURN:      Count of integer
517
 *
518
 * DESCRIPTION: Get length of bytes needed to store the integers
519
 *
520
 *****************************************************************************/
521
 
522
UINT32
523
DtGetBufferLength (
524
    char                    *Buffer)
525
{
526
    UINT32                  ByteLength = 0;
527
 
528
 
529
    while (*Buffer)
530
    {
531
        if (*Buffer == ' ')
532
        {
533
            ByteLength++;
534
 
535
            while (*Buffer == ' ')
536
            {
537
                Buffer++;
538
            }
539
        }
540
 
541
        Buffer++;
542
    }
543
 
544
    return (++ByteLength);
545
}
546
 
547
 
548
/******************************************************************************
549
 *
550
 * FUNCTION:    DtGetFieldLength
551
 *
2216 Serge 552
 * PARAMETERS:  Field               - Current field
1498 serge 553
 *              Info                - Data table info
554
 *
555
 * RETURN:      Field length
556
 *
557
 * DESCRIPTION: Get length of bytes needed to compile the field
558
 *
2216 Serge 559
 * Note: This function must remain in sync with AcpiDmDumpTable.
560
 *
1498 serge 561
 *****************************************************************************/
562
 
563
UINT32
564
DtGetFieldLength (
565
    DT_FIELD                *Field,
566
    ACPI_DMTABLE_INFO       *Info)
567
{
568
    UINT32                  ByteLength = 0;
569
    char                    *Value;
570
 
571
 
572
    /* Length is based upon the opcode for this field in the info table */
573
 
574
    switch (Info->Opcode)
575
    {
576
    case ACPI_DMT_FLAG0:
577
    case ACPI_DMT_FLAG1:
578
    case ACPI_DMT_FLAG2:
579
    case ACPI_DMT_FLAG3:
580
    case ACPI_DMT_FLAG4:
581
    case ACPI_DMT_FLAG5:
582
    case ACPI_DMT_FLAG6:
583
    case ACPI_DMT_FLAG7:
584
    case ACPI_DMT_FLAGS0:
585
    case ACPI_DMT_FLAGS2:
2216 Serge 586
    case ACPI_DMT_LABEL:
1498 serge 587
        ByteLength = 0;
588
        break;
589
 
590
    case ACPI_DMT_UINT8:
591
    case ACPI_DMT_CHKSUM:
592
    case ACPI_DMT_SPACEID:
2216 Serge 593
    case ACPI_DMT_ACCWIDTH:
594
    case ACPI_DMT_IVRS:
1498 serge 595
    case ACPI_DMT_MADT:
596
    case ACPI_DMT_SRAT:
597
    case ACPI_DMT_ASF:
598
    case ACPI_DMT_HESTNTYP:
599
    case ACPI_DMT_FADTPM:
2216 Serge 600
    case ACPI_DMT_EINJACT:
601
    case ACPI_DMT_EINJINST:
602
    case ACPI_DMT_ERSTACT:
603
    case ACPI_DMT_ERSTINST:
1498 serge 604
        ByteLength = 1;
605
        break;
606
 
607
    case ACPI_DMT_UINT16:
608
    case ACPI_DMT_DMAR:
609
    case ACPI_DMT_HEST:
610
    case ACPI_DMT_PCI_PATH:
611
        ByteLength = 2;
612
        break;
613
 
614
    case ACPI_DMT_UINT24:
615
        ByteLength = 3;
616
        break;
617
 
618
    case ACPI_DMT_UINT32:
619
    case ACPI_DMT_NAME4:
2216 Serge 620
    case ACPI_DMT_SLIC:
1498 serge 621
    case ACPI_DMT_SIG:
622
        ByteLength = 4;
623
        break;
624
 
625
    case ACPI_DMT_NAME6:
626
        ByteLength = 6;
627
        break;
628
 
629
    case ACPI_DMT_UINT56:
2216 Serge 630
    case ACPI_DMT_BUF7:
1498 serge 631
        ByteLength = 7;
632
        break;
633
 
634
    case ACPI_DMT_UINT64:
635
    case ACPI_DMT_NAME8:
636
        ByteLength = 8;
637
        break;
638
 
639
    case ACPI_DMT_STRING:
2216 Serge 640
        Value = DtGetFieldValue (Field);
641
        if (Value)
642
        {
643
            ByteLength = ACPI_STRLEN (Value) + 1;
644
        }
645
        else
646
        {   /* At this point, this is a fatal error */
1498 serge 647
 
2216 Serge 648
            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
649
            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
650
            return (0);
651
        }
1498 serge 652
        break;
653
 
654
    case ACPI_DMT_GAS:
655
        ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
656
        break;
657
 
658
    case ACPI_DMT_HESTNTFY:
659
        ByteLength = sizeof (ACPI_HEST_NOTIFY);
660
        break;
661
 
662
    case ACPI_DMT_BUFFER:
2216 Serge 663
        Value = DtGetFieldValue (Field);
1498 serge 664
        if (Value)
665
        {
666
            ByteLength = DtGetBufferLength (Value);
667
        }
668
        else
669
        {   /* At this point, this is a fatal error */
670
 
671
            sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
672
            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
2216 Serge 673
            return (0);
1498 serge 674
        }
675
        break;
676
 
677
    case ACPI_DMT_BUF16:
2216 Serge 678
    case ACPI_DMT_UUID:
1498 serge 679
        ByteLength = 16;
680
        break;
681
 
2216 Serge 682
    case ACPI_DMT_BUF128:
683
        ByteLength = 128;
684
        break;
685
 
686
    case ACPI_DMT_UNICODE:
687
        Value = DtGetFieldValue (Field);
688
 
689
        /* TBD: error if Value is NULL? (as below?) */
690
 
691
        ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
692
        break;
693
 
1498 serge 694
    default:
695
        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
2216 Serge 696
        return (0);
1498 serge 697
    }
698
 
699
    return (ByteLength);
700
}
701
 
702
 
703
/******************************************************************************
704
 *
705
 * FUNCTION:    DtSum
706
 *
707
 * PARAMETERS:  DT_WALK_CALLBACK:
708
 *              Subtable            - Subtable
709
 *              Context             - Unused
710
 *              ReturnValue         - Store the checksum of subtable
711
 *
712
 * RETURN:      Status
713
 *
714
 * DESCRIPTION: Get the checksum of subtable
715
 *
716
 *****************************************************************************/
717
 
718
static void
719
DtSum (
720
    DT_SUBTABLE             *Subtable,
721
    void                    *Context,
722
    void                    *ReturnValue)
723
{
724
    UINT8                   Checksum;
725
    UINT8                   *Sum = ReturnValue;
726
 
727
 
728
    Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
729
    *Sum = (UINT8) (*Sum + Checksum);
730
}
731
 
732
 
733
/******************************************************************************
734
 *
735
 * FUNCTION:    DtSetTableChecksum
736
 *
737
 * PARAMETERS:  ChecksumPointer     - Where to return the checksum
738
 *
739
 * RETURN:      None
740
 *
741
 * DESCRIPTION: Set checksum of the whole data table into the checksum field
742
 *
743
 *****************************************************************************/
744
 
745
void
746
DtSetTableChecksum (
747
    UINT8                   *ChecksumPointer)
748
{
749
    UINT8                   Checksum = 0;
750
    UINT8                   OldSum;
751
 
752
 
753
    DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
754
 
755
    OldSum = *ChecksumPointer;
756
    Checksum = (UINT8) (Checksum - OldSum);
757
 
758
    /* Compute the final checksum */
759
 
760
    Checksum = (UINT8) (0 - Checksum);
761
    *ChecksumPointer = Checksum;
762
}
763
 
764
 
765
/******************************************************************************
766
 *
767
 * FUNCTION:    DtSetTableLength
768
 *
769
 * PARAMETERS:  None
770
 *
771
 * RETURN:      None
772
 *
773
 * DESCRIPTION: Walk the subtables and set all the length fields
774
 *
775
 *****************************************************************************/
776
 
777
void
778
DtSetTableLength (
779
    void)
780
{
781
    DT_SUBTABLE             *ParentTable;
782
    DT_SUBTABLE             *ChildTable;
783
 
784
 
785
    ParentTable = Gbl_RootTable;
786
    ChildTable = NULL;
787
 
788
    if (!ParentTable)
789
    {
790
        return;
791
    }
792
 
793
    DtSetSubtableLength (ParentTable);
794
 
795
    while (1)
796
    {
797
        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
798
        if (ChildTable)
799
        {
2216 Serge 800
            if (ChildTable->LengthField)
801
            {
802
                DtSetSubtableLength (ChildTable);
803
            }
804
 
1498 serge 805
            if (ChildTable->Child)
806
            {
807
                ParentTable = ChildTable;
808
                ChildTable = NULL;
809
            }
810
            else
811
            {
812
                ParentTable->TotalLength += ChildTable->TotalLength;
813
                if (ParentTable->LengthField)
814
                {
815
                    DtSetSubtableLength (ParentTable);
816
                }
817
            }
818
        }
819
        else
820
        {
821
            ChildTable = ParentTable;
822
 
823
            if (ChildTable == Gbl_RootTable)
824
            {
825
                break;
826
            }
827
 
828
            ParentTable = DtGetParentSubtable (ParentTable);
829
 
830
            ParentTable->TotalLength += ChildTable->TotalLength;
831
            if (ParentTable->LengthField)
832
            {
833
                DtSetSubtableLength (ParentTable);
834
            }
835
        }
836
    }
837
}
838
 
839
 
840
/******************************************************************************
841
 *
842
 * FUNCTION:    DtWalkTableTree
843
 *
844
 * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
845
 *              UserFunction        - Called during the walk
846
 *              Context             - Passed to user function
847
 *              ReturnValue         - The return value of UserFunction
848
 *
849
 * RETURN:      None
850
 *
851
 * DESCRIPTION: Performs a depth-first walk of the subtable tree
852
 *
853
 *****************************************************************************/
854
 
855
void
856
DtWalkTableTree (
857
    DT_SUBTABLE             *StartTable,
858
    DT_WALK_CALLBACK        UserFunction,
859
    void                    *Context,
860
    void                    *ReturnValue)
861
{
862
    DT_SUBTABLE             *ParentTable;
863
    DT_SUBTABLE             *ChildTable;
864
 
865
 
866
    ParentTable = StartTable;
867
    ChildTable = NULL;
868
 
869
    if (!ParentTable)
870
    {
871
        return;
872
    }
873
 
874
    UserFunction (ParentTable, Context, ReturnValue);
875
 
876
    while (1)
877
    {
878
        ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
879
        if (ChildTable)
880
        {
881
            UserFunction (ChildTable, Context, ReturnValue);
882
 
883
            if (ChildTable->Child)
884
            {
885
                ParentTable = ChildTable;
886
                ChildTable = NULL;
887
            }
888
        }
889
        else
890
        {
891
            ChildTable = ParentTable;
892
            if (ChildTable == Gbl_RootTable)
893
            {
894
                break;
895
            }
896
 
897
            ParentTable = DtGetParentSubtable (ParentTable);
898
 
899
            if (ChildTable->Peer == StartTable)
900
            {
901
                break;
902
            }
903
        }
904
    }
905
}
906
 
907
 
908
/******************************************************************************
909
 *
910
 * FUNCTION:    DtFreeFieldList
911
 *
912
 * PARAMETERS:  None
913
 *
914
 * RETURN:      None
915
 *
916
 * DESCRIPTION: Free the field list
917
 *
918
 *****************************************************************************/
919
 
920
void
921
DtFreeFieldList (
922
    void)
923
{
924
    DT_FIELD                *Field = Gbl_FieldList;
925
    DT_FIELD                *NextField;
926
 
927
 
928
    /* Walk and free entire field list */
929
 
930
    while (Field)
931
    {
932
        NextField = Field->Next; /* Save link */
933
 
934
        if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
935
        {
936
            ACPI_FREE (Field->Name);
937
            ACPI_FREE (Field->Value);
938
        }
939
 
940
        ACPI_FREE (Field);
941
        Field = NextField;
942
    }
943
}