dtutils.c revision 208625
189948Simp/****************************************************************************** 289948Simp * 389948Simp * Module Name: dtutils.c - Utility routines for the data table compiler 4139749Simp * 589948Simp *****************************************************************************/ 689948Simp 789948Simp/****************************************************************************** 889948Simp * 989948Simp * 1. Copyright Notice 1089948Simp * 1189948Simp * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 1289948Simp * All rights reserved. 1389948Simp * 1489948Simp * 2. License 1589948Simp * 1689948Simp * 2.1. This is your license from Intel Corp. under its intellectual property 1789948Simp * rights. You may have additional license terms from the party that provided 1889948Simp * you this software, covering your right to use that party's intellectual 1989948Simp * property rights. 2089948Simp * 2189948Simp * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2289948Simp * copy of the source code appearing in this file ("Covered Code") an 2389948Simp * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2489948Simp * base code distributed originally by Intel ("Original Intel Code") to copy, 2589948Simp * make derivatives, distribute, use and display any portion of the Covered 2689948Simp * Code in any form, with the right to sublicense such rights; and 2789948Simp * 2889948Simp * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2989948Simp * license (with the right to sublicense), under only those claims of Intel 3089948Simp * patents that are infringed by the Original Intel Code, to make, use, sell, 3189948Simp * offer to sell, and import the Covered Code and derivative works thereof 3289948Simp * solely to the minimum extent necessary to exercise the above copyright 3389948Simp * license, and in no event shall the patent license extend to any additions 3489948Simp * to or modifications of the Original Intel Code. No other license or right 3589948Simp * is granted directly or by implication, estoppel or otherwise; 3689948Simp * 3789948Simp * The above copyright and patent license is granted only if the following 3889948Simp * conditions are met: 3989948Simp * 4089948Simp * 3. Conditions 4189948Simp * 4289948Simp * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4389948Simp * Redistribution of source code of any substantial portion of the Covered 4489948Simp * Code or modification with rights to further distribute source must include 4589948Simp * the above Copyright Notice, the above License, this list of Conditions, 4689948Simp * and the following Disclaimer and Export Compliance provision. In addition, 4789948Simp * Licensee must cause all Covered Code to which Licensee contributes to 4889948Simp * contain a file documenting the changes Licensee made to create that Covered 4989948Simp * Code and the date of any change. Licensee must include in that file the 5089948Simp * documentation of any changes made by any predecessor Licensee. Licensee 5189948Simp * must include a prominent statement that the modification is derived, 5289948Simp * directly or indirectly, from Original Intel Code. 5389948Simp * 5489948Simp * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5589948Simp * Redistribution of source code of any substantial portion of the Covered 5689948Simp * Code or modification without rights to further distribute source must 5789948Simp * include the following Disclaimer and Export Compliance provision in the 58100703Simp * documentation and/or other materials provided with distribution. In 59100703Simp * addition, Licensee may not authorize further sublicense of source of any 60100703Simp * portion of the Covered Code, and must include terms to the effect that the 6189948Simp * license from Licensee to its licensee is limited to the intellectual 6289948Simp * property embodied in the software Licensee provides to its licensee, and 6389948Simp * not to intellectual property embodied in modifications its licensee may 6489948Simp * make. 6589948Simp * 6689948Simp * 3.3. Redistribution of Executable. Redistribution in executable form of any 6789948Simp * substantial portion of the Covered Code or modification must reproduce the 6889948Simp * above Copyright Notice, and the following Disclaimer and Export Compliance 6989948Simp * provision in the documentation and/or other materials provided with the 7089948Simp * distribution. 7189948Simp * 7289948Simp * 3.4. Intel retains all right, title, and interest in and to the Original 7389948Simp * Intel Code. 7489948Simp * 7589948Simp * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7689948Simp * Intel shall be used in advertising or otherwise to promote the sale, use or 7789948Simp * other dealings in products derived from or relating to the Covered Code 7889948Simp * without prior written authorization from Intel. 7989948Simp * 8089948Simp * 4. Disclaimer and Export Compliance 8189948Simp * 8289948Simp * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8389948Simp * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8489948Simp * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8589948Simp * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8689948Simp * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8789948Simp * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8889948Simp * PARTICULAR PURPOSE. 8989948Simp * 9089948Simp * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9189948Simp * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9289948Simp * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9389948Simp * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9489948Simp * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9589948Simp * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9689948Simp * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9789948Simp * LIMITED REMEDY. 9889948Simp * 9989948Simp * 4.3. Licensee shall not export, either directly or indirectly, any of this 10089948Simp * software or system incorporating such software without first obtaining any 10189948Simp * required license or other approval from the U. S. Department of Commerce or 10289948Simp * any other agency or department of the United States Government. In the 10389948Simp * event Licensee exports any such software from the United States or 104110841Simp * re-exports any such software from a foreign destination, Licensee shall 105110841Simp * ensure that the distribution and export/re-export of the software is in 106110841Simp * compliance with all laws, regulations, orders, or other restrictions of the 107110841Simp * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108110841Simp * any of its subsidiaries will export/re-export any technical data, process, 109110841Simp * software, or service, directly or indirectly, to any country for which the 11089948Simp * United States government or any agency thereof requires an export license, 11189948Simp * other governmental approval, or letter of assurance, without first obtaining 11289948Simp * such license, approval or letter. 11389948Simp * 11489948Simp *****************************************************************************/ 11589948Simp 11689948Simp#define __DTUTILS_C__ 11789948Simp 11889948Simp#include "aslcompiler.h" 11989948Simp#include "dtcompiler.h" 12089948Simp#include "actables.h" 12189948Simp 12289948Simp#define _COMPONENT DT_COMPILER 12389948Simp ACPI_MODULE_NAME ("dtutils") 12489948Simp 12589948Simp/* Local prototypes */ 12689948Simp 12789948Simpstatic void 12889948SimpDtSum ( 12989948Simp DT_SUBTABLE *Subtable, 13089948Simp void *Context, 13189948Simp void *ReturnValue); 13289948Simp 13389948Simp 13489948Simp/****************************************************************************** 13589948Simp * 13689948Simp * FUNCTION: DtError 13789948Simp * 13889948Simp * PARAMETERS: Level - Seriousness (Warning/error, etc.) 13989948Simp * MessageId - Index into global message buffer 14089948Simp * Op - Parse node where error happened 14189948Simp * ExtraMessage - additional error message 14289948Simp * 14389948Simp * RETURN: None 14489948Simp * 14589948Simp * DESCRIPTION: Common error interface for data table compiler 14689948Simp * 14789948Simp *****************************************************************************/ 14889948Simp 14989948Simpvoid 15089948SimpDtError ( 15189948Simp UINT8 Level, 15289948Simp UINT8 MessageId, 15389948Simp DT_FIELD *FieldObject, 15489948Simp char *ExtraMessage) 15589948Simp{ 15689948Simp 15789948Simp switch (Level) 15889948Simp { 15989948Simp case ASL_WARNING2: 16089948Simp case ASL_WARNING3: 16189948Simp if (Gbl_WarningLevel < Level) 16289948Simp { 16389948Simp return; 16489948Simp } 16589948Simp break; 16689948Simp 16789948Simp default: 16889948Simp break; 16989948Simp } 17089948Simp 17189948Simp if (FieldObject) 17289948Simp { 17389948Simp AslCommonError (Level, MessageId, 17489948Simp FieldObject->Line, 17589948Simp FieldObject->Line, 17689948Simp FieldObject->ByteOffset, 17789948Simp FieldObject->Column, 17889948Simp Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 17989948Simp } 18089948Simp else 18189948Simp { 18289948Simp AslCommonError (Level, MessageId, 0, 18389948Simp 0, 0, 0, 0, ExtraMessage); 18489948Simp } 18589948Simp} 18689948Simp 18789948Simp 18889948Simp/****************************************************************************** 18989948Simp * 19089948Simp * FUNCTION: DtNameError 19189948Simp * 19289948Simp * PARAMETERS: Level - Seriousness (Warning/error, etc.) 19389948Simp * MessageId - Index into global message buffer 19489948Simp * Op - Parse node where error happened 19589948Simp * ExtraMessage - additional error message 19689948Simp * 19789948Simp * RETURN: None 19889948Simp * 19989948Simp * DESCRIPTION: Error interface for named objects 20089948Simp * 20189948Simp *****************************************************************************/ 20289948Simp 20389948Simpvoid 20489948SimpDtNameError ( 20589948Simp UINT8 Level, 20689948Simp UINT8 MessageId, 20789948Simp DT_FIELD *FieldObject, 20889948Simp char *ExtraMessage) 20989948Simp{ 21089948Simp 21189948Simp switch (Level) 21289948Simp { 21389948Simp case ASL_WARNING2: 21489948Simp case ASL_WARNING3: 21589948Simp if (Gbl_WarningLevel < Level) 21689948Simp { 21789948Simp return; 21889948Simp } 21989948Simp break; 22089948Simp 22189948Simp default: 22289948Simp break; 22389948Simp } 22489948Simp 22589948Simp if (FieldObject) 22689948Simp { 22789948Simp AslCommonError (Level, MessageId, 22889948Simp FieldObject->Line, 22989948Simp FieldObject->Line, 23089948Simp FieldObject->ByteOffset, 23189948Simp FieldObject->NameColumn, 23289948Simp Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 23389948Simp } 23489948Simp else 23589948Simp { 23689948Simp AslCommonError (Level, MessageId, 0, 23789948Simp 0, 0, 0, 0, ExtraMessage); 23889948Simp } 23989948Simp} 24089948Simp 24189948Simp 24289948Simp/******************************************************************************* 24389948Simp * 24489948Simp * FUNCTION: DtFatal 24589948Simp * 24689948Simp * PARAMETERS: None 24789948Simp * 24889948Simp * RETURN: None 24989948Simp * 25089948Simp * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 25189948Simp * compile or I/O errors 25289948Simp * 25389948Simp ******************************************************************************/ 25489948Simp 25589948Simpvoid 25689948SimpDtFatal ( 25789948Simp UINT8 MessageId, 25889948Simp DT_FIELD *FieldObject, 25989948Simp char *ExtraMessage) 26089948Simp{ 26189948Simp 26289948Simp DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage); 26389948Simp 26489948Simp CmCleanupAndExit (); 26589948Simp exit (1); 26689948Simp} 26789948Simp 26889948Simp 26989948Simp/****************************************************************************** 27089948Simp * 27189948Simp * FUNCTION: DtStrtoul64 27289948Simp * 27389948Simp * PARAMETERS: String - Null terminated string 27489948Simp * ReturnInteger - Where the converted integer is returned 27589948Simp * 27689948Simp * RETURN: Status 27789948Simp * 27889948Simp * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned 27989948Simp * value. Assumes no leading "0x" for the constant. 28089948Simp * 28189948Simp * Portability note: The reason this function exists is because a 64-bit 28289948Simp * sscanf is not available in all environments. 28389948Simp * 28489948Simp *****************************************************************************/ 28589948Simp 28689948SimpACPI_STATUS 28789948SimpDtStrtoul64 ( 28889948Simp char *String, 28989948Simp UINT64 *ReturnInteger) 29089948Simp{ 29189948Simp char *ThisChar = String; 29289948Simp UINT32 ThisDigit; 29389948Simp UINT64 ReturnValue = 0; 29489948Simp int DigitCount = 0; 29589948Simp 29689948Simp 29789948Simp /* Skip over any white space in the buffer */ 29889948Simp 29989948Simp while ((*ThisChar == ' ') || (*ThisChar == '\t')) 30089948Simp { 30189948Simp ThisChar++; 30289948Simp } 30389948Simp 30489948Simp /* Skip leading zeros */ 30589948Simp 30689948Simp while ((*ThisChar) == '0') 30789948Simp { 30889948Simp ThisChar++; 30989948Simp } 31089948Simp 31189948Simp /* Convert character-by-character */ 31289948Simp 31389948Simp while (*ThisChar) 31489948Simp { 31589948Simp if (ACPI_IS_DIGIT (*ThisChar)) 31689948Simp { 31789948Simp /* Convert ASCII 0-9 to Decimal value */ 31889948Simp 31989948Simp ThisDigit = ((UINT8) *ThisChar) - '0'; 32089948Simp } 32189948Simp else /* Letter */ 32289948Simp { 32389948Simp ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar); 32489948Simp if (!ACPI_IS_XDIGIT ((char) ThisDigit)) 32589948Simp { 32689948Simp /* Not A-F */ 32789948Simp 32889948Simp return (AE_BAD_CHARACTER); 32989948Simp } 33089948Simp 33189948Simp /* Convert ASCII Hex char (A-F) to value */ 33289948Simp 33389948Simp ThisDigit = (ThisDigit - 'A') + 10; 33489948Simp } 33589948Simp 33689948Simp /* Insert the 4-bit hex digit */ 33789948Simp 33889948Simp ReturnValue <<= 4; 33989948Simp ReturnValue += ThisDigit; 34089948Simp 34189948Simp ThisChar++; 34289948Simp DigitCount++; 34389948Simp if (DigitCount > 16) 34489948Simp { 34589948Simp /* Value is too large (> 64 bits/8 bytes/16 hex digits) */ 34689948Simp 34789948Simp return (AE_LIMIT); 34889948Simp } 34989948Simp } 35089948Simp 35189948Simp *ReturnInteger = ReturnValue; 35289948Simp return (AE_OK); 35389948Simp} 35489948Simp 35589948Simp 35689948Simp/****************************************************************************** 35789948Simp * 358201450Simp * FUNCTION: DtGetFileSize 35989948Simp * 36089948Simp * PARAMETERS: Handle - Open file handler 36189948Simp * 36289948Simp * RETURN: Current file size 36389948Simp * 36489948Simp * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the 36589948Simp * offset. Seek back to the original location. 36689948Simp * 36789948Simp *****************************************************************************/ 36889948Simp 36989948SimpUINT32 37089948SimpDtGetFileSize ( 37189948Simp FILE *Handle) 37289948Simp{ 37389948Simp int CurrentOffset; 37489948Simp int LastOffset; 37589948Simp 37689948Simp 37789948Simp CurrentOffset = ftell (Handle); 37889948Simp fseek (Handle, 0, SEEK_END); 37989948Simp LastOffset = ftell (Handle); 38089948Simp fseek (Handle, CurrentOffset, SEEK_SET); 38189948Simp 38289948Simp return ((UINT32) LastOffset); 38389948Simp} 38489948Simp 38589948Simp 38689948Simp/****************************************************************************** 38789948Simp * 38889948Simp * FUNCTION: DtGetFieldValue 389110841Simp * 390110841Simp * PARAMETERS: Field - Current field list pointer 391110841Simp * Name - Field name 392110841Simp * 393110841Simp * RETURN: Field value 394110841Simp * 395110841Simp * DESCRIPTION: Get field value 396110841Simp * 397110841Simp *****************************************************************************/ 398115887Simp 399115887Simpchar * 400115887SimpDtGetFieldValue ( 401115887Simp DT_FIELD *Field, 402115887Simp char *Name) 403115887Simp{ 404115887Simp 405161240Simp /* Search the field list for the name */ 406161240Simp 407161240Simp while (Field) 408161240Simp { 409161240Simp if (!ACPI_STRCMP (Name, Field->Name)) 410161240Simp { 41189948Simp return (Field->Value); 41289948Simp } 41389948Simp 41489948Simp Field = Field->Next; 41589948Simp } 41689948Simp 41789948Simp return (NULL); 41889948Simp} 41989948Simp 42089948Simp 42189948Simp/****************************************************************************** 42289948Simp * 42389948Simp * FUNCTION: DtGetFieldType 42489948Simp * 42589948Simp * PARAMETERS: Info - Data table info 42689948Simp * 42789948Simp * RETURN: Field type 42889948Simp * 42989948Simp * DESCRIPTION: Get field type 43089948Simp * 43189948Simp *****************************************************************************/ 43289948Simp 43389948SimpUINT8 43489948SimpDtGetFieldType ( 43589948Simp ACPI_DMTABLE_INFO *Info) 43689948Simp{ 43789948Simp UINT8 Type; 43889948Simp 43989948Simp 44089948Simp /* DT_FLAG means that this is the start of a block of flag bits */ 44189948Simp /* TBD - we can make these a separate opcode later */ 44289948Simp 44389948Simp if (Info->Flags & DT_FLAG) 44489948Simp { 44589948Simp return (DT_FIELD_TYPE_FLAGS_INTEGER); 44689948Simp } 44789948Simp 44889948Simp /* Type is based upon the opcode for this field in the info table */ 44989948Simp 45089948Simp switch (Info->Opcode) 451100703Simp { 452100703Simp 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 509UINT32 510DtGetBufferLength ( 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 548UINT32 549DtGetFieldLength ( 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 674static void 675DtSum ( 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 701void 702DtSetTableChecksum ( 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 733void 734DtSetTableLength ( 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 806void 807DtWalkTableTree ( 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 871void 872DtFreeFieldList ( 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} 895