1 /****************************************************************************** 2 * 3 * Module Name: dttable1.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2021, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 /* Compile all complex data tables, signatures starting with A-I */ 45 46 #include "aslcompiler.h" 47 48 #define _COMPONENT DT_COMPILER 49 ACPI_MODULE_NAME ("dttable1") 50 51 52 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 53 { 54 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 55 {ACPI_DMT_EXIT, 0, NULL, 0} 56 }; 57 58 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 59 { 60 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 61 {ACPI_DMT_EXIT, 0, NULL, 0} 62 }; 63 64 65 /****************************************************************************** 66 * 67 * FUNCTION: DtCompileAest 68 * 69 * PARAMETERS: List - Current field list pointer 70 * 71 * RETURN: Status 72 * 73 * DESCRIPTION: Compile AEST. 74 * 75 * NOTE: Assumes the following table structure: 76 * For all AEST Error Nodes: 77 * 1) An AEST Error Node, followed immediately by: 78 * 2) Any node-specific data 79 * 3) An Interface Structure (one) 80 * 4) A list (array) of Interrupt Structures, the count as specified 81 * in the NodeInterruptCount field of the Error Node header. 82 * 83 * AEST - ARM Error Source table. Conforms to: 84 * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020 85 * 86 *****************************************************************************/ 87 88 ACPI_STATUS 89 DtCompileAest ( 90 void **List) 91 { 92 ACPI_AEST_HEADER *ErrorNodeHeader; 93 ACPI_AEST_PROCESSOR *AestProcessor; 94 DT_SUBTABLE *Subtable; 95 DT_SUBTABLE *ParentTable; 96 ACPI_DMTABLE_INFO *InfoTable; 97 ACPI_STATUS Status; 98 UINT32 i; 99 UINT32 Offset; 100 DT_FIELD **PFieldList = (DT_FIELD **) List; 101 102 103 while (*PFieldList) 104 { 105 /* Compile the common error node header */ 106 107 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr, 108 &Subtable); 109 if (ACPI_FAILURE (Status)) 110 { 111 return (Status); 112 } 113 114 ParentTable = DtPeekSubtable (); 115 DtInsertSubtable (ParentTable, Subtable); 116 117 /* Everything past the error node header will be a subtable */ 118 119 DtPushSubtable (Subtable); 120 121 /* 122 * Compile the node-specific structure (Based on the error 123 * node header Type field) 124 */ 125 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer); 126 127 /* Point past the common error node header */ 128 129 Offset = sizeof (ACPI_AEST_HEADER); 130 ErrorNodeHeader->NodeSpecificOffset = Offset; 131 132 /* Decode the error node type */ 133 134 switch (ErrorNodeHeader->Type) 135 { 136 case ACPI_AEST_PROCESSOR_ERROR_NODE: 137 138 InfoTable = AcpiDmTableInfoAestProcError; 139 break; 140 141 case ACPI_AEST_MEMORY_ERROR_NODE: 142 143 InfoTable = AcpiDmTableInfoAestMemError; 144 break; 145 146 case ACPI_AEST_SMMU_ERROR_NODE: 147 148 InfoTable = AcpiDmTableInfoAestSmmuError; 149 break; 150 151 case ACPI_AEST_VENDOR_ERROR_NODE: 152 153 InfoTable = AcpiDmTableInfoAestVendorError; 154 break; 155 156 case ACPI_AEST_GIC_ERROR_NODE: 157 158 InfoTable = AcpiDmTableInfoAestGicError; 159 break; 160 161 /* Error case below */ 162 default: 163 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n", 164 ErrorNodeHeader->Type); 165 return (AE_ERROR); 166 } 167 168 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 169 if (ACPI_FAILURE (Status)) 170 { 171 return (Status); 172 } 173 174 /* Point past the node-specific structure */ 175 176 Offset += Subtable->Length; 177 ErrorNodeHeader->NodeInterfaceOffset = Offset; 178 179 ParentTable = DtPeekSubtable (); 180 DtInsertSubtable (ParentTable, Subtable); 181 182 /* Compile any additional node-specific substructures */ 183 184 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE) 185 { 186 /* 187 * Special handling for PROCESSOR_ERROR_NODE subtables 188 * (to handle the Resource Substructure via the ResourceType 189 * field). 190 */ 191 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, 192 Subtable->Buffer); 193 194 switch (AestProcessor->ResourceType) 195 { 196 case ACPI_AEST_CACHE_RESOURCE: 197 198 InfoTable = AcpiDmTableInfoAestCacheRsrc; 199 break; 200 201 case ACPI_AEST_TLB_RESOURCE: 202 203 InfoTable = AcpiDmTableInfoAestTlbRsrc; 204 break; 205 206 case ACPI_AEST_GENERIC_RESOURCE: 207 208 InfoTable = AcpiDmTableInfoAestGenRsrc; 209 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n", 210 AestProcessor->ResourceType); 211 return (AE_ERROR); 212 213 /* Error case below */ 214 default: 215 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n", 216 AestProcessor->ResourceType); 217 return (AE_ERROR); 218 } 219 220 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 221 if (ACPI_FAILURE (Status)) 222 { 223 return (Status); 224 } 225 226 /* Point past the resource substructure subtable */ 227 228 Offset += Subtable->Length; 229 ErrorNodeHeader->NodeInterfaceOffset = Offset; 230 231 ParentTable = DtPeekSubtable (); 232 DtInsertSubtable (ParentTable, Subtable); 233 } 234 235 /* Compile the (required) node interface structure */ 236 237 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface, 238 &Subtable); 239 if (ACPI_FAILURE (Status)) 240 { 241 return (Status); 242 } 243 244 ErrorNodeHeader->NodeInterruptOffset = 0; 245 ParentTable = DtPeekSubtable (); 246 DtInsertSubtable (ParentTable, Subtable); 247 248 /* Compile each of the node interrupt structures */ 249 250 if (ErrorNodeHeader->NodeInterruptCount) 251 { 252 /* Point to the first interrupt structure */ 253 254 Offset += Subtable->Length; 255 ErrorNodeHeader->NodeInterruptOffset = Offset; 256 } 257 258 /* Compile each of the interrupt structures */ 259 260 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++) 261 { 262 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt, 263 &Subtable); 264 if (ACPI_FAILURE (Status)) 265 { 266 return (Status); 267 } 268 269 ParentTable = DtPeekSubtable (); 270 DtInsertSubtable (ParentTable, Subtable); 271 } 272 273 /* Prepare for the next AEST Error node */ 274 275 DtPopSubtable (); 276 } 277 278 return (AE_OK); 279 } 280 281 282 /****************************************************************************** 283 * 284 * FUNCTION: DtCompileAsf 285 * 286 * PARAMETERS: List - Current field list pointer 287 * 288 * RETURN: Status 289 * 290 * DESCRIPTION: Compile ASF!. 291 * 292 *****************************************************************************/ 293 294 ACPI_STATUS 295 DtCompileAsf ( 296 void **List) 297 { 298 ACPI_ASF_INFO *AsfTable; 299 DT_SUBTABLE *Subtable; 300 DT_SUBTABLE *ParentTable; 301 ACPI_DMTABLE_INFO *InfoTable; 302 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 303 UINT32 DataCount = 0; 304 ACPI_STATUS Status; 305 UINT32 i; 306 DT_FIELD **PFieldList = (DT_FIELD **) List; 307 DT_FIELD *SubtableStart; 308 309 310 while (*PFieldList) 311 { 312 SubtableStart = *PFieldList; 313 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 314 &Subtable); 315 if (ACPI_FAILURE (Status)) 316 { 317 return (Status); 318 } 319 320 ParentTable = DtPeekSubtable (); 321 DtInsertSubtable (ParentTable, Subtable); 322 DtPushSubtable (Subtable); 323 324 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 325 326 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 327 { 328 case ACPI_ASF_TYPE_INFO: 329 330 InfoTable = AcpiDmTableInfoAsf0; 331 break; 332 333 case ACPI_ASF_TYPE_ALERT: 334 335 InfoTable = AcpiDmTableInfoAsf1; 336 break; 337 338 case ACPI_ASF_TYPE_CONTROL: 339 340 InfoTable = AcpiDmTableInfoAsf2; 341 break; 342 343 case ACPI_ASF_TYPE_BOOT: 344 345 InfoTable = AcpiDmTableInfoAsf3; 346 break; 347 348 case ACPI_ASF_TYPE_ADDRESS: 349 350 InfoTable = AcpiDmTableInfoAsf4; 351 break; 352 353 default: 354 355 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 356 return (AE_ERROR); 357 } 358 359 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 360 if (ACPI_FAILURE (Status)) 361 { 362 return (Status); 363 } 364 365 ParentTable = DtPeekSubtable (); 366 DtInsertSubtable (ParentTable, Subtable); 367 368 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 369 { 370 case ACPI_ASF_TYPE_INFO: 371 372 DataInfoTable = NULL; 373 break; 374 375 case ACPI_ASF_TYPE_ALERT: 376 377 DataInfoTable = AcpiDmTableInfoAsf1a; 378 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 379 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 380 sizeof (ACPI_ASF_HEADER)))->Alerts; 381 break; 382 383 case ACPI_ASF_TYPE_CONTROL: 384 385 DataInfoTable = AcpiDmTableInfoAsf2a; 386 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 387 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 388 sizeof (ACPI_ASF_HEADER)))->Controls; 389 break; 390 391 case ACPI_ASF_TYPE_BOOT: 392 393 DataInfoTable = NULL; 394 break; 395 396 case ACPI_ASF_TYPE_ADDRESS: 397 398 DataInfoTable = TableInfoAsfAddress; 399 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 400 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 401 sizeof (ACPI_ASF_HEADER)))->Devices; 402 break; 403 404 default: 405 406 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 407 return (AE_ERROR); 408 } 409 410 if (DataInfoTable) 411 { 412 switch (AsfTable->Header.Type & 0x7F) 413 { 414 case ACPI_ASF_TYPE_ADDRESS: 415 416 while (DataCount > 0) 417 { 418 Status = DtCompileTable (PFieldList, DataInfoTable, 419 &Subtable); 420 if (ACPI_FAILURE (Status)) 421 { 422 return (Status); 423 } 424 425 DtInsertSubtable (ParentTable, Subtable); 426 DataCount = DataCount - Subtable->Length; 427 } 428 break; 429 430 default: 431 432 for (i = 0; i < DataCount; i++) 433 { 434 Status = DtCompileTable (PFieldList, DataInfoTable, 435 &Subtable); 436 if (ACPI_FAILURE (Status)) 437 { 438 return (Status); 439 } 440 441 DtInsertSubtable (ParentTable, Subtable); 442 } 443 break; 444 } 445 } 446 447 DtPopSubtable (); 448 } 449 450 return (AE_OK); 451 } 452 453 454 /****************************************************************************** 455 * 456 * FUNCTION: DtCompileCedt 457 * 458 * PARAMETERS: List - Current field list pointer 459 * 460 * RETURN: Status 461 * 462 * DESCRIPTION: Compile CEDT. 463 * 464 *****************************************************************************/ 465 466 ACPI_STATUS 467 DtCompileCedt ( 468 void **List) 469 { 470 ACPI_STATUS Status; 471 DT_SUBTABLE *Subtable; 472 DT_SUBTABLE *ParentTable; 473 DT_FIELD **PFieldList = (DT_FIELD **) List; 474 ACPI_CEDT_HEADER *CedtHeader; 475 DT_FIELD *SubtableStart; 476 477 478 /* Walk the parse tree */ 479 480 while (*PFieldList) 481 { 482 SubtableStart = *PFieldList; 483 484 /* CEDT Header */ 485 486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr, 487 &Subtable); 488 if (ACPI_FAILURE (Status)) 489 { 490 return (Status); 491 } 492 493 ParentTable = DtPeekSubtable (); 494 DtInsertSubtable (ParentTable, Subtable); 495 DtPushSubtable (Subtable); 496 497 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer); 498 499 switch (CedtHeader->Type) 500 { 501 case ACPI_CEDT_TYPE_CHBS: 502 503 break; 504 505 default: 506 507 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT"); 508 return (AE_ERROR); 509 } 510 511 /* CEDT Subtable */ 512 513 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable); 514 if (ACPI_FAILURE (Status)) 515 { 516 return (Status); 517 } 518 519 ParentTable = DtPeekSubtable (); 520 DtInsertSubtable (ParentTable, Subtable); 521 DtPopSubtable (); 522 } 523 524 return (AE_OK); 525 } 526 527 528 /****************************************************************************** 529 * 530 * FUNCTION: DtCompileCpep 531 * 532 * PARAMETERS: List - Current field list pointer 533 * 534 * RETURN: Status 535 * 536 * DESCRIPTION: Compile CPEP. 537 * 538 *****************************************************************************/ 539 540 ACPI_STATUS 541 DtCompileCpep ( 542 void **List) 543 { 544 ACPI_STATUS Status; 545 546 547 Status = DtCompileTwoSubtables (List, 548 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 549 return (Status); 550 } 551 552 553 /****************************************************************************** 554 * 555 * FUNCTION: DtCompileCsrt 556 * 557 * PARAMETERS: List - Current field list pointer 558 * 559 * RETURN: Status 560 * 561 * DESCRIPTION: Compile CSRT. 562 * 563 *****************************************************************************/ 564 565 ACPI_STATUS 566 DtCompileCsrt ( 567 void **List) 568 { 569 ACPI_STATUS Status = AE_OK; 570 DT_SUBTABLE *Subtable; 571 DT_SUBTABLE *ParentTable; 572 DT_FIELD **PFieldList = (DT_FIELD **) List; 573 UINT32 DescriptorCount; 574 UINT32 GroupLength; 575 576 577 /* Subtables (Resource Groups) */ 578 579 ParentTable = DtPeekSubtable (); 580 while (*PFieldList) 581 { 582 /* Resource group subtable */ 583 584 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 585 &Subtable); 586 if (ACPI_FAILURE (Status)) 587 { 588 return (Status); 589 } 590 591 /* Compute the number of resource descriptors */ 592 593 GroupLength = 594 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 595 Subtable->Buffer))->Length - 596 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 597 Subtable->Buffer))->SharedInfoLength - 598 sizeof (ACPI_CSRT_GROUP); 599 600 DescriptorCount = (GroupLength / 601 sizeof (ACPI_CSRT_DESCRIPTOR)); 602 603 DtInsertSubtable (ParentTable, Subtable); 604 DtPushSubtable (Subtable); 605 ParentTable = DtPeekSubtable (); 606 607 /* Shared info subtable (One per resource group) */ 608 609 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 610 &Subtable); 611 if (ACPI_FAILURE (Status)) 612 { 613 return (Status); 614 } 615 616 DtInsertSubtable (ParentTable, Subtable); 617 618 /* Sub-Subtables (Resource Descriptors) */ 619 620 while (*PFieldList && DescriptorCount) 621 { 622 623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 624 &Subtable); 625 if (ACPI_FAILURE (Status)) 626 { 627 return (Status); 628 } 629 630 DtInsertSubtable (ParentTable, Subtable); 631 632 DtPushSubtable (Subtable); 633 ParentTable = DtPeekSubtable (); 634 if (*PFieldList) 635 { 636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 637 &Subtable); 638 if (ACPI_FAILURE (Status)) 639 { 640 return (Status); 641 } 642 if (Subtable) 643 { 644 DtInsertSubtable (ParentTable, Subtable); 645 } 646 } 647 648 DtPopSubtable (); 649 ParentTable = DtPeekSubtable (); 650 DescriptorCount--; 651 } 652 653 DtPopSubtable (); 654 ParentTable = DtPeekSubtable (); 655 } 656 657 return (Status); 658 } 659 660 661 /****************************************************************************** 662 * 663 * FUNCTION: DtCompileDbg2 664 * 665 * PARAMETERS: List - Current field list pointer 666 * 667 * RETURN: Status 668 * 669 * DESCRIPTION: Compile DBG2. 670 * 671 *****************************************************************************/ 672 673 ACPI_STATUS 674 DtCompileDbg2 ( 675 void **List) 676 { 677 ACPI_STATUS Status; 678 DT_SUBTABLE *Subtable; 679 DT_SUBTABLE *ParentTable; 680 DT_FIELD **PFieldList = (DT_FIELD **) List; 681 UINT32 SubtableCount; 682 ACPI_DBG2_HEADER *Dbg2Header; 683 ACPI_DBG2_DEVICE *DeviceInfo; 684 UINT16 CurrentOffset; 685 UINT32 i; 686 687 688 /* Main table */ 689 690 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable); 691 if (ACPI_FAILURE (Status)) 692 { 693 return (Status); 694 } 695 696 ParentTable = DtPeekSubtable (); 697 DtInsertSubtable (ParentTable, Subtable); 698 699 /* Main table fields */ 700 701 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 702 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 703 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 704 705 SubtableCount = Dbg2Header->InfoCount; 706 DtPushSubtable (Subtable); 707 708 /* Process all Device Information subtables (Count = InfoCount) */ 709 710 while (*PFieldList && SubtableCount) 711 { 712 /* Subtable: Debug Device Information */ 713 714 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 715 &Subtable); 716 if (ACPI_FAILURE (Status)) 717 { 718 return (Status); 719 } 720 721 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 722 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 723 724 ParentTable = DtPeekSubtable (); 725 DtInsertSubtable (ParentTable, Subtable); 726 DtPushSubtable (Subtable); 727 728 ParentTable = DtPeekSubtable (); 729 730 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 731 732 DeviceInfo->BaseAddressOffset = CurrentOffset; 733 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 734 { 735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 736 &Subtable); 737 if (ACPI_FAILURE (Status)) 738 { 739 return (Status); 740 } 741 742 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 743 DtInsertSubtable (ParentTable, Subtable); 744 } 745 746 /* AddressSize array (Required, size = RegisterCount) */ 747 748 DeviceInfo->AddressSizeOffset = CurrentOffset; 749 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 750 { 751 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 752 &Subtable); 753 if (ACPI_FAILURE (Status)) 754 { 755 return (Status); 756 } 757 758 CurrentOffset += (UINT16) sizeof (UINT32); 759 DtInsertSubtable (ParentTable, Subtable); 760 } 761 762 /* NamespaceString device identifier (Required, size = NamePathLength) */ 763 764 DeviceInfo->NamepathOffset = CurrentOffset; 765 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 766 &Subtable); 767 if (ACPI_FAILURE (Status)) 768 { 769 return (Status); 770 } 771 772 /* Update the device info header */ 773 774 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 775 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 776 DtInsertSubtable (ParentTable, Subtable); 777 778 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 779 780 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 781 &Subtable); 782 if (Status == AE_END_OF_TABLE) 783 { 784 /* optional field was not found and we're at the end of the file */ 785 786 goto subtableDone; 787 } 788 else if (ACPI_FAILURE (Status)) 789 { 790 return (Status); 791 } 792 793 /* Update the device info header (zeros if no OEM data present) */ 794 795 DeviceInfo->OemDataOffset = 0; 796 DeviceInfo->OemDataLength = 0; 797 798 /* Optional subtable (OemData) */ 799 800 if (Subtable && Subtable->Length) 801 { 802 DeviceInfo->OemDataOffset = CurrentOffset; 803 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 804 805 DtInsertSubtable (ParentTable, Subtable); 806 } 807 subtableDone: 808 SubtableCount--; 809 DtPopSubtable (); /* Get next Device Information subtable */ 810 } 811 812 DtPopSubtable (); 813 return (AE_OK); 814 } 815 816 817 /****************************************************************************** 818 * 819 * FUNCTION: DtCompileDmar 820 * 821 * PARAMETERS: List - Current field list pointer 822 * 823 * RETURN: Status 824 * 825 * DESCRIPTION: Compile DMAR. 826 * 827 *****************************************************************************/ 828 829 ACPI_STATUS 830 DtCompileDmar ( 831 void **List) 832 { 833 ACPI_STATUS Status; 834 DT_SUBTABLE *Subtable; 835 DT_SUBTABLE *ParentTable; 836 DT_FIELD **PFieldList = (DT_FIELD **) List; 837 DT_FIELD *SubtableStart; 838 ACPI_DMTABLE_INFO *InfoTable; 839 ACPI_DMAR_HEADER *DmarHeader; 840 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 841 UINT32 DeviceScopeLength; 842 UINT32 PciPathLength; 843 844 845 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 846 if (ACPI_FAILURE (Status)) 847 { 848 return (Status); 849 } 850 851 ParentTable = DtPeekSubtable (); 852 DtInsertSubtable (ParentTable, Subtable); 853 DtPushSubtable (Subtable); 854 855 while (*PFieldList) 856 { 857 /* DMAR Header */ 858 859 SubtableStart = *PFieldList; 860 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 861 &Subtable); 862 if (ACPI_FAILURE (Status)) 863 { 864 return (Status); 865 } 866 867 ParentTable = DtPeekSubtable (); 868 DtInsertSubtable (ParentTable, Subtable); 869 DtPushSubtable (Subtable); 870 871 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 872 873 switch (DmarHeader->Type) 874 { 875 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 876 877 InfoTable = AcpiDmTableInfoDmar0; 878 break; 879 880 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 881 882 InfoTable = AcpiDmTableInfoDmar1; 883 break; 884 885 case ACPI_DMAR_TYPE_ROOT_ATS: 886 887 InfoTable = AcpiDmTableInfoDmar2; 888 break; 889 890 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 891 892 InfoTable = AcpiDmTableInfoDmar3; 893 break; 894 895 case ACPI_DMAR_TYPE_NAMESPACE: 896 897 InfoTable = AcpiDmTableInfoDmar4; 898 break; 899 900 default: 901 902 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 903 return (AE_ERROR); 904 } 905 906 /* DMAR Subtable */ 907 908 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 909 if (ACPI_FAILURE (Status)) 910 { 911 return (Status); 912 } 913 914 ParentTable = DtPeekSubtable (); 915 DtInsertSubtable (ParentTable, Subtable); 916 917 /* 918 * Optional Device Scope subtables 919 */ 920 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 921 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 922 { 923 /* These types do not support device scopes */ 924 925 DtPopSubtable (); 926 continue; 927 } 928 929 DtPushSubtable (Subtable); 930 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 931 ParentTable->Length; 932 while (DeviceScopeLength) 933 { 934 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 935 &Subtable); 936 if (Status == AE_NOT_FOUND) 937 { 938 break; 939 } 940 941 ParentTable = DtPeekSubtable (); 942 DtInsertSubtable (ParentTable, Subtable); 943 DtPushSubtable (Subtable); 944 945 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 946 947 /* Optional PCI Paths */ 948 949 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 950 while (PciPathLength) 951 { 952 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 953 &Subtable); 954 if (Status == AE_NOT_FOUND) 955 { 956 DtPopSubtable (); 957 break; 958 } 959 960 ParentTable = DtPeekSubtable (); 961 DtInsertSubtable (ParentTable, Subtable); 962 PciPathLength -= Subtable->Length; 963 } 964 965 DtPopSubtable (); 966 DeviceScopeLength -= DmarDeviceScope->Length; 967 } 968 969 DtPopSubtable (); 970 DtPopSubtable (); 971 } 972 973 return (AE_OK); 974 } 975 976 977 /****************************************************************************** 978 * 979 * FUNCTION: DtCompileDrtm 980 * 981 * PARAMETERS: List - Current field list pointer 982 * 983 * RETURN: Status 984 * 985 * DESCRIPTION: Compile DRTM. 986 * 987 *****************************************************************************/ 988 989 ACPI_STATUS 990 DtCompileDrtm ( 991 void **List) 992 { 993 ACPI_STATUS Status; 994 DT_SUBTABLE *Subtable; 995 DT_SUBTABLE *ParentTable; 996 DT_FIELD **PFieldList = (DT_FIELD **) List; 997 UINT32 Count; 998 /* ACPI_TABLE_DRTM *Drtm; */ 999 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1000 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1001 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1002 1003 1004 ParentTable = DtPeekSubtable (); 1005 1006 /* Compile DRTM header */ 1007 1008 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1009 &Subtable); 1010 if (ACPI_FAILURE (Status)) 1011 { 1012 return (Status); 1013 } 1014 DtInsertSubtable (ParentTable, Subtable); 1015 1016 /* 1017 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1018 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1019 */ 1020 #if 0 1021 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1022 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1023 #endif 1024 /* Compile VTL */ 1025 1026 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1027 &Subtable); 1028 if (ACPI_FAILURE (Status)) 1029 { 1030 return (Status); 1031 } 1032 1033 DtInsertSubtable (ParentTable, Subtable); 1034 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1035 1036 DtPushSubtable (Subtable); 1037 ParentTable = DtPeekSubtable (); 1038 Count = 0; 1039 1040 while (*PFieldList) 1041 { 1042 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1043 &Subtable); 1044 if (ACPI_FAILURE (Status)) 1045 { 1046 return (Status); 1047 } 1048 if (!Subtable) 1049 { 1050 break; 1051 } 1052 DtInsertSubtable (ParentTable, Subtable); 1053 Count++; 1054 } 1055 1056 DrtmVtl->ValidatedTableCount = Count; 1057 DtPopSubtable (); 1058 ParentTable = DtPeekSubtable (); 1059 1060 /* Compile RL */ 1061 1062 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1063 &Subtable); 1064 if (ACPI_FAILURE (Status)) 1065 { 1066 return (Status); 1067 } 1068 1069 DtInsertSubtable (ParentTable, Subtable); 1070 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1071 1072 DtPushSubtable (Subtable); 1073 ParentTable = DtPeekSubtable (); 1074 Count = 0; 1075 1076 while (*PFieldList) 1077 { 1078 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1079 &Subtable); 1080 if (ACPI_FAILURE (Status)) 1081 { 1082 return (Status); 1083 } 1084 1085 if (!Subtable) 1086 { 1087 break; 1088 } 1089 1090 DtInsertSubtable (ParentTable, Subtable); 1091 Count++; 1092 } 1093 1094 DrtmRl->ResourceCount = Count; 1095 DtPopSubtable (); 1096 ParentTable = DtPeekSubtable (); 1097 1098 /* Compile DPS */ 1099 1100 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1101 &Subtable); 1102 if (ACPI_FAILURE (Status)) 1103 { 1104 return (Status); 1105 } 1106 DtInsertSubtable (ParentTable, Subtable); 1107 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1108 1109 1110 return (AE_OK); 1111 } 1112 1113 1114 /****************************************************************************** 1115 * 1116 * FUNCTION: DtCompileEinj 1117 * 1118 * PARAMETERS: List - Current field list pointer 1119 * 1120 * RETURN: Status 1121 * 1122 * DESCRIPTION: Compile EINJ. 1123 * 1124 *****************************************************************************/ 1125 1126 ACPI_STATUS 1127 DtCompileEinj ( 1128 void **List) 1129 { 1130 ACPI_STATUS Status; 1131 1132 1133 Status = DtCompileTwoSubtables (List, 1134 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1135 return (Status); 1136 } 1137 1138 1139 /****************************************************************************** 1140 * 1141 * FUNCTION: DtCompileErst 1142 * 1143 * PARAMETERS: List - Current field list pointer 1144 * 1145 * RETURN: Status 1146 * 1147 * DESCRIPTION: Compile ERST. 1148 * 1149 *****************************************************************************/ 1150 1151 ACPI_STATUS 1152 DtCompileErst ( 1153 void **List) 1154 { 1155 ACPI_STATUS Status; 1156 1157 1158 Status = DtCompileTwoSubtables (List, 1159 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 1160 return (Status); 1161 } 1162 1163 1164 /****************************************************************************** 1165 * 1166 * FUNCTION: DtCompileGtdt 1167 * 1168 * PARAMETERS: List - Current field list pointer 1169 * 1170 * RETURN: Status 1171 * 1172 * DESCRIPTION: Compile GTDT. 1173 * 1174 *****************************************************************************/ 1175 1176 ACPI_STATUS 1177 DtCompileGtdt ( 1178 void **List) 1179 { 1180 ACPI_STATUS Status; 1181 DT_SUBTABLE *Subtable; 1182 DT_SUBTABLE *ParentTable; 1183 DT_FIELD **PFieldList = (DT_FIELD **) List; 1184 DT_FIELD *SubtableStart; 1185 ACPI_SUBTABLE_HEADER *GtdtHeader; 1186 ACPI_DMTABLE_INFO *InfoTable; 1187 UINT32 GtCount; 1188 ACPI_TABLE_HEADER *Header; 1189 1190 1191 ParentTable = DtPeekSubtable (); 1192 1193 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1194 1195 /* Compile the main table */ 1196 1197 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1198 &Subtable); 1199 if (ACPI_FAILURE (Status)) 1200 { 1201 return (Status); 1202 } 1203 1204 /* GTDT revision 3 later contains 2 extra fields before subtables */ 1205 1206 if (Header->Revision > 2) 1207 { 1208 ParentTable = DtPeekSubtable (); 1209 DtInsertSubtable (ParentTable, Subtable); 1210 1211 Status = DtCompileTable (PFieldList, 1212 AcpiDmTableInfoGtdtEl2, &Subtable); 1213 if (ACPI_FAILURE (Status)) 1214 { 1215 return (Status); 1216 } 1217 } 1218 1219 ParentTable = DtPeekSubtable (); 1220 DtInsertSubtable (ParentTable, Subtable); 1221 1222 while (*PFieldList) 1223 { 1224 SubtableStart = *PFieldList; 1225 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1226 &Subtable); 1227 if (ACPI_FAILURE (Status)) 1228 { 1229 return (Status); 1230 } 1231 1232 ParentTable = DtPeekSubtable (); 1233 DtInsertSubtable (ParentTable, Subtable); 1234 DtPushSubtable (Subtable); 1235 1236 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1237 1238 switch (GtdtHeader->Type) 1239 { 1240 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1241 1242 InfoTable = AcpiDmTableInfoGtdt0; 1243 break; 1244 1245 case ACPI_GTDT_TYPE_WATCHDOG: 1246 1247 InfoTable = AcpiDmTableInfoGtdt1; 1248 break; 1249 1250 default: 1251 1252 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1253 return (AE_ERROR); 1254 } 1255 1256 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1257 if (ACPI_FAILURE (Status)) 1258 { 1259 return (Status); 1260 } 1261 1262 ParentTable = DtPeekSubtable (); 1263 DtInsertSubtable (ParentTable, Subtable); 1264 1265 /* 1266 * Additional GT block subtable data 1267 */ 1268 1269 switch (GtdtHeader->Type) 1270 { 1271 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1272 1273 DtPushSubtable (Subtable); 1274 ParentTable = DtPeekSubtable (); 1275 1276 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1277 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1278 1279 while (GtCount) 1280 { 1281 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1282 &Subtable); 1283 if (ACPI_FAILURE (Status)) 1284 { 1285 return (Status); 1286 } 1287 1288 DtInsertSubtable (ParentTable, Subtable); 1289 GtCount--; 1290 } 1291 1292 DtPopSubtable (); 1293 break; 1294 1295 default: 1296 1297 break; 1298 } 1299 1300 DtPopSubtable (); 1301 } 1302 1303 return (AE_OK); 1304 } 1305 1306 1307 /****************************************************************************** 1308 * 1309 * FUNCTION: DtCompileFpdt 1310 * 1311 * PARAMETERS: List - Current field list pointer 1312 * 1313 * RETURN: Status 1314 * 1315 * DESCRIPTION: Compile FPDT. 1316 * 1317 *****************************************************************************/ 1318 1319 ACPI_STATUS 1320 DtCompileFpdt ( 1321 void **List) 1322 { 1323 ACPI_STATUS Status; 1324 ACPI_FPDT_HEADER *FpdtHeader; 1325 DT_SUBTABLE *Subtable; 1326 DT_SUBTABLE *ParentTable; 1327 ACPI_DMTABLE_INFO *InfoTable; 1328 DT_FIELD **PFieldList = (DT_FIELD **) List; 1329 DT_FIELD *SubtableStart; 1330 1331 1332 while (*PFieldList) 1333 { 1334 SubtableStart = *PFieldList; 1335 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1336 &Subtable); 1337 if (ACPI_FAILURE (Status)) 1338 { 1339 return (Status); 1340 } 1341 1342 ParentTable = DtPeekSubtable (); 1343 DtInsertSubtable (ParentTable, Subtable); 1344 DtPushSubtable (Subtable); 1345 1346 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1347 1348 switch (FpdtHeader->Type) 1349 { 1350 case ACPI_FPDT_TYPE_BOOT: 1351 1352 InfoTable = AcpiDmTableInfoFpdt0; 1353 break; 1354 1355 case ACPI_FPDT_TYPE_S3PERF: 1356 1357 InfoTable = AcpiDmTableInfoFpdt1; 1358 break; 1359 1360 default: 1361 1362 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1363 return (AE_ERROR); 1364 break; 1365 } 1366 1367 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1368 if (ACPI_FAILURE (Status)) 1369 { 1370 return (Status); 1371 } 1372 1373 ParentTable = DtPeekSubtable (); 1374 DtInsertSubtable (ParentTable, Subtable); 1375 DtPopSubtable (); 1376 } 1377 1378 return (AE_OK); 1379 } 1380 1381 1382 /****************************************************************************** 1383 * 1384 * FUNCTION: DtCompileHest 1385 * 1386 * PARAMETERS: List - Current field list pointer 1387 * 1388 * RETURN: Status 1389 * 1390 * DESCRIPTION: Compile HEST. 1391 * 1392 *****************************************************************************/ 1393 1394 ACPI_STATUS 1395 DtCompileHest ( 1396 void **List) 1397 { 1398 ACPI_STATUS Status; 1399 DT_SUBTABLE *Subtable; 1400 DT_SUBTABLE *ParentTable; 1401 DT_FIELD **PFieldList = (DT_FIELD **) List; 1402 DT_FIELD *SubtableStart; 1403 ACPI_DMTABLE_INFO *InfoTable; 1404 UINT16 Type; 1405 UINT32 BankCount; 1406 1407 1408 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1409 &Subtable); 1410 if (ACPI_FAILURE (Status)) 1411 { 1412 return (Status); 1413 } 1414 1415 ParentTable = DtPeekSubtable (); 1416 DtInsertSubtable (ParentTable, Subtable); 1417 1418 while (*PFieldList) 1419 { 1420 /* Get subtable type */ 1421 1422 SubtableStart = *PFieldList; 1423 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1424 1425 switch (Type) 1426 { 1427 case ACPI_HEST_TYPE_IA32_CHECK: 1428 1429 InfoTable = AcpiDmTableInfoHest0; 1430 break; 1431 1432 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1433 1434 InfoTable = AcpiDmTableInfoHest1; 1435 break; 1436 1437 case ACPI_HEST_TYPE_IA32_NMI: 1438 1439 InfoTable = AcpiDmTableInfoHest2; 1440 break; 1441 1442 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1443 1444 InfoTable = AcpiDmTableInfoHest6; 1445 break; 1446 1447 case ACPI_HEST_TYPE_AER_ENDPOINT: 1448 1449 InfoTable = AcpiDmTableInfoHest7; 1450 break; 1451 1452 case ACPI_HEST_TYPE_AER_BRIDGE: 1453 1454 InfoTable = AcpiDmTableInfoHest8; 1455 break; 1456 1457 case ACPI_HEST_TYPE_GENERIC_ERROR: 1458 1459 InfoTable = AcpiDmTableInfoHest9; 1460 break; 1461 1462 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1463 1464 InfoTable = AcpiDmTableInfoHest10; 1465 break; 1466 1467 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1468 1469 InfoTable = AcpiDmTableInfoHest11; 1470 break; 1471 1472 default: 1473 1474 /* Cannot continue on unknown type */ 1475 1476 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1477 return (AE_ERROR); 1478 } 1479 1480 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1481 if (ACPI_FAILURE (Status)) 1482 { 1483 return (Status); 1484 } 1485 1486 DtInsertSubtable (ParentTable, Subtable); 1487 1488 /* 1489 * Additional subtable data - IA32 Error Bank(s) 1490 */ 1491 BankCount = 0; 1492 switch (Type) 1493 { 1494 case ACPI_HEST_TYPE_IA32_CHECK: 1495 1496 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1497 Subtable->Buffer))->NumHardwareBanks; 1498 break; 1499 1500 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1501 1502 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1503 Subtable->Buffer))->NumHardwareBanks; 1504 break; 1505 1506 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1507 1508 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1509 Subtable->Buffer))->NumHardwareBanks; 1510 break; 1511 1512 default: 1513 1514 break; 1515 } 1516 1517 while (BankCount) 1518 { 1519 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1520 &Subtable); 1521 if (ACPI_FAILURE (Status)) 1522 { 1523 return (Status); 1524 } 1525 1526 DtInsertSubtable (ParentTable, Subtable); 1527 BankCount--; 1528 } 1529 } 1530 1531 return (AE_OK); 1532 } 1533 1534 1535 /****************************************************************************** 1536 * 1537 * FUNCTION: DtCompileHmat 1538 * 1539 * PARAMETERS: List - Current field list pointer 1540 * 1541 * RETURN: Status 1542 * 1543 * DESCRIPTION: Compile HMAT. 1544 * 1545 *****************************************************************************/ 1546 1547 ACPI_STATUS 1548 DtCompileHmat ( 1549 void **List) 1550 { 1551 ACPI_STATUS Status; 1552 DT_SUBTABLE *Subtable; 1553 DT_SUBTABLE *ParentTable; 1554 DT_FIELD **PFieldList = (DT_FIELD **) List; 1555 DT_FIELD *SubtableStart; 1556 DT_FIELD *EntryStart; 1557 ACPI_HMAT_STRUCTURE *HmatStruct; 1558 ACPI_HMAT_LOCALITY *HmatLocality; 1559 ACPI_HMAT_CACHE *HmatCache; 1560 ACPI_DMTABLE_INFO *InfoTable; 1561 UINT32 IntPDNumber; 1562 UINT32 TgtPDNumber; 1563 UINT64 EntryNumber; 1564 UINT16 SMBIOSHandleNumber; 1565 1566 1567 ParentTable = DtPeekSubtable (); 1568 1569 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1570 &Subtable); 1571 if (ACPI_FAILURE (Status)) 1572 { 1573 return (Status); 1574 } 1575 DtInsertSubtable (ParentTable, Subtable); 1576 1577 while (*PFieldList) 1578 { 1579 /* Compile HMAT structure header */ 1580 1581 SubtableStart = *PFieldList; 1582 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1583 &Subtable); 1584 if (ACPI_FAILURE (Status)) 1585 { 1586 return (Status); 1587 } 1588 DtInsertSubtable (ParentTable, Subtable); 1589 1590 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1591 HmatStruct->Length = Subtable->Length; 1592 1593 /* Compile HMAT structure body */ 1594 1595 switch (HmatStruct->Type) 1596 { 1597 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1598 1599 InfoTable = AcpiDmTableInfoHmat0; 1600 break; 1601 1602 case ACPI_HMAT_TYPE_LOCALITY: 1603 1604 InfoTable = AcpiDmTableInfoHmat1; 1605 break; 1606 1607 case ACPI_HMAT_TYPE_CACHE: 1608 1609 InfoTable = AcpiDmTableInfoHmat2; 1610 break; 1611 1612 default: 1613 1614 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 1615 return (AE_ERROR); 1616 } 1617 1618 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1619 if (ACPI_FAILURE (Status)) 1620 { 1621 return (Status); 1622 } 1623 DtInsertSubtable (ParentTable, Subtable); 1624 HmatStruct->Length += Subtable->Length; 1625 1626 /* Compile HMAT structure additionals */ 1627 1628 switch (HmatStruct->Type) 1629 { 1630 case ACPI_HMAT_TYPE_LOCALITY: 1631 1632 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 1633 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1634 1635 /* Compile initiator proximity domain list */ 1636 1637 IntPDNumber = 0; 1638 while (*PFieldList) 1639 { 1640 Status = DtCompileTable (PFieldList, 1641 AcpiDmTableInfoHmat1a, &Subtable); 1642 if (ACPI_FAILURE (Status)) 1643 { 1644 return (Status); 1645 } 1646 if (!Subtable) 1647 { 1648 break; 1649 } 1650 DtInsertSubtable (ParentTable, Subtable); 1651 HmatStruct->Length += Subtable->Length; 1652 IntPDNumber++; 1653 } 1654 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 1655 1656 /* Compile target proximity domain list */ 1657 1658 TgtPDNumber = 0; 1659 while (*PFieldList) 1660 { 1661 Status = DtCompileTable (PFieldList, 1662 AcpiDmTableInfoHmat1b, &Subtable); 1663 if (ACPI_FAILURE (Status)) 1664 { 1665 return (Status); 1666 } 1667 if (!Subtable) 1668 { 1669 break; 1670 } 1671 DtInsertSubtable (ParentTable, Subtable); 1672 HmatStruct->Length += Subtable->Length; 1673 TgtPDNumber++; 1674 } 1675 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 1676 1677 /* Save start of the entries for reporting errors */ 1678 1679 EntryStart = *PFieldList; 1680 1681 /* Compile latency/bandwidth entries */ 1682 1683 EntryNumber = 0; 1684 while (*PFieldList) 1685 { 1686 Status = DtCompileTable (PFieldList, 1687 AcpiDmTableInfoHmat1c, &Subtable); 1688 if (ACPI_FAILURE (Status)) 1689 { 1690 return (Status); 1691 } 1692 if (!Subtable) 1693 { 1694 break; 1695 } 1696 DtInsertSubtable (ParentTable, Subtable); 1697 HmatStruct->Length += Subtable->Length; 1698 EntryNumber++; 1699 } 1700 1701 /* Validate number of entries */ 1702 1703 if (EntryNumber != 1704 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 1705 { 1706 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 1707 return (AE_ERROR); 1708 } 1709 break; 1710 1711 case ACPI_HMAT_TYPE_CACHE: 1712 1713 /* Compile SMBIOS handles */ 1714 1715 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 1716 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1717 SMBIOSHandleNumber = 0; 1718 while (*PFieldList) 1719 { 1720 Status = DtCompileTable (PFieldList, 1721 AcpiDmTableInfoHmat2a, &Subtable); 1722 if (ACPI_FAILURE (Status)) 1723 { 1724 return (Status); 1725 } 1726 if (!Subtable) 1727 { 1728 break; 1729 } 1730 DtInsertSubtable (ParentTable, Subtable); 1731 HmatStruct->Length += Subtable->Length; 1732 SMBIOSHandleNumber++; 1733 } 1734 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 1735 break; 1736 1737 default: 1738 1739 break; 1740 } 1741 } 1742 1743 return (AE_OK); 1744 } 1745 1746 1747 /****************************************************************************** 1748 * 1749 * FUNCTION: DtCompileIort 1750 * 1751 * PARAMETERS: List - Current field list pointer 1752 * 1753 * RETURN: Status 1754 * 1755 * DESCRIPTION: Compile IORT. 1756 * 1757 *****************************************************************************/ 1758 1759 ACPI_STATUS 1760 DtCompileIort ( 1761 void **List) 1762 { 1763 ACPI_STATUS Status; 1764 DT_SUBTABLE *Subtable; 1765 DT_SUBTABLE *ParentTable; 1766 DT_FIELD **PFieldList = (DT_FIELD **) List; 1767 DT_FIELD *SubtableStart; 1768 ACPI_TABLE_HEADER *Table; 1769 ACPI_TABLE_IORT *Iort; 1770 ACPI_IORT_NODE *IortNode; 1771 ACPI_IORT_ITS_GROUP *IortItsGroup; 1772 ACPI_IORT_SMMU *IortSmmu; 1773 ACPI_IORT_RMR *IortRmr; 1774 UINT32 NodeNumber; 1775 UINT32 NodeLength; 1776 UINT32 IdMappingNumber; 1777 UINT32 ItsNumber; 1778 UINT32 ContextIrptNumber; 1779 UINT32 PmuIrptNumber; 1780 UINT32 PaddingLength; 1781 UINT8 Revision; 1782 UINT32 RmrCount; 1783 1784 1785 ParentTable = DtPeekSubtable (); 1786 1787 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1788 &Subtable); 1789 if (ACPI_FAILURE (Status)) 1790 { 1791 return (Status); 1792 } 1793 DtInsertSubtable (ParentTable, Subtable); 1794 1795 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1796 Revision = Table->Revision; 1797 1798 /* Both IORT Rev E and E.a have known issues and are not supported */ 1799 1800 if (Revision == 1 || Revision == 2) 1801 { 1802 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 1803 return (AE_ERROR); 1804 } 1805 1806 /* 1807 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1808 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1809 */ 1810 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1811 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1812 1813 /* 1814 * OptionalPadding - Variable-length data 1815 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1816 * Optionally allows the generic data types to be used for filling 1817 * this field. 1818 */ 1819 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1820 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1821 &Subtable); 1822 if (ACPI_FAILURE (Status)) 1823 { 1824 return (Status); 1825 } 1826 if (Subtable) 1827 { 1828 DtInsertSubtable (ParentTable, Subtable); 1829 Iort->NodeOffset += Subtable->Length; 1830 } 1831 else 1832 { 1833 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1834 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1835 if (ACPI_FAILURE (Status)) 1836 { 1837 return (Status); 1838 } 1839 Iort->NodeOffset += PaddingLength; 1840 } 1841 1842 NodeNumber = 0; 1843 while (*PFieldList) 1844 { 1845 SubtableStart = *PFieldList; 1846 if (Revision == 0) 1847 { 1848 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1849 &Subtable); 1850 } 1851 else if (Revision >= 3) 1852 { 1853 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 1854 &Subtable); 1855 } 1856 1857 if (ACPI_FAILURE (Status)) 1858 { 1859 return (Status); 1860 } 1861 1862 DtInsertSubtable (ParentTable, Subtable); 1863 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1864 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1865 1866 DtPushSubtable (Subtable); 1867 ParentTable = DtPeekSubtable (); 1868 1869 switch (IortNode->Type) 1870 { 1871 case ACPI_IORT_NODE_ITS_GROUP: 1872 1873 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1874 &Subtable); 1875 if (ACPI_FAILURE (Status)) 1876 { 1877 return (Status); 1878 } 1879 1880 DtInsertSubtable (ParentTable, Subtable); 1881 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1882 NodeLength += Subtable->Length; 1883 1884 ItsNumber = 0; 1885 while (*PFieldList) 1886 { 1887 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1888 &Subtable); 1889 if (ACPI_FAILURE (Status)) 1890 { 1891 return (Status); 1892 } 1893 if (!Subtable) 1894 { 1895 break; 1896 } 1897 1898 DtInsertSubtable (ParentTable, Subtable); 1899 NodeLength += Subtable->Length; 1900 ItsNumber++; 1901 } 1902 1903 IortItsGroup->ItsCount = ItsNumber; 1904 break; 1905 1906 case ACPI_IORT_NODE_NAMED_COMPONENT: 1907 1908 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 1909 &Subtable); 1910 if (ACPI_FAILURE (Status)) 1911 { 1912 return (Status); 1913 } 1914 1915 DtInsertSubtable (ParentTable, Subtable); 1916 NodeLength += Subtable->Length; 1917 1918 /* 1919 * Padding - Variable-length data 1920 * Optionally allows the offset of the ID mappings to be used 1921 * for filling this field. 1922 */ 1923 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 1924 &Subtable); 1925 if (ACPI_FAILURE (Status)) 1926 { 1927 return (Status); 1928 } 1929 1930 if (Subtable) 1931 { 1932 DtInsertSubtable (ParentTable, Subtable); 1933 NodeLength += Subtable->Length; 1934 } 1935 else 1936 { 1937 if (NodeLength > IortNode->MappingOffset) 1938 { 1939 return (AE_BAD_DATA); 1940 } 1941 1942 if (NodeLength < IortNode->MappingOffset) 1943 { 1944 Status = DtCompilePadding ( 1945 IortNode->MappingOffset - NodeLength, 1946 &Subtable); 1947 if (ACPI_FAILURE (Status)) 1948 { 1949 return (Status); 1950 } 1951 1952 DtInsertSubtable (ParentTable, Subtable); 1953 NodeLength = IortNode->MappingOffset; 1954 } 1955 } 1956 break; 1957 1958 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 1959 1960 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 1961 &Subtable); 1962 if (ACPI_FAILURE (Status)) 1963 { 1964 return (Status); 1965 } 1966 1967 DtInsertSubtable (ParentTable, Subtable); 1968 NodeLength += Subtable->Length; 1969 break; 1970 1971 case ACPI_IORT_NODE_SMMU: 1972 1973 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 1974 &Subtable); 1975 if (ACPI_FAILURE (Status)) 1976 { 1977 return (Status); 1978 } 1979 1980 DtInsertSubtable (ParentTable, Subtable); 1981 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 1982 NodeLength += Subtable->Length; 1983 1984 /* Compile global interrupt array */ 1985 1986 IortSmmu->GlobalInterruptOffset = NodeLength; 1987 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 1988 &Subtable); 1989 if (ACPI_FAILURE (Status)) 1990 { 1991 return (Status); 1992 } 1993 1994 DtInsertSubtable (ParentTable, Subtable); 1995 NodeLength += Subtable->Length; 1996 1997 /* Compile context interrupt array */ 1998 1999 ContextIrptNumber = 0; 2000 IortSmmu->ContextInterruptOffset = NodeLength; 2001 while (*PFieldList) 2002 { 2003 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2004 &Subtable); 2005 if (ACPI_FAILURE (Status)) 2006 { 2007 return (Status); 2008 } 2009 2010 if (!Subtable) 2011 { 2012 break; 2013 } 2014 2015 DtInsertSubtable (ParentTable, Subtable); 2016 NodeLength += Subtable->Length; 2017 ContextIrptNumber++; 2018 } 2019 2020 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2021 2022 /* Compile PMU interrupt array */ 2023 2024 PmuIrptNumber = 0; 2025 IortSmmu->PmuInterruptOffset = NodeLength; 2026 while (*PFieldList) 2027 { 2028 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2029 &Subtable); 2030 if (ACPI_FAILURE (Status)) 2031 { 2032 return (Status); 2033 } 2034 2035 if (!Subtable) 2036 { 2037 break; 2038 } 2039 2040 DtInsertSubtable (ParentTable, Subtable); 2041 NodeLength += Subtable->Length; 2042 PmuIrptNumber++; 2043 } 2044 2045 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2046 break; 2047 2048 case ACPI_IORT_NODE_SMMU_V3: 2049 2050 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2051 &Subtable); 2052 if (ACPI_FAILURE (Status)) 2053 { 2054 return (Status); 2055 } 2056 2057 DtInsertSubtable (ParentTable, Subtable); 2058 NodeLength += Subtable->Length; 2059 break; 2060 2061 case ACPI_IORT_NODE_PMCG: 2062 2063 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2064 &Subtable); 2065 if (ACPI_FAILURE (Status)) 2066 { 2067 return (Status); 2068 } 2069 2070 DtInsertSubtable (ParentTable, Subtable); 2071 NodeLength += Subtable->Length; 2072 break; 2073 2074 case ACPI_IORT_NODE_RMR: 2075 2076 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2077 &Subtable); 2078 if (ACPI_FAILURE (Status)) 2079 { 2080 return (Status); 2081 } 2082 2083 DtInsertSubtable (ParentTable, Subtable); 2084 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2085 NodeLength += Subtable->Length; 2086 2087 /* Compile RMR Descriptors */ 2088 2089 RmrCount = 0; 2090 IortRmr->RmrOffset = NodeLength; 2091 while (*PFieldList) 2092 { 2093 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2094 &Subtable); 2095 if (ACPI_FAILURE (Status)) 2096 { 2097 return (Status); 2098 } 2099 2100 if (!Subtable) 2101 { 2102 break; 2103 } 2104 2105 DtInsertSubtable (ParentTable, Subtable); 2106 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2107 RmrCount++; 2108 } 2109 2110 IortRmr->RmrCount = RmrCount; 2111 break; 2112 2113 default: 2114 2115 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 2116 return (AE_ERROR); 2117 } 2118 2119 /* Compile Array of ID mappings */ 2120 2121 IortNode->MappingOffset = NodeLength; 2122 IdMappingNumber = 0; 2123 while (*PFieldList) 2124 { 2125 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 2126 &Subtable); 2127 if (ACPI_FAILURE (Status)) 2128 { 2129 return (Status); 2130 } 2131 2132 if (!Subtable) 2133 { 2134 break; 2135 } 2136 2137 DtInsertSubtable (ParentTable, Subtable); 2138 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 2139 IdMappingNumber++; 2140 } 2141 2142 IortNode->MappingCount = IdMappingNumber; 2143 if (!IdMappingNumber) 2144 { 2145 IortNode->MappingOffset = 0; 2146 } 2147 2148 /* 2149 * Node length can be determined by DT_LENGTH option 2150 * IortNode->Length = NodeLength; 2151 */ 2152 DtPopSubtable (); 2153 ParentTable = DtPeekSubtable (); 2154 NodeNumber++; 2155 } 2156 2157 Iort->NodeCount = NodeNumber; 2158 return (AE_OK); 2159 } 2160 2161 2162 /****************************************************************************** 2163 * 2164 * FUNCTION: DtCompileIvrs 2165 * 2166 * PARAMETERS: List - Current field list pointer 2167 * 2168 * RETURN: Status 2169 * 2170 * DESCRIPTION: Compile IVRS. Notes: 2171 * The IVRS is essentially a flat table, with the following 2172 * structure: 2173 * <Main ACPI Table Header> 2174 * <Main subtable - virtualization info> 2175 * <IVHD> 2176 * <Device Entries> 2177 * ... 2178 * <IVHD> 2179 * <Device Entries> 2180 * <IVMD> 2181 * ... 2182 * 2183 *****************************************************************************/ 2184 2185 ACPI_STATUS 2186 DtCompileIvrs ( 2187 void **List) 2188 { 2189 ACPI_STATUS Status; 2190 DT_SUBTABLE *Subtable; 2191 DT_SUBTABLE *ParentTable; 2192 DT_SUBTABLE *MainSubtable; 2193 DT_FIELD **PFieldList = (DT_FIELD **) List; 2194 DT_FIELD *SubtableStart; 2195 ACPI_DMTABLE_INFO *InfoTable = NULL; 2196 UINT8 SubtableType; 2197 UINT8 Temp64[16]; 2198 UINT8 Temp8; 2199 2200 2201 /* Main table */ 2202 2203 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 2204 &Subtable); 2205 if (ACPI_FAILURE (Status)) 2206 { 2207 return (Status); 2208 } 2209 2210 ParentTable = DtPeekSubtable (); 2211 DtInsertSubtable (ParentTable, Subtable); 2212 DtPushSubtable (Subtable); 2213 2214 /* Save a pointer to the main subtable */ 2215 2216 MainSubtable = Subtable; 2217 2218 while (*PFieldList) 2219 { 2220 SubtableStart = *PFieldList; 2221 2222 /* Compile the SubtableType integer */ 2223 2224 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 2225 2226 switch (SubtableType) 2227 { 2228 2229 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 2230 2231 case ACPI_IVRS_TYPE_HARDWARE1: 2232 2233 InfoTable = AcpiDmTableInfoIvrsHware1; 2234 break; 2235 2236 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 2237 2238 case ACPI_IVRS_TYPE_HARDWARE2: 2239 case ACPI_IVRS_TYPE_HARDWARE3: 2240 2241 InfoTable = AcpiDmTableInfoIvrsHware23; 2242 break; 2243 2244 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 2245 2246 case ACPI_IVRS_TYPE_MEMORY1: 2247 case ACPI_IVRS_TYPE_MEMORY2: 2248 case ACPI_IVRS_TYPE_MEMORY3: 2249 2250 InfoTable = AcpiDmTableInfoIvrsMemory; 2251 break; 2252 2253 /* 4-byte device entries */ 2254 2255 case ACPI_IVRS_TYPE_PAD4: 2256 case ACPI_IVRS_TYPE_ALL: 2257 case ACPI_IVRS_TYPE_SELECT: 2258 case ACPI_IVRS_TYPE_START: 2259 case ACPI_IVRS_TYPE_END: 2260 2261 InfoTable = AcpiDmTableInfoIvrs4; 2262 break; 2263 2264 /* 8-byte device entries, type A */ 2265 2266 case ACPI_IVRS_TYPE_ALIAS_SELECT: 2267 case ACPI_IVRS_TYPE_ALIAS_START: 2268 2269 InfoTable = AcpiDmTableInfoIvrs8a; 2270 break; 2271 2272 /* 8-byte device entries, type B */ 2273 2274 case ACPI_IVRS_TYPE_EXT_SELECT: 2275 case ACPI_IVRS_TYPE_EXT_START: 2276 2277 InfoTable = AcpiDmTableInfoIvrs8b; 2278 break; 2279 2280 /* 8-byte device entries, type C */ 2281 2282 case ACPI_IVRS_TYPE_SPECIAL: 2283 2284 InfoTable = AcpiDmTableInfoIvrs8c; 2285 break; 2286 2287 /* Variable device entries, type F0h */ 2288 2289 case ACPI_IVRS_TYPE_HID: 2290 2291 InfoTable = AcpiDmTableInfoIvrsHid; 2292 break; 2293 2294 default: 2295 2296 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 2297 "IVRS Device Entry"); 2298 return (AE_ERROR); 2299 } 2300 2301 /* Compile the InfoTable from above */ 2302 2303 Status = DtCompileTable (PFieldList, InfoTable, 2304 &Subtable); 2305 if (ACPI_FAILURE (Status)) 2306 { 2307 return (Status); 2308 } 2309 2310 ParentTable = DtPeekSubtable (); 2311 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 2312 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 2313 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 2314 SubtableType != ACPI_IVRS_TYPE_HID && 2315 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 2316 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 2317 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 2318 { 2319 if (ParentTable) 2320 DtInsertSubtable (ParentTable, Subtable); 2321 } 2322 2323 switch (SubtableType) 2324 { 2325 case ACPI_IVRS_TYPE_HARDWARE1: 2326 case ACPI_IVRS_TYPE_HARDWARE2: 2327 case ACPI_IVRS_TYPE_HARDWARE3: 2328 case ACPI_IVRS_TYPE_MEMORY1: 2329 case ACPI_IVRS_TYPE_MEMORY2: 2330 case ACPI_IVRS_TYPE_MEMORY3: 2331 2332 /* Insert these IVHDs/IVMDs at the root subtable */ 2333 2334 DtInsertSubtable (MainSubtable, Subtable); 2335 DtPushSubtable (Subtable); 2336 ParentTable = MainSubtable; 2337 break; 2338 2339 case ACPI_IVRS_TYPE_HID: 2340 2341 /* Special handling for the HID named device entry (0xF0) */ 2342 2343 if (ParentTable) 2344 { 2345 DtInsertSubtable (ParentTable, Subtable); 2346 } 2347 2348 /* 2349 * Process the HID value. First, get the HID value as a string. 2350 */ 2351 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2352 2353 /* 2354 * Determine if the HID is an integer or a string. 2355 * An integer is defined to be 32 bits, with the upper 32 bits 2356 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 2357 * integer or a character string. If an integer, the lower 2358 * 4 bytes of the field contain the integer and the upper 2359 * 4 bytes are padded with 0". 2360 */ 2361 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2362 { 2363 /* Compile the HID value as an integer */ 2364 2365 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2366 2367 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 2368 &Subtable); 2369 if (ACPI_FAILURE (Status)) 2370 { 2371 return (Status); 2372 } 2373 } 2374 else 2375 { 2376 /* Compile the HID value as a string */ 2377 2378 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 2379 &Subtable); 2380 if (ACPI_FAILURE (Status)) 2381 { 2382 return (Status); 2383 } 2384 } 2385 2386 DtInsertSubtable (ParentTable, Subtable); 2387 2388 /* 2389 * Process the CID value. First, get the CID value as a string. 2390 */ 2391 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2392 2393 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2394 { 2395 /* Compile the CID value as an integer */ 2396 2397 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2398 2399 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 2400 &Subtable); 2401 if (ACPI_FAILURE (Status)) 2402 { 2403 return (Status); 2404 } 2405 } 2406 else 2407 { 2408 /* Compile the CID value as a string */ 2409 2410 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 2411 &Subtable); 2412 if (ACPI_FAILURE (Status)) 2413 { 2414 return (Status); 2415 } 2416 } 2417 2418 DtInsertSubtable (ParentTable, Subtable); 2419 2420 /* 2421 * Process the UID value. First, get and decode the "UID Format" field (Integer). 2422 */ 2423 if (!*PFieldList) 2424 { 2425 return (AE_OK); 2426 } 2427 2428 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 2429 2430 switch (Temp8) 2431 { 2432 case ACPI_IVRS_UID_NOT_PRESENT: 2433 break; 2434 2435 case ACPI_IVRS_UID_IS_INTEGER: 2436 2437 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 2438 &Subtable); 2439 if (ACPI_FAILURE (Status)) 2440 { 2441 return (Status); 2442 } 2443 DtInsertSubtable (ParentTable, Subtable); 2444 break; 2445 2446 case ACPI_IVRS_UID_IS_STRING: 2447 2448 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 2449 &Subtable); 2450 if (ACPI_FAILURE (Status)) 2451 { 2452 return (Status); 2453 } 2454 DtInsertSubtable (ParentTable, Subtable); 2455 break; 2456 2457 default: 2458 2459 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 2460 "IVRS Device Entry"); 2461 return (AE_ERROR); 2462 } 2463 2464 default: 2465 2466 /* All other subtable types come through here */ 2467 break; 2468 } 2469 } 2470 2471 return (AE_OK); 2472 } 2473