dtutils.c revision 245582
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 85208625Sjkim switch (Level) 86208625Sjkim { 87208625Sjkim case ASL_WARNING2: 88208625Sjkim case ASL_WARNING3: 89208625Sjkim if (Gbl_WarningLevel < Level) 90208625Sjkim { 91208625Sjkim return; 92208625Sjkim } 93208625Sjkim break; 94208625Sjkim 95208625Sjkim default: 96208625Sjkim break; 97208625Sjkim } 98208625Sjkim 99208625Sjkim if (FieldObject) 100208625Sjkim { 101208625Sjkim AslCommonError (Level, MessageId, 102208625Sjkim FieldObject->Line, 103208625Sjkim FieldObject->Line, 104208625Sjkim FieldObject->ByteOffset, 105208625Sjkim FieldObject->Column, 106208625Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 107208625Sjkim } 108208625Sjkim else 109208625Sjkim { 110208625Sjkim AslCommonError (Level, MessageId, 0, 111208625Sjkim 0, 0, 0, 0, ExtraMessage); 112208625Sjkim } 113208625Sjkim} 114208625Sjkim 115208625Sjkim 116208625Sjkim/****************************************************************************** 117208625Sjkim * 118208625Sjkim * FUNCTION: DtNameError 119208625Sjkim * 120208625Sjkim * PARAMETERS: Level - Seriousness (Warning/error, etc.) 121208625Sjkim * MessageId - Index into global message buffer 122208625Sjkim * Op - Parse node where error happened 123208625Sjkim * ExtraMessage - additional error message 124208625Sjkim * 125208625Sjkim * RETURN: None 126208625Sjkim * 127208625Sjkim * DESCRIPTION: Error interface for named objects 128208625Sjkim * 129208625Sjkim *****************************************************************************/ 130208625Sjkim 131208625Sjkimvoid 132208625SjkimDtNameError ( 133208625Sjkim UINT8 Level, 134208625Sjkim UINT8 MessageId, 135208625Sjkim DT_FIELD *FieldObject, 136208625Sjkim char *ExtraMessage) 137208625Sjkim{ 138208625Sjkim 139208625Sjkim switch (Level) 140208625Sjkim { 141208625Sjkim case ASL_WARNING2: 142208625Sjkim case ASL_WARNING3: 143208625Sjkim if (Gbl_WarningLevel < Level) 144208625Sjkim { 145208625Sjkim return; 146208625Sjkim } 147208625Sjkim break; 148208625Sjkim 149208625Sjkim default: 150208625Sjkim break; 151208625Sjkim } 152208625Sjkim 153208625Sjkim if (FieldObject) 154208625Sjkim { 155208625Sjkim AslCommonError (Level, MessageId, 156208625Sjkim FieldObject->Line, 157208625Sjkim FieldObject->Line, 158208625Sjkim FieldObject->ByteOffset, 159208625Sjkim FieldObject->NameColumn, 160208625Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 161208625Sjkim } 162208625Sjkim else 163208625Sjkim { 164208625Sjkim AslCommonError (Level, MessageId, 0, 165208625Sjkim 0, 0, 0, 0, ExtraMessage); 166208625Sjkim } 167208625Sjkim} 168208625Sjkim 169208625Sjkim 170208625Sjkim/******************************************************************************* 171208625Sjkim * 172208625Sjkim * FUNCTION: DtFatal 173208625Sjkim * 174208625Sjkim * PARAMETERS: None 175208625Sjkim * 176208625Sjkim * RETURN: None 177208625Sjkim * 178208625Sjkim * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 179208625Sjkim * compile or I/O errors 180208625Sjkim * 181208625Sjkim ******************************************************************************/ 182208625Sjkim 183208625Sjkimvoid 184208625SjkimDtFatal ( 185208625Sjkim UINT8 MessageId, 186208625Sjkim DT_FIELD *FieldObject, 187208625Sjkim char *ExtraMessage) 188208625Sjkim{ 189208625Sjkim 190208625Sjkim DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage); 191208625Sjkim 192220663Sjkim/* 193220663Sjkim * TBD: remove this entire function, DtFatal 194220663Sjkim * 195220663Sjkim * We cannot abort the compiler on error, because we may be compiling a 196220663Sjkim * list of files. We must move on to the next file. 197220663Sjkim */ 198220663Sjkim#ifdef __OBSOLETE 199208625Sjkim CmCleanupAndExit (); 200208625Sjkim exit (1); 201220663Sjkim#endif 202208625Sjkim} 203208625Sjkim 204208625Sjkim 205208625Sjkim/****************************************************************************** 206208625Sjkim * 207208625Sjkim * FUNCTION: DtStrtoul64 208208625Sjkim * 209208625Sjkim * PARAMETERS: String - Null terminated string 210208625Sjkim * ReturnInteger - Where the converted integer is returned 211208625Sjkim * 212208625Sjkim * RETURN: Status 213208625Sjkim * 214208625Sjkim * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned 215208625Sjkim * value. Assumes no leading "0x" for the constant. 216208625Sjkim * 217208625Sjkim * Portability note: The reason this function exists is because a 64-bit 218208625Sjkim * sscanf is not available in all environments. 219208625Sjkim * 220208625Sjkim *****************************************************************************/ 221208625Sjkim 222208625SjkimACPI_STATUS 223208625SjkimDtStrtoul64 ( 224208625Sjkim char *String, 225208625Sjkim UINT64 *ReturnInteger) 226208625Sjkim{ 227208625Sjkim char *ThisChar = String; 228208625Sjkim UINT32 ThisDigit; 229208625Sjkim UINT64 ReturnValue = 0; 230208625Sjkim int DigitCount = 0; 231208625Sjkim 232208625Sjkim 233208625Sjkim /* Skip over any white space in the buffer */ 234208625Sjkim 235208625Sjkim while ((*ThisChar == ' ') || (*ThisChar == '\t')) 236208625Sjkim { 237208625Sjkim ThisChar++; 238208625Sjkim } 239208625Sjkim 240208625Sjkim /* Skip leading zeros */ 241208625Sjkim 242208625Sjkim while ((*ThisChar) == '0') 243208625Sjkim { 244208625Sjkim ThisChar++; 245208625Sjkim } 246208625Sjkim 247208625Sjkim /* Convert character-by-character */ 248208625Sjkim 249208625Sjkim while (*ThisChar) 250208625Sjkim { 251208625Sjkim if (ACPI_IS_DIGIT (*ThisChar)) 252208625Sjkim { 253208625Sjkim /* Convert ASCII 0-9 to Decimal value */ 254208625Sjkim 255208625Sjkim ThisDigit = ((UINT8) *ThisChar) - '0'; 256208625Sjkim } 257208625Sjkim else /* Letter */ 258208625Sjkim { 259208625Sjkim ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar); 260208625Sjkim if (!ACPI_IS_XDIGIT ((char) ThisDigit)) 261208625Sjkim { 262208625Sjkim /* Not A-F */ 263208625Sjkim 264208625Sjkim return (AE_BAD_CHARACTER); 265208625Sjkim } 266208625Sjkim 267208625Sjkim /* Convert ASCII Hex char (A-F) to value */ 268208625Sjkim 269208625Sjkim ThisDigit = (ThisDigit - 'A') + 10; 270208625Sjkim } 271208625Sjkim 272208625Sjkim /* Insert the 4-bit hex digit */ 273208625Sjkim 274208625Sjkim ReturnValue <<= 4; 275208625Sjkim ReturnValue += ThisDigit; 276208625Sjkim 277208625Sjkim ThisChar++; 278208625Sjkim DigitCount++; 279208625Sjkim if (DigitCount > 16) 280208625Sjkim { 281208625Sjkim /* Value is too large (> 64 bits/8 bytes/16 hex digits) */ 282208625Sjkim 283208625Sjkim return (AE_LIMIT); 284208625Sjkim } 285208625Sjkim } 286208625Sjkim 287208625Sjkim *ReturnInteger = ReturnValue; 288208625Sjkim return (AE_OK); 289208625Sjkim} 290208625Sjkim 291208625Sjkim 292208625Sjkim/****************************************************************************** 293208625Sjkim * 294208625Sjkim * FUNCTION: DtGetFileSize 295208625Sjkim * 296208625Sjkim * PARAMETERS: Handle - Open file handler 297208625Sjkim * 298208625Sjkim * RETURN: Current file size 299208625Sjkim * 300208625Sjkim * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the 301208625Sjkim * offset. Seek back to the original location. 302208625Sjkim * 303208625Sjkim *****************************************************************************/ 304208625Sjkim 305208625SjkimUINT32 306208625SjkimDtGetFileSize ( 307208625Sjkim FILE *Handle) 308208625Sjkim{ 309208625Sjkim int CurrentOffset; 310208625Sjkim int LastOffset; 311208625Sjkim 312208625Sjkim 313208625Sjkim CurrentOffset = ftell (Handle); 314208625Sjkim fseek (Handle, 0, SEEK_END); 315208625Sjkim LastOffset = ftell (Handle); 316208625Sjkim fseek (Handle, CurrentOffset, SEEK_SET); 317208625Sjkim 318208625Sjkim return ((UINT32) LastOffset); 319208625Sjkim} 320208625Sjkim 321208625Sjkim 322208625Sjkim/****************************************************************************** 323208625Sjkim * 324208625Sjkim * FUNCTION: DtGetFieldValue 325208625Sjkim * 326208625Sjkim * PARAMETERS: Field - Current field list pointer 327208625Sjkim * 328208625Sjkim * RETURN: Field value 329208625Sjkim * 330208625Sjkim * DESCRIPTION: Get field value 331208625Sjkim * 332208625Sjkim *****************************************************************************/ 333208625Sjkim 334208625Sjkimchar * 335208625SjkimDtGetFieldValue ( 336220663Sjkim DT_FIELD *Field) 337208625Sjkim{ 338220663Sjkim if (!Field) 339208625Sjkim { 340220663Sjkim return (NULL); 341208625Sjkim } 342208625Sjkim 343220663Sjkim return (Field->Value); 344208625Sjkim} 345208625Sjkim 346208625Sjkim 347208625Sjkim/****************************************************************************** 348208625Sjkim * 349208625Sjkim * FUNCTION: DtGetFieldType 350208625Sjkim * 351208625Sjkim * PARAMETERS: Info - Data table info 352208625Sjkim * 353208625Sjkim * RETURN: Field type 354208625Sjkim * 355208625Sjkim * DESCRIPTION: Get field type 356208625Sjkim * 357208625Sjkim *****************************************************************************/ 358208625Sjkim 359208625SjkimUINT8 360208625SjkimDtGetFieldType ( 361208625Sjkim ACPI_DMTABLE_INFO *Info) 362208625Sjkim{ 363208625Sjkim UINT8 Type; 364208625Sjkim 365208625Sjkim 366208625Sjkim /* DT_FLAG means that this is the start of a block of flag bits */ 367208625Sjkim /* TBD - we can make these a separate opcode later */ 368208625Sjkim 369208625Sjkim if (Info->Flags & DT_FLAG) 370208625Sjkim { 371208625Sjkim return (DT_FIELD_TYPE_FLAGS_INTEGER); 372208625Sjkim } 373208625Sjkim 374208625Sjkim /* Type is based upon the opcode for this field in the info table */ 375208625Sjkim 376208625Sjkim switch (Info->Opcode) 377208625Sjkim { 378208625Sjkim case ACPI_DMT_FLAG0: 379208625Sjkim case ACPI_DMT_FLAG1: 380208625Sjkim case ACPI_DMT_FLAG2: 381208625Sjkim case ACPI_DMT_FLAG3: 382208625Sjkim case ACPI_DMT_FLAG4: 383208625Sjkim case ACPI_DMT_FLAG5: 384208625Sjkim case ACPI_DMT_FLAG6: 385208625Sjkim case ACPI_DMT_FLAG7: 386208625Sjkim case ACPI_DMT_FLAGS0: 387228110Sjkim case ACPI_DMT_FLAGS1: 388208625Sjkim case ACPI_DMT_FLAGS2: 389228110Sjkim case ACPI_DMT_FLAGS4: 390208625Sjkim Type = DT_FIELD_TYPE_FLAG; 391208625Sjkim break; 392208625Sjkim 393208625Sjkim case ACPI_DMT_NAME4: 394208625Sjkim case ACPI_DMT_SIG: 395208625Sjkim case ACPI_DMT_NAME6: 396208625Sjkim case ACPI_DMT_NAME8: 397208625Sjkim case ACPI_DMT_STRING: 398208625Sjkim Type = DT_FIELD_TYPE_STRING; 399208625Sjkim break; 400208625Sjkim 401208625Sjkim case ACPI_DMT_BUFFER: 402218590Sjkim case ACPI_DMT_BUF7: 403208625Sjkim case ACPI_DMT_BUF16: 404219707Sjkim case ACPI_DMT_BUF128: 405209734Sjkim case ACPI_DMT_PCI_PATH: 406208625Sjkim Type = DT_FIELD_TYPE_BUFFER; 407208625Sjkim break; 408208625Sjkim 409208625Sjkim case ACPI_DMT_GAS: 410208625Sjkim case ACPI_DMT_HESTNTFY: 411208625Sjkim Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 412208625Sjkim break; 413208625Sjkim 414217365Sjkim case ACPI_DMT_UNICODE: 415217365Sjkim Type = DT_FIELD_TYPE_UNICODE; 416217365Sjkim break; 417217365Sjkim 418217365Sjkim case ACPI_DMT_UUID: 419217365Sjkim Type = DT_FIELD_TYPE_UUID; 420217365Sjkim break; 421217365Sjkim 422217365Sjkim case ACPI_DMT_DEVICE_PATH: 423217365Sjkim Type = DT_FIELD_TYPE_DEVICE_PATH; 424217365Sjkim break; 425217365Sjkim 426218590Sjkim case ACPI_DMT_LABEL: 427218590Sjkim Type = DT_FIELD_TYPE_LABEL; 428218590Sjkim break; 429218590Sjkim 430208625Sjkim default: 431208625Sjkim Type = DT_FIELD_TYPE_INTEGER; 432208625Sjkim break; 433208625Sjkim } 434208625Sjkim 435208625Sjkim return (Type); 436208625Sjkim} 437208625Sjkim 438208625Sjkim 439208625Sjkim/****************************************************************************** 440208625Sjkim * 441208625Sjkim * FUNCTION: DtGetBufferLength 442208625Sjkim * 443208625Sjkim * PARAMETERS: Buffer - List of integers, 444208625Sjkim * for example "10 3A 4F 2E" 445208625Sjkim * 446208625Sjkim * RETURN: Count of integer 447208625Sjkim * 448208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers 449208625Sjkim * 450208625Sjkim *****************************************************************************/ 451208625Sjkim 452208625SjkimUINT32 453208625SjkimDtGetBufferLength ( 454208625Sjkim char *Buffer) 455208625Sjkim{ 456208625Sjkim UINT32 ByteLength = 0; 457208625Sjkim 458208625Sjkim 459208625Sjkim while (*Buffer) 460208625Sjkim { 461208625Sjkim if (*Buffer == ' ') 462208625Sjkim { 463208625Sjkim ByteLength++; 464208625Sjkim 465208625Sjkim while (*Buffer == ' ') 466208625Sjkim { 467208625Sjkim Buffer++; 468208625Sjkim } 469208625Sjkim } 470208625Sjkim 471208625Sjkim Buffer++; 472208625Sjkim } 473208625Sjkim 474208625Sjkim return (++ByteLength); 475208625Sjkim} 476208625Sjkim 477208625Sjkim 478208625Sjkim/****************************************************************************** 479208625Sjkim * 480208625Sjkim * FUNCTION: DtGetFieldLength 481208625Sjkim * 482220663Sjkim * PARAMETERS: Field - Current field 483208625Sjkim * Info - Data table info 484208625Sjkim * 485208625Sjkim * RETURN: Field length 486208625Sjkim * 487208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field 488208625Sjkim * 489209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable. 490209734Sjkim * 491208625Sjkim *****************************************************************************/ 492208625Sjkim 493208625SjkimUINT32 494208625SjkimDtGetFieldLength ( 495208625Sjkim DT_FIELD *Field, 496208625Sjkim ACPI_DMTABLE_INFO *Info) 497208625Sjkim{ 498208625Sjkim UINT32 ByteLength = 0; 499208625Sjkim char *Value; 500208625Sjkim 501208625Sjkim 502208625Sjkim /* Length is based upon the opcode for this field in the info table */ 503208625Sjkim 504208625Sjkim switch (Info->Opcode) 505208625Sjkim { 506208625Sjkim case ACPI_DMT_FLAG0: 507208625Sjkim case ACPI_DMT_FLAG1: 508208625Sjkim case ACPI_DMT_FLAG2: 509208625Sjkim case ACPI_DMT_FLAG3: 510208625Sjkim case ACPI_DMT_FLAG4: 511208625Sjkim case ACPI_DMT_FLAG5: 512208625Sjkim case ACPI_DMT_FLAG6: 513208625Sjkim case ACPI_DMT_FLAG7: 514208625Sjkim case ACPI_DMT_FLAGS0: 515228110Sjkim case ACPI_DMT_FLAGS1: 516208625Sjkim case ACPI_DMT_FLAGS2: 517228110Sjkim case ACPI_DMT_FLAGS4: 518218590Sjkim case ACPI_DMT_LABEL: 519228110Sjkim case ACPI_DMT_EXTRA_TEXT: 520208625Sjkim ByteLength = 0; 521208625Sjkim break; 522208625Sjkim 523208625Sjkim case ACPI_DMT_UINT8: 524208625Sjkim case ACPI_DMT_CHKSUM: 525208625Sjkim case ACPI_DMT_SPACEID: 526216471Sjkim case ACPI_DMT_ACCWIDTH: 527209734Sjkim case ACPI_DMT_IVRS: 528208625Sjkim case ACPI_DMT_MADT: 529228110Sjkim case ACPI_DMT_PMTT: 530208625Sjkim case ACPI_DMT_SRAT: 531208625Sjkim case ACPI_DMT_ASF: 532208625Sjkim case ACPI_DMT_HESTNTYP: 533208625Sjkim case ACPI_DMT_FADTPM: 534209734Sjkim case ACPI_DMT_EINJACT: 535209734Sjkim case ACPI_DMT_EINJINST: 536209734Sjkim case ACPI_DMT_ERSTACT: 537209734Sjkim case ACPI_DMT_ERSTINST: 538208625Sjkim ByteLength = 1; 539208625Sjkim break; 540208625Sjkim 541208625Sjkim case ACPI_DMT_UINT16: 542208625Sjkim case ACPI_DMT_DMAR: 543208625Sjkim case ACPI_DMT_HEST: 544208625Sjkim case ACPI_DMT_PCI_PATH: 545208625Sjkim ByteLength = 2; 546208625Sjkim break; 547208625Sjkim 548208625Sjkim case ACPI_DMT_UINT24: 549208625Sjkim ByteLength = 3; 550208625Sjkim break; 551208625Sjkim 552208625Sjkim case ACPI_DMT_UINT32: 553208625Sjkim case ACPI_DMT_NAME4: 554219707Sjkim case ACPI_DMT_SLIC: 555208625Sjkim case ACPI_DMT_SIG: 556208625Sjkim ByteLength = 4; 557208625Sjkim break; 558208625Sjkim 559228110Sjkim case ACPI_DMT_UINT40: 560228110Sjkim ByteLength = 5; 561228110Sjkim break; 562228110Sjkim 563228110Sjkim case ACPI_DMT_UINT48: 564208625Sjkim case ACPI_DMT_NAME6: 565208625Sjkim ByteLength = 6; 566208625Sjkim break; 567208625Sjkim 568208625Sjkim case ACPI_DMT_UINT56: 569218590Sjkim case ACPI_DMT_BUF7: 570208625Sjkim ByteLength = 7; 571208625Sjkim break; 572208625Sjkim 573208625Sjkim case ACPI_DMT_UINT64: 574208625Sjkim case ACPI_DMT_NAME8: 575208625Sjkim ByteLength = 8; 576208625Sjkim break; 577208625Sjkim 578208625Sjkim case ACPI_DMT_STRING: 579220663Sjkim Value = DtGetFieldValue (Field); 580217365Sjkim if (Value) 581217365Sjkim { 582217365Sjkim ByteLength = ACPI_STRLEN (Value) + 1; 583217365Sjkim } 584217365Sjkim else 585217365Sjkim { /* At this point, this is a fatal error */ 586208625Sjkim 587217365Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 588217365Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 589220663Sjkim return (0); 590217365Sjkim } 591208625Sjkim break; 592208625Sjkim 593208625Sjkim case ACPI_DMT_GAS: 594208625Sjkim ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 595208625Sjkim break; 596208625Sjkim 597208625Sjkim case ACPI_DMT_HESTNTFY: 598208625Sjkim ByteLength = sizeof (ACPI_HEST_NOTIFY); 599208625Sjkim break; 600208625Sjkim 601208625Sjkim case ACPI_DMT_BUFFER: 602220663Sjkim Value = DtGetFieldValue (Field); 603208625Sjkim if (Value) 604208625Sjkim { 605208625Sjkim ByteLength = DtGetBufferLength (Value); 606208625Sjkim } 607208625Sjkim else 608208625Sjkim { /* At this point, this is a fatal error */ 609208625Sjkim 610208625Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 611208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 612220663Sjkim return (0); 613208625Sjkim } 614208625Sjkim break; 615208625Sjkim 616208625Sjkim case ACPI_DMT_BUF16: 617217365Sjkim case ACPI_DMT_UUID: 618208625Sjkim ByteLength = 16; 619208625Sjkim break; 620208625Sjkim 621219707Sjkim case ACPI_DMT_BUF128: 622219707Sjkim ByteLength = 128; 623219707Sjkim break; 624219707Sjkim 625217365Sjkim case ACPI_DMT_UNICODE: 626220663Sjkim Value = DtGetFieldValue (Field); 627217365Sjkim 628217365Sjkim /* TBD: error if Value is NULL? (as below?) */ 629217365Sjkim 630217365Sjkim ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16); 631217365Sjkim break; 632217365Sjkim 633208625Sjkim default: 634208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 635220663Sjkim return (0); 636208625Sjkim } 637208625Sjkim 638208625Sjkim return (ByteLength); 639208625Sjkim} 640208625Sjkim 641208625Sjkim 642208625Sjkim/****************************************************************************** 643208625Sjkim * 644208625Sjkim * FUNCTION: DtSum 645208625Sjkim * 646208625Sjkim * PARAMETERS: DT_WALK_CALLBACK: 647208625Sjkim * Subtable - Subtable 648208625Sjkim * Context - Unused 649208625Sjkim * ReturnValue - Store the checksum of subtable 650208625Sjkim * 651208625Sjkim * RETURN: Status 652208625Sjkim * 653208625Sjkim * DESCRIPTION: Get the checksum of subtable 654208625Sjkim * 655208625Sjkim *****************************************************************************/ 656208625Sjkim 657208625Sjkimstatic void 658208625SjkimDtSum ( 659208625Sjkim DT_SUBTABLE *Subtable, 660208625Sjkim void *Context, 661208625Sjkim void *ReturnValue) 662208625Sjkim{ 663208625Sjkim UINT8 Checksum; 664208625Sjkim UINT8 *Sum = ReturnValue; 665208625Sjkim 666208625Sjkim 667208625Sjkim Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 668208625Sjkim *Sum = (UINT8) (*Sum + Checksum); 669208625Sjkim} 670208625Sjkim 671208625Sjkim 672208625Sjkim/****************************************************************************** 673208625Sjkim * 674208625Sjkim * FUNCTION: DtSetTableChecksum 675208625Sjkim * 676208625Sjkim * PARAMETERS: ChecksumPointer - Where to return the checksum 677208625Sjkim * 678208625Sjkim * RETURN: None 679208625Sjkim * 680208625Sjkim * DESCRIPTION: Set checksum of the whole data table into the checksum field 681208625Sjkim * 682208625Sjkim *****************************************************************************/ 683208625Sjkim 684208625Sjkimvoid 685208625SjkimDtSetTableChecksum ( 686208625Sjkim UINT8 *ChecksumPointer) 687208625Sjkim{ 688208625Sjkim UINT8 Checksum = 0; 689208625Sjkim UINT8 OldSum; 690208625Sjkim 691208625Sjkim 692208625Sjkim DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 693208625Sjkim 694208625Sjkim OldSum = *ChecksumPointer; 695208625Sjkim Checksum = (UINT8) (Checksum - OldSum); 696208625Sjkim 697208625Sjkim /* Compute the final checksum */ 698208625Sjkim 699208625Sjkim Checksum = (UINT8) (0 - Checksum); 700208625Sjkim *ChecksumPointer = Checksum; 701208625Sjkim} 702208625Sjkim 703208625Sjkim 704208625Sjkim/****************************************************************************** 705208625Sjkim * 706208625Sjkim * FUNCTION: DtSetTableLength 707208625Sjkim * 708208625Sjkim * PARAMETERS: None 709208625Sjkim * 710208625Sjkim * RETURN: None 711208625Sjkim * 712208625Sjkim * DESCRIPTION: Walk the subtables and set all the length fields 713208625Sjkim * 714208625Sjkim *****************************************************************************/ 715208625Sjkim 716208625Sjkimvoid 717208625SjkimDtSetTableLength ( 718208625Sjkim void) 719208625Sjkim{ 720208625Sjkim DT_SUBTABLE *ParentTable; 721208625Sjkim DT_SUBTABLE *ChildTable; 722208625Sjkim 723208625Sjkim 724208625Sjkim ParentTable = Gbl_RootTable; 725208625Sjkim ChildTable = NULL; 726208625Sjkim 727208625Sjkim if (!ParentTable) 728208625Sjkim { 729208625Sjkim return; 730208625Sjkim } 731208625Sjkim 732208625Sjkim DtSetSubtableLength (ParentTable); 733208625Sjkim 734208625Sjkim while (1) 735208625Sjkim { 736208625Sjkim ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 737208625Sjkim if (ChildTable) 738208625Sjkim { 739209734Sjkim if (ChildTable->LengthField) 740209734Sjkim { 741209734Sjkim DtSetSubtableLength (ChildTable); 742209734Sjkim } 743209734Sjkim 744208625Sjkim if (ChildTable->Child) 745208625Sjkim { 746208625Sjkim ParentTable = ChildTable; 747208625Sjkim ChildTable = NULL; 748208625Sjkim } 749208625Sjkim else 750208625Sjkim { 751208625Sjkim ParentTable->TotalLength += ChildTable->TotalLength; 752208625Sjkim if (ParentTable->LengthField) 753208625Sjkim { 754208625Sjkim DtSetSubtableLength (ParentTable); 755208625Sjkim } 756208625Sjkim } 757208625Sjkim } 758208625Sjkim else 759208625Sjkim { 760208625Sjkim ChildTable = ParentTable; 761208625Sjkim 762208625Sjkim if (ChildTable == Gbl_RootTable) 763208625Sjkim { 764208625Sjkim break; 765208625Sjkim } 766208625Sjkim 767208625Sjkim ParentTable = DtGetParentSubtable (ParentTable); 768208625Sjkim 769208625Sjkim ParentTable->TotalLength += ChildTable->TotalLength; 770208625Sjkim if (ParentTable->LengthField) 771208625Sjkim { 772208625Sjkim DtSetSubtableLength (ParentTable); 773208625Sjkim } 774208625Sjkim } 775208625Sjkim } 776208625Sjkim} 777208625Sjkim 778208625Sjkim 779208625Sjkim/****************************************************************************** 780208625Sjkim * 781208625Sjkim * FUNCTION: DtWalkTableTree 782208625Sjkim * 783208625Sjkim * PARAMETERS: StartTable - Subtable in the tree where walking begins 784208625Sjkim * UserFunction - Called during the walk 785208625Sjkim * Context - Passed to user function 786208625Sjkim * ReturnValue - The return value of UserFunction 787208625Sjkim * 788208625Sjkim * RETURN: None 789208625Sjkim * 790208625Sjkim * DESCRIPTION: Performs a depth-first walk of the subtable tree 791208625Sjkim * 792208625Sjkim *****************************************************************************/ 793208625Sjkim 794208625Sjkimvoid 795208625SjkimDtWalkTableTree ( 796208625Sjkim DT_SUBTABLE *StartTable, 797208625Sjkim DT_WALK_CALLBACK UserFunction, 798208625Sjkim void *Context, 799208625Sjkim void *ReturnValue) 800208625Sjkim{ 801208625Sjkim DT_SUBTABLE *ParentTable; 802208625Sjkim DT_SUBTABLE *ChildTable; 803208625Sjkim 804208625Sjkim 805208625Sjkim ParentTable = StartTable; 806208625Sjkim ChildTable = NULL; 807208625Sjkim 808208625Sjkim if (!ParentTable) 809208625Sjkim { 810208625Sjkim return; 811208625Sjkim } 812208625Sjkim 813208625Sjkim UserFunction (ParentTable, Context, ReturnValue); 814208625Sjkim 815208625Sjkim while (1) 816208625Sjkim { 817208625Sjkim ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 818208625Sjkim if (ChildTable) 819208625Sjkim { 820208625Sjkim UserFunction (ChildTable, Context, ReturnValue); 821208625Sjkim 822208625Sjkim if (ChildTable->Child) 823208625Sjkim { 824208625Sjkim ParentTable = ChildTable; 825208625Sjkim ChildTable = NULL; 826208625Sjkim } 827208625Sjkim } 828208625Sjkim else 829208625Sjkim { 830208625Sjkim ChildTable = ParentTable; 831208625Sjkim if (ChildTable == Gbl_RootTable) 832208625Sjkim { 833208625Sjkim break; 834208625Sjkim } 835208625Sjkim 836208625Sjkim ParentTable = DtGetParentSubtable (ParentTable); 837208625Sjkim 838208625Sjkim if (ChildTable->Peer == StartTable) 839208625Sjkim { 840208625Sjkim break; 841208625Sjkim } 842208625Sjkim } 843208625Sjkim } 844208625Sjkim} 845208625Sjkim 846208625Sjkim 847208625Sjkim/****************************************************************************** 848208625Sjkim * 849208625Sjkim * FUNCTION: DtFreeFieldList 850208625Sjkim * 851208625Sjkim * PARAMETERS: None 852208625Sjkim * 853208625Sjkim * RETURN: None 854208625Sjkim * 855208625Sjkim * DESCRIPTION: Free the field list 856208625Sjkim * 857208625Sjkim *****************************************************************************/ 858208625Sjkim 859208625Sjkimvoid 860208625SjkimDtFreeFieldList ( 861208625Sjkim void) 862208625Sjkim{ 863208625Sjkim DT_FIELD *Field = Gbl_FieldList; 864208625Sjkim DT_FIELD *NextField; 865208625Sjkim 866208625Sjkim 867208625Sjkim /* Walk and free entire field list */ 868208625Sjkim 869208625Sjkim while (Field) 870208625Sjkim { 871208625Sjkim NextField = Field->Next; /* Save link */ 872208625Sjkim 873208625Sjkim if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED)) 874208625Sjkim { 875208625Sjkim ACPI_FREE (Field->Name); 876208625Sjkim ACPI_FREE (Field->Value); 877208625Sjkim } 878208625Sjkim 879208625Sjkim ACPI_FREE (Field); 880208625Sjkim Field = NextField; 881208625Sjkim } 882208625Sjkim} 883