1208625Sjkim/****************************************************************************** 2208625Sjkim * 3208625Sjkim * Module Name: dtutils.c - Utility routines for the data table compiler 4208625Sjkim * 5208625Sjkim *****************************************************************************/ 6208625Sjkim 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 44209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 45209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h> 46209746Sjkim#include <contrib/dev/acpica/include/actables.h> 47208625Sjkim 48208625Sjkim#define _COMPONENT DT_COMPILER 49208625Sjkim ACPI_MODULE_NAME ("dtutils") 50208625Sjkim 51208625Sjkim/* Local prototypes */ 52208625Sjkim 53208625Sjkimstatic void 54208625SjkimDtSum ( 55208625Sjkim DT_SUBTABLE *Subtable, 56208625Sjkim void *Context, 57208625Sjkim void *ReturnValue); 58208625Sjkim 59208625Sjkim 60208625Sjkim/****************************************************************************** 61208625Sjkim * 62208625Sjkim * FUNCTION: DtError 63208625Sjkim * 64208625Sjkim * PARAMETERS: Level - Seriousness (Warning/error, etc.) 65208625Sjkim * MessageId - Index into global message buffer 66208625Sjkim * Op - Parse node where error happened 67208625Sjkim * ExtraMessage - additional error message 68208625Sjkim * 69208625Sjkim * RETURN: None 70208625Sjkim * 71208625Sjkim * DESCRIPTION: Common error interface for data table compiler 72208625Sjkim * 73208625Sjkim *****************************************************************************/ 74208625Sjkim 75208625Sjkimvoid 76208625SjkimDtError ( 77208625Sjkim UINT8 Level, 78281075Sdim UINT16 MessageId, 79208625Sjkim DT_FIELD *FieldObject, 80208625Sjkim char *ExtraMessage) 81208625Sjkim{ 82208625Sjkim 83250838Sjkim /* Check if user wants to ignore this exception */ 84250838Sjkim 85250838Sjkim if (AslIsExceptionDisabled (Level, MessageId)) 86208625Sjkim { 87250838Sjkim return; 88208625Sjkim } 89208625Sjkim 90208625Sjkim if (FieldObject) 91208625Sjkim { 92208625Sjkim AslCommonError (Level, MessageId, 93208625Sjkim FieldObject->Line, 94208625Sjkim FieldObject->Line, 95208625Sjkim FieldObject->ByteOffset, 96208625Sjkim FieldObject->Column, 97208625Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 98208625Sjkim } 99208625Sjkim else 100208625Sjkim { 101208625Sjkim AslCommonError (Level, MessageId, 0, 102208625Sjkim 0, 0, 0, 0, ExtraMessage); 103208625Sjkim } 104208625Sjkim} 105208625Sjkim 106208625Sjkim 107208625Sjkim/****************************************************************************** 108208625Sjkim * 109208625Sjkim * FUNCTION: DtNameError 110208625Sjkim * 111208625Sjkim * PARAMETERS: Level - Seriousness (Warning/error, etc.) 112208625Sjkim * MessageId - Index into global message buffer 113208625Sjkim * Op - Parse node where error happened 114208625Sjkim * ExtraMessage - additional error message 115208625Sjkim * 116208625Sjkim * RETURN: None 117208625Sjkim * 118208625Sjkim * DESCRIPTION: Error interface for named objects 119208625Sjkim * 120208625Sjkim *****************************************************************************/ 121208625Sjkim 122208625Sjkimvoid 123208625SjkimDtNameError ( 124208625Sjkim UINT8 Level, 125281075Sdim UINT16 MessageId, 126208625Sjkim DT_FIELD *FieldObject, 127208625Sjkim char *ExtraMessage) 128208625Sjkim{ 129208625Sjkim 130208625Sjkim switch (Level) 131208625Sjkim { 132208625Sjkim case ASL_WARNING2: 133208625Sjkim case ASL_WARNING3: 134250838Sjkim 135208625Sjkim if (Gbl_WarningLevel < Level) 136208625Sjkim { 137208625Sjkim return; 138208625Sjkim } 139208625Sjkim break; 140208625Sjkim 141208625Sjkim default: 142250838Sjkim 143208625Sjkim break; 144208625Sjkim } 145208625Sjkim 146208625Sjkim if (FieldObject) 147208625Sjkim { 148208625Sjkim AslCommonError (Level, MessageId, 149208625Sjkim FieldObject->Line, 150208625Sjkim FieldObject->Line, 151208625Sjkim FieldObject->ByteOffset, 152208625Sjkim FieldObject->NameColumn, 153208625Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 154208625Sjkim } 155208625Sjkim else 156208625Sjkim { 157208625Sjkim AslCommonError (Level, MessageId, 0, 158208625Sjkim 0, 0, 0, 0, ExtraMessage); 159208625Sjkim } 160208625Sjkim} 161208625Sjkim 162208625Sjkim 163208625Sjkim/******************************************************************************* 164208625Sjkim * 165208625Sjkim * FUNCTION: DtFatal 166208625Sjkim * 167208625Sjkim * PARAMETERS: None 168208625Sjkim * 169208625Sjkim * RETURN: None 170208625Sjkim * 171208625Sjkim * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 172208625Sjkim * compile or I/O errors 173208625Sjkim * 174208625Sjkim ******************************************************************************/ 175208625Sjkim 176208625Sjkimvoid 177208625SjkimDtFatal ( 178281075Sdim UINT16 MessageId, 179208625Sjkim DT_FIELD *FieldObject, 180208625Sjkim char *ExtraMessage) 181208625Sjkim{ 182208625Sjkim 183208625Sjkim DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage); 184208625Sjkim 185220663Sjkim/* 186220663Sjkim * TBD: remove this entire function, DtFatal 187220663Sjkim * 188220663Sjkim * We cannot abort the compiler on error, because we may be compiling a 189220663Sjkim * list of files. We must move on to the next file. 190220663Sjkim */ 191220663Sjkim#ifdef __OBSOLETE 192208625Sjkim CmCleanupAndExit (); 193208625Sjkim exit (1); 194220663Sjkim#endif 195208625Sjkim} 196208625Sjkim 197208625Sjkim 198208625Sjkim/****************************************************************************** 199208625Sjkim * 200208625Sjkim * FUNCTION: DtStrtoul64 201208625Sjkim * 202208625Sjkim * PARAMETERS: String - Null terminated string 203208625Sjkim * ReturnInteger - Where the converted integer is returned 204208625Sjkim * 205208625Sjkim * RETURN: Status 206208625Sjkim * 207208625Sjkim * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned 208208625Sjkim * value. Assumes no leading "0x" for the constant. 209208625Sjkim * 210208625Sjkim * Portability note: The reason this function exists is because a 64-bit 211208625Sjkim * sscanf is not available in all environments. 212208625Sjkim * 213208625Sjkim *****************************************************************************/ 214208625Sjkim 215208625SjkimACPI_STATUS 216208625SjkimDtStrtoul64 ( 217208625Sjkim char *String, 218208625Sjkim UINT64 *ReturnInteger) 219208625Sjkim{ 220208625Sjkim char *ThisChar = String; 221208625Sjkim UINT32 ThisDigit; 222208625Sjkim UINT64 ReturnValue = 0; 223208625Sjkim int DigitCount = 0; 224208625Sjkim 225208625Sjkim 226208625Sjkim /* Skip over any white space in the buffer */ 227208625Sjkim 228208625Sjkim while ((*ThisChar == ' ') || (*ThisChar == '\t')) 229208625Sjkim { 230208625Sjkim ThisChar++; 231208625Sjkim } 232208625Sjkim 233208625Sjkim /* Skip leading zeros */ 234208625Sjkim 235208625Sjkim while ((*ThisChar) == '0') 236208625Sjkim { 237208625Sjkim ThisChar++; 238208625Sjkim } 239208625Sjkim 240208625Sjkim /* Convert character-by-character */ 241208625Sjkim 242208625Sjkim while (*ThisChar) 243208625Sjkim { 244306536Sjkim if (isdigit ((int) *ThisChar)) 245208625Sjkim { 246208625Sjkim /* Convert ASCII 0-9 to Decimal value */ 247208625Sjkim 248208625Sjkim ThisDigit = ((UINT8) *ThisChar) - '0'; 249208625Sjkim } 250208625Sjkim else /* Letter */ 251208625Sjkim { 252306536Sjkim ThisDigit = (UINT32) toupper ((int) *ThisChar); 253306536Sjkim if (!isxdigit ((int) ThisDigit)) 254208625Sjkim { 255208625Sjkim /* Not A-F */ 256208625Sjkim 257208625Sjkim return (AE_BAD_CHARACTER); 258208625Sjkim } 259208625Sjkim 260208625Sjkim /* Convert ASCII Hex char (A-F) to value */ 261208625Sjkim 262208625Sjkim ThisDigit = (ThisDigit - 'A') + 10; 263208625Sjkim } 264208625Sjkim 265208625Sjkim /* Insert the 4-bit hex digit */ 266208625Sjkim 267208625Sjkim ReturnValue <<= 4; 268208625Sjkim ReturnValue += ThisDigit; 269208625Sjkim 270208625Sjkim ThisChar++; 271208625Sjkim DigitCount++; 272208625Sjkim if (DigitCount > 16) 273208625Sjkim { 274208625Sjkim /* Value is too large (> 64 bits/8 bytes/16 hex digits) */ 275208625Sjkim 276208625Sjkim return (AE_LIMIT); 277208625Sjkim } 278208625Sjkim } 279208625Sjkim 280208625Sjkim *ReturnInteger = ReturnValue; 281208625Sjkim return (AE_OK); 282208625Sjkim} 283208625Sjkim 284208625Sjkim 285208625Sjkim/****************************************************************************** 286208625Sjkim * 287208625Sjkim * FUNCTION: DtGetFieldValue 288208625Sjkim * 289208625Sjkim * PARAMETERS: Field - Current field list pointer 290208625Sjkim * 291208625Sjkim * RETURN: Field value 292208625Sjkim * 293208625Sjkim * DESCRIPTION: Get field value 294208625Sjkim * 295208625Sjkim *****************************************************************************/ 296208625Sjkim 297208625Sjkimchar * 298208625SjkimDtGetFieldValue ( 299220663Sjkim DT_FIELD *Field) 300208625Sjkim{ 301220663Sjkim if (!Field) 302208625Sjkim { 303220663Sjkim return (NULL); 304208625Sjkim } 305208625Sjkim 306220663Sjkim return (Field->Value); 307208625Sjkim} 308208625Sjkim 309208625Sjkim 310208625Sjkim/****************************************************************************** 311208625Sjkim * 312208625Sjkim * FUNCTION: DtGetFieldType 313208625Sjkim * 314208625Sjkim * PARAMETERS: Info - Data table info 315208625Sjkim * 316208625Sjkim * RETURN: Field type 317208625Sjkim * 318208625Sjkim * DESCRIPTION: Get field type 319208625Sjkim * 320208625Sjkim *****************************************************************************/ 321208625Sjkim 322208625SjkimUINT8 323208625SjkimDtGetFieldType ( 324208625Sjkim ACPI_DMTABLE_INFO *Info) 325208625Sjkim{ 326208625Sjkim UINT8 Type; 327208625Sjkim 328208625Sjkim 329208625Sjkim /* DT_FLAG means that this is the start of a block of flag bits */ 330208625Sjkim /* TBD - we can make these a separate opcode later */ 331208625Sjkim 332208625Sjkim if (Info->Flags & DT_FLAG) 333208625Sjkim { 334208625Sjkim return (DT_FIELD_TYPE_FLAGS_INTEGER); 335208625Sjkim } 336208625Sjkim 337208625Sjkim /* Type is based upon the opcode for this field in the info table */ 338208625Sjkim 339208625Sjkim switch (Info->Opcode) 340208625Sjkim { 341208625Sjkim case ACPI_DMT_FLAG0: 342208625Sjkim case ACPI_DMT_FLAG1: 343208625Sjkim case ACPI_DMT_FLAG2: 344208625Sjkim case ACPI_DMT_FLAG3: 345208625Sjkim case ACPI_DMT_FLAG4: 346208625Sjkim case ACPI_DMT_FLAG5: 347208625Sjkim case ACPI_DMT_FLAG6: 348208625Sjkim case ACPI_DMT_FLAG7: 349208625Sjkim case ACPI_DMT_FLAGS0: 350228110Sjkim case ACPI_DMT_FLAGS1: 351208625Sjkim case ACPI_DMT_FLAGS2: 352228110Sjkim case ACPI_DMT_FLAGS4: 353250838Sjkim 354208625Sjkim Type = DT_FIELD_TYPE_FLAG; 355208625Sjkim break; 356208625Sjkim 357208625Sjkim case ACPI_DMT_NAME4: 358208625Sjkim case ACPI_DMT_SIG: 359208625Sjkim case ACPI_DMT_NAME6: 360208625Sjkim case ACPI_DMT_NAME8: 361208625Sjkim case ACPI_DMT_STRING: 362250838Sjkim 363208625Sjkim Type = DT_FIELD_TYPE_STRING; 364208625Sjkim break; 365208625Sjkim 366208625Sjkim case ACPI_DMT_BUFFER: 367281687Sjkim case ACPI_DMT_RAW_BUFFER: 368218590Sjkim case ACPI_DMT_BUF7: 369252279Sjkim case ACPI_DMT_BUF10: 370208625Sjkim case ACPI_DMT_BUF16: 371219707Sjkim case ACPI_DMT_BUF128: 372209734Sjkim case ACPI_DMT_PCI_PATH: 373250838Sjkim 374208625Sjkim Type = DT_FIELD_TYPE_BUFFER; 375208625Sjkim break; 376208625Sjkim 377208625Sjkim case ACPI_DMT_GAS: 378208625Sjkim case ACPI_DMT_HESTNTFY: 379284460Sjkim case ACPI_DMT_IORTMEM: 380250838Sjkim 381208625Sjkim Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 382208625Sjkim break; 383208625Sjkim 384217365Sjkim case ACPI_DMT_UNICODE: 385250838Sjkim 386217365Sjkim Type = DT_FIELD_TYPE_UNICODE; 387217365Sjkim break; 388217365Sjkim 389217365Sjkim case ACPI_DMT_UUID: 390250838Sjkim 391217365Sjkim Type = DT_FIELD_TYPE_UUID; 392217365Sjkim break; 393217365Sjkim 394217365Sjkim case ACPI_DMT_DEVICE_PATH: 395250838Sjkim 396217365Sjkim Type = DT_FIELD_TYPE_DEVICE_PATH; 397217365Sjkim break; 398217365Sjkim 399218590Sjkim case ACPI_DMT_LABEL: 400250838Sjkim 401218590Sjkim Type = DT_FIELD_TYPE_LABEL; 402218590Sjkim break; 403218590Sjkim 404208625Sjkim default: 405250838Sjkim 406208625Sjkim Type = DT_FIELD_TYPE_INTEGER; 407208625Sjkim break; 408208625Sjkim } 409208625Sjkim 410208625Sjkim return (Type); 411208625Sjkim} 412208625Sjkim 413208625Sjkim 414208625Sjkim/****************************************************************************** 415208625Sjkim * 416208625Sjkim * FUNCTION: DtGetBufferLength 417208625Sjkim * 418208625Sjkim * PARAMETERS: Buffer - List of integers, 419208625Sjkim * for example "10 3A 4F 2E" 420208625Sjkim * 421208625Sjkim * RETURN: Count of integer 422208625Sjkim * 423208625Sjkim * DESCRIPTION: Get length of bytes needed to store the integers 424208625Sjkim * 425208625Sjkim *****************************************************************************/ 426208625Sjkim 427208625SjkimUINT32 428208625SjkimDtGetBufferLength ( 429208625Sjkim char *Buffer) 430208625Sjkim{ 431208625Sjkim UINT32 ByteLength = 0; 432208625Sjkim 433208625Sjkim 434208625Sjkim while (*Buffer) 435208625Sjkim { 436208625Sjkim if (*Buffer == ' ') 437208625Sjkim { 438208625Sjkim ByteLength++; 439208625Sjkim 440208625Sjkim while (*Buffer == ' ') 441208625Sjkim { 442208625Sjkim Buffer++; 443208625Sjkim } 444208625Sjkim } 445208625Sjkim 446208625Sjkim Buffer++; 447208625Sjkim } 448208625Sjkim 449208625Sjkim return (++ByteLength); 450208625Sjkim} 451208625Sjkim 452208625Sjkim 453208625Sjkim/****************************************************************************** 454208625Sjkim * 455208625Sjkim * FUNCTION: DtGetFieldLength 456208625Sjkim * 457220663Sjkim * PARAMETERS: Field - Current field 458208625Sjkim * Info - Data table info 459208625Sjkim * 460208625Sjkim * RETURN: Field length 461208625Sjkim * 462208625Sjkim * DESCRIPTION: Get length of bytes needed to compile the field 463208625Sjkim * 464209734Sjkim * Note: This function must remain in sync with AcpiDmDumpTable. 465209734Sjkim * 466208625Sjkim *****************************************************************************/ 467208625Sjkim 468208625SjkimUINT32 469208625SjkimDtGetFieldLength ( 470208625Sjkim DT_FIELD *Field, 471208625Sjkim ACPI_DMTABLE_INFO *Info) 472208625Sjkim{ 473208625Sjkim UINT32 ByteLength = 0; 474208625Sjkim char *Value; 475208625Sjkim 476208625Sjkim 477208625Sjkim /* Length is based upon the opcode for this field in the info table */ 478208625Sjkim 479208625Sjkim switch (Info->Opcode) 480208625Sjkim { 481208625Sjkim case ACPI_DMT_FLAG0: 482208625Sjkim case ACPI_DMT_FLAG1: 483208625Sjkim case ACPI_DMT_FLAG2: 484208625Sjkim case ACPI_DMT_FLAG3: 485208625Sjkim case ACPI_DMT_FLAG4: 486208625Sjkim case ACPI_DMT_FLAG5: 487208625Sjkim case ACPI_DMT_FLAG6: 488208625Sjkim case ACPI_DMT_FLAG7: 489208625Sjkim case ACPI_DMT_FLAGS0: 490228110Sjkim case ACPI_DMT_FLAGS1: 491208625Sjkim case ACPI_DMT_FLAGS2: 492228110Sjkim case ACPI_DMT_FLAGS4: 493218590Sjkim case ACPI_DMT_LABEL: 494228110Sjkim case ACPI_DMT_EXTRA_TEXT: 495250838Sjkim 496208625Sjkim ByteLength = 0; 497208625Sjkim break; 498208625Sjkim 499208625Sjkim case ACPI_DMT_UINT8: 500208625Sjkim case ACPI_DMT_CHKSUM: 501208625Sjkim case ACPI_DMT_SPACEID: 502216471Sjkim case ACPI_DMT_ACCWIDTH: 503209734Sjkim case ACPI_DMT_IVRS: 504281075Sdim case ACPI_DMT_GTDT: 505208625Sjkim case ACPI_DMT_MADT: 506281075Sdim case ACPI_DMT_PCCT: 507228110Sjkim case ACPI_DMT_PMTT: 508208625Sjkim case ACPI_DMT_SRAT: 509208625Sjkim case ACPI_DMT_ASF: 510208625Sjkim case ACPI_DMT_HESTNTYP: 511208625Sjkim case ACPI_DMT_FADTPM: 512209734Sjkim case ACPI_DMT_EINJACT: 513209734Sjkim case ACPI_DMT_EINJINST: 514209734Sjkim case ACPI_DMT_ERSTACT: 515209734Sjkim case ACPI_DMT_ERSTINST: 516281075Sdim case ACPI_DMT_DMAR_SCOPE: 517250838Sjkim 518208625Sjkim ByteLength = 1; 519208625Sjkim break; 520208625Sjkim 521208625Sjkim case ACPI_DMT_UINT16: 522208625Sjkim case ACPI_DMT_DMAR: 523208625Sjkim case ACPI_DMT_HEST: 524284460Sjkim case ACPI_DMT_NFIT: 525208625Sjkim case ACPI_DMT_PCI_PATH: 526250838Sjkim 527208625Sjkim ByteLength = 2; 528208625Sjkim break; 529208625Sjkim 530208625Sjkim case ACPI_DMT_UINT24: 531250838Sjkim 532208625Sjkim ByteLength = 3; 533208625Sjkim break; 534208625Sjkim 535208625Sjkim case ACPI_DMT_UINT32: 536208625Sjkim case ACPI_DMT_NAME4: 537208625Sjkim case ACPI_DMT_SIG: 538281075Sdim case ACPI_DMT_LPIT: 539250838Sjkim 540208625Sjkim ByteLength = 4; 541208625Sjkim break; 542208625Sjkim 543228110Sjkim case ACPI_DMT_UINT40: 544250838Sjkim 545228110Sjkim ByteLength = 5; 546228110Sjkim break; 547228110Sjkim 548228110Sjkim case ACPI_DMT_UINT48: 549208625Sjkim case ACPI_DMT_NAME6: 550250838Sjkim 551208625Sjkim ByteLength = 6; 552208625Sjkim break; 553208625Sjkim 554208625Sjkim case ACPI_DMT_UINT56: 555218590Sjkim case ACPI_DMT_BUF7: 556250838Sjkim 557208625Sjkim ByteLength = 7; 558208625Sjkim break; 559208625Sjkim 560208625Sjkim case ACPI_DMT_UINT64: 561208625Sjkim case ACPI_DMT_NAME8: 562250838Sjkim 563208625Sjkim ByteLength = 8; 564208625Sjkim break; 565208625Sjkim 566208625Sjkim case ACPI_DMT_STRING: 567250838Sjkim 568220663Sjkim Value = DtGetFieldValue (Field); 569217365Sjkim if (Value) 570217365Sjkim { 571306536Sjkim ByteLength = strlen (Value) + 1; 572217365Sjkim } 573217365Sjkim else 574217365Sjkim { /* At this point, this is a fatal error */ 575208625Sjkim 576217365Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 577217365Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 578220663Sjkim return (0); 579217365Sjkim } 580208625Sjkim break; 581208625Sjkim 582208625Sjkim case ACPI_DMT_GAS: 583250838Sjkim 584208625Sjkim ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 585208625Sjkim break; 586208625Sjkim 587208625Sjkim case ACPI_DMT_HESTNTFY: 588250838Sjkim 589208625Sjkim ByteLength = sizeof (ACPI_HEST_NOTIFY); 590208625Sjkim break; 591208625Sjkim 592284460Sjkim case ACPI_DMT_IORTMEM: 593284460Sjkim 594284460Sjkim ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS); 595284460Sjkim break; 596284460Sjkim 597208625Sjkim case ACPI_DMT_BUFFER: 598281687Sjkim case ACPI_DMT_RAW_BUFFER: 599250838Sjkim 600220663Sjkim Value = DtGetFieldValue (Field); 601208625Sjkim if (Value) 602208625Sjkim { 603208625Sjkim ByteLength = DtGetBufferLength (Value); 604208625Sjkim } 605208625Sjkim else 606208625Sjkim { /* At this point, this is a fatal error */ 607208625Sjkim 608208625Sjkim sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 609208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 610220663Sjkim return (0); 611208625Sjkim } 612208625Sjkim break; 613208625Sjkim 614252279Sjkim case ACPI_DMT_BUF10: 615252279Sjkim 616252279Sjkim ByteLength = 10; 617252279Sjkim break; 618252279Sjkim 619208625Sjkim case ACPI_DMT_BUF16: 620217365Sjkim case ACPI_DMT_UUID: 621250838Sjkim 622208625Sjkim ByteLength = 16; 623208625Sjkim break; 624208625Sjkim 625219707Sjkim case ACPI_DMT_BUF128: 626250838Sjkim 627219707Sjkim ByteLength = 128; 628219707Sjkim break; 629219707Sjkim 630217365Sjkim case ACPI_DMT_UNICODE: 631250838Sjkim 632220663Sjkim Value = DtGetFieldValue (Field); 633217365Sjkim 634217365Sjkim /* TBD: error if Value is NULL? (as below?) */ 635217365Sjkim 636306536Sjkim ByteLength = (strlen (Value) + 1) * sizeof(UINT16); 637217365Sjkim break; 638217365Sjkim 639208625Sjkim default: 640250838Sjkim 641208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 642220663Sjkim return (0); 643208625Sjkim } 644208625Sjkim 645208625Sjkim return (ByteLength); 646208625Sjkim} 647208625Sjkim 648208625Sjkim 649208625Sjkim/****************************************************************************** 650208625Sjkim * 651208625Sjkim * FUNCTION: DtSum 652208625Sjkim * 653208625Sjkim * PARAMETERS: DT_WALK_CALLBACK: 654208625Sjkim * Subtable - Subtable 655208625Sjkim * Context - Unused 656208625Sjkim * ReturnValue - Store the checksum of subtable 657208625Sjkim * 658208625Sjkim * RETURN: Status 659208625Sjkim * 660208625Sjkim * DESCRIPTION: Get the checksum of subtable 661208625Sjkim * 662208625Sjkim *****************************************************************************/ 663208625Sjkim 664208625Sjkimstatic void 665208625SjkimDtSum ( 666208625Sjkim DT_SUBTABLE *Subtable, 667208625Sjkim void *Context, 668208625Sjkim void *ReturnValue) 669208625Sjkim{ 670208625Sjkim UINT8 Checksum; 671208625Sjkim UINT8 *Sum = ReturnValue; 672208625Sjkim 673208625Sjkim 674208625Sjkim Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 675208625Sjkim *Sum = (UINT8) (*Sum + Checksum); 676208625Sjkim} 677208625Sjkim 678208625Sjkim 679208625Sjkim/****************************************************************************** 680208625Sjkim * 681208625Sjkim * FUNCTION: DtSetTableChecksum 682208625Sjkim * 683208625Sjkim * PARAMETERS: ChecksumPointer - Where to return the checksum 684208625Sjkim * 685208625Sjkim * RETURN: None 686208625Sjkim * 687208625Sjkim * DESCRIPTION: Set checksum of the whole data table into the checksum field 688208625Sjkim * 689208625Sjkim *****************************************************************************/ 690208625Sjkim 691208625Sjkimvoid 692208625SjkimDtSetTableChecksum ( 693208625Sjkim UINT8 *ChecksumPointer) 694208625Sjkim{ 695208625Sjkim UINT8 Checksum = 0; 696208625Sjkim UINT8 OldSum; 697208625Sjkim 698208625Sjkim 699208625Sjkim DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 700208625Sjkim 701208625Sjkim OldSum = *ChecksumPointer; 702208625Sjkim Checksum = (UINT8) (Checksum - OldSum); 703208625Sjkim 704208625Sjkim /* Compute the final checksum */ 705208625Sjkim 706208625Sjkim Checksum = (UINT8) (0 - Checksum); 707208625Sjkim *ChecksumPointer = Checksum; 708208625Sjkim} 709208625Sjkim 710208625Sjkim 711208625Sjkim/****************************************************************************** 712208625Sjkim * 713208625Sjkim * FUNCTION: DtSetTableLength 714208625Sjkim * 715208625Sjkim * PARAMETERS: None 716208625Sjkim * 717208625Sjkim * RETURN: None 718208625Sjkim * 719208625Sjkim * DESCRIPTION: Walk the subtables and set all the length fields 720208625Sjkim * 721208625Sjkim *****************************************************************************/ 722208625Sjkim 723208625Sjkimvoid 724208625SjkimDtSetTableLength ( 725208625Sjkim void) 726208625Sjkim{ 727208625Sjkim DT_SUBTABLE *ParentTable; 728208625Sjkim DT_SUBTABLE *ChildTable; 729208625Sjkim 730208625Sjkim 731208625Sjkim ParentTable = Gbl_RootTable; 732208625Sjkim ChildTable = NULL; 733208625Sjkim 734208625Sjkim if (!ParentTable) 735208625Sjkim { 736208625Sjkim return; 737208625Sjkim } 738208625Sjkim 739208625Sjkim DtSetSubtableLength (ParentTable); 740208625Sjkim 741208625Sjkim while (1) 742208625Sjkim { 743208625Sjkim ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 744208625Sjkim if (ChildTable) 745208625Sjkim { 746209734Sjkim if (ChildTable->LengthField) 747209734Sjkim { 748209734Sjkim DtSetSubtableLength (ChildTable); 749209734Sjkim } 750209734Sjkim 751208625Sjkim if (ChildTable->Child) 752208625Sjkim { 753208625Sjkim ParentTable = ChildTable; 754208625Sjkim ChildTable = NULL; 755208625Sjkim } 756208625Sjkim else 757208625Sjkim { 758208625Sjkim ParentTable->TotalLength += ChildTable->TotalLength; 759208625Sjkim if (ParentTable->LengthField) 760208625Sjkim { 761208625Sjkim DtSetSubtableLength (ParentTable); 762208625Sjkim } 763208625Sjkim } 764208625Sjkim } 765208625Sjkim else 766208625Sjkim { 767208625Sjkim ChildTable = ParentTable; 768208625Sjkim 769208625Sjkim if (ChildTable == Gbl_RootTable) 770208625Sjkim { 771208625Sjkim break; 772208625Sjkim } 773208625Sjkim 774208625Sjkim ParentTable = DtGetParentSubtable (ParentTable); 775208625Sjkim 776208625Sjkim ParentTable->TotalLength += ChildTable->TotalLength; 777208625Sjkim if (ParentTable->LengthField) 778208625Sjkim { 779208625Sjkim DtSetSubtableLength (ParentTable); 780208625Sjkim } 781208625Sjkim } 782208625Sjkim } 783208625Sjkim} 784208625Sjkim 785208625Sjkim 786208625Sjkim/****************************************************************************** 787208625Sjkim * 788208625Sjkim * FUNCTION: DtWalkTableTree 789208625Sjkim * 790208625Sjkim * PARAMETERS: StartTable - Subtable in the tree where walking begins 791208625Sjkim * UserFunction - Called during the walk 792208625Sjkim * Context - Passed to user function 793208625Sjkim * ReturnValue - The return value of UserFunction 794208625Sjkim * 795208625Sjkim * RETURN: None 796208625Sjkim * 797208625Sjkim * DESCRIPTION: Performs a depth-first walk of the subtable tree 798208625Sjkim * 799208625Sjkim *****************************************************************************/ 800208625Sjkim 801208625Sjkimvoid 802208625SjkimDtWalkTableTree ( 803208625Sjkim DT_SUBTABLE *StartTable, 804208625Sjkim DT_WALK_CALLBACK UserFunction, 805208625Sjkim void *Context, 806208625Sjkim void *ReturnValue) 807208625Sjkim{ 808208625Sjkim DT_SUBTABLE *ParentTable; 809208625Sjkim DT_SUBTABLE *ChildTable; 810208625Sjkim 811208625Sjkim 812208625Sjkim ParentTable = StartTable; 813208625Sjkim ChildTable = NULL; 814208625Sjkim 815208625Sjkim if (!ParentTable) 816208625Sjkim { 817208625Sjkim return; 818208625Sjkim } 819208625Sjkim 820208625Sjkim UserFunction (ParentTable, Context, ReturnValue); 821208625Sjkim 822208625Sjkim while (1) 823208625Sjkim { 824208625Sjkim ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 825208625Sjkim if (ChildTable) 826208625Sjkim { 827208625Sjkim UserFunction (ChildTable, Context, ReturnValue); 828208625Sjkim 829208625Sjkim if (ChildTable->Child) 830208625Sjkim { 831208625Sjkim ParentTable = ChildTable; 832208625Sjkim ChildTable = NULL; 833208625Sjkim } 834208625Sjkim } 835208625Sjkim else 836208625Sjkim { 837208625Sjkim ChildTable = ParentTable; 838208625Sjkim if (ChildTable == Gbl_RootTable) 839208625Sjkim { 840208625Sjkim break; 841208625Sjkim } 842208625Sjkim 843208625Sjkim ParentTable = DtGetParentSubtable (ParentTable); 844208625Sjkim 845208625Sjkim if (ChildTable->Peer == StartTable) 846208625Sjkim { 847208625Sjkim break; 848208625Sjkim } 849208625Sjkim } 850208625Sjkim } 851208625Sjkim} 852208625Sjkim 853208625Sjkim 854281075Sdim/******************************************************************************* 855208625Sjkim * 856281075Sdim * FUNCTION: UtSubtableCacheCalloc 857208625Sjkim * 858208625Sjkim * PARAMETERS: None 859208625Sjkim * 860281075Sdim * RETURN: Pointer to the buffer. Aborts on allocation failure 861281075Sdim * 862281075Sdim * DESCRIPTION: Allocate a subtable object buffer. Bypass the local 863281075Sdim * dynamic memory manager for performance reasons (This has a 864281075Sdim * major impact on the speed of the compiler.) 865281075Sdim * 866281075Sdim ******************************************************************************/ 867281075Sdim 868281075SdimDT_SUBTABLE * 869281075SdimUtSubtableCacheCalloc ( 870281075Sdim void) 871281075Sdim{ 872281075Sdim ASL_CACHE_INFO *Cache; 873281075Sdim 874281075Sdim 875281075Sdim if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) 876281075Sdim { 877281075Sdim /* Allocate a new buffer */ 878281075Sdim 879281075Sdim Cache = UtLocalCalloc (sizeof (Cache->Next) + 880281075Sdim (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); 881281075Sdim 882281075Sdim /* Link new cache buffer to head of list */ 883281075Sdim 884281075Sdim Cache->Next = Gbl_SubtableCacheList; 885281075Sdim Gbl_SubtableCacheList = Cache; 886281075Sdim 887281075Sdim /* Setup cache management pointers */ 888281075Sdim 889281075Sdim Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); 890281075Sdim Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; 891281075Sdim } 892281075Sdim 893281075Sdim Gbl_SubtableCount++; 894281075Sdim return (Gbl_SubtableCacheNext++); 895281075Sdim} 896281075Sdim 897281075Sdim 898281075Sdim/******************************************************************************* 899281075Sdim * 900281075Sdim * FUNCTION: UtFieldCacheCalloc 901281075Sdim * 902281075Sdim * PARAMETERS: None 903281075Sdim * 904281075Sdim * RETURN: Pointer to the buffer. Aborts on allocation failure 905281075Sdim * 906281075Sdim * DESCRIPTION: Allocate a field object buffer. Bypass the local 907281075Sdim * dynamic memory manager for performance reasons (This has a 908281075Sdim * major impact on the speed of the compiler.) 909281075Sdim * 910281075Sdim ******************************************************************************/ 911281075Sdim 912281075SdimDT_FIELD * 913281075SdimUtFieldCacheCalloc ( 914281075Sdim void) 915281075Sdim{ 916281075Sdim ASL_CACHE_INFO *Cache; 917281075Sdim 918281075Sdim 919281075Sdim if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) 920281075Sdim { 921281075Sdim /* Allocate a new buffer */ 922281075Sdim 923281075Sdim Cache = UtLocalCalloc (sizeof (Cache->Next) + 924281075Sdim (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); 925281075Sdim 926281075Sdim /* Link new cache buffer to head of list */ 927281075Sdim 928281075Sdim Cache->Next = Gbl_FieldCacheList; 929281075Sdim Gbl_FieldCacheList = Cache; 930281075Sdim 931281075Sdim /* Setup cache management pointers */ 932281075Sdim 933281075Sdim Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); 934281075Sdim Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; 935281075Sdim } 936281075Sdim 937281075Sdim Gbl_FieldCount++; 938281075Sdim return (Gbl_FieldCacheNext++); 939281075Sdim} 940281075Sdim 941281075Sdim 942281075Sdim/******************************************************************************* 943281075Sdim * 944281075Sdim * FUNCTION: DtDeleteCaches 945281075Sdim * 946281075Sdim * PARAMETERS: None 947281075Sdim * 948208625Sjkim * RETURN: None 949208625Sjkim * 950281075Sdim * DESCRIPTION: Delete all local cache buffer blocks 951208625Sjkim * 952281075Sdim ******************************************************************************/ 953208625Sjkim 954208625Sjkimvoid 955281075SdimDtDeleteCaches ( 956208625Sjkim void) 957208625Sjkim{ 958281075Sdim UINT32 BufferCount; 959281075Sdim ASL_CACHE_INFO *Next; 960208625Sjkim 961208625Sjkim 962281075Sdim /* Field cache */ 963208625Sjkim 964281075Sdim BufferCount = 0; 965281075Sdim while (Gbl_FieldCacheList) 966208625Sjkim { 967281075Sdim Next = Gbl_FieldCacheList->Next; 968281075Sdim ACPI_FREE (Gbl_FieldCacheList); 969281075Sdim Gbl_FieldCacheList = Next; 970281075Sdim BufferCount++; 971281075Sdim } 972208625Sjkim 973281075Sdim DbgPrint (ASL_DEBUG_OUTPUT, 974281075Sdim "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", 975281075Sdim Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, 976281075Sdim (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); 977208625Sjkim 978281075Sdim Gbl_FieldCount = 0; 979281075Sdim Gbl_FieldCacheNext = NULL; 980281075Sdim Gbl_FieldCacheLast = NULL; 981281075Sdim 982281075Sdim /* Subtable cache */ 983281075Sdim 984281075Sdim BufferCount = 0; 985281075Sdim while (Gbl_SubtableCacheList) 986281075Sdim { 987281075Sdim Next = Gbl_SubtableCacheList->Next; 988281075Sdim ACPI_FREE (Gbl_SubtableCacheList); 989281075Sdim Gbl_SubtableCacheList = Next; 990281075Sdim BufferCount++; 991208625Sjkim } 992281075Sdim 993281075Sdim DbgPrint (ASL_DEBUG_OUTPUT, 994281075Sdim "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", 995281075Sdim Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, 996281075Sdim (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); 997281075Sdim 998281075Sdim Gbl_SubtableCount = 0; 999281075Sdim Gbl_SubtableCacheNext = NULL; 1000281075Sdim Gbl_SubtableCacheLast = NULL; 1001208625Sjkim} 1002