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