dtutils.c revision 250838
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: 400208625Sjkim case ACPI_DMT_BUF16: 401219707Sjkim case ACPI_DMT_BUF128: 402209734Sjkim case ACPI_DMT_PCI_PATH: 403250838Sjkim 404208625Sjkim Type = DT_FIELD_TYPE_BUFFER; 405208625Sjkim break; 406208625Sjkim 407208625Sjkim case ACPI_DMT_GAS: 408208625Sjkim case ACPI_DMT_HESTNTFY: 409250838Sjkim 410208625Sjkim Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 411208625Sjkim break; 412208625Sjkim 413217365Sjkim case ACPI_DMT_UNICODE: 414250838Sjkim 415217365Sjkim Type = DT_FIELD_TYPE_UNICODE; 416217365Sjkim break; 417217365Sjkim 418217365Sjkim case ACPI_DMT_UUID: 419250838Sjkim 420217365Sjkim Type = DT_FIELD_TYPE_UUID; 421217365Sjkim break; 422217365Sjkim 423217365Sjkim case ACPI_DMT_DEVICE_PATH: 424250838Sjkim 425217365Sjkim Type = DT_FIELD_TYPE_DEVICE_PATH; 426217365Sjkim break; 427217365Sjkim 428218590Sjkim case ACPI_DMT_LABEL: 429250838Sjkim 430218590Sjkim Type = DT_FIELD_TYPE_LABEL; 431218590Sjkim break; 432218590Sjkim 433208625Sjkim default: 434250838Sjkim 435208625Sjkim Type = DT_FIELD_TYPE_INTEGER; 436208625Sjkim break; 437208625Sjkim } 438208625Sjkim 439208625Sjkim return (Type); 440208625Sjkim} 441208625Sjkim 442208625Sjkim 443208625Sjkim/****************************************************************************** 444208625Sjkim * 445208625Sjkim * FUNCTION: DtGetBufferLength 446208625Sjkim * 447208625Sjkim * PARAMETERS: Buffer - List of integers, 448208625Sjkim * for example "10 3A 4F 2E" 449208625Sjkim * 450208625Sjkim * RETURN: Count of integer 451208625Sjkim * 452208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers 453208625Sjkim * 454208625Sjkim *****************************************************************************/ 455208625Sjkim 456208625SjkimUINT32 457208625SjkimDtGetBufferLength ( 458208625Sjkim char *Buffer) 459208625Sjkim{ 460208625Sjkim UINT32 ByteLength = 0; 461208625Sjkim 462208625Sjkim 463208625Sjkim while (*Buffer) 464208625Sjkim { 465208625Sjkim if (*Buffer == ' ') 466208625Sjkim { 467208625Sjkim ByteLength++; 468208625Sjkim 469208625Sjkim while (*Buffer == ' ') 470208625Sjkim { 471208625Sjkim Buffer++; 472208625Sjkim } 473208625Sjkim } 474208625Sjkim 475208625Sjkim Buffer++; 476208625Sjkim } 477208625Sjkim 478208625Sjkim return (++ByteLength); 479208625Sjkim} 480208625Sjkim 481208625Sjkim 482208625Sjkim/****************************************************************************** 483208625Sjkim * 484208625Sjkim * FUNCTION: DtGetFieldLength 485208625Sjkim * 486220663Sjkim * PARAMETERS: Field - Current field 487208625Sjkim * Info - Data table info 488208625Sjkim * 489208625Sjkim * RETURN: Field length 490208625Sjkim * 491208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field 492208625Sjkim * 493209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable. 494209734Sjkim * 495208625Sjkim *****************************************************************************/ 496208625Sjkim 497208625SjkimUINT32 498208625SjkimDtGetFieldLength ( 499208625Sjkim DT_FIELD *Field, 500208625Sjkim ACPI_DMTABLE_INFO *Info) 501208625Sjkim{ 502208625Sjkim UINT32 ByteLength = 0; 503208625Sjkim char *Value; 504208625Sjkim 505208625Sjkim 506208625Sjkim /* Length is based upon the opcode for this field in the info table */ 507208625Sjkim 508208625Sjkim switch (Info->Opcode) 509208625Sjkim { 510208625Sjkim case ACPI_DMT_FLAG0: 511208625Sjkim case ACPI_DMT_FLAG1: 512208625Sjkim case ACPI_DMT_FLAG2: 513208625Sjkim case ACPI_DMT_FLAG3: 514208625Sjkim case ACPI_DMT_FLAG4: 515208625Sjkim case ACPI_DMT_FLAG5: 516208625Sjkim case ACPI_DMT_FLAG6: 517208625Sjkim case ACPI_DMT_FLAG7: 518208625Sjkim case ACPI_DMT_FLAGS0: 519228110Sjkim case ACPI_DMT_FLAGS1: 520208625Sjkim case ACPI_DMT_FLAGS2: 521228110Sjkim case ACPI_DMT_FLAGS4: 522218590Sjkim case ACPI_DMT_LABEL: 523228110Sjkim case ACPI_DMT_EXTRA_TEXT: 524250838Sjkim 525208625Sjkim ByteLength = 0; 526208625Sjkim break; 527208625Sjkim 528208625Sjkim case ACPI_DMT_UINT8: 529208625Sjkim case ACPI_DMT_CHKSUM: 530208625Sjkim case ACPI_DMT_SPACEID: 531216471Sjkim case ACPI_DMT_ACCWIDTH: 532209734Sjkim case ACPI_DMT_IVRS: 533208625Sjkim case ACPI_DMT_MADT: 534228110Sjkim case ACPI_DMT_PMTT: 535208625Sjkim case ACPI_DMT_SRAT: 536208625Sjkim case ACPI_DMT_ASF: 537208625Sjkim case ACPI_DMT_HESTNTYP: 538208625Sjkim case ACPI_DMT_FADTPM: 539209734Sjkim case ACPI_DMT_EINJACT: 540209734Sjkim case ACPI_DMT_EINJINST: 541209734Sjkim case ACPI_DMT_ERSTACT: 542209734Sjkim case ACPI_DMT_ERSTINST: 543250838Sjkim 544208625Sjkim ByteLength = 1; 545208625Sjkim break; 546208625Sjkim 547208625Sjkim case ACPI_DMT_UINT16: 548208625Sjkim case ACPI_DMT_DMAR: 549208625Sjkim case ACPI_DMT_HEST: 550208625Sjkim case ACPI_DMT_PCI_PATH: 551250838Sjkim 552208625Sjkim ByteLength = 2; 553208625Sjkim break; 554208625Sjkim 555208625Sjkim case ACPI_DMT_UINT24: 556250838Sjkim 557208625Sjkim ByteLength = 3; 558208625Sjkim break; 559208625Sjkim 560208625Sjkim case ACPI_DMT_UINT32: 561208625Sjkim case ACPI_DMT_NAME4: 562219707Sjkim case ACPI_DMT_SLIC: 563208625Sjkim case ACPI_DMT_SIG: 564250838Sjkim 565208625Sjkim ByteLength = 4; 566208625Sjkim break; 567208625Sjkim 568228110Sjkim case ACPI_DMT_UINT40: 569250838Sjkim 570228110Sjkim ByteLength = 5; 571228110Sjkim break; 572228110Sjkim 573228110Sjkim case ACPI_DMT_UINT48: 574208625Sjkim case ACPI_DMT_NAME6: 575250838Sjkim 576208625Sjkim ByteLength = 6; 577208625Sjkim break; 578208625Sjkim 579208625Sjkim case ACPI_DMT_UINT56: 580218590Sjkim case ACPI_DMT_BUF7: 581250838Sjkim 582208625Sjkim ByteLength = 7; 583208625Sjkim break; 584208625Sjkim 585208625Sjkim case ACPI_DMT_UINT64: 586208625Sjkim case ACPI_DMT_NAME8: 587250838Sjkim 588208625Sjkim ByteLength = 8; 589208625Sjkim break; 590208625Sjkim 591208625Sjkim case ACPI_DMT_STRING: 592250838Sjkim 593220663Sjkim Value = DtGetFieldValue (Field); 594217365Sjkim if (Value) 595217365Sjkim { 596217365Sjkim ByteLength = ACPI_STRLEN (Value) + 1; 597217365Sjkim } 598217365Sjkim else 599217365Sjkim { /* At this point, this is a fatal error */ 600208625Sjkim 601217365Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 602217365Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 603220663Sjkim return (0); 604217365Sjkim } 605208625Sjkim break; 606208625Sjkim 607208625Sjkim case ACPI_DMT_GAS: 608250838Sjkim 609208625Sjkim ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 610208625Sjkim break; 611208625Sjkim 612208625Sjkim case ACPI_DMT_HESTNTFY: 613250838Sjkim 614208625Sjkim ByteLength = sizeof (ACPI_HEST_NOTIFY); 615208625Sjkim break; 616208625Sjkim 617208625Sjkim case ACPI_DMT_BUFFER: 618250838Sjkim 619220663Sjkim Value = DtGetFieldValue (Field); 620208625Sjkim if (Value) 621208625Sjkim { 622208625Sjkim ByteLength = DtGetBufferLength (Value); 623208625Sjkim } 624208625Sjkim else 625208625Sjkim { /* At this point, this is a fatal error */ 626208625Sjkim 627208625Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 628208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 629220663Sjkim return (0); 630208625Sjkim } 631208625Sjkim break; 632208625Sjkim 633208625Sjkim case ACPI_DMT_BUF16: 634217365Sjkim case ACPI_DMT_UUID: 635250838Sjkim 636208625Sjkim ByteLength = 16; 637208625Sjkim break; 638208625Sjkim 639219707Sjkim case ACPI_DMT_BUF128: 640250838Sjkim 641219707Sjkim ByteLength = 128; 642219707Sjkim break; 643219707Sjkim 644217365Sjkim case ACPI_DMT_UNICODE: 645250838Sjkim 646220663Sjkim Value = DtGetFieldValue (Field); 647217365Sjkim 648217365Sjkim /* TBD: error if Value is NULL? (as below?) */ 649217365Sjkim 650217365Sjkim ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16); 651217365Sjkim break; 652217365Sjkim 653208625Sjkim default: 654250838Sjkim 655208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 656220663Sjkim return (0); 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