1208625Sjkim/****************************************************************************** 2208625Sjkim * 3208625Sjkim * Module Name: dtutils.c - Utility routines for the data table compiler 4208625Sjkim * 5208625Sjkim *****************************************************************************/ 6208625Sjkim 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9208625Sjkim * All rights reserved. 10208625Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25208625Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29208625Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43208625Sjkim 44208625Sjkim#define __DTUTILS_C__ 45208625Sjkim 46209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 47209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h> 48209746Sjkim#include <contrib/dev/acpica/include/actables.h> 49208625Sjkim 50208625Sjkim#define _COMPONENT DT_COMPILER 51208625Sjkim ACPI_MODULE_NAME ("dtutils") 52208625Sjkim 53208625Sjkim/* Local prototypes */ 54208625Sjkim 55208625Sjkimstatic void 56208625SjkimDtSum ( 57208625Sjkim DT_SUBTABLE *Subtable, 58208625Sjkim void *Context, 59208625Sjkim void *ReturnValue); 60208625Sjkim 61208625Sjkim 62208625Sjkim/****************************************************************************** 63208625Sjkim * 64208625Sjkim * FUNCTION: DtError 65208625Sjkim * 66208625Sjkim * PARAMETERS: Level - Seriousness (Warning/error, etc.) 67208625Sjkim * MessageId - Index into global message buffer 68208625Sjkim * Op - Parse node where error happened 69208625Sjkim * ExtraMessage - additional error message 70208625Sjkim * 71208625Sjkim * RETURN: None 72208625Sjkim * 73208625Sjkim * DESCRIPTION: Common error interface for data table compiler 74208625Sjkim * 75208625Sjkim *****************************************************************************/ 76208625Sjkim 77208625Sjkimvoid 78208625SjkimDtError ( 79208625Sjkim UINT8 Level, 80208625Sjkim UINT8 MessageId, 81208625Sjkim DT_FIELD *FieldObject, 82208625Sjkim char *ExtraMessage) 83208625Sjkim{ 84208625Sjkim 85250838Sjkim /* Check if user wants to ignore this exception */ 86250838Sjkim 87250838Sjkim if (AslIsExceptionDisabled (Level, MessageId)) 88208625Sjkim { 89250838Sjkim return; 90208625Sjkim } 91208625Sjkim 92208625Sjkim if (FieldObject) 93208625Sjkim { 94208625Sjkim AslCommonError (Level, MessageId, 95208625Sjkim FieldObject->Line, 96208625Sjkim FieldObject->Line, 97208625Sjkim FieldObject->ByteOffset, 98208625Sjkim FieldObject->Column, 99208625Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 100208625Sjkim } 101208625Sjkim else 102208625Sjkim { 103208625Sjkim AslCommonError (Level, MessageId, 0, 104208625Sjkim 0, 0, 0, 0, ExtraMessage); 105208625Sjkim } 106208625Sjkim} 107208625Sjkim 108208625Sjkim 109208625Sjkim/****************************************************************************** 110208625Sjkim * 111208625Sjkim * FUNCTION: DtNameError 112208625Sjkim * 113208625Sjkim * PARAMETERS: Level - Seriousness (Warning/error, etc.) 114208625Sjkim * MessageId - Index into global message buffer 115208625Sjkim * Op - Parse node where error happened 116208625Sjkim * ExtraMessage - additional error message 117208625Sjkim * 118208625Sjkim * RETURN: None 119208625Sjkim * 120208625Sjkim * DESCRIPTION: Error interface for named objects 121208625Sjkim * 122208625Sjkim *****************************************************************************/ 123208625Sjkim 124208625Sjkimvoid 125208625SjkimDtNameError ( 126208625Sjkim UINT8 Level, 127208625Sjkim UINT8 MessageId, 128208625Sjkim DT_FIELD *FieldObject, 129208625Sjkim char *ExtraMessage) 130208625Sjkim{ 131208625Sjkim 132208625Sjkim switch (Level) 133208625Sjkim { 134208625Sjkim case ASL_WARNING2: 135208625Sjkim case ASL_WARNING3: 136250838Sjkim 137208625Sjkim if (Gbl_WarningLevel < Level) 138208625Sjkim { 139208625Sjkim return; 140208625Sjkim } 141208625Sjkim break; 142208625Sjkim 143208625Sjkim default: 144250838Sjkim 145208625Sjkim break; 146208625Sjkim } 147208625Sjkim 148208625Sjkim if (FieldObject) 149208625Sjkim { 150208625Sjkim AslCommonError (Level, MessageId, 151208625Sjkim FieldObject->Line, 152208625Sjkim FieldObject->Line, 153208625Sjkim FieldObject->ByteOffset, 154208625Sjkim FieldObject->NameColumn, 155208625Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 156208625Sjkim } 157208625Sjkim else 158208625Sjkim { 159208625Sjkim AslCommonError (Level, MessageId, 0, 160208625Sjkim 0, 0, 0, 0, ExtraMessage); 161208625Sjkim } 162208625Sjkim} 163208625Sjkim 164208625Sjkim 165208625Sjkim/******************************************************************************* 166208625Sjkim * 167208625Sjkim * FUNCTION: DtFatal 168208625Sjkim * 169208625Sjkim * PARAMETERS: None 170208625Sjkim * 171208625Sjkim * RETURN: None 172208625Sjkim * 173208625Sjkim * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 174208625Sjkim * compile or I/O errors 175208625Sjkim * 176208625Sjkim ******************************************************************************/ 177208625Sjkim 178208625Sjkimvoid 179208625SjkimDtFatal ( 180208625Sjkim UINT8 MessageId, 181208625Sjkim DT_FIELD *FieldObject, 182208625Sjkim char *ExtraMessage) 183208625Sjkim{ 184208625Sjkim 185208625Sjkim DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage); 186208625Sjkim 187220663Sjkim/* 188220663Sjkim * TBD: remove this entire function, DtFatal 189220663Sjkim * 190220663Sjkim * We cannot abort the compiler on error, because we may be compiling a 191220663Sjkim * list of files. We must move on to the next file. 192220663Sjkim */ 193220663Sjkim#ifdef __OBSOLETE 194208625Sjkim CmCleanupAndExit (); 195208625Sjkim exit (1); 196220663Sjkim#endif 197208625Sjkim} 198208625Sjkim 199208625Sjkim 200208625Sjkim/****************************************************************************** 201208625Sjkim * 202208625Sjkim * FUNCTION: DtStrtoul64 203208625Sjkim * 204208625Sjkim * PARAMETERS: String - Null terminated string 205208625Sjkim * ReturnInteger - Where the converted integer is returned 206208625Sjkim * 207208625Sjkim * RETURN: Status 208208625Sjkim * 209208625Sjkim * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned 210208625Sjkim * value. Assumes no leading "0x" for the constant. 211208625Sjkim * 212208625Sjkim * Portability note: The reason this function exists is because a 64-bit 213208625Sjkim * sscanf is not available in all environments. 214208625Sjkim * 215208625Sjkim *****************************************************************************/ 216208625Sjkim 217208625SjkimACPI_STATUS 218208625SjkimDtStrtoul64 ( 219208625Sjkim char *String, 220208625Sjkim UINT64 *ReturnInteger) 221208625Sjkim{ 222208625Sjkim char *ThisChar = String; 223208625Sjkim UINT32 ThisDigit; 224208625Sjkim UINT64 ReturnValue = 0; 225208625Sjkim int DigitCount = 0; 226208625Sjkim 227208625Sjkim 228208625Sjkim /* Skip over any white space in the buffer */ 229208625Sjkim 230208625Sjkim while ((*ThisChar == ' ') || (*ThisChar == '\t')) 231208625Sjkim { 232208625Sjkim ThisChar++; 233208625Sjkim } 234208625Sjkim 235208625Sjkim /* Skip leading zeros */ 236208625Sjkim 237208625Sjkim while ((*ThisChar) == '0') 238208625Sjkim { 239208625Sjkim ThisChar++; 240208625Sjkim } 241208625Sjkim 242208625Sjkim /* Convert character-by-character */ 243208625Sjkim 244208625Sjkim while (*ThisChar) 245208625Sjkim { 246208625Sjkim if (ACPI_IS_DIGIT (*ThisChar)) 247208625Sjkim { 248208625Sjkim /* Convert ASCII 0-9 to Decimal value */ 249208625Sjkim 250208625Sjkim ThisDigit = ((UINT8) *ThisChar) - '0'; 251208625Sjkim } 252208625Sjkim else /* Letter */ 253208625Sjkim { 254208625Sjkim ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar); 255208625Sjkim if (!ACPI_IS_XDIGIT ((char) ThisDigit)) 256208625Sjkim { 257208625Sjkim /* Not A-F */ 258208625Sjkim 259208625Sjkim return (AE_BAD_CHARACTER); 260208625Sjkim } 261208625Sjkim 262208625Sjkim /* Convert ASCII Hex char (A-F) to value */ 263208625Sjkim 264208625Sjkim ThisDigit = (ThisDigit - 'A') + 10; 265208625Sjkim } 266208625Sjkim 267208625Sjkim /* Insert the 4-bit hex digit */ 268208625Sjkim 269208625Sjkim ReturnValue <<= 4; 270208625Sjkim ReturnValue += ThisDigit; 271208625Sjkim 272208625Sjkim ThisChar++; 273208625Sjkim DigitCount++; 274208625Sjkim if (DigitCount > 16) 275208625Sjkim { 276208625Sjkim /* Value is too large (> 64 bits/8 bytes/16 hex digits) */ 277208625Sjkim 278208625Sjkim return (AE_LIMIT); 279208625Sjkim } 280208625Sjkim } 281208625Sjkim 282208625Sjkim *ReturnInteger = ReturnValue; 283208625Sjkim return (AE_OK); 284208625Sjkim} 285208625Sjkim 286208625Sjkim 287208625Sjkim/****************************************************************************** 288208625Sjkim * 289208625Sjkim * FUNCTION: DtGetFileSize 290208625Sjkim * 291208625Sjkim * PARAMETERS: Handle - Open file handler 292208625Sjkim * 293208625Sjkim * RETURN: Current file size 294208625Sjkim * 295208625Sjkim * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the 296208625Sjkim * offset. Seek back to the original location. 297208625Sjkim * 298208625Sjkim *****************************************************************************/ 299208625Sjkim 300208625SjkimUINT32 301208625SjkimDtGetFileSize ( 302208625Sjkim FILE *Handle) 303208625Sjkim{ 304208625Sjkim int CurrentOffset; 305208625Sjkim int LastOffset; 306208625Sjkim 307208625Sjkim 308208625Sjkim CurrentOffset = ftell (Handle); 309208625Sjkim fseek (Handle, 0, SEEK_END); 310208625Sjkim LastOffset = ftell (Handle); 311208625Sjkim fseek (Handle, CurrentOffset, SEEK_SET); 312208625Sjkim 313208625Sjkim return ((UINT32) LastOffset); 314208625Sjkim} 315208625Sjkim 316208625Sjkim 317208625Sjkim/****************************************************************************** 318208625Sjkim * 319208625Sjkim * FUNCTION: DtGetFieldValue 320208625Sjkim * 321208625Sjkim * PARAMETERS: Field - Current field list pointer 322208625Sjkim * 323208625Sjkim * RETURN: Field value 324208625Sjkim * 325208625Sjkim * DESCRIPTION: Get field value 326208625Sjkim * 327208625Sjkim *****************************************************************************/ 328208625Sjkim 329208625Sjkimchar * 330208625SjkimDtGetFieldValue ( 331220663Sjkim DT_FIELD *Field) 332208625Sjkim{ 333220663Sjkim if (!Field) 334208625Sjkim { 335220663Sjkim return (NULL); 336208625Sjkim } 337208625Sjkim 338220663Sjkim return (Field->Value); 339208625Sjkim} 340208625Sjkim 341208625Sjkim 342208625Sjkim/****************************************************************************** 343208625Sjkim * 344208625Sjkim * FUNCTION: DtGetFieldType 345208625Sjkim * 346208625Sjkim * PARAMETERS: Info - Data table info 347208625Sjkim * 348208625Sjkim * RETURN: Field type 349208625Sjkim * 350208625Sjkim * DESCRIPTION: Get field type 351208625Sjkim * 352208625Sjkim *****************************************************************************/ 353208625Sjkim 354208625SjkimUINT8 355208625SjkimDtGetFieldType ( 356208625Sjkim ACPI_DMTABLE_INFO *Info) 357208625Sjkim{ 358208625Sjkim UINT8 Type; 359208625Sjkim 360208625Sjkim 361208625Sjkim /* DT_FLAG means that this is the start of a block of flag bits */ 362208625Sjkim /* TBD - we can make these a separate opcode later */ 363208625Sjkim 364208625Sjkim if (Info->Flags & DT_FLAG) 365208625Sjkim { 366208625Sjkim return (DT_FIELD_TYPE_FLAGS_INTEGER); 367208625Sjkim } 368208625Sjkim 369208625Sjkim /* Type is based upon the opcode for this field in the info table */ 370208625Sjkim 371208625Sjkim switch (Info->Opcode) 372208625Sjkim { 373208625Sjkim case ACPI_DMT_FLAG0: 374208625Sjkim case ACPI_DMT_FLAG1: 375208625Sjkim case ACPI_DMT_FLAG2: 376208625Sjkim case ACPI_DMT_FLAG3: 377208625Sjkim case ACPI_DMT_FLAG4: 378208625Sjkim case ACPI_DMT_FLAG5: 379208625Sjkim case ACPI_DMT_FLAG6: 380208625Sjkim case ACPI_DMT_FLAG7: 381208625Sjkim case ACPI_DMT_FLAGS0: 382228110Sjkim case ACPI_DMT_FLAGS1: 383208625Sjkim case ACPI_DMT_FLAGS2: 384228110Sjkim case ACPI_DMT_FLAGS4: 385250838Sjkim 386208625Sjkim Type = DT_FIELD_TYPE_FLAG; 387208625Sjkim break; 388208625Sjkim 389208625Sjkim case ACPI_DMT_NAME4: 390208625Sjkim case ACPI_DMT_SIG: 391208625Sjkim case ACPI_DMT_NAME6: 392208625Sjkim case ACPI_DMT_NAME8: 393208625Sjkim case ACPI_DMT_STRING: 394250838Sjkim 395208625Sjkim Type = DT_FIELD_TYPE_STRING; 396208625Sjkim break; 397208625Sjkim 398208625Sjkim case ACPI_DMT_BUFFER: 399218590Sjkim case ACPI_DMT_BUF7: 400252279Sjkim case ACPI_DMT_BUF10: 401208625Sjkim case ACPI_DMT_BUF16: 402219707Sjkim case ACPI_DMT_BUF128: 403209734Sjkim case ACPI_DMT_PCI_PATH: 404250838Sjkim 405208625Sjkim Type = DT_FIELD_TYPE_BUFFER; 406208625Sjkim break; 407208625Sjkim 408208625Sjkim case ACPI_DMT_GAS: 409208625Sjkim case ACPI_DMT_HESTNTFY: 410250838Sjkim 411208625Sjkim Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 412208625Sjkim break; 413208625Sjkim 414217365Sjkim case ACPI_DMT_UNICODE: 415250838Sjkim 416217365Sjkim Type = DT_FIELD_TYPE_UNICODE; 417217365Sjkim break; 418217365Sjkim 419217365Sjkim case ACPI_DMT_UUID: 420250838Sjkim 421217365Sjkim Type = DT_FIELD_TYPE_UUID; 422217365Sjkim break; 423217365Sjkim 424217365Sjkim case ACPI_DMT_DEVICE_PATH: 425250838Sjkim 426217365Sjkim Type = DT_FIELD_TYPE_DEVICE_PATH; 427217365Sjkim break; 428217365Sjkim 429218590Sjkim case ACPI_DMT_LABEL: 430250838Sjkim 431218590Sjkim Type = DT_FIELD_TYPE_LABEL; 432218590Sjkim break; 433218590Sjkim 434208625Sjkim default: 435250838Sjkim 436208625Sjkim Type = DT_FIELD_TYPE_INTEGER; 437208625Sjkim break; 438208625Sjkim } 439208625Sjkim 440208625Sjkim return (Type); 441208625Sjkim} 442208625Sjkim 443208625Sjkim 444208625Sjkim/****************************************************************************** 445208625Sjkim * 446208625Sjkim * FUNCTION: DtGetBufferLength 447208625Sjkim * 448208625Sjkim * PARAMETERS: Buffer - List of integers, 449208625Sjkim * for example "10 3A 4F 2E" 450208625Sjkim * 451208625Sjkim * RETURN: Count of integer 452208625Sjkim * 453208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers 454208625Sjkim * 455208625Sjkim *****************************************************************************/ 456208625Sjkim 457208625SjkimUINT32 458208625SjkimDtGetBufferLength ( 459208625Sjkim char *Buffer) 460208625Sjkim{ 461208625Sjkim UINT32 ByteLength = 0; 462208625Sjkim 463208625Sjkim 464208625Sjkim while (*Buffer) 465208625Sjkim { 466208625Sjkim if (*Buffer == ' ') 467208625Sjkim { 468208625Sjkim ByteLength++; 469208625Sjkim 470208625Sjkim while (*Buffer == ' ') 471208625Sjkim { 472208625Sjkim Buffer++; 473208625Sjkim } 474208625Sjkim } 475208625Sjkim 476208625Sjkim Buffer++; 477208625Sjkim } 478208625Sjkim 479208625Sjkim return (++ByteLength); 480208625Sjkim} 481208625Sjkim 482208625Sjkim 483208625Sjkim/****************************************************************************** 484208625Sjkim * 485208625Sjkim * FUNCTION: DtGetFieldLength 486208625Sjkim * 487220663Sjkim * PARAMETERS: Field - Current field 488208625Sjkim * Info - Data table info 489208625Sjkim * 490208625Sjkim * RETURN: Field length 491208625Sjkim * 492208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field 493208625Sjkim * 494209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable. 495209734Sjkim * 496208625Sjkim *****************************************************************************/ 497208625Sjkim 498208625SjkimUINT32 499208625SjkimDtGetFieldLength ( 500208625Sjkim DT_FIELD *Field, 501208625Sjkim ACPI_DMTABLE_INFO *Info) 502208625Sjkim{ 503208625Sjkim UINT32 ByteLength = 0; 504208625Sjkim char *Value; 505208625Sjkim 506208625Sjkim 507208625Sjkim /* Length is based upon the opcode for this field in the info table */ 508208625Sjkim 509208625Sjkim switch (Info->Opcode) 510208625Sjkim { 511208625Sjkim case ACPI_DMT_FLAG0: 512208625Sjkim case ACPI_DMT_FLAG1: 513208625Sjkim case ACPI_DMT_FLAG2: 514208625Sjkim case ACPI_DMT_FLAG3: 515208625Sjkim case ACPI_DMT_FLAG4: 516208625Sjkim case ACPI_DMT_FLAG5: 517208625Sjkim case ACPI_DMT_FLAG6: 518208625Sjkim case ACPI_DMT_FLAG7: 519208625Sjkim case ACPI_DMT_FLAGS0: 520228110Sjkim case ACPI_DMT_FLAGS1: 521208625Sjkim case ACPI_DMT_FLAGS2: 522228110Sjkim case ACPI_DMT_FLAGS4: 523218590Sjkim case ACPI_DMT_LABEL: 524228110Sjkim case ACPI_DMT_EXTRA_TEXT: 525250838Sjkim 526208625Sjkim ByteLength = 0; 527208625Sjkim break; 528208625Sjkim 529208625Sjkim case ACPI_DMT_UINT8: 530208625Sjkim case ACPI_DMT_CHKSUM: 531208625Sjkim case ACPI_DMT_SPACEID: 532216471Sjkim case ACPI_DMT_ACCWIDTH: 533209734Sjkim case ACPI_DMT_IVRS: 534208625Sjkim case ACPI_DMT_MADT: 535228110Sjkim case ACPI_DMT_PMTT: 536208625Sjkim case ACPI_DMT_SRAT: 537208625Sjkim case ACPI_DMT_ASF: 538208625Sjkim case ACPI_DMT_HESTNTYP: 539208625Sjkim case ACPI_DMT_FADTPM: 540209734Sjkim case ACPI_DMT_EINJACT: 541209734Sjkim case ACPI_DMT_EINJINST: 542209734Sjkim case ACPI_DMT_ERSTACT: 543209734Sjkim case ACPI_DMT_ERSTINST: 544250838Sjkim 545208625Sjkim ByteLength = 1; 546208625Sjkim break; 547208625Sjkim 548208625Sjkim case ACPI_DMT_UINT16: 549208625Sjkim case ACPI_DMT_DMAR: 550208625Sjkim case ACPI_DMT_HEST: 551208625Sjkim case ACPI_DMT_PCI_PATH: 552250838Sjkim 553208625Sjkim ByteLength = 2; 554208625Sjkim break; 555208625Sjkim 556208625Sjkim case ACPI_DMT_UINT24: 557250838Sjkim 558208625Sjkim ByteLength = 3; 559208625Sjkim break; 560208625Sjkim 561208625Sjkim case ACPI_DMT_UINT32: 562208625Sjkim case ACPI_DMT_NAME4: 563219707Sjkim case ACPI_DMT_SLIC: 564208625Sjkim case ACPI_DMT_SIG: 565250838Sjkim 566208625Sjkim ByteLength = 4; 567208625Sjkim break; 568208625Sjkim 569228110Sjkim case ACPI_DMT_UINT40: 570250838Sjkim 571228110Sjkim ByteLength = 5; 572228110Sjkim break; 573228110Sjkim 574228110Sjkim case ACPI_DMT_UINT48: 575208625Sjkim case ACPI_DMT_NAME6: 576250838Sjkim 577208625Sjkim ByteLength = 6; 578208625Sjkim break; 579208625Sjkim 580208625Sjkim case ACPI_DMT_UINT56: 581218590Sjkim case ACPI_DMT_BUF7: 582250838Sjkim 583208625Sjkim ByteLength = 7; 584208625Sjkim break; 585208625Sjkim 586208625Sjkim case ACPI_DMT_UINT64: 587208625Sjkim case ACPI_DMT_NAME8: 588250838Sjkim 589208625Sjkim ByteLength = 8; 590208625Sjkim break; 591208625Sjkim 592208625Sjkim case ACPI_DMT_STRING: 593250838Sjkim 594220663Sjkim Value = DtGetFieldValue (Field); 595217365Sjkim if (Value) 596217365Sjkim { 597217365Sjkim ByteLength = ACPI_STRLEN (Value) + 1; 598217365Sjkim } 599217365Sjkim else 600217365Sjkim { /* At this point, this is a fatal error */ 601208625Sjkim 602217365Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 603217365Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 604220663Sjkim return (0); 605217365Sjkim } 606208625Sjkim break; 607208625Sjkim 608208625Sjkim case ACPI_DMT_GAS: 609250838Sjkim 610208625Sjkim ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 611208625Sjkim break; 612208625Sjkim 613208625Sjkim case ACPI_DMT_HESTNTFY: 614250838Sjkim 615208625Sjkim ByteLength = sizeof (ACPI_HEST_NOTIFY); 616208625Sjkim break; 617208625Sjkim 618208625Sjkim case ACPI_DMT_BUFFER: 619250838Sjkim 620220663Sjkim Value = DtGetFieldValue (Field); 621208625Sjkim if (Value) 622208625Sjkim { 623208625Sjkim ByteLength = DtGetBufferLength (Value); 624208625Sjkim } 625208625Sjkim else 626208625Sjkim { /* At this point, this is a fatal error */ 627208625Sjkim 628208625Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 629208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 630220663Sjkim return (0); 631208625Sjkim } 632208625Sjkim break; 633208625Sjkim 634252279Sjkim case ACPI_DMT_BUF10: 635252279Sjkim 636252279Sjkim ByteLength = 10; 637252279Sjkim break; 638252279Sjkim 639208625Sjkim case ACPI_DMT_BUF16: 640217365Sjkim case ACPI_DMT_UUID: 641250838Sjkim 642208625Sjkim ByteLength = 16; 643208625Sjkim break; 644208625Sjkim 645219707Sjkim case ACPI_DMT_BUF128: 646250838Sjkim 647219707Sjkim ByteLength = 128; 648219707Sjkim break; 649219707Sjkim 650217365Sjkim case ACPI_DMT_UNICODE: 651250838Sjkim 652220663Sjkim Value = DtGetFieldValue (Field); 653217365Sjkim 654217365Sjkim /* TBD: error if Value is NULL? (as below?) */ 655217365Sjkim 656217365Sjkim ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16); 657217365Sjkim break; 658217365Sjkim 659208625Sjkim default: 660250838Sjkim 661208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 662220663Sjkim return (0); 663208625Sjkim } 664208625Sjkim 665208625Sjkim return (ByteLength); 666208625Sjkim} 667208625Sjkim 668208625Sjkim 669208625Sjkim/****************************************************************************** 670208625Sjkim * 671208625Sjkim * FUNCTION: DtSum 672208625Sjkim * 673208625Sjkim * PARAMETERS: DT_WALK_CALLBACK: 674208625Sjkim * Subtable - Subtable 675208625Sjkim * Context - Unused 676208625Sjkim * ReturnValue - Store the checksum of subtable 677208625Sjkim * 678208625Sjkim * RETURN: Status 679208625Sjkim * 680208625Sjkim * DESCRIPTION: Get the checksum of subtable 681208625Sjkim * 682208625Sjkim *****************************************************************************/ 683208625Sjkim 684208625Sjkimstatic void 685208625SjkimDtSum ( 686208625Sjkim DT_SUBTABLE *Subtable, 687208625Sjkim void *Context, 688208625Sjkim void *ReturnValue) 689208625Sjkim{ 690208625Sjkim UINT8 Checksum; 691208625Sjkim UINT8 *Sum = ReturnValue; 692208625Sjkim 693208625Sjkim 694208625Sjkim Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 695208625Sjkim *Sum = (UINT8) (*Sum + Checksum); 696208625Sjkim} 697208625Sjkim 698208625Sjkim 699208625Sjkim/****************************************************************************** 700208625Sjkim * 701208625Sjkim * FUNCTION: DtSetTableChecksum 702208625Sjkim * 703208625Sjkim * PARAMETERS: ChecksumPointer - Where to return the checksum 704208625Sjkim * 705208625Sjkim * RETURN: None 706208625Sjkim * 707208625Sjkim * DESCRIPTION: Set checksum of the whole data table into the checksum field 708208625Sjkim * 709208625Sjkim *****************************************************************************/ 710208625Sjkim 711208625Sjkimvoid 712208625SjkimDtSetTableChecksum ( 713208625Sjkim UINT8 *ChecksumPointer) 714208625Sjkim{ 715208625Sjkim UINT8 Checksum = 0; 716208625Sjkim UINT8 OldSum; 717208625Sjkim 718208625Sjkim 719208625Sjkim DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 720208625Sjkim 721208625Sjkim OldSum = *ChecksumPointer; 722208625Sjkim Checksum = (UINT8) (Checksum - OldSum); 723208625Sjkim 724208625Sjkim /* Compute the final checksum */ 725208625Sjkim 726208625Sjkim Checksum = (UINT8) (0 - Checksum); 727208625Sjkim *ChecksumPointer = Checksum; 728208625Sjkim} 729208625Sjkim 730208625Sjkim 731208625Sjkim/****************************************************************************** 732208625Sjkim * 733208625Sjkim * FUNCTION: DtSetTableLength 734208625Sjkim * 735208625Sjkim * PARAMETERS: None 736208625Sjkim * 737208625Sjkim * RETURN: None 738208625Sjkim * 739208625Sjkim * DESCRIPTION: Walk the subtables and set all the length fields 740208625Sjkim * 741208625Sjkim *****************************************************************************/ 742208625Sjkim 743208625Sjkimvoid 744208625SjkimDtSetTableLength ( 745208625Sjkim void) 746208625Sjkim{ 747208625Sjkim DT_SUBTABLE *ParentTable; 748208625Sjkim DT_SUBTABLE *ChildTable; 749208625Sjkim 750208625Sjkim 751208625Sjkim ParentTable = Gbl_RootTable; 752208625Sjkim ChildTable = NULL; 753208625Sjkim 754208625Sjkim if (!ParentTable) 755208625Sjkim { 756208625Sjkim return; 757208625Sjkim } 758208625Sjkim 759208625Sjkim DtSetSubtableLength (ParentTable); 760208625Sjkim 761208625Sjkim while (1) 762208625Sjkim { 763208625Sjkim ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 764208625Sjkim if (ChildTable) 765208625Sjkim { 766209734Sjkim if (ChildTable->LengthField) 767209734Sjkim { 768209734Sjkim DtSetSubtableLength (ChildTable); 769209734Sjkim } 770209734Sjkim 771208625Sjkim if (ChildTable->Child) 772208625Sjkim { 773208625Sjkim ParentTable = ChildTable; 774208625Sjkim ChildTable = NULL; 775208625Sjkim } 776208625Sjkim else 777208625Sjkim { 778208625Sjkim ParentTable->TotalLength += ChildTable->TotalLength; 779208625Sjkim if (ParentTable->LengthField) 780208625Sjkim { 781208625Sjkim DtSetSubtableLength (ParentTable); 782208625Sjkim } 783208625Sjkim } 784208625Sjkim } 785208625Sjkim else 786208625Sjkim { 787208625Sjkim ChildTable = ParentTable; 788208625Sjkim 789208625Sjkim if (ChildTable == Gbl_RootTable) 790208625Sjkim { 791208625Sjkim break; 792208625Sjkim } 793208625Sjkim 794208625Sjkim ParentTable = DtGetParentSubtable (ParentTable); 795208625Sjkim 796208625Sjkim ParentTable->TotalLength += ChildTable->TotalLength; 797208625Sjkim if (ParentTable->LengthField) 798208625Sjkim { 799208625Sjkim DtSetSubtableLength (ParentTable); 800208625Sjkim } 801208625Sjkim } 802208625Sjkim } 803208625Sjkim} 804208625Sjkim 805208625Sjkim 806208625Sjkim/****************************************************************************** 807208625Sjkim * 808208625Sjkim * FUNCTION: DtWalkTableTree 809208625Sjkim * 810208625Sjkim * PARAMETERS: StartTable - Subtable in the tree where walking begins 811208625Sjkim * UserFunction - Called during the walk 812208625Sjkim * Context - Passed to user function 813208625Sjkim * ReturnValue - The return value of UserFunction 814208625Sjkim * 815208625Sjkim * RETURN: None 816208625Sjkim * 817208625Sjkim * DESCRIPTION: Performs a depth-first walk of the subtable tree 818208625Sjkim * 819208625Sjkim *****************************************************************************/ 820208625Sjkim 821208625Sjkimvoid 822208625SjkimDtWalkTableTree ( 823208625Sjkim DT_SUBTABLE *StartTable, 824208625Sjkim DT_WALK_CALLBACK UserFunction, 825208625Sjkim void *Context, 826208625Sjkim void *ReturnValue) 827208625Sjkim{ 828208625Sjkim DT_SUBTABLE *ParentTable; 829208625Sjkim DT_SUBTABLE *ChildTable; 830208625Sjkim 831208625Sjkim 832208625Sjkim ParentTable = StartTable; 833208625Sjkim ChildTable = NULL; 834208625Sjkim 835208625Sjkim if (!ParentTable) 836208625Sjkim { 837208625Sjkim return; 838208625Sjkim } 839208625Sjkim 840208625Sjkim UserFunction (ParentTable, Context, ReturnValue); 841208625Sjkim 842208625Sjkim while (1) 843208625Sjkim { 844208625Sjkim ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 845208625Sjkim if (ChildTable) 846208625Sjkim { 847208625Sjkim UserFunction (ChildTable, Context, ReturnValue); 848208625Sjkim 849208625Sjkim if (ChildTable->Child) 850208625Sjkim { 851208625Sjkim ParentTable = ChildTable; 852208625Sjkim ChildTable = NULL; 853208625Sjkim } 854208625Sjkim } 855208625Sjkim else 856208625Sjkim { 857208625Sjkim ChildTable = ParentTable; 858208625Sjkim if (ChildTable == Gbl_RootTable) 859208625Sjkim { 860208625Sjkim break; 861208625Sjkim } 862208625Sjkim 863208625Sjkim ParentTable = DtGetParentSubtable (ParentTable); 864208625Sjkim 865208625Sjkim if (ChildTable->Peer == StartTable) 866208625Sjkim { 867208625Sjkim break; 868208625Sjkim } 869208625Sjkim } 870208625Sjkim } 871208625Sjkim} 872208625Sjkim 873208625Sjkim 874208625Sjkim/****************************************************************************** 875208625Sjkim * 876208625Sjkim * FUNCTION: DtFreeFieldList 877208625Sjkim * 878208625Sjkim * PARAMETERS: None 879208625Sjkim * 880208625Sjkim * RETURN: None 881208625Sjkim * 882208625Sjkim * DESCRIPTION: Free the field list 883208625Sjkim * 884208625Sjkim *****************************************************************************/ 885208625Sjkim 886208625Sjkimvoid 887208625SjkimDtFreeFieldList ( 888208625Sjkim void) 889208625Sjkim{ 890208625Sjkim DT_FIELD *Field = Gbl_FieldList; 891208625Sjkim DT_FIELD *NextField; 892208625Sjkim 893208625Sjkim 894208625Sjkim /* Walk and free entire field list */ 895208625Sjkim 896208625Sjkim while (Field) 897208625Sjkim { 898208625Sjkim NextField = Field->Next; /* Save link */ 899208625Sjkim 900208625Sjkim if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED)) 901208625Sjkim { 902208625Sjkim ACPI_FREE (Field->Name); 903208625Sjkim ACPI_FREE (Field->Value); 904208625Sjkim } 905208625Sjkim 906208625Sjkim ACPI_FREE (Field); 907208625Sjkim Field = NextField; 908208625Sjkim } 909208625Sjkim} 910