1 /****************************************************************************** 2 * 3 * Module Name: dttable1.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2026, 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 ACPI_AEST_NODE_INTERFACE_HEADER *AestNodeHeader; 102 UINT8 Revision; 103 ACPI_TABLE_HEADER *Header; 104 105 ParentTable = DtPeekSubtable (); 106 107 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 108 Revision = Header->Revision; 109 110 while (*PFieldList) 111 { 112 /* Compile the common error node header */ 113 114 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr, 115 &Subtable); 116 if (ACPI_FAILURE (Status)) 117 { 118 return (Status); 119 } 120 121 ParentTable = DtPeekSubtable (); 122 DtInsertSubtable (ParentTable, Subtable); 123 124 /* Everything past the error node header will be a subtable */ 125 126 DtPushSubtable (Subtable); 127 128 /* 129 * Compile the node-specific structure (Based on the error 130 * node header Type field) 131 */ 132 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer); 133 134 /* Point past the common error node header */ 135 136 Offset = sizeof (ACPI_AEST_HEADER); 137 ErrorNodeHeader->NodeSpecificOffset = Offset; 138 139 /* Decode the error node type */ 140 141 switch (ErrorNodeHeader->Type) 142 { 143 case ACPI_AEST_PROCESSOR_ERROR_NODE: 144 145 InfoTable = AcpiDmTableInfoAestProcError; 146 break; 147 148 case ACPI_AEST_MEMORY_ERROR_NODE: 149 150 InfoTable = AcpiDmTableInfoAestMemError; 151 break; 152 153 case ACPI_AEST_SMMU_ERROR_NODE: 154 155 InfoTable = AcpiDmTableInfoAestSmmuError; 156 break; 157 158 case ACPI_AEST_VENDOR_ERROR_NODE: 159 switch (Revision) 160 { 161 case 1: 162 InfoTable = AcpiDmTableInfoAestVendorError; 163 break; 164 165 case 2: 166 InfoTable = AcpiDmTableInfoAestVendorV2Error; 167 break; 168 169 default: 170 AcpiOsPrintf ("Unknown AEST Vendor Error Revision: %X\n", 171 Revision); 172 return (AE_ERROR); 173 } 174 break; 175 176 case ACPI_AEST_GIC_ERROR_NODE: 177 178 InfoTable = AcpiDmTableInfoAestGicError; 179 break; 180 181 case ACPI_AEST_PCIE_ERROR_NODE: 182 183 InfoTable = AcpiDmTableInfoAestPCIeError; 184 break; 185 186 case ACPI_AEST_PROXY_ERROR_NODE: 187 188 InfoTable = AcpiDmTableInfoAestProxyError; 189 break; 190 191 /* Error case below */ 192 default: 193 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n", 194 ErrorNodeHeader->Type); 195 return (AE_ERROR); 196 } 197 198 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 199 if (ACPI_FAILURE (Status)) 200 { 201 return (Status); 202 } 203 204 /* Point past the node-specific structure */ 205 206 Offset += Subtable->Length; 207 ErrorNodeHeader->NodeInterfaceOffset = Offset; 208 209 ParentTable = DtPeekSubtable (); 210 DtInsertSubtable (ParentTable, Subtable); 211 212 /* Compile any additional node-specific substructures */ 213 214 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE) 215 { 216 /* 217 * Special handling for PROCESSOR_ERROR_NODE subtables 218 * (to handle the Resource Substructure via the ResourceType 219 * field). 220 */ 221 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, 222 Subtable->Buffer); 223 224 switch (AestProcessor->ResourceType) 225 { 226 case ACPI_AEST_CACHE_RESOURCE: 227 228 InfoTable = AcpiDmTableInfoAestCacheRsrc; 229 break; 230 231 case ACPI_AEST_TLB_RESOURCE: 232 233 InfoTable = AcpiDmTableInfoAestTlbRsrc; 234 break; 235 236 case ACPI_AEST_GENERIC_RESOURCE: 237 238 InfoTable = AcpiDmTableInfoAestGenRsrc; 239 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n", 240 AestProcessor->ResourceType); 241 return (AE_ERROR); 242 243 /* Error case below */ 244 default: 245 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n", 246 AestProcessor->ResourceType); 247 return (AE_ERROR); 248 } 249 250 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 251 if (ACPI_FAILURE (Status)) 252 { 253 return (Status); 254 } 255 256 /* Point past the resource substructure subtable */ 257 258 Offset += Subtable->Length; 259 ErrorNodeHeader->NodeInterfaceOffset = Offset; 260 261 ParentTable = DtPeekSubtable (); 262 DtInsertSubtable (ParentTable, Subtable); 263 } 264 265 /* Compile the (required) node interface structure */ 266 if (Revision == 1) 267 { 268 InfoTable = AcpiDmTableInfoAestXface; 269 } 270 else if (Revision == 2) 271 { 272 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXfaceHeader, 273 &Subtable); 274 if (ACPI_FAILURE (Status)) 275 { 276 return (Status); 277 } 278 279 ParentTable = DtPeekSubtable (); 280 DtInsertSubtable (ParentTable, Subtable); 281 282 Offset += Subtable->Length; 283 284 AestNodeHeader = ACPI_CAST_PTR (ACPI_AEST_NODE_INTERFACE_HEADER, 285 Subtable->Buffer); 286 287 switch (AestNodeHeader->GroupFormat) 288 { 289 case ACPI_AEST_NODE_GROUP_FORMAT_4K: 290 291 InfoTable = AcpiDmTableInfoAestXface4k; 292 break; 293 294 case ACPI_AEST_NODE_GROUP_FORMAT_16K: 295 296 InfoTable = AcpiDmTableInfoAestXface16k; 297 break; 298 299 case ACPI_AEST_NODE_GROUP_FORMAT_64K: 300 301 InfoTable = AcpiDmTableInfoAestXface64k; 302 break; 303 304 /* Error case below */ 305 default: 306 AcpiOsPrintf ("Unknown AEST Interface Group Format: %X\n", 307 AestNodeHeader->GroupFormat); 308 return (AE_ERROR); 309 } 310 } 311 else 312 { 313 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision); 314 } 315 316 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 317 if (ACPI_FAILURE (Status)) 318 { 319 return (Status); 320 } 321 322 ErrorNodeHeader->NodeInterruptOffset = 0; 323 ParentTable = DtPeekSubtable (); 324 DtInsertSubtable (ParentTable, Subtable); 325 326 /* Compile each of the node interrupt structures */ 327 328 if (ErrorNodeHeader->NodeInterruptCount) 329 { 330 /* Point to the first interrupt structure */ 331 332 Offset += Subtable->Length; 333 ErrorNodeHeader->NodeInterruptOffset = Offset; 334 } 335 336 /* Compile each of the interrupt structures */ 337 338 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++) 339 { 340 switch (Revision) { 341 case 1: 342 343 InfoTable = AcpiDmTableInfoAestXrupt; 344 break; 345 346 case 2: 347 348 InfoTable = AcpiDmTableInfoAestXruptV2; 349 break; 350 351 default: 352 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision); 353 return (AE_ERROR); 354 } 355 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 356 if (ACPI_FAILURE (Status)) 357 { 358 return (Status); 359 } 360 361 ParentTable = DtPeekSubtable (); 362 DtInsertSubtable (ParentTable, Subtable); 363 } 364 365 /* Prepare for the next AEST Error node */ 366 367 DtPopSubtable (); 368 } 369 370 return (AE_OK); 371 } 372 373 374 /****************************************************************************** 375 * 376 * FUNCTION: DtCompileApmt 377 * 378 * PARAMETERS: List - Current field list pointer 379 * 380 * RETURN: Status 381 * 382 * DESCRIPTION: Compile APMT. 383 * 384 *****************************************************************************/ 385 386 ACPI_STATUS 387 DtCompileApmt ( 388 void **List) 389 { 390 ACPI_STATUS Status; 391 ACPI_TABLE_HEADER *Header; 392 ACPI_APMT_NODE *ApmtNode; 393 ACPI_APMT_NODE *PeerApmtNode; 394 DT_SUBTABLE *Subtable; 395 DT_SUBTABLE *PeerSubtable; 396 DT_SUBTABLE *ParentTable; 397 DT_FIELD **PFieldList = (DT_FIELD**)List; 398 DT_FIELD *SubtableStart; 399 UINT32 CurLength; 400 char MsgBuffer[64] = ""; 401 402 ParentTable = DtPeekSubtable(); 403 404 Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer); 405 406 CurLength = sizeof(ACPI_TABLE_HEADER); 407 408 /* Walk the parse tree */ 409 410 while (*PFieldList) 411 { 412 /* APMT Node Subtable */ 413 414 SubtableStart = *PFieldList; 415 416 Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable); 417 418 if (ACPI_FAILURE(Status)) 419 { 420 return (Status); 421 } 422 423 ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer); 424 425 if (ApmtNode->Length != sizeof(ACPI_APMT_NODE)) 426 { 427 DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT"); 428 return (AE_ERROR); 429 } 430 431 if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT) 432 { 433 snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type); 434 DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer); 435 return (AE_ERROR); 436 } 437 438 PeerSubtable = DtGetNextSubtable(ParentTable, NULL); 439 440 /* Validate the node id needs to be unique. */ 441 while(PeerSubtable) 442 { 443 PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer); 444 if (PeerApmtNode->Id == ApmtNode->Id) 445 { 446 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id); 447 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer); 448 return (AE_ERROR); 449 } 450 451 PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable); 452 } 453 454 CurLength += ApmtNode->Length; 455 456 DtInsertSubtable(ParentTable, Subtable); 457 } 458 459 if (Header->Length != CurLength) 460 { 461 snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)", 462 Header->Length, CurLength); 463 DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer); 464 return (AE_ERROR); 465 } 466 467 return (AE_OK); 468 } 469 470 /****************************************************************************** 471 * 472 * FUNCTION: DtCompileAsf 473 * 474 * PARAMETERS: List - Current field list pointer 475 * 476 * RETURN: Status 477 * 478 * DESCRIPTION: Compile ASF!. 479 * 480 *****************************************************************************/ 481 482 ACPI_STATUS 483 DtCompileAsf ( 484 void **List) 485 { 486 ACPI_ASF_INFO *AsfTable; 487 DT_SUBTABLE *Subtable; 488 DT_SUBTABLE *ParentTable; 489 ACPI_DMTABLE_INFO *InfoTable; 490 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 491 UINT32 DataCount = 0; 492 ACPI_STATUS Status; 493 UINT32 i; 494 DT_FIELD **PFieldList = (DT_FIELD **) List; 495 DT_FIELD *SubtableStart; 496 497 498 while (*PFieldList) 499 { 500 SubtableStart = *PFieldList; 501 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 502 &Subtable); 503 if (ACPI_FAILURE (Status)) 504 { 505 return (Status); 506 } 507 508 ParentTable = DtPeekSubtable (); 509 DtInsertSubtable (ParentTable, Subtable); 510 DtPushSubtable (Subtable); 511 512 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 513 514 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 515 { 516 case ACPI_ASF_TYPE_INFO: 517 518 InfoTable = AcpiDmTableInfoAsf0; 519 break; 520 521 case ACPI_ASF_TYPE_ALERT: 522 523 InfoTable = AcpiDmTableInfoAsf1; 524 break; 525 526 case ACPI_ASF_TYPE_CONTROL: 527 528 InfoTable = AcpiDmTableInfoAsf2; 529 break; 530 531 case ACPI_ASF_TYPE_BOOT: 532 533 InfoTable = AcpiDmTableInfoAsf3; 534 break; 535 536 case ACPI_ASF_TYPE_ADDRESS: 537 538 InfoTable = AcpiDmTableInfoAsf4; 539 break; 540 541 default: 542 543 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 544 return (AE_ERROR); 545 } 546 547 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 548 if (ACPI_FAILURE (Status)) 549 { 550 return (Status); 551 } 552 553 ParentTable = DtPeekSubtable (); 554 DtInsertSubtable (ParentTable, Subtable); 555 556 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 557 { 558 case ACPI_ASF_TYPE_INFO: 559 560 DataInfoTable = NULL; 561 break; 562 563 case ACPI_ASF_TYPE_ALERT: 564 565 DataInfoTable = AcpiDmTableInfoAsf1a; 566 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 567 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 568 sizeof (ACPI_ASF_HEADER)))->Alerts; 569 break; 570 571 case ACPI_ASF_TYPE_CONTROL: 572 573 DataInfoTable = AcpiDmTableInfoAsf2a; 574 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 575 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 576 sizeof (ACPI_ASF_HEADER)))->Controls; 577 break; 578 579 case ACPI_ASF_TYPE_BOOT: 580 581 DataInfoTable = NULL; 582 break; 583 584 case ACPI_ASF_TYPE_ADDRESS: 585 586 DataInfoTable = TableInfoAsfAddress; 587 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 588 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 589 sizeof (ACPI_ASF_HEADER)))->Devices; 590 break; 591 592 default: 593 594 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 595 return (AE_ERROR); 596 } 597 598 if (DataInfoTable) 599 { 600 switch (AsfTable->Header.Type & 0x7F) 601 { 602 case ACPI_ASF_TYPE_ADDRESS: 603 604 while (DataCount > 0) 605 { 606 Status = DtCompileTable (PFieldList, DataInfoTable, 607 &Subtable); 608 if (ACPI_FAILURE (Status)) 609 { 610 return (Status); 611 } 612 613 DtInsertSubtable (ParentTable, Subtable); 614 DataCount = DataCount - Subtable->Length; 615 } 616 break; 617 618 default: 619 620 for (i = 0; i < DataCount; i++) 621 { 622 Status = DtCompileTable (PFieldList, DataInfoTable, 623 &Subtable); 624 if (ACPI_FAILURE (Status)) 625 { 626 return (Status); 627 } 628 629 DtInsertSubtable (ParentTable, Subtable); 630 } 631 break; 632 } 633 } 634 635 DtPopSubtable (); 636 } 637 638 return (AE_OK); 639 } 640 641 /****************************************************************************** 642 * 643 * FUNCTION: DtCompileAspt 644 * 645 * PARAMETERS: List - Current field list pointer 646 * 647 * RETURN: Status 648 * 649 * DESCRIPTION: Compile ASPT. 650 * 651 *****************************************************************************/ 652 653 ACPI_STATUS 654 DtCompileAspt ( 655 void **List) 656 { 657 ACPI_ASPT_HEADER *AsptTable; 658 DT_SUBTABLE *Subtable; 659 DT_SUBTABLE *ParentTable; 660 ACPI_DMTABLE_INFO *InfoTable; 661 ACPI_STATUS Status; 662 DT_FIELD **PFieldList = (DT_FIELD **) List; 663 DT_FIELD *SubtableStart; 664 665 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable); 666 if (ACPI_FAILURE (Status)) 667 { 668 return (Status); 669 } 670 671 ParentTable = DtPeekSubtable (); 672 DtInsertSubtable (ParentTable, Subtable); 673 674 while (*PFieldList) 675 { 676 SubtableStart = *PFieldList; 677 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr, 678 &Subtable); 679 if (ACPI_FAILURE (Status)) 680 { 681 return (Status); 682 } 683 684 ParentTable = DtPeekSubtable (); 685 DtInsertSubtable (ParentTable, Subtable); 686 DtPushSubtable (Subtable); 687 688 AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer); 689 690 switch (AsptTable->Type) /* Mask off top bit */ 691 { 692 case ACPI_ASPT_TYPE_GLOBAL_REGS: 693 694 InfoTable = AcpiDmTableInfoAspt0; 695 break; 696 697 case ACPI_ASPT_TYPE_SEV_MBOX_REGS: 698 699 InfoTable = AcpiDmTableInfoAspt1; 700 break; 701 702 case ACPI_ASPT_TYPE_ACPI_MBOX_REGS: 703 704 InfoTable = AcpiDmTableInfoAspt2; 705 break; 706 707 default: 708 709 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT"); 710 return (AE_ERROR); 711 } 712 713 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 714 if (ACPI_FAILURE (Status)) 715 { 716 return (Status); 717 } 718 ParentTable = DtPeekSubtable (); 719 DtInsertSubtable (ParentTable, Subtable); 720 DtPopSubtable (); 721 } 722 723 return (AE_OK); 724 } 725 726 727 /****************************************************************************** 728 * 729 * FUNCTION: DtCompileCdat 730 * 731 * PARAMETERS: List - Current field list pointer 732 * 733 * RETURN: Status 734 * 735 * DESCRIPTION: Compile CDAT. 736 * 737 *****************************************************************************/ 738 739 ACPI_STATUS 740 DtCompileCdat ( 741 void **List) 742 { 743 ACPI_STATUS Status = AE_OK; 744 DT_SUBTABLE *Subtable; 745 DT_SUBTABLE *ParentTable; 746 DT_FIELD **PFieldList = (DT_FIELD **) List; 747 ACPI_CDAT_HEADER *CdatHeader; 748 ACPI_DMTABLE_INFO *InfoTable = NULL; 749 DT_FIELD *SubtableStart; 750 751 752 /* Walk the parse tree. 753 * 754 * Note: Main table consists of only the CDAT table header 755 * (This is not the standard ACPI table header, however)-- 756 * Followed by some number of subtables. 757 */ 758 while (*PFieldList) 759 { 760 SubtableStart = *PFieldList; 761 762 /* Compile the expected CDAT Subtable header */ 763 764 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader, 765 &Subtable); 766 if (ACPI_FAILURE (Status)) 767 { 768 return (Status); 769 } 770 771 ParentTable = DtPeekSubtable (); 772 DtInsertSubtable (ParentTable, Subtable); 773 DtPushSubtable (Subtable); 774 775 CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer); 776 777 /* Decode the subtable by type */ 778 779 switch (CdatHeader->Type) 780 { 781 case ACPI_CDAT_TYPE_DSMAS: 782 InfoTable = AcpiDmTableInfoCdat0; 783 break; 784 785 case ACPI_CDAT_TYPE_DSLBIS: 786 InfoTable = AcpiDmTableInfoCdat1; 787 break; 788 789 case ACPI_CDAT_TYPE_DSMSCIS: 790 InfoTable = AcpiDmTableInfoCdat2; 791 break; 792 793 case ACPI_CDAT_TYPE_DSIS: 794 InfoTable = AcpiDmTableInfoCdat3; 795 break; 796 797 case ACPI_CDAT_TYPE_DSEMTS: 798 InfoTable = AcpiDmTableInfoCdat4; 799 break; 800 801 case ACPI_CDAT_TYPE_SSLBIS: 802 InfoTable = AcpiDmTableInfoCdat5; 803 break; 804 805 default: 806 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT"); 807 } 808 809 /* Compile the CDAT subtable */ 810 811 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 812 if (ACPI_FAILURE (Status)) 813 { 814 return (Status); 815 } 816 817 ParentTable = DtPeekSubtable (); 818 DtInsertSubtable (ParentTable, Subtable); 819 820 switch (CdatHeader->Type) 821 { 822 /* Multiple entries supported for this type */ 823 824 case ACPI_CDAT_TYPE_SSLBIS: 825 826 /* 827 * Check for multiple SSLBEs 828 */ 829 while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID")) 830 { 831 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable); 832 if (ACPI_FAILURE (Status)) 833 { 834 return (Status); 835 } 836 ParentTable = DtPeekSubtable (); 837 DtInsertSubtable (ParentTable, Subtable); 838 } 839 break; 840 841 default: 842 break; 843 } 844 845 /* Pop off the CDAT Subtable header subtree */ 846 847 DtPopSubtable (); 848 } 849 850 return (AE_OK); 851 } 852 853 854 /****************************************************************************** 855 * 856 * FUNCTION: DtCompileCedt 857 * 858 * PARAMETERS: List - Current field list pointer 859 * 860 * RETURN: Status 861 * 862 * DESCRIPTION: Compile CEDT. 863 * 864 *****************************************************************************/ 865 866 ACPI_STATUS 867 DtCompileCedt ( 868 void **List) 869 { 870 ACPI_STATUS Status; 871 DT_SUBTABLE *Subtable; 872 DT_SUBTABLE *ParentTable; 873 DT_FIELD **PFieldList = (DT_FIELD **) List; 874 ACPI_CEDT_HEADER *CedtHeader; 875 DT_FIELD *SubtableStart; 876 877 878 /* Walk the parse tree */ 879 880 while (*PFieldList) 881 { 882 /* if CFMWS and has more than one target, then set to zero later */ 883 884 int InsertFlag = 1; 885 SubtableStart = *PFieldList; 886 887 /* CEDT Header */ 888 889 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr, 890 &Subtable); 891 if (ACPI_FAILURE (Status)) 892 { 893 return (Status); 894 } 895 896 ParentTable = DtPeekSubtable (); 897 DtInsertSubtable (ParentTable, Subtable); 898 DtPushSubtable (Subtable); 899 900 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer); 901 902 switch (CedtHeader->Type) 903 { 904 case ACPI_CEDT_TYPE_CHBS: 905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable); 906 if (ACPI_FAILURE (Status)) 907 { 908 return (Status); 909 } 910 break; 911 case ACPI_CEDT_TYPE_CFMWS: { 912 unsigned char *dump; 913 unsigned int idx, offset, max = 0; 914 915 /* Compile table with first "Interleave target" */ 916 917 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable); 918 if (ACPI_FAILURE (Status)) 919 { 920 return (Status); 921 } 922 923 /* Look in buffer for the number of targets */ 924 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays); 925 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */ 926 max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */ 927 if (max > 8) max=1; /* Error in encoding Interleaving Ways. */ 928 if (max == 1) /* if only one target, then break here. */ 929 break; /* break if only one target. */ 930 931 /* We need to add more interleave targets, so write the current Subtable. */ 932 933 ParentTable = DtPeekSubtable (); 934 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt1 table so we can put in */ 935 DtPushSubtable (Subtable); /* the targets > the first. */ 936 937 /* Now, find out all interleave targets beyond the first. */ 938 939 for (idx = 1; idx < max; idx++) { 940 ParentTable = DtPeekSubtable (); 941 942 if (*PFieldList) 943 { 944 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable); 945 if (ACPI_FAILURE (Status)) 946 { 947 return (Status); 948 } 949 if (Subtable) 950 { 951 DtInsertSubtable (ParentTable, Subtable); /* got a target, so insert table. */ 952 InsertFlag = 0; 953 } 954 } 955 } 956 957 DtPopSubtable (); 958 ParentTable = DtPeekSubtable (); 959 break; 960 } 961 case ACPI_CEDT_TYPE_CXIMS: { 962 unsigned char *dump; 963 unsigned int idx, offset, max = 0; 964 965 /* Compile table with first "Xor map" */ 966 967 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2, &Subtable); 968 if (ACPI_FAILURE (Status)) 969 { 970 return (Status); 971 } 972 973 /* Look in buffer for the number of Xor maps */ 974 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CXIMS, NrXormaps); 975 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt2 */ 976 max = dump[offset]; 977 978 /* We need to add more XOR maps, so write the current Subtable. */ 979 980 ParentTable = DtPeekSubtable (); 981 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt2 table so we can put in */ 982 DtPushSubtable (Subtable); 983 984 /* Now, find out all Xor maps beyond the first. */ 985 986 for (idx = 1; idx < max; idx++) { 987 ParentTable = DtPeekSubtable (); 988 989 if (*PFieldList) 990 { 991 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2_te, &Subtable); 992 if (ACPI_FAILURE (Status)) 993 { 994 return (Status); 995 } 996 if (Subtable) 997 { 998 DtInsertSubtable (ParentTable, Subtable); /* got an Xor map, so insert table. */ 999 InsertFlag = 0; 1000 } 1001 } 1002 } 1003 1004 DtPopSubtable (); 1005 ParentTable = DtPeekSubtable (); 1006 break; 1007 } 1008 1009 default: 1010 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT"); 1011 return (AE_ERROR); 1012 } 1013 1014 ParentTable = DtPeekSubtable (); 1015 if (InsertFlag == 1) { 1016 DtInsertSubtable (ParentTable, Subtable); 1017 } 1018 DtPopSubtable (); 1019 } 1020 1021 return (AE_OK); 1022 } 1023 1024 1025 /****************************************************************************** 1026 * 1027 * FUNCTION: DtCompileCpep 1028 * 1029 * PARAMETERS: List - Current field list pointer 1030 * 1031 * RETURN: Status 1032 * 1033 * DESCRIPTION: Compile CPEP. 1034 * 1035 *****************************************************************************/ 1036 1037 ACPI_STATUS 1038 DtCompileCpep ( 1039 void **List) 1040 { 1041 ACPI_STATUS Status; 1042 1043 1044 Status = DtCompileTwoSubtables (List, 1045 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 1046 return (Status); 1047 } 1048 1049 1050 /****************************************************************************** 1051 * 1052 * FUNCTION: DtCompileCsrt 1053 * 1054 * PARAMETERS: List - Current field list pointer 1055 * 1056 * RETURN: Status 1057 * 1058 * DESCRIPTION: Compile CSRT. 1059 * 1060 *****************************************************************************/ 1061 1062 ACPI_STATUS 1063 DtCompileCsrt ( 1064 void **List) 1065 { 1066 ACPI_STATUS Status = AE_OK; 1067 DT_SUBTABLE *Subtable; 1068 DT_SUBTABLE *ParentTable; 1069 DT_FIELD **PFieldList = (DT_FIELD **) List; 1070 UINT32 DescriptorCount; 1071 UINT32 GroupLength; 1072 1073 1074 /* Subtables (Resource Groups) */ 1075 1076 ParentTable = DtPeekSubtable (); 1077 while (*PFieldList) 1078 { 1079 /* Resource group subtable */ 1080 1081 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 1082 &Subtable); 1083 if (ACPI_FAILURE (Status)) 1084 { 1085 return (Status); 1086 } 1087 1088 /* Compute the number of resource descriptors */ 1089 1090 GroupLength = 1091 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 1092 Subtable->Buffer))->Length - 1093 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 1094 Subtable->Buffer))->SharedInfoLength - 1095 sizeof (ACPI_CSRT_GROUP); 1096 1097 DescriptorCount = (GroupLength / 1098 sizeof (ACPI_CSRT_DESCRIPTOR)); 1099 1100 DtInsertSubtable (ParentTable, Subtable); 1101 DtPushSubtable (Subtable); 1102 ParentTable = DtPeekSubtable (); 1103 1104 /* Shared info subtable (One per resource group) */ 1105 1106 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 1107 &Subtable); 1108 if (ACPI_FAILURE (Status)) 1109 { 1110 return (Status); 1111 } 1112 1113 DtInsertSubtable (ParentTable, Subtable); 1114 1115 /* Sub-Subtables (Resource Descriptors) */ 1116 1117 while (*PFieldList && DescriptorCount) 1118 { 1119 1120 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 1121 &Subtable); 1122 if (ACPI_FAILURE (Status)) 1123 { 1124 return (Status); 1125 } 1126 1127 DtInsertSubtable (ParentTable, Subtable); 1128 1129 DtPushSubtable (Subtable); 1130 ParentTable = DtPeekSubtable (); 1131 if (*PFieldList) 1132 { 1133 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 1134 &Subtable); 1135 if (ACPI_FAILURE (Status)) 1136 { 1137 return (Status); 1138 } 1139 if (Subtable) 1140 { 1141 DtInsertSubtable (ParentTable, Subtable); 1142 } 1143 } 1144 1145 DtPopSubtable (); 1146 ParentTable = DtPeekSubtable (); 1147 DescriptorCount--; 1148 } 1149 1150 DtPopSubtable (); 1151 ParentTable = DtPeekSubtable (); 1152 } 1153 1154 return (Status); 1155 } 1156 1157 1158 /****************************************************************************** 1159 * 1160 * FUNCTION: DtCompileDbg2 1161 * 1162 * PARAMETERS: List - Current field list pointer 1163 * 1164 * RETURN: Status 1165 * 1166 * DESCRIPTION: Compile DBG2. 1167 * 1168 *****************************************************************************/ 1169 1170 ACPI_STATUS 1171 DtCompileDbg2 ( 1172 void **List) 1173 { 1174 ACPI_STATUS Status; 1175 DT_SUBTABLE *Subtable; 1176 DT_SUBTABLE *ParentTable; 1177 DT_FIELD **PFieldList = (DT_FIELD **) List; 1178 UINT32 SubtableCount; 1179 ACPI_DBG2_HEADER *Dbg2Header; 1180 ACPI_DBG2_DEVICE *DeviceInfo; 1181 UINT16 CurrentOffset; 1182 UINT32 i; 1183 1184 1185 /* Main table */ 1186 1187 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable); 1188 if (ACPI_FAILURE (Status)) 1189 { 1190 return (Status); 1191 } 1192 1193 ParentTable = DtPeekSubtable (); 1194 DtInsertSubtable (ParentTable, Subtable); 1195 1196 /* Main table fields */ 1197 1198 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 1199 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 1200 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 1201 1202 SubtableCount = Dbg2Header->InfoCount; 1203 DtPushSubtable (Subtable); 1204 1205 /* Process all Device Information subtables (Count = InfoCount) */ 1206 1207 while (*PFieldList && SubtableCount) 1208 { 1209 /* Subtable: Debug Device Information */ 1210 1211 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 1212 &Subtable); 1213 if (ACPI_FAILURE (Status)) 1214 { 1215 return (Status); 1216 } 1217 1218 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 1219 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 1220 1221 ParentTable = DtPeekSubtable (); 1222 DtInsertSubtable (ParentTable, Subtable); 1223 DtPushSubtable (Subtable); 1224 1225 ParentTable = DtPeekSubtable (); 1226 1227 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 1228 1229 DeviceInfo->BaseAddressOffset = CurrentOffset; 1230 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 1231 { 1232 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 1233 &Subtable); 1234 if (ACPI_FAILURE (Status)) 1235 { 1236 return (Status); 1237 } 1238 1239 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 1240 DtInsertSubtable (ParentTable, Subtable); 1241 } 1242 1243 /* AddressSize array (Required, size = RegisterCount) */ 1244 1245 DeviceInfo->AddressSizeOffset = CurrentOffset; 1246 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 1247 { 1248 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 1249 &Subtable); 1250 if (ACPI_FAILURE (Status)) 1251 { 1252 return (Status); 1253 } 1254 1255 CurrentOffset += (UINT16) sizeof (UINT32); 1256 DtInsertSubtable (ParentTable, Subtable); 1257 } 1258 1259 /* NamespaceString device identifier (Required, size = NamePathLength) */ 1260 1261 DeviceInfo->NamepathOffset = CurrentOffset; 1262 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 1263 &Subtable); 1264 if (ACPI_FAILURE (Status)) 1265 { 1266 return (Status); 1267 } 1268 1269 /* Update the device info header */ 1270 1271 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 1272 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 1273 DtInsertSubtable (ParentTable, Subtable); 1274 1275 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 1276 1277 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 1278 &Subtable); 1279 if (Status == AE_END_OF_TABLE) 1280 { 1281 /* optional field was not found and we're at the end of the file */ 1282 1283 goto subtableDone; 1284 } 1285 else if (ACPI_FAILURE (Status)) 1286 { 1287 return (Status); 1288 } 1289 1290 /* Update the device info header (zeros if no OEM data present) */ 1291 1292 DeviceInfo->OemDataOffset = 0; 1293 DeviceInfo->OemDataLength = 0; 1294 1295 /* Optional subtable (OemData) */ 1296 1297 if (Subtable && Subtable->Length) 1298 { 1299 DeviceInfo->OemDataOffset = CurrentOffset; 1300 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 1301 1302 DtInsertSubtable (ParentTable, Subtable); 1303 } 1304 subtableDone: 1305 SubtableCount--; 1306 DtPopSubtable (); /* Get next Device Information subtable */ 1307 } 1308 1309 DtPopSubtable (); 1310 return (AE_OK); 1311 } 1312 1313 1314 /****************************************************************************** 1315 * 1316 * FUNCTION: DtCompileDmar 1317 * 1318 * PARAMETERS: List - Current field list pointer 1319 * 1320 * RETURN: Status 1321 * 1322 * DESCRIPTION: Compile DMAR. 1323 * 1324 *****************************************************************************/ 1325 1326 ACPI_STATUS 1327 DtCompileDmar ( 1328 void **List) 1329 { 1330 ACPI_STATUS Status; 1331 DT_SUBTABLE *Subtable; 1332 DT_SUBTABLE *ParentTable; 1333 DT_FIELD **PFieldList = (DT_FIELD **) List; 1334 DT_FIELD *SubtableStart; 1335 ACPI_DMTABLE_INFO *InfoTable; 1336 ACPI_DMAR_HEADER *DmarHeader; 1337 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 1338 UINT32 DeviceScopeLength; 1339 UINT32 PciPathLength; 1340 1341 1342 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 1343 if (ACPI_FAILURE (Status)) 1344 { 1345 return (Status); 1346 } 1347 1348 ParentTable = DtPeekSubtable (); 1349 DtInsertSubtable (ParentTable, Subtable); 1350 DtPushSubtable (Subtable); 1351 1352 while (*PFieldList) 1353 { 1354 /* DMAR Header */ 1355 1356 SubtableStart = *PFieldList; 1357 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 1358 &Subtable); 1359 if (ACPI_FAILURE (Status)) 1360 { 1361 return (Status); 1362 } 1363 1364 ParentTable = DtPeekSubtable (); 1365 DtInsertSubtable (ParentTable, Subtable); 1366 DtPushSubtable (Subtable); 1367 1368 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 1369 1370 switch (DmarHeader->Type) 1371 { 1372 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1373 1374 InfoTable = AcpiDmTableInfoDmar0; 1375 break; 1376 1377 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1378 1379 InfoTable = AcpiDmTableInfoDmar1; 1380 break; 1381 1382 case ACPI_DMAR_TYPE_ROOT_ATS: 1383 1384 InfoTable = AcpiDmTableInfoDmar2; 1385 break; 1386 1387 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1388 1389 InfoTable = AcpiDmTableInfoDmar3; 1390 break; 1391 1392 case ACPI_DMAR_TYPE_NAMESPACE: 1393 1394 InfoTable = AcpiDmTableInfoDmar4; 1395 break; 1396 1397 case ACPI_DMAR_TYPE_SATC: 1398 1399 InfoTable = AcpiDmTableInfoDmar5; 1400 break; 1401 1402 case ACPI_DMAR_TYPE_SIDP: 1403 1404 InfoTable = AcpiDmTableInfoDmar6; 1405 break; 1406 1407 default: 1408 1409 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 1410 return (AE_ERROR); 1411 } 1412 1413 /* DMAR Subtable */ 1414 1415 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1416 if (ACPI_FAILURE (Status)) 1417 { 1418 return (Status); 1419 } 1420 1421 ParentTable = DtPeekSubtable (); 1422 DtInsertSubtable (ParentTable, Subtable); 1423 1424 /* 1425 * Optional Device Scope subtables 1426 */ 1427 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 1428 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 1429 { 1430 /* These types do not support device scopes */ 1431 1432 DtPopSubtable (); 1433 continue; 1434 } 1435 1436 DtPushSubtable (Subtable); 1437 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 1438 ParentTable->Length; 1439 while (DeviceScopeLength) 1440 { 1441 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 1442 &Subtable); 1443 if (Status == AE_NOT_FOUND) 1444 { 1445 break; 1446 } 1447 1448 ParentTable = DtPeekSubtable (); 1449 DtInsertSubtable (ParentTable, Subtable); 1450 DtPushSubtable (Subtable); 1451 1452 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 1453 1454 /* Optional PCI Paths */ 1455 1456 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 1457 while (PciPathLength) 1458 { 1459 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 1460 &Subtable); 1461 if (Status == AE_NOT_FOUND) 1462 { 1463 DtPopSubtable (); 1464 break; 1465 } 1466 1467 ParentTable = DtPeekSubtable (); 1468 DtInsertSubtable (ParentTable, Subtable); 1469 PciPathLength -= Subtable->Length; 1470 } 1471 1472 DtPopSubtable (); 1473 DeviceScopeLength -= DmarDeviceScope->Length; 1474 } 1475 1476 DtPopSubtable (); 1477 DtPopSubtable (); 1478 } 1479 1480 return (AE_OK); 1481 } 1482 1483 1484 /****************************************************************************** 1485 * 1486 * FUNCTION: DtCompileDrtm 1487 * 1488 * PARAMETERS: List - Current field list pointer 1489 * 1490 * RETURN: Status 1491 * 1492 * DESCRIPTION: Compile DRTM. 1493 * 1494 *****************************************************************************/ 1495 1496 ACPI_STATUS 1497 DtCompileDrtm ( 1498 void **List) 1499 { 1500 ACPI_STATUS Status; 1501 DT_SUBTABLE *Subtable; 1502 DT_SUBTABLE *ParentTable; 1503 DT_FIELD **PFieldList = (DT_FIELD **) List; 1504 UINT32 Count; 1505 /* ACPI_TABLE_DRTM *Drtm; */ 1506 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1507 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1508 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1509 1510 1511 ParentTable = DtPeekSubtable (); 1512 1513 /* Compile DRTM header */ 1514 1515 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1516 &Subtable); 1517 if (ACPI_FAILURE (Status)) 1518 { 1519 return (Status); 1520 } 1521 DtInsertSubtable (ParentTable, Subtable); 1522 1523 /* 1524 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1525 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1526 */ 1527 #if 0 1528 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1529 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1530 #endif 1531 /* Compile VTL */ 1532 1533 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1534 &Subtable); 1535 if (ACPI_FAILURE (Status)) 1536 { 1537 return (Status); 1538 } 1539 1540 DtInsertSubtable (ParentTable, Subtable); 1541 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1542 1543 DtPushSubtable (Subtable); 1544 ParentTable = DtPeekSubtable (); 1545 Count = 0; 1546 1547 while (*PFieldList) 1548 { 1549 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1550 &Subtable); 1551 if (ACPI_FAILURE (Status)) 1552 { 1553 return (Status); 1554 } 1555 if (!Subtable) 1556 { 1557 break; 1558 } 1559 DtInsertSubtable (ParentTable, Subtable); 1560 Count++; 1561 } 1562 1563 DrtmVtl->ValidatedTableCount = Count; 1564 DtPopSubtable (); 1565 ParentTable = DtPeekSubtable (); 1566 1567 /* Compile RL */ 1568 1569 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1570 &Subtable); 1571 if (ACPI_FAILURE (Status)) 1572 { 1573 return (Status); 1574 } 1575 1576 DtInsertSubtable (ParentTable, Subtable); 1577 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1578 1579 DtPushSubtable (Subtable); 1580 ParentTable = DtPeekSubtable (); 1581 Count = 0; 1582 1583 while (*PFieldList) 1584 { 1585 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1586 &Subtable); 1587 if (ACPI_FAILURE (Status)) 1588 { 1589 return (Status); 1590 } 1591 1592 if (!Subtable) 1593 { 1594 break; 1595 } 1596 1597 DtInsertSubtable (ParentTable, Subtable); 1598 Count++; 1599 } 1600 1601 DrtmRl->ResourceCount = Count; 1602 DtPopSubtable (); 1603 ParentTable = DtPeekSubtable (); 1604 1605 /* Compile DPS */ 1606 1607 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1608 &Subtable); 1609 if (ACPI_FAILURE (Status)) 1610 { 1611 return (Status); 1612 } 1613 DtInsertSubtable (ParentTable, Subtable); 1614 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1615 1616 1617 return (AE_OK); 1618 } 1619 1620 1621 /****************************************************************************** 1622 * 1623 * FUNCTION: DtCompileDtpr 1624 * 1625 * PARAMETERS: List - Current field list pointer 1626 * 1627 * RETURN: Status 1628 * 1629 * DESCRIPTION: Compile DTPR. 1630 * 1631 *****************************************************************************/ 1632 1633 ACPI_STATUS 1634 DtCompileDtpr ( 1635 void **List) 1636 { 1637 ACPI_STATUS Status; 1638 DT_SUBTABLE *Subtable; 1639 DT_SUBTABLE *ParentTable; 1640 DT_FIELD **PFieldList = (DT_FIELD **) List; 1641 ACPI_TABLE_DTPR *Dtpr; 1642 ACPI_TPR_INSTANCE *TprInst; 1643 UINT32 i, InsCnt, SrlCnt, TprCnt; 1644 1645 1646 ParentTable = DtPeekSubtable (); 1647 1648 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtpr, &Subtable); 1649 if (ACPI_FAILURE (Status)) 1650 { 1651 return (Status); 1652 } 1653 1654 DtInsertSubtable (ParentTable, Subtable); 1655 1656 Dtpr = ACPI_SUB_PTR (ACPI_TABLE_DTPR, Subtable->Buffer, 1657 sizeof (ACPI_TABLE_HEADER)); 1658 if (!Dtpr) 1659 { 1660 AcpiOsPrintf ("DTPR buffer pointer is NULL\n"); 1661 return (AE_NULL_OBJECT); 1662 } 1663 1664 InsCnt = Dtpr->InsCnt; 1665 1666 while (*PFieldList) 1667 { 1668 for (i = 0; i < InsCnt; i++) 1669 { 1670 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprInstance, 1671 &Subtable); 1672 if (ACPI_FAILURE (Status)) 1673 { 1674 return (Status); 1675 } 1676 1677 TprInst = ACPI_CAST_PTR (ACPI_TPR_INSTANCE, Subtable->Buffer); 1678 if (!TprInst) 1679 { 1680 AcpiOsPrintf ("Tpr Instance buffer pointer is NULL\n"); 1681 return (AE_NULL_OBJECT); 1682 } 1683 1684 TprCnt = TprInst->TprCnt; 1685 DtInsertSubtable (ParentTable, Subtable); 1686 DtPushSubtable (Subtable); 1687 ParentTable = DtPeekSubtable (); 1688 1689 while (*PFieldList && TprCnt) 1690 { 1691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprArr, 1692 &Subtable); 1693 if (ACPI_FAILURE (Status)) 1694 { 1695 return (Status); 1696 } 1697 1698 DtInsertSubtable (ParentTable, Subtable); 1699 TprCnt--; 1700 } 1701 1702 DtPopSubtable(); 1703 ParentTable = DtPeekSubtable (); 1704 } 1705 1706 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprSerializeReq0, 1707 &Subtable); 1708 if (ACPI_FAILURE (Status)) 1709 { 1710 return (Status); 1711 } 1712 1713 SrlCnt = *ACPI_CAST_PTR(UINT32, Subtable->Buffer); 1714 DtInsertSubtable (ParentTable, Subtable); 1715 DtPushSubtable (Subtable); 1716 ParentTable = DtPeekSubtable (); 1717 1718 while (*PFieldList && SrlCnt) 1719 { 1720 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprSerializeReq1, 1721 &Subtable); 1722 if (ACPI_FAILURE (Status)) 1723 { 1724 return (Status); 1725 } 1726 1727 DtInsertSubtable (ParentTable, Subtable); 1728 SrlCnt--; 1729 } 1730 1731 1732 DtPopSubtable(); 1733 ParentTable = DtPeekSubtable (); 1734 } 1735 1736 return Status; 1737 } 1738 1739 /****************************************************************************** 1740 * 1741 * FUNCTION: DtCompileEinj 1742 * 1743 * PARAMETERS: List - Current field list pointer 1744 * 1745 * RETURN: Status 1746 * 1747 * DESCRIPTION: Compile EINJ. 1748 * 1749 *****************************************************************************/ 1750 1751 ACPI_STATUS 1752 DtCompileEinj ( 1753 void **List) 1754 { 1755 ACPI_STATUS Status; 1756 1757 1758 Status = DtCompileTwoSubtables (List, 1759 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1760 return (Status); 1761 } 1762 1763 1764 /****************************************************************************** 1765 * 1766 * FUNCTION: DtCompileErdt 1767 * 1768 * PARAMETERS: List - Current field list pointer 1769 * 1770 * RETURN: Status 1771 * 1772 * DESCRIPTION: Compile ERST. Complex table with subtables and subsubtables. 1773 * 1774 *****************************************************************************/ 1775 1776 ACPI_STATUS 1777 DtCompileErdt ( 1778 void **List) 1779 { 1780 ACPI_STATUS Status; 1781 DT_SUBTABLE *Subtable, *RmddSubtable = NULL, *Subsubtable; 1782 DT_SUBTABLE *ParentTable; 1783 DT_FIELD **PFieldList = (DT_FIELD **) List; 1784 DT_FIELD *SubtableStart; 1785 ACPI_SUBTBL_HDR_16 *ErdtHeader; 1786 ACPI_DMTABLE_INFO *InfoTable; 1787 ACPI_ERDT_MMRC *Mmrc; 1788 ACPI_ERDT_IBRD *Ibrd; 1789 UINT32 NumEntries; 1790 BOOLEAN SeenRmdd = FALSE; 1791 BOOLEAN SeenSubtable = FALSE; 1792 1793 Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdt, 1794 &Subtable); 1795 if (ACPI_FAILURE (Status)) 1796 { 1797 return (Status); 1798 } 1799 1800 ParentTable = DtPeekSubtable (); 1801 DtInsertSubtable (ParentTable, Subtable); 1802 1803 while (*PFieldList) 1804 { 1805 SubtableStart = *PFieldList; 1806 Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdtHdr, 1807 &Subtable); 1808 if (ACPI_FAILURE (Status)) 1809 { 1810 return (Status); 1811 } 1812 1813 ErdtHeader = ACPI_CAST_PTR (ACPI_SUBTBL_HDR_16, Subtable->Buffer); 1814 1815 /* RMDD tables at top level. All others are subtables of preceeding RMDD */ 1816 if (ErdtHeader->Type == ACPI_ERDT_TYPE_RMDD) 1817 { 1818 if (SeenRmdd && SeenSubtable) 1819 DtPopSubtable (); 1820 SeenRmdd = TRUE; 1821 SeenSubtable = FALSE; 1822 RmddSubtable = Subtable; 1823 } 1824 else 1825 { 1826 if (!SeenSubtable) 1827 { 1828 DtPushSubtable (RmddSubtable); 1829 SeenSubtable = TRUE; 1830 } 1831 } 1832 1833 ParentTable = DtPeekSubtable (); 1834 DtInsertSubtable (ParentTable, Subtable); 1835 DtPushSubtable (Subtable); 1836 1837 switch (ErdtHeader->Type) 1838 { 1839 case ACPI_ERDT_TYPE_RMDD: 1840 InfoTable = AcpiDmTableInfoErdtRmdd; 1841 break; 1842 1843 case ACPI_ERDT_TYPE_CACD: 1844 InfoTable = AcpiDmTableInfoErdtCacd; 1845 break; 1846 1847 case ACPI_ERDT_TYPE_DACD: 1848 InfoTable = AcpiDmTableInfoErdtDacd; 1849 break; 1850 1851 case ACPI_ERDT_TYPE_CMRC: 1852 InfoTable = AcpiDmTableInfoErdtCmrc; 1853 break; 1854 1855 case ACPI_ERDT_TYPE_MMRC: 1856 InfoTable = AcpiDmTableInfoErdtMmrc; 1857 break; 1858 1859 case ACPI_ERDT_TYPE_MARC: 1860 InfoTable = AcpiDmTableInfoErdtMarc; 1861 break; 1862 1863 case ACPI_ERDT_TYPE_CARC: 1864 InfoTable = AcpiDmTableInfoErdtCarc; 1865 break; 1866 1867 case ACPI_ERDT_TYPE_CMRD: 1868 InfoTable = AcpiDmTableInfoErdtCmrd; 1869 break; 1870 1871 case ACPI_ERDT_TYPE_IBRD: 1872 InfoTable = AcpiDmTableInfoErdtIbrd; 1873 break; 1874 1875 case ACPI_ERDT_TYPE_IBAD: 1876 InfoTable = AcpiDmTableInfoErdtIbad; 1877 break; 1878 1879 case ACPI_ERDT_TYPE_CARD: 1880 InfoTable = AcpiDmTableInfoErdtCard; 1881 break; 1882 1883 default: 1884 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ERDT"); 1885 return (AE_ERROR); 1886 } 1887 1888 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1889 if (ACPI_FAILURE (Status)) 1890 { 1891 return (Status); 1892 } 1893 1894 ParentTable = DtPeekSubtable (); 1895 DtInsertSubtable (ParentTable, Subtable); 1896 1897 /* Some subtable types end with flex arrays */ 1898 1899 switch (ErdtHeader->Type) 1900 { 1901 case ACPI_ERDT_TYPE_CACD: 1902 while (*PFieldList) 1903 { 1904 Status = DtCompileTable (PFieldList, 1905 AcpiDmTableInfoErdtCacdX2apic, &Subtable); 1906 if (ACPI_FAILURE (Status)) 1907 { 1908 return (Status); 1909 } 1910 if (!Subtable) 1911 { 1912 break; 1913 } 1914 1915 ParentTable = DtPeekSubtable (); 1916 DtInsertSubtable (ParentTable, Subtable); 1917 } 1918 break; 1919 1920 case ACPI_ERDT_TYPE_DACD: 1921 while (*PFieldList) 1922 { 1923 Status = DtCompileTable (PFieldList, 1924 AcpiDmTableInfoErdtDacdScope, &Subtable); 1925 if (ACPI_FAILURE (Status)) 1926 { 1927 return (Status); 1928 } 1929 if (!Subtable) 1930 { 1931 break; 1932 } 1933 1934 DtPushSubtable (Subtable); 1935 while (*PFieldList) 1936 { 1937 Status = DtCompileTable (PFieldList, 1938 AcpiDmTableInfoErdtDacdPath, &Subsubtable); 1939 if (ACPI_FAILURE (Status)) 1940 { 1941 return (Status); 1942 } 1943 if (!Subsubtable) 1944 { 1945 break; 1946 } 1947 1948 ParentTable = DtPeekSubtable (); 1949 DtInsertSubtable (ParentTable, Subsubtable); 1950 } 1951 DtPopSubtable (); 1952 1953 ParentTable = DtPeekSubtable (); 1954 DtInsertSubtable (ParentTable, Subtable); 1955 } 1956 break; 1957 1958 case ACPI_ERDT_TYPE_MMRC: 1959 Mmrc = ACPI_SUB_PTR (ACPI_ERDT_MMRC, Subtable->Buffer, 1960 sizeof(ACPI_SUBTBL_HDR_16)); 1961 NumEntries = 0; 1962 while (*PFieldList) 1963 { 1964 Status = DtCompileTable (PFieldList, 1965 AcpiDmTableInfoErdtMmrcCorrFactor, &Subtable); 1966 if (ACPI_FAILURE (Status)) 1967 { 1968 return (Status); 1969 } 1970 if (!Subtable) 1971 { 1972 break; 1973 } 1974 1975 ParentTable = DtPeekSubtable (); 1976 DtInsertSubtable (ParentTable, Subtable); 1977 NumEntries++; 1978 } 1979 Mmrc->CorrFactorListLen = NumEntries; 1980 break; 1981 1982 case ACPI_ERDT_TYPE_IBRD: 1983 Ibrd = ACPI_SUB_PTR (ACPI_ERDT_IBRD, Subtable->Buffer, 1984 sizeof(ACPI_SUBTBL_HDR_16)); 1985 NumEntries = 0; 1986 while (*PFieldList) 1987 { 1988 Status = DtCompileTable (PFieldList, 1989 AcpiDmTableInfoErdtIbrdCorrFactor, &Subtable); 1990 if (ACPI_FAILURE (Status)) 1991 { 1992 return (Status); 1993 } 1994 if (!Subtable) 1995 { 1996 break; 1997 } 1998 1999 ParentTable = DtPeekSubtable (); 2000 DtInsertSubtable (ParentTable, Subtable); 2001 NumEntries++; 2002 } 2003 Ibrd->CorrFactorListLen = NumEntries; 2004 break; 2005 2006 default: 2007 /* Already checked for valid subtable type above */ 2008 2009 break; 2010 } 2011 DtPopSubtable (); 2012 } 2013 2014 if (SeenSubtable) 2015 { 2016 DtPopSubtable (); 2017 } 2018 2019 return (AE_OK); 2020 } 2021 2022 2023 /****************************************************************************** 2024 * 2025 * FUNCTION: DtCompileErst 2026 * 2027 * PARAMETERS: List - Current field list pointer 2028 * 2029 * RETURN: Status 2030 * 2031 * DESCRIPTION: Compile ERST. 2032 * 2033 *****************************************************************************/ 2034 2035 ACPI_STATUS 2036 DtCompileErst ( 2037 void **List) 2038 { 2039 ACPI_STATUS Status; 2040 2041 2042 Status = DtCompileTwoSubtables (List, 2043 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 2044 return (Status); 2045 } 2046 2047 2048 /****************************************************************************** 2049 * 2050 * FUNCTION: DtCompileGtdt 2051 * 2052 * PARAMETERS: List - Current field list pointer 2053 * 2054 * RETURN: Status 2055 * 2056 * DESCRIPTION: Compile GTDT. 2057 * 2058 *****************************************************************************/ 2059 2060 ACPI_STATUS 2061 DtCompileGtdt ( 2062 void **List) 2063 { 2064 ACPI_STATUS Status; 2065 DT_SUBTABLE *Subtable; 2066 DT_SUBTABLE *ParentTable; 2067 DT_FIELD **PFieldList = (DT_FIELD **) List; 2068 DT_FIELD *SubtableStart; 2069 ACPI_SUBTABLE_HEADER *GtdtHeader; 2070 ACPI_DMTABLE_INFO *InfoTable; 2071 UINT32 GtCount; 2072 ACPI_TABLE_HEADER *Header; 2073 2074 2075 ParentTable = DtPeekSubtable (); 2076 2077 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2078 2079 /* Compile the main table */ 2080 2081 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 2082 &Subtable); 2083 if (ACPI_FAILURE (Status)) 2084 { 2085 return (Status); 2086 } 2087 2088 /* GTDT revision 3 later contains 2 extra fields before subtables */ 2089 2090 if (Header->Revision > 2) 2091 { 2092 ParentTable = DtPeekSubtable (); 2093 DtInsertSubtable (ParentTable, Subtable); 2094 2095 Status = DtCompileTable (PFieldList, 2096 AcpiDmTableInfoGtdtEl2, &Subtable); 2097 if (ACPI_FAILURE (Status)) 2098 { 2099 return (Status); 2100 } 2101 } 2102 2103 ParentTable = DtPeekSubtable (); 2104 DtInsertSubtable (ParentTable, Subtable); 2105 2106 while (*PFieldList) 2107 { 2108 SubtableStart = *PFieldList; 2109 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 2110 &Subtable); 2111 if (ACPI_FAILURE (Status)) 2112 { 2113 return (Status); 2114 } 2115 2116 ParentTable = DtPeekSubtable (); 2117 DtInsertSubtable (ParentTable, Subtable); 2118 DtPushSubtable (Subtable); 2119 2120 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2121 2122 switch (GtdtHeader->Type) 2123 { 2124 case ACPI_GTDT_TYPE_TIMER_BLOCK: 2125 2126 InfoTable = AcpiDmTableInfoGtdt0; 2127 break; 2128 2129 case ACPI_GTDT_TYPE_WATCHDOG: 2130 2131 InfoTable = AcpiDmTableInfoGtdt1; 2132 break; 2133 2134 default: 2135 2136 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 2137 return (AE_ERROR); 2138 } 2139 2140 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2141 if (ACPI_FAILURE (Status)) 2142 { 2143 return (Status); 2144 } 2145 2146 ParentTable = DtPeekSubtable (); 2147 DtInsertSubtable (ParentTable, Subtable); 2148 2149 /* 2150 * Additional GT block subtable data 2151 */ 2152 2153 switch (GtdtHeader->Type) 2154 { 2155 case ACPI_GTDT_TYPE_TIMER_BLOCK: 2156 2157 DtPushSubtable (Subtable); 2158 ParentTable = DtPeekSubtable (); 2159 2160 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 2161 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 2162 2163 while (GtCount) 2164 { 2165 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 2166 &Subtable); 2167 if (ACPI_FAILURE (Status)) 2168 { 2169 return (Status); 2170 } 2171 2172 DtInsertSubtable (ParentTable, Subtable); 2173 GtCount--; 2174 } 2175 2176 DtPopSubtable (); 2177 break; 2178 2179 default: 2180 2181 break; 2182 } 2183 2184 DtPopSubtable (); 2185 } 2186 2187 return (AE_OK); 2188 } 2189 2190 2191 /****************************************************************************** 2192 * 2193 * FUNCTION: DtCompileFpdt 2194 * 2195 * PARAMETERS: List - Current field list pointer 2196 * 2197 * RETURN: Status 2198 * 2199 * DESCRIPTION: Compile FPDT. 2200 * 2201 *****************************************************************************/ 2202 2203 ACPI_STATUS 2204 DtCompileFpdt ( 2205 void **List) 2206 { 2207 ACPI_STATUS Status; 2208 ACPI_FPDT_HEADER *FpdtHeader; 2209 DT_SUBTABLE *Subtable; 2210 DT_SUBTABLE *ParentTable; 2211 ACPI_DMTABLE_INFO *InfoTable; 2212 DT_FIELD **PFieldList = (DT_FIELD **) List; 2213 DT_FIELD *SubtableStart; 2214 2215 2216 while (*PFieldList) 2217 { 2218 SubtableStart = *PFieldList; 2219 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 2220 &Subtable); 2221 if (ACPI_FAILURE (Status)) 2222 { 2223 return (Status); 2224 } 2225 2226 ParentTable = DtPeekSubtable (); 2227 DtInsertSubtable (ParentTable, Subtable); 2228 DtPushSubtable (Subtable); 2229 2230 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 2231 2232 switch (FpdtHeader->Type) 2233 { 2234 case ACPI_FPDT_TYPE_BOOT: 2235 2236 InfoTable = AcpiDmTableInfoFpdt0; 2237 break; 2238 2239 case ACPI_FPDT_TYPE_S3PERF: 2240 2241 InfoTable = AcpiDmTableInfoFpdt1; 2242 break; 2243 2244 default: 2245 2246 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 2247 return (AE_ERROR); 2248 break; 2249 } 2250 2251 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2252 if (ACPI_FAILURE (Status)) 2253 { 2254 return (Status); 2255 } 2256 2257 ParentTable = DtPeekSubtable (); 2258 DtInsertSubtable (ParentTable, Subtable); 2259 DtPopSubtable (); 2260 } 2261 2262 return (AE_OK); 2263 } 2264 2265 2266 /****************************************************************************** 2267 * 2268 * FUNCTION: DtCompileHest 2269 * 2270 * PARAMETERS: List - Current field list pointer 2271 * 2272 * RETURN: Status 2273 * 2274 * DESCRIPTION: Compile HEST. 2275 * 2276 *****************************************************************************/ 2277 2278 ACPI_STATUS 2279 DtCompileHest ( 2280 void **List) 2281 { 2282 ACPI_STATUS Status; 2283 DT_SUBTABLE *Subtable; 2284 DT_SUBTABLE *ParentTable; 2285 DT_FIELD **PFieldList = (DT_FIELD **) List; 2286 DT_FIELD *SubtableStart; 2287 ACPI_DMTABLE_INFO *InfoTable; 2288 UINT16 Type; 2289 UINT32 BankCount; 2290 2291 2292 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 2293 &Subtable); 2294 if (ACPI_FAILURE (Status)) 2295 { 2296 return (Status); 2297 } 2298 2299 ParentTable = DtPeekSubtable (); 2300 DtInsertSubtable (ParentTable, Subtable); 2301 2302 while (*PFieldList) 2303 { 2304 /* Get subtable type */ 2305 2306 SubtableStart = *PFieldList; 2307 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 2308 2309 switch (Type) 2310 { 2311 case ACPI_HEST_TYPE_IA32_CHECK: 2312 2313 InfoTable = AcpiDmTableInfoHest0; 2314 break; 2315 2316 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 2317 2318 InfoTable = AcpiDmTableInfoHest1; 2319 break; 2320 2321 case ACPI_HEST_TYPE_IA32_NMI: 2322 2323 InfoTable = AcpiDmTableInfoHest2; 2324 break; 2325 2326 case ACPI_HEST_TYPE_AER_ROOT_PORT: 2327 2328 InfoTable = AcpiDmTableInfoHest6; 2329 break; 2330 2331 case ACPI_HEST_TYPE_AER_ENDPOINT: 2332 2333 InfoTable = AcpiDmTableInfoHest7; 2334 break; 2335 2336 case ACPI_HEST_TYPE_AER_BRIDGE: 2337 2338 InfoTable = AcpiDmTableInfoHest8; 2339 break; 2340 2341 case ACPI_HEST_TYPE_GENERIC_ERROR: 2342 2343 InfoTable = AcpiDmTableInfoHest9; 2344 break; 2345 2346 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 2347 2348 InfoTable = AcpiDmTableInfoHest10; 2349 break; 2350 2351 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 2352 2353 InfoTable = AcpiDmTableInfoHest11; 2354 break; 2355 2356 default: 2357 2358 /* Cannot continue on unknown type */ 2359 2360 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 2361 return (AE_ERROR); 2362 } 2363 2364 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2365 if (ACPI_FAILURE (Status)) 2366 { 2367 return (Status); 2368 } 2369 2370 DtInsertSubtable (ParentTable, Subtable); 2371 2372 /* 2373 * Additional subtable data - IA32 Error Bank(s) 2374 */ 2375 BankCount = 0; 2376 switch (Type) 2377 { 2378 case ACPI_HEST_TYPE_IA32_CHECK: 2379 2380 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 2381 Subtable->Buffer))->NumHardwareBanks; 2382 break; 2383 2384 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 2385 2386 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 2387 Subtable->Buffer))->NumHardwareBanks; 2388 break; 2389 2390 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 2391 2392 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 2393 Subtable->Buffer))->NumHardwareBanks; 2394 break; 2395 2396 default: 2397 2398 break; 2399 } 2400 2401 while (BankCount) 2402 { 2403 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 2404 &Subtable); 2405 if (ACPI_FAILURE (Status)) 2406 { 2407 return (Status); 2408 } 2409 2410 DtInsertSubtable (ParentTable, Subtable); 2411 BankCount--; 2412 } 2413 } 2414 2415 return (AE_OK); 2416 } 2417 2418 2419 /****************************************************************************** 2420 * 2421 * FUNCTION: DtCompileHmat 2422 * 2423 * PARAMETERS: List - Current field list pointer 2424 * 2425 * RETURN: Status 2426 * 2427 * DESCRIPTION: Compile HMAT. 2428 * 2429 *****************************************************************************/ 2430 2431 ACPI_STATUS 2432 DtCompileHmat ( 2433 void **List) 2434 { 2435 ACPI_STATUS Status; 2436 DT_SUBTABLE *Subtable; 2437 DT_SUBTABLE *ParentTable; 2438 DT_FIELD **PFieldList = (DT_FIELD **) List; 2439 DT_FIELD *SubtableStart; 2440 DT_FIELD *EntryStart; 2441 ACPI_HMAT_STRUCTURE *HmatStruct; 2442 ACPI_HMAT_LOCALITY *HmatLocality; 2443 ACPI_HMAT_CACHE *HmatCache; 2444 ACPI_DMTABLE_INFO *InfoTable; 2445 UINT32 IntPDNumber; 2446 UINT32 TgtPDNumber; 2447 UINT64 EntryNumber; 2448 UINT16 SMBIOSHandleNumber; 2449 2450 2451 ParentTable = DtPeekSubtable (); 2452 2453 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 2454 &Subtable); 2455 if (ACPI_FAILURE (Status)) 2456 { 2457 return (Status); 2458 } 2459 DtInsertSubtable (ParentTable, Subtable); 2460 2461 while (*PFieldList) 2462 { 2463 /* Compile HMAT structure header */ 2464 2465 SubtableStart = *PFieldList; 2466 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 2467 &Subtable); 2468 if (ACPI_FAILURE (Status)) 2469 { 2470 return (Status); 2471 } 2472 DtInsertSubtable (ParentTable, Subtable); 2473 2474 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 2475 HmatStruct->Length = Subtable->Length; 2476 2477 /* Compile HMAT structure body */ 2478 2479 switch (HmatStruct->Type) 2480 { 2481 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 2482 2483 InfoTable = AcpiDmTableInfoHmat0; 2484 break; 2485 2486 case ACPI_HMAT_TYPE_LOCALITY: 2487 2488 InfoTable = AcpiDmTableInfoHmat1; 2489 break; 2490 2491 case ACPI_HMAT_TYPE_CACHE: 2492 2493 InfoTable = AcpiDmTableInfoHmat2; 2494 break; 2495 2496 default: 2497 2498 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 2499 return (AE_ERROR); 2500 } 2501 2502 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2503 if (ACPI_FAILURE (Status)) 2504 { 2505 return (Status); 2506 } 2507 DtInsertSubtable (ParentTable, Subtable); 2508 HmatStruct->Length += Subtable->Length; 2509 2510 /* Compile HMAT structure additional */ 2511 2512 switch (HmatStruct->Type) 2513 { 2514 case ACPI_HMAT_TYPE_LOCALITY: 2515 2516 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 2517 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2518 2519 /* Compile initiator proximity domain list */ 2520 2521 IntPDNumber = 0; 2522 while (*PFieldList) 2523 { 2524 Status = DtCompileTable (PFieldList, 2525 AcpiDmTableInfoHmat1a, &Subtable); 2526 if (ACPI_FAILURE (Status)) 2527 { 2528 return (Status); 2529 } 2530 if (!Subtable) 2531 { 2532 break; 2533 } 2534 DtInsertSubtable (ParentTable, Subtable); 2535 HmatStruct->Length += Subtable->Length; 2536 IntPDNumber++; 2537 } 2538 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 2539 2540 /* Compile target proximity domain list */ 2541 2542 TgtPDNumber = 0; 2543 while (*PFieldList) 2544 { 2545 Status = DtCompileTable (PFieldList, 2546 AcpiDmTableInfoHmat1b, &Subtable); 2547 if (ACPI_FAILURE (Status)) 2548 { 2549 return (Status); 2550 } 2551 if (!Subtable) 2552 { 2553 break; 2554 } 2555 DtInsertSubtable (ParentTable, Subtable); 2556 HmatStruct->Length += Subtable->Length; 2557 TgtPDNumber++; 2558 } 2559 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 2560 2561 /* Save start of the entries for reporting errors */ 2562 2563 EntryStart = *PFieldList; 2564 2565 /* Compile latency/bandwidth entries */ 2566 2567 EntryNumber = 0; 2568 while (*PFieldList) 2569 { 2570 Status = DtCompileTable (PFieldList, 2571 AcpiDmTableInfoHmat1c, &Subtable); 2572 if (ACPI_FAILURE (Status)) 2573 { 2574 return (Status); 2575 } 2576 if (!Subtable) 2577 { 2578 break; 2579 } 2580 DtInsertSubtable (ParentTable, Subtable); 2581 HmatStruct->Length += Subtable->Length; 2582 EntryNumber++; 2583 } 2584 2585 /* Validate number of entries */ 2586 2587 if (EntryNumber != 2588 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 2589 { 2590 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 2591 return (AE_ERROR); 2592 } 2593 break; 2594 2595 case ACPI_HMAT_TYPE_CACHE: 2596 2597 /* Compile SMBIOS handles */ 2598 2599 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 2600 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2601 SMBIOSHandleNumber = 0; 2602 while (*PFieldList) 2603 { 2604 Status = DtCompileTable (PFieldList, 2605 AcpiDmTableInfoHmat2a, &Subtable); 2606 if (ACPI_FAILURE (Status)) 2607 { 2608 return (Status); 2609 } 2610 if (!Subtable) 2611 { 2612 break; 2613 } 2614 DtInsertSubtable (ParentTable, Subtable); 2615 HmatStruct->Length += Subtable->Length; 2616 SMBIOSHandleNumber++; 2617 } 2618 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 2619 break; 2620 2621 default: 2622 2623 break; 2624 } 2625 } 2626 2627 return (AE_OK); 2628 } 2629 2630 2631 /****************************************************************************** 2632 * 2633 * FUNCTION: DtCompileIort 2634 * 2635 * PARAMETERS: List - Current field list pointer 2636 * 2637 * RETURN: Status 2638 * 2639 * DESCRIPTION: Compile IORT. 2640 * 2641 *****************************************************************************/ 2642 2643 ACPI_STATUS 2644 DtCompileIort ( 2645 void **List) 2646 { 2647 ACPI_STATUS Status; 2648 DT_SUBTABLE *Subtable; 2649 DT_SUBTABLE *ParentTable; 2650 DT_FIELD **PFieldList = (DT_FIELD **) List; 2651 DT_FIELD *SubtableStart; 2652 ACPI_TABLE_HEADER *Table; 2653 ACPI_TABLE_IORT *Iort; 2654 ACPI_IORT_NODE *IortNode; 2655 ACPI_IORT_ITS_GROUP *IortItsGroup; 2656 ACPI_IORT_SMMU *IortSmmu; 2657 ACPI_IORT_RMR *IortRmr; 2658 UINT32 NodeNumber; 2659 UINT32 NodeLength; 2660 UINT32 IdMappingNumber; 2661 UINT32 ItsNumber; 2662 UINT32 ContextIrptNumber; 2663 UINT32 PmuIrptNumber; 2664 UINT32 PaddingLength; 2665 UINT8 Revision; 2666 UINT32 RmrCount; 2667 2668 2669 ParentTable = DtPeekSubtable (); 2670 2671 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 2672 &Subtable); 2673 if (ACPI_FAILURE (Status)) 2674 { 2675 return (Status); 2676 } 2677 DtInsertSubtable (ParentTable, Subtable); 2678 2679 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2680 Revision = Table->Revision; 2681 2682 /* IORT Revisions E, E.a & E.c have known issues and are not supported */ 2683 2684 if (Revision == 1 || Revision == 2 || Revision == 4) 2685 { 2686 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 2687 return (AE_ERROR); 2688 } 2689 2690 /* 2691 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 2692 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 2693 */ 2694 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 2695 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 2696 2697 /* 2698 * OptionalPadding - Variable-length data 2699 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 2700 * Optionally allows the generic data types to be used for filling 2701 * this field. 2702 */ 2703 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 2704 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 2705 &Subtable); 2706 if (ACPI_FAILURE (Status)) 2707 { 2708 return (Status); 2709 } 2710 if (Subtable) 2711 { 2712 DtInsertSubtable (ParentTable, Subtable); 2713 Iort->NodeOffset += Subtable->Length; 2714 } 2715 else 2716 { 2717 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 2718 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 2719 if (ACPI_FAILURE (Status)) 2720 { 2721 return (Status); 2722 } 2723 Iort->NodeOffset += PaddingLength; 2724 } 2725 2726 NodeNumber = 0; 2727 while (*PFieldList) 2728 { 2729 SubtableStart = *PFieldList; 2730 if (Revision == 0) 2731 { 2732 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 2733 &Subtable); 2734 } 2735 else if (Revision >= 3) 2736 { 2737 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 2738 &Subtable); 2739 } 2740 2741 if (ACPI_FAILURE (Status)) 2742 { 2743 return (Status); 2744 } 2745 2746 DtInsertSubtable (ParentTable, Subtable); 2747 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 2748 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 2749 2750 DtPushSubtable (Subtable); 2751 ParentTable = DtPeekSubtable (); 2752 2753 switch (IortNode->Type) 2754 { 2755 case ACPI_IORT_NODE_ITS_GROUP: 2756 2757 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 2758 &Subtable); 2759 if (ACPI_FAILURE (Status)) 2760 { 2761 return (Status); 2762 } 2763 2764 DtInsertSubtable (ParentTable, Subtable); 2765 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 2766 NodeLength += Subtable->Length; 2767 2768 ItsNumber = 0; 2769 while (*PFieldList) 2770 { 2771 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 2772 &Subtable); 2773 if (ACPI_FAILURE (Status)) 2774 { 2775 return (Status); 2776 } 2777 if (!Subtable) 2778 { 2779 break; 2780 } 2781 2782 DtInsertSubtable (ParentTable, Subtable); 2783 NodeLength += Subtable->Length; 2784 ItsNumber++; 2785 } 2786 2787 IortItsGroup->ItsCount = ItsNumber; 2788 break; 2789 2790 case ACPI_IORT_NODE_NAMED_COMPONENT: 2791 2792 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 2793 &Subtable); 2794 if (ACPI_FAILURE (Status)) 2795 { 2796 return (Status); 2797 } 2798 2799 DtInsertSubtable (ParentTable, Subtable); 2800 NodeLength += Subtable->Length; 2801 2802 /* 2803 * Padding - Variable-length data 2804 * Optionally allows the offset of the ID mappings to be used 2805 * for filling this field. 2806 */ 2807 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 2808 &Subtable); 2809 if (ACPI_FAILURE (Status)) 2810 { 2811 return (Status); 2812 } 2813 2814 if (Subtable) 2815 { 2816 DtInsertSubtable (ParentTable, Subtable); 2817 NodeLength += Subtable->Length; 2818 } 2819 else 2820 { 2821 if (NodeLength > IortNode->MappingOffset) 2822 { 2823 return (AE_BAD_DATA); 2824 } 2825 2826 if (NodeLength < IortNode->MappingOffset) 2827 { 2828 Status = DtCompilePadding ( 2829 IortNode->MappingOffset - NodeLength, 2830 &Subtable); 2831 if (ACPI_FAILURE (Status)) 2832 { 2833 return (Status); 2834 } 2835 2836 DtInsertSubtable (ParentTable, Subtable); 2837 NodeLength = IortNode->MappingOffset; 2838 } 2839 } 2840 break; 2841 2842 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 2843 2844 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 2845 &Subtable); 2846 if (ACPI_FAILURE (Status)) 2847 { 2848 return (Status); 2849 } 2850 2851 DtInsertSubtable (ParentTable, Subtable); 2852 NodeLength += Subtable->Length; 2853 break; 2854 2855 case ACPI_IORT_NODE_SMMU: 2856 2857 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 2858 &Subtable); 2859 if (ACPI_FAILURE (Status)) 2860 { 2861 return (Status); 2862 } 2863 2864 DtInsertSubtable (ParentTable, Subtable); 2865 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 2866 NodeLength += Subtable->Length; 2867 2868 /* Compile global interrupt array */ 2869 2870 IortSmmu->GlobalInterruptOffset = NodeLength; 2871 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 2872 &Subtable); 2873 if (ACPI_FAILURE (Status)) 2874 { 2875 return (Status); 2876 } 2877 2878 DtInsertSubtable (ParentTable, Subtable); 2879 NodeLength += Subtable->Length; 2880 2881 /* Compile context interrupt array */ 2882 2883 ContextIrptNumber = 0; 2884 IortSmmu->ContextInterruptOffset = NodeLength; 2885 while (*PFieldList) 2886 { 2887 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2888 &Subtable); 2889 if (ACPI_FAILURE (Status)) 2890 { 2891 return (Status); 2892 } 2893 2894 if (!Subtable) 2895 { 2896 break; 2897 } 2898 2899 DtInsertSubtable (ParentTable, Subtable); 2900 NodeLength += Subtable->Length; 2901 ContextIrptNumber++; 2902 } 2903 2904 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2905 2906 /* Compile PMU interrupt array */ 2907 2908 PmuIrptNumber = 0; 2909 IortSmmu->PmuInterruptOffset = NodeLength; 2910 while (*PFieldList) 2911 { 2912 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2913 &Subtable); 2914 if (ACPI_FAILURE (Status)) 2915 { 2916 return (Status); 2917 } 2918 2919 if (!Subtable) 2920 { 2921 break; 2922 } 2923 2924 DtInsertSubtable (ParentTable, Subtable); 2925 NodeLength += Subtable->Length; 2926 PmuIrptNumber++; 2927 } 2928 2929 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2930 break; 2931 2932 case ACPI_IORT_NODE_SMMU_V3: 2933 2934 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2935 &Subtable); 2936 if (ACPI_FAILURE (Status)) 2937 { 2938 return (Status); 2939 } 2940 2941 DtInsertSubtable (ParentTable, Subtable); 2942 NodeLength += Subtable->Length; 2943 break; 2944 2945 case ACPI_IORT_NODE_PMCG: 2946 2947 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2948 &Subtable); 2949 if (ACPI_FAILURE (Status)) 2950 { 2951 return (Status); 2952 } 2953 2954 DtInsertSubtable (ParentTable, Subtable); 2955 NodeLength += Subtable->Length; 2956 break; 2957 2958 case ACPI_IORT_NODE_RMR: 2959 2960 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2961 &Subtable); 2962 if (ACPI_FAILURE (Status)) 2963 { 2964 return (Status); 2965 } 2966 2967 DtInsertSubtable (ParentTable, Subtable); 2968 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2969 NodeLength += Subtable->Length; 2970 2971 /* Compile RMR Descriptors */ 2972 2973 RmrCount = 0; 2974 IortRmr->RmrOffset = NodeLength; 2975 while (*PFieldList) 2976 { 2977 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2978 &Subtable); 2979 if (ACPI_FAILURE (Status)) 2980 { 2981 return (Status); 2982 } 2983 2984 if (!Subtable) 2985 { 2986 break; 2987 } 2988 2989 DtInsertSubtable (ParentTable, Subtable); 2990 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2991 RmrCount++; 2992 } 2993 2994 IortRmr->RmrCount = RmrCount; 2995 break; 2996 2997 case ACPI_IORT_NODE_IWB: 2998 2999 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort7, 3000 &Subtable); 3001 if (ACPI_FAILURE (Status)) 3002 { 3003 return (Status); 3004 } 3005 3006 DtInsertSubtable (ParentTable, Subtable); 3007 NodeLength += Subtable->Length; 3008 break; 3009 3010 default: 3011 3012 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 3013 return (AE_ERROR); 3014 } 3015 3016 /* Compile Array of ID mappings */ 3017 3018 IortNode->MappingOffset = NodeLength; 3019 IdMappingNumber = 0; 3020 while (*PFieldList) 3021 { 3022 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 3023 &Subtable); 3024 if (ACPI_FAILURE (Status)) 3025 { 3026 return (Status); 3027 } 3028 3029 if (!Subtable) 3030 { 3031 break; 3032 } 3033 3034 DtInsertSubtable (ParentTable, Subtable); 3035 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 3036 IdMappingNumber++; 3037 } 3038 3039 IortNode->MappingCount = IdMappingNumber; 3040 if (!IdMappingNumber) 3041 { 3042 IortNode->MappingOffset = 0; 3043 } 3044 3045 /* 3046 * Node length can be determined by DT_LENGTH option 3047 * IortNode->Length = NodeLength; 3048 */ 3049 DtPopSubtable (); 3050 ParentTable = DtPeekSubtable (); 3051 NodeNumber++; 3052 } 3053 3054 Iort->NodeCount = NodeNumber; 3055 return (AE_OK); 3056 } 3057 3058 3059 /****************************************************************************** 3060 * 3061 * FUNCTION: DtCompileIovt 3062 * 3063 * PARAMETERS: List - Current field list pointer 3064 * 3065 * RETURN: Status 3066 * 3067 * DESCRIPTION: Compile Iovt. Notes: 3068 * The IOVT is essentially a flat table, with the following 3069 * structure: 3070 * <Main ACPI Table Header> 3071 * <Main subtable - virtualization info> 3072 * <IOVT> 3073 * <Device Entries> 3074 * ... 3075 * <IOVT> 3076 * <IOVT> 3077 * ... 3078 * 3079 *****************************************************************************/ 3080 3081 ACPI_STATUS 3082 DtCompileIovt ( 3083 void **List) 3084 { 3085 ACPI_STATUS Status; 3086 DT_SUBTABLE *Subtable; 3087 DT_SUBTABLE *ParentTable; 3088 DT_FIELD **PFieldList = (DT_FIELD **) List; 3089 ACPI_TABLE_IOVT *Iovt; 3090 UINT16 IommuCount; 3091 ACPI_IOVT_IOMMU *Iommu; 3092 UINT32 DeviceEntryNum; 3093 3094 3095 ParentTable = DtPeekSubtable (); 3096 /* Main table */ 3097 3098 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIovt, 3099 &Subtable); 3100 if (ACPI_FAILURE (Status)) 3101 { 3102 return (Status); 3103 } 3104 3105 DtInsertSubtable (ParentTable, Subtable); 3106 DtPushSubtable (Subtable); 3107 3108 Iovt = ACPI_SUB_PTR (ACPI_TABLE_IOVT, Subtable->Buffer, 3109 sizeof (ACPI_TABLE_HEADER)); 3110 3111 for (IommuCount = 0; IommuCount < Iovt->IommuCount; IommuCount++) 3112 { 3113 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIovt0, 3114 &Subtable); 3115 if (ACPI_FAILURE (Status)) 3116 { 3117 return (Status); 3118 } 3119 3120 ParentTable = DtPeekSubtable (); 3121 DtInsertSubtable (ParentTable, Subtable); 3122 DtPushSubtable (Subtable); 3123 3124 Iommu = ACPI_CAST_PTR(ACPI_IOVT_IOMMU, Subtable->Buffer); 3125 for (DeviceEntryNum = 0; DeviceEntryNum < Iommu->DeviceEntryNum; DeviceEntryNum++) 3126 { 3127 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIovtdev, 3128 &Subtable); 3129 if (ACPI_FAILURE (Status)) 3130 { 3131 return (Status); 3132 } 3133 3134 ParentTable = DtPeekSubtable (); 3135 DtInsertSubtable (ParentTable, Subtable); 3136 } 3137 DtPopSubtable(); 3138 } 3139 3140 return (AE_OK); 3141 } 3142 3143 3144 /****************************************************************************** 3145 * 3146 * FUNCTION: DtCompileIvrs 3147 * 3148 * PARAMETERS: List - Current field list pointer 3149 * 3150 * RETURN: Status 3151 * 3152 * DESCRIPTION: Compile IVRS. Notes: 3153 * The IVRS is essentially a flat table, with the following 3154 * structure: 3155 * <Main ACPI Table Header> 3156 * <Main subtable - virtualization info> 3157 * <IVHD> 3158 * <Device Entries> 3159 * ... 3160 * <IVHD> 3161 * <Device Entries> 3162 * <IVMD> 3163 * ... 3164 * 3165 *****************************************************************************/ 3166 3167 ACPI_STATUS 3168 DtCompileIvrs ( 3169 void **List) 3170 { 3171 ACPI_STATUS Status; 3172 DT_SUBTABLE *Subtable; 3173 DT_SUBTABLE *ParentTable; 3174 DT_SUBTABLE *MainSubtable; 3175 DT_FIELD **PFieldList = (DT_FIELD **) List; 3176 DT_FIELD *SubtableStart; 3177 ACPI_DMTABLE_INFO *InfoTable = NULL; 3178 UINT8 SubtableType; 3179 UINT8 Temp64[16]; 3180 UINT8 Temp8; 3181 3182 3183 /* Main table */ 3184 3185 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 3186 &Subtable); 3187 if (ACPI_FAILURE (Status)) 3188 { 3189 return (Status); 3190 } 3191 3192 ParentTable = DtPeekSubtable (); 3193 DtInsertSubtable (ParentTable, Subtable); 3194 DtPushSubtable (Subtable); 3195 3196 /* Save a pointer to the main subtable */ 3197 3198 MainSubtable = Subtable; 3199 3200 while (*PFieldList) 3201 { 3202 SubtableStart = *PFieldList; 3203 3204 /* Compile the SubtableType integer */ 3205 3206 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 3207 3208 switch (SubtableType) 3209 { 3210 3211 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 3212 3213 case ACPI_IVRS_TYPE_HARDWARE1: 3214 3215 InfoTable = AcpiDmTableInfoIvrsHware1; 3216 break; 3217 3218 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 3219 3220 case ACPI_IVRS_TYPE_HARDWARE2: 3221 case ACPI_IVRS_TYPE_HARDWARE3: 3222 3223 InfoTable = AcpiDmTableInfoIvrsHware23; 3224 break; 3225 3226 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 3227 3228 case ACPI_IVRS_TYPE_MEMORY1: 3229 case ACPI_IVRS_TYPE_MEMORY2: 3230 case ACPI_IVRS_TYPE_MEMORY3: 3231 3232 InfoTable = AcpiDmTableInfoIvrsMemory; 3233 break; 3234 3235 /* 4-byte device entries */ 3236 3237 case ACPI_IVRS_TYPE_PAD4: 3238 case ACPI_IVRS_TYPE_ALL: 3239 case ACPI_IVRS_TYPE_SELECT: 3240 case ACPI_IVRS_TYPE_START: 3241 case ACPI_IVRS_TYPE_END: 3242 3243 InfoTable = AcpiDmTableInfoIvrs4; 3244 break; 3245 3246 /* 8-byte device entries, type A */ 3247 3248 case ACPI_IVRS_TYPE_ALIAS_SELECT: 3249 case ACPI_IVRS_TYPE_ALIAS_START: 3250 3251 InfoTable = AcpiDmTableInfoIvrs8a; 3252 break; 3253 3254 /* 8-byte device entries, type B */ 3255 3256 case ACPI_IVRS_TYPE_EXT_SELECT: 3257 case ACPI_IVRS_TYPE_EXT_START: 3258 3259 InfoTable = AcpiDmTableInfoIvrs8b; 3260 break; 3261 3262 /* 8-byte device entries, type C */ 3263 3264 case ACPI_IVRS_TYPE_SPECIAL: 3265 3266 InfoTable = AcpiDmTableInfoIvrs8c; 3267 break; 3268 3269 /* Variable device entries, type F0h */ 3270 3271 case ACPI_IVRS_TYPE_HID: 3272 3273 InfoTable = AcpiDmTableInfoIvrsHid; 3274 break; 3275 3276 default: 3277 3278 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 3279 "IVRS Device Entry"); 3280 return (AE_ERROR); 3281 } 3282 3283 /* Compile the InfoTable from above */ 3284 3285 Status = DtCompileTable (PFieldList, InfoTable, 3286 &Subtable); 3287 if (ACPI_FAILURE (Status)) 3288 { 3289 return (Status); 3290 } 3291 3292 ParentTable = DtPeekSubtable (); 3293 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 3294 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 3295 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 3296 SubtableType != ACPI_IVRS_TYPE_HID && 3297 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 3298 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 3299 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 3300 { 3301 if (ParentTable) 3302 DtInsertSubtable (ParentTable, Subtable); 3303 } 3304 3305 switch (SubtableType) 3306 { 3307 case ACPI_IVRS_TYPE_HARDWARE1: 3308 case ACPI_IVRS_TYPE_HARDWARE2: 3309 case ACPI_IVRS_TYPE_HARDWARE3: 3310 case ACPI_IVRS_TYPE_MEMORY1: 3311 case ACPI_IVRS_TYPE_MEMORY2: 3312 case ACPI_IVRS_TYPE_MEMORY3: 3313 3314 /* Insert these IVHDs/IVMDs at the root subtable */ 3315 3316 DtInsertSubtable (MainSubtable, Subtable); 3317 DtPushSubtable (Subtable); 3318 break; 3319 3320 case ACPI_IVRS_TYPE_HID: 3321 3322 /* Special handling for the HID named device entry (0xF0) */ 3323 3324 if (ParentTable) 3325 { 3326 DtInsertSubtable (ParentTable, Subtable); 3327 } 3328 3329 /* 3330 * Process the HID value. First, get the HID value as a string. 3331 */ 3332 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 3333 3334 /* 3335 * Determine if the HID is an integer or a string. 3336 * An integer is defined to be 32 bits, with the upper 32 bits 3337 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 3338 * integer or a character string. If an integer, the lower 3339 * 4 bytes of the field contain the integer and the upper 3340 * 4 bytes are padded with 0". 3341 */ 3342 if (UtIsIdInteger ((UINT8 *) &Temp64)) 3343 { 3344 /* Compile the HID value as an integer */ 3345 3346 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 3347 3348 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 3349 &Subtable); 3350 if (ACPI_FAILURE (Status)) 3351 { 3352 return (Status); 3353 } 3354 } 3355 else 3356 { 3357 /* Compile the HID value as a string */ 3358 3359 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 3360 &Subtable); 3361 if (ACPI_FAILURE (Status)) 3362 { 3363 return (Status); 3364 } 3365 } 3366 3367 DtInsertSubtable (ParentTable, Subtable); 3368 3369 /* 3370 * Process the CID value. First, get the CID value as a string. 3371 */ 3372 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 3373 3374 if (UtIsIdInteger ((UINT8 *) &Temp64)) 3375 { 3376 /* Compile the CID value as an integer */ 3377 3378 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 3379 3380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 3381 &Subtable); 3382 if (ACPI_FAILURE (Status)) 3383 { 3384 return (Status); 3385 } 3386 } 3387 else 3388 { 3389 /* Compile the CID value as a string */ 3390 3391 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 3392 &Subtable); 3393 if (ACPI_FAILURE (Status)) 3394 { 3395 return (Status); 3396 } 3397 } 3398 3399 DtInsertSubtable (ParentTable, Subtable); 3400 3401 /* 3402 * Process the UID value. First, get and decode the "UID Format" field (Integer). 3403 */ 3404 if (!*PFieldList) 3405 { 3406 return (AE_OK); 3407 } 3408 3409 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 3410 3411 switch (Temp8) 3412 { 3413 case ACPI_IVRS_UID_NOT_PRESENT: 3414 break; 3415 3416 case ACPI_IVRS_UID_IS_INTEGER: 3417 3418 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 3419 &Subtable); 3420 if (ACPI_FAILURE (Status)) 3421 { 3422 return (Status); 3423 } 3424 DtInsertSubtable (ParentTable, Subtable); 3425 break; 3426 3427 case ACPI_IVRS_UID_IS_STRING: 3428 3429 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 3430 &Subtable); 3431 if (ACPI_FAILURE (Status)) 3432 { 3433 return (Status); 3434 } 3435 DtInsertSubtable (ParentTable, Subtable); 3436 break; 3437 3438 default: 3439 3440 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 3441 "IVRS Device Entry"); 3442 return (AE_ERROR); 3443 } 3444 3445 default: 3446 3447 /* All other subtable types come through here */ 3448 break; 3449 } 3450 } 3451 3452 return (AE_OK); 3453 } 3454 3455 3456 /****************************************************************************** 3457 * 3458 * FUNCTION: DtCompileRimt 3459 * 3460 * PARAMETERS: List - Current field list pointer 3461 * 3462 * RETURN: Status 3463 * 3464 * DESCRIPTION: Compile RIMT. 3465 * 3466 *****************************************************************************/ 3467 3468 ACPI_STATUS 3469 DtCompileRimt ( 3470 void **List) 3471 { 3472 ACPI_RIMT_PLATFORM_DEVICE *PlatDevNode; 3473 ACPI_RIMT_PCIE_RC *PcieRcNode; 3474 ACPI_TABLE_RIMT *Rimt; 3475 ACPI_RIMT_IOMMU *IommuNode; 3476 ACPI_RIMT_NODE *RimtNode; 3477 ACPI_STATUS Status; 3478 DT_SUBTABLE *Subtable; 3479 DT_SUBTABLE *ParentTable; 3480 DT_FIELD **PFieldList = (DT_FIELD **) List; 3481 DT_FIELD *SubtableStart; 3482 UINT32 NodeNumber; 3483 UINT32 NodeLength; 3484 UINT16 IdMappingNumber; 3485 UINT32 i; 3486 3487 3488 ParentTable = DtPeekSubtable (); 3489 3490 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimt, &Subtable); 3491 if (ACPI_FAILURE (Status)) 3492 { 3493 return (Status); 3494 } 3495 3496 DtInsertSubtable (ParentTable, Subtable); 3497 3498 /* 3499 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3500 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3501 */ 3502 Rimt = ACPI_SUB_PTR (ACPI_TABLE_RIMT, Subtable->Buffer, 3503 sizeof (ACPI_TABLE_HEADER)); 3504 3505 NodeNumber = 0; 3506 while (*PFieldList) 3507 { 3508 SubtableStart = *PFieldList; 3509 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtNodeHdr, &Subtable); 3510 3511 if (ACPI_FAILURE (Status)) 3512 { 3513 return (Status); 3514 } 3515 3516 DtInsertSubtable (ParentTable, Subtable); 3517 RimtNode = ACPI_CAST_PTR (ACPI_RIMT_NODE, Subtable->Buffer); 3518 NodeLength = ACPI_OFFSET (ACPI_RIMT_NODE, NodeData); 3519 3520 DtPushSubtable (Subtable); 3521 ParentTable = DtPeekSubtable (); 3522 3523 switch (RimtNode->Type) 3524 { 3525 case ACPI_RIMT_NODE_TYPE_IOMMU: 3526 3527 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtIommu, 3528 &Subtable); 3529 if (ACPI_FAILURE (Status)) 3530 { 3531 return (Status); 3532 } 3533 3534 IommuNode = ACPI_CAST_PTR (ACPI_RIMT_IOMMU, Subtable->Buffer); 3535 DtInsertSubtable (ParentTable, Subtable); 3536 NodeLength += Subtable->Length; 3537 3538 for (i = 0; i < IommuNode->NumInterruptWires; i++) 3539 { 3540 while (*PFieldList) 3541 { 3542 Status = DtCompileTable (PFieldList, 3543 AcpiDmTableInfoRimtIommuWire, 3544 &Subtable); 3545 if (ACPI_FAILURE (Status)) 3546 { 3547 return (Status); 3548 } 3549 if (!Subtable) 3550 { 3551 break; 3552 } 3553 3554 DtInsertSubtable (ParentTable, Subtable); 3555 NodeLength += Subtable->Length; 3556 } 3557 } 3558 3559 break; 3560 3561 case ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX: 3562 3563 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPcieRc, 3564 &Subtable); 3565 if (ACPI_FAILURE (Status)) 3566 { 3567 return (Status); 3568 } 3569 3570 DtInsertSubtable (ParentTable, Subtable); 3571 PcieRcNode = ACPI_CAST_PTR (ACPI_RIMT_PCIE_RC, Subtable->Buffer); 3572 NodeLength += Subtable->Length; 3573 3574 /* Compile Array of ID mappings */ 3575 3576 PcieRcNode->IdMappingOffset = (UINT16) NodeLength; 3577 IdMappingNumber = 0; 3578 while (*PFieldList) 3579 { 3580 Status = DtCompileTable (PFieldList, 3581 AcpiDmTableInfoRimtIdMapping, 3582 &Subtable); 3583 if (ACPI_FAILURE (Status)) 3584 { 3585 return (Status); 3586 } 3587 3588 if (!Subtable) 3589 { 3590 break; 3591 } 3592 3593 DtInsertSubtable (ParentTable, Subtable); 3594 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING); 3595 IdMappingNumber++; 3596 } 3597 3598 PcieRcNode->NumIdMappings = IdMappingNumber; 3599 if (!IdMappingNumber) 3600 { 3601 PcieRcNode->IdMappingOffset = 0; 3602 } 3603 3604 break; 3605 3606 case ACPI_RIMT_NODE_TYPE_PLAT_DEVICE: 3607 3608 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDev, 3609 &Subtable); 3610 if (ACPI_FAILURE (Status)) 3611 { 3612 return (Status); 3613 } 3614 3615 DtInsertSubtable (ParentTable, Subtable); 3616 PlatDevNode = ACPI_CAST_PTR (ACPI_RIMT_PLATFORM_DEVICE, Subtable->Buffer); 3617 NodeLength += Subtable->Length; 3618 3619 /* 3620 * Padding - Variable-length data 3621 * Optionally allows the offset of the ID mappings to be used 3622 * for filling this field. 3623 */ 3624 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDevPad, 3625 &Subtable); 3626 if (ACPI_FAILURE (Status)) 3627 { 3628 return (Status); 3629 } 3630 3631 if (Subtable) 3632 { 3633 DtInsertSubtable (ParentTable, Subtable); 3634 NodeLength += Subtable->Length; 3635 } 3636 else 3637 { 3638 if (NodeLength > PlatDevNode->IdMappingOffset) 3639 { 3640 return (AE_BAD_DATA); 3641 } 3642 3643 if (NodeLength < PlatDevNode->IdMappingOffset) 3644 { 3645 Status = DtCompilePadding ( 3646 PlatDevNode->IdMappingOffset - (UINT16) NodeLength, 3647 &Subtable); 3648 if (ACPI_FAILURE (Status)) 3649 { 3650 return (Status); 3651 } 3652 3653 DtInsertSubtable (ParentTable, Subtable); 3654 NodeLength = PlatDevNode->IdMappingOffset; 3655 } 3656 } 3657 3658 /* Compile Array of ID mappings */ 3659 3660 PlatDevNode->IdMappingOffset = (UINT16) NodeLength; 3661 IdMappingNumber = 0; 3662 while (*PFieldList) 3663 { 3664 Status = DtCompileTable (PFieldList, 3665 AcpiDmTableInfoRimtIdMapping, 3666 &Subtable); 3667 if (ACPI_FAILURE (Status)) 3668 { 3669 return (Status); 3670 } 3671 3672 if (!Subtable) 3673 { 3674 break; 3675 } 3676 3677 DtInsertSubtable (ParentTable, Subtable); 3678 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING); 3679 IdMappingNumber++; 3680 } 3681 3682 PlatDevNode->NumIdMappings = IdMappingNumber; 3683 if (!IdMappingNumber) 3684 { 3685 PlatDevNode->IdMappingOffset = 0; 3686 } 3687 3688 break; 3689 3690 3691 default: 3692 3693 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RIMT"); 3694 return (AE_ERROR); 3695 } 3696 3697 DtPopSubtable (); 3698 ParentTable = DtPeekSubtable (); 3699 NodeNumber++; 3700 } 3701 3702 Rimt->NumNodes = NodeNumber; 3703 return (AE_OK); 3704 } 3705