1 /****************************************************************************** 2 * 3 * Module Name: dttable1.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 MERCHANTIBILITY 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: DtCompileAsf 68 * 69 * PARAMETERS: List - Current field list pointer 70 * 71 * RETURN: Status 72 * 73 * DESCRIPTION: Compile ASF!. 74 * 75 *****************************************************************************/ 76 77 ACPI_STATUS 78 DtCompileAsf ( 79 void **List) 80 { 81 ACPI_ASF_INFO *AsfTable; 82 DT_SUBTABLE *Subtable; 83 DT_SUBTABLE *ParentTable; 84 ACPI_DMTABLE_INFO *InfoTable; 85 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 86 UINT32 DataCount = 0; 87 ACPI_STATUS Status; 88 UINT32 i; 89 DT_FIELD **PFieldList = (DT_FIELD **) List; 90 DT_FIELD *SubtableStart; 91 92 93 while (*PFieldList) 94 { 95 SubtableStart = *PFieldList; 96 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 97 &Subtable, TRUE); 98 if (ACPI_FAILURE (Status)) 99 { 100 return (Status); 101 } 102 103 ParentTable = DtPeekSubtable (); 104 DtInsertSubtable (ParentTable, Subtable); 105 DtPushSubtable (Subtable); 106 107 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 108 109 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 110 { 111 case ACPI_ASF_TYPE_INFO: 112 113 InfoTable = AcpiDmTableInfoAsf0; 114 break; 115 116 case ACPI_ASF_TYPE_ALERT: 117 118 InfoTable = AcpiDmTableInfoAsf1; 119 break; 120 121 case ACPI_ASF_TYPE_CONTROL: 122 123 InfoTable = AcpiDmTableInfoAsf2; 124 break; 125 126 case ACPI_ASF_TYPE_BOOT: 127 128 InfoTable = AcpiDmTableInfoAsf3; 129 break; 130 131 case ACPI_ASF_TYPE_ADDRESS: 132 133 InfoTable = AcpiDmTableInfoAsf4; 134 break; 135 136 default: 137 138 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 139 return (AE_ERROR); 140 } 141 142 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 143 if (ACPI_FAILURE (Status)) 144 { 145 return (Status); 146 } 147 148 ParentTable = DtPeekSubtable (); 149 DtInsertSubtable (ParentTable, Subtable); 150 151 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 152 { 153 case ACPI_ASF_TYPE_INFO: 154 155 DataInfoTable = NULL; 156 break; 157 158 case ACPI_ASF_TYPE_ALERT: 159 160 DataInfoTable = AcpiDmTableInfoAsf1a; 161 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 162 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 163 sizeof (ACPI_ASF_HEADER)))->Alerts; 164 break; 165 166 case ACPI_ASF_TYPE_CONTROL: 167 168 DataInfoTable = AcpiDmTableInfoAsf2a; 169 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 170 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 171 sizeof (ACPI_ASF_HEADER)))->Controls; 172 break; 173 174 case ACPI_ASF_TYPE_BOOT: 175 176 DataInfoTable = NULL; 177 break; 178 179 case ACPI_ASF_TYPE_ADDRESS: 180 181 DataInfoTable = TableInfoAsfAddress; 182 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 183 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 184 sizeof (ACPI_ASF_HEADER)))->Devices; 185 break; 186 187 default: 188 189 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 190 return (AE_ERROR); 191 } 192 193 if (DataInfoTable) 194 { 195 switch (AsfTable->Header.Type & 0x7F) 196 { 197 case ACPI_ASF_TYPE_ADDRESS: 198 199 while (DataCount > 0) 200 { 201 Status = DtCompileTable (PFieldList, DataInfoTable, 202 &Subtable, TRUE); 203 if (ACPI_FAILURE (Status)) 204 { 205 return (Status); 206 } 207 208 DtInsertSubtable (ParentTable, Subtable); 209 DataCount = DataCount - Subtable->Length; 210 } 211 break; 212 213 default: 214 215 for (i = 0; i < DataCount; i++) 216 { 217 Status = DtCompileTable (PFieldList, DataInfoTable, 218 &Subtable, TRUE); 219 if (ACPI_FAILURE (Status)) 220 { 221 return (Status); 222 } 223 224 DtInsertSubtable (ParentTable, Subtable); 225 } 226 break; 227 } 228 } 229 230 DtPopSubtable (); 231 } 232 233 return (AE_OK); 234 } 235 236 237 /****************************************************************************** 238 * 239 * FUNCTION: DtCompileCpep 240 * 241 * PARAMETERS: List - Current field list pointer 242 * 243 * RETURN: Status 244 * 245 * DESCRIPTION: Compile CPEP. 246 * 247 *****************************************************************************/ 248 249 ACPI_STATUS 250 DtCompileCpep ( 251 void **List) 252 { 253 ACPI_STATUS Status; 254 255 256 Status = DtCompileTwoSubtables (List, 257 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 258 return (Status); 259 } 260 261 262 /****************************************************************************** 263 * 264 * FUNCTION: DtCompileCsrt 265 * 266 * PARAMETERS: List - Current field list pointer 267 * 268 * RETURN: Status 269 * 270 * DESCRIPTION: Compile CSRT. 271 * 272 *****************************************************************************/ 273 274 ACPI_STATUS 275 DtCompileCsrt ( 276 void **List) 277 { 278 ACPI_STATUS Status = AE_OK; 279 DT_SUBTABLE *Subtable; 280 DT_SUBTABLE *ParentTable; 281 DT_FIELD **PFieldList = (DT_FIELD **) List; 282 UINT32 DescriptorCount; 283 UINT32 GroupLength; 284 285 286 /* Subtables (Resource Groups) */ 287 288 ParentTable = DtPeekSubtable (); 289 while (*PFieldList) 290 { 291 /* Resource group subtable */ 292 293 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 294 &Subtable, TRUE); 295 if (ACPI_FAILURE (Status)) 296 { 297 return (Status); 298 } 299 300 /* Compute the number of resource descriptors */ 301 302 GroupLength = 303 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 304 Subtable->Buffer))->Length - 305 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 306 Subtable->Buffer))->SharedInfoLength - 307 sizeof (ACPI_CSRT_GROUP); 308 309 DescriptorCount = (GroupLength / 310 sizeof (ACPI_CSRT_DESCRIPTOR)); 311 312 DtInsertSubtable (ParentTable, Subtable); 313 DtPushSubtable (Subtable); 314 ParentTable = DtPeekSubtable (); 315 316 /* Shared info subtable (One per resource group) */ 317 318 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 319 &Subtable, TRUE); 320 if (ACPI_FAILURE (Status)) 321 { 322 return (Status); 323 } 324 325 DtInsertSubtable (ParentTable, Subtable); 326 327 /* Sub-Subtables (Resource Descriptors) */ 328 329 while (*PFieldList && DescriptorCount) 330 { 331 332 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 333 &Subtable, TRUE); 334 if (ACPI_FAILURE (Status)) 335 { 336 return (Status); 337 } 338 339 DtInsertSubtable (ParentTable, Subtable); 340 341 DtPushSubtable (Subtable); 342 ParentTable = DtPeekSubtable (); 343 if (*PFieldList) 344 { 345 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 346 &Subtable, TRUE); 347 if (ACPI_FAILURE (Status)) 348 { 349 return (Status); 350 } 351 if (Subtable) 352 { 353 DtInsertSubtable (ParentTable, Subtable); 354 } 355 } 356 357 DtPopSubtable (); 358 ParentTable = DtPeekSubtable (); 359 DescriptorCount--; 360 } 361 362 DtPopSubtable (); 363 ParentTable = DtPeekSubtable (); 364 } 365 366 return (Status); 367 } 368 369 370 /****************************************************************************** 371 * 372 * FUNCTION: DtCompileDbg2 373 * 374 * PARAMETERS: List - Current field list pointer 375 * 376 * RETURN: Status 377 * 378 * DESCRIPTION: Compile DBG2. 379 * 380 *****************************************************************************/ 381 382 ACPI_STATUS 383 DtCompileDbg2 ( 384 void **List) 385 { 386 ACPI_STATUS Status; 387 DT_SUBTABLE *Subtable; 388 DT_SUBTABLE *ParentTable; 389 DT_FIELD **PFieldList = (DT_FIELD **) List; 390 UINT32 SubtableCount; 391 ACPI_DBG2_HEADER *Dbg2Header; 392 ACPI_DBG2_DEVICE *DeviceInfo; 393 UINT16 CurrentOffset; 394 UINT32 i; 395 396 397 /* Main table */ 398 399 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE); 400 if (ACPI_FAILURE (Status)) 401 { 402 return (Status); 403 } 404 405 ParentTable = DtPeekSubtable (); 406 DtInsertSubtable (ParentTable, Subtable); 407 408 /* Main table fields */ 409 410 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 411 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 412 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 413 414 SubtableCount = Dbg2Header->InfoCount; 415 DtPushSubtable (Subtable); 416 417 /* Process all Device Information subtables (Count = InfoCount) */ 418 419 while (*PFieldList && SubtableCount) 420 { 421 /* Subtable: Debug Device Information */ 422 423 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 424 &Subtable, TRUE); 425 if (ACPI_FAILURE (Status)) 426 { 427 return (Status); 428 } 429 430 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 431 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 432 433 ParentTable = DtPeekSubtable (); 434 DtInsertSubtable (ParentTable, Subtable); 435 DtPushSubtable (Subtable); 436 437 ParentTable = DtPeekSubtable (); 438 439 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 440 441 DeviceInfo->BaseAddressOffset = CurrentOffset; 442 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 443 { 444 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 445 &Subtable, TRUE); 446 if (ACPI_FAILURE (Status)) 447 { 448 return (Status); 449 } 450 451 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 452 DtInsertSubtable (ParentTable, Subtable); 453 } 454 455 /* AddressSize array (Required, size = RegisterCount) */ 456 457 DeviceInfo->AddressSizeOffset = CurrentOffset; 458 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 459 { 460 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 461 &Subtable, TRUE); 462 if (ACPI_FAILURE (Status)) 463 { 464 return (Status); 465 } 466 467 CurrentOffset += (UINT16) sizeof (UINT32); 468 DtInsertSubtable (ParentTable, Subtable); 469 } 470 471 /* NamespaceString device identifier (Required, size = NamePathLength) */ 472 473 DeviceInfo->NamepathOffset = CurrentOffset; 474 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 475 &Subtable, TRUE); 476 if (ACPI_FAILURE (Status)) 477 { 478 return (Status); 479 } 480 481 /* Update the device info header */ 482 483 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 484 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 485 DtInsertSubtable (ParentTable, Subtable); 486 487 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 488 489 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 490 &Subtable, TRUE); 491 if (ACPI_FAILURE (Status)) 492 { 493 return (Status); 494 } 495 496 /* Update the device info header (zeros if no OEM data present) */ 497 498 DeviceInfo->OemDataOffset = 0; 499 DeviceInfo->OemDataLength = 0; 500 501 /* Optional subtable (OemData) */ 502 503 if (Subtable && Subtable->Length) 504 { 505 DeviceInfo->OemDataOffset = CurrentOffset; 506 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 507 508 DtInsertSubtable (ParentTable, Subtable); 509 } 510 511 SubtableCount--; 512 DtPopSubtable (); /* Get next Device Information subtable */ 513 } 514 515 DtPopSubtable (); 516 return (AE_OK); 517 } 518 519 520 /****************************************************************************** 521 * 522 * FUNCTION: DtCompileDmar 523 * 524 * PARAMETERS: List - Current field list pointer 525 * 526 * RETURN: Status 527 * 528 * DESCRIPTION: Compile DMAR. 529 * 530 *****************************************************************************/ 531 532 ACPI_STATUS 533 DtCompileDmar ( 534 void **List) 535 { 536 ACPI_STATUS Status; 537 DT_SUBTABLE *Subtable; 538 DT_SUBTABLE *ParentTable; 539 DT_FIELD **PFieldList = (DT_FIELD **) List; 540 DT_FIELD *SubtableStart; 541 ACPI_DMTABLE_INFO *InfoTable; 542 ACPI_DMAR_HEADER *DmarHeader; 543 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 544 UINT32 DeviceScopeLength; 545 UINT32 PciPathLength; 546 547 548 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); 549 if (ACPI_FAILURE (Status)) 550 { 551 return (Status); 552 } 553 554 ParentTable = DtPeekSubtable (); 555 DtInsertSubtable (ParentTable, Subtable); 556 DtPushSubtable (Subtable); 557 558 while (*PFieldList) 559 { 560 /* DMAR Header */ 561 562 SubtableStart = *PFieldList; 563 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 564 &Subtable, TRUE); 565 if (ACPI_FAILURE (Status)) 566 { 567 return (Status); 568 } 569 570 ParentTable = DtPeekSubtable (); 571 DtInsertSubtable (ParentTable, Subtable); 572 DtPushSubtable (Subtable); 573 574 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 575 576 switch (DmarHeader->Type) 577 { 578 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 579 580 InfoTable = AcpiDmTableInfoDmar0; 581 break; 582 583 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 584 585 InfoTable = AcpiDmTableInfoDmar1; 586 break; 587 588 case ACPI_DMAR_TYPE_ROOT_ATS: 589 590 InfoTable = AcpiDmTableInfoDmar2; 591 break; 592 593 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 594 595 InfoTable = AcpiDmTableInfoDmar3; 596 break; 597 598 case ACPI_DMAR_TYPE_NAMESPACE: 599 600 InfoTable = AcpiDmTableInfoDmar4; 601 break; 602 603 default: 604 605 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 606 return (AE_ERROR); 607 } 608 609 /* DMAR Subtable */ 610 611 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 612 if (ACPI_FAILURE (Status)) 613 { 614 return (Status); 615 } 616 617 ParentTable = DtPeekSubtable (); 618 DtInsertSubtable (ParentTable, Subtable); 619 620 /* 621 * Optional Device Scope subtables 622 */ 623 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 624 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 625 { 626 /* These types do not support device scopes */ 627 628 DtPopSubtable (); 629 continue; 630 } 631 632 DtPushSubtable (Subtable); 633 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 634 ParentTable->Length; 635 while (DeviceScopeLength) 636 { 637 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 638 &Subtable, FALSE); 639 if (Status == AE_NOT_FOUND) 640 { 641 break; 642 } 643 644 ParentTable = DtPeekSubtable (); 645 DtInsertSubtable (ParentTable, Subtable); 646 DtPushSubtable (Subtable); 647 648 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 649 650 /* Optional PCI Paths */ 651 652 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 653 while (PciPathLength) 654 { 655 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 656 &Subtable, FALSE); 657 if (Status == AE_NOT_FOUND) 658 { 659 DtPopSubtable (); 660 break; 661 } 662 663 ParentTable = DtPeekSubtable (); 664 DtInsertSubtable (ParentTable, Subtable); 665 PciPathLength -= Subtable->Length; 666 } 667 668 DtPopSubtable (); 669 DeviceScopeLength -= DmarDeviceScope->Length; 670 } 671 672 DtPopSubtable (); 673 DtPopSubtable (); 674 } 675 676 return (AE_OK); 677 } 678 679 680 /****************************************************************************** 681 * 682 * FUNCTION: DtCompileDrtm 683 * 684 * PARAMETERS: List - Current field list pointer 685 * 686 * RETURN: Status 687 * 688 * DESCRIPTION: Compile DRTM. 689 * 690 *****************************************************************************/ 691 692 ACPI_STATUS 693 DtCompileDrtm ( 694 void **List) 695 { 696 ACPI_STATUS Status; 697 DT_SUBTABLE *Subtable; 698 DT_SUBTABLE *ParentTable; 699 DT_FIELD **PFieldList = (DT_FIELD **) List; 700 UINT32 Count; 701 /* ACPI_TABLE_DRTM *Drtm; */ 702 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 703 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 704 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 705 706 707 ParentTable = DtPeekSubtable (); 708 709 /* Compile DRTM header */ 710 711 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 712 &Subtable, TRUE); 713 if (ACPI_FAILURE (Status)) 714 { 715 return (Status); 716 } 717 DtInsertSubtable (ParentTable, Subtable); 718 719 /* 720 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care 721 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 722 */ 723 #if 0 724 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 725 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 726 #endif 727 /* Compile VTL */ 728 729 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 730 &Subtable, TRUE); 731 if (ACPI_FAILURE (Status)) 732 { 733 return (Status); 734 } 735 736 DtInsertSubtable (ParentTable, Subtable); 737 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 738 739 DtPushSubtable (Subtable); 740 ParentTable = DtPeekSubtable (); 741 Count = 0; 742 743 while (*PFieldList) 744 { 745 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 746 &Subtable, TRUE); 747 if (ACPI_FAILURE (Status)) 748 { 749 return (Status); 750 } 751 if (!Subtable) 752 { 753 break; 754 } 755 DtInsertSubtable (ParentTable, Subtable); 756 Count++; 757 } 758 759 DrtmVtl->ValidatedTableCount = Count; 760 DtPopSubtable (); 761 ParentTable = DtPeekSubtable (); 762 763 /* Compile RL */ 764 765 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 766 &Subtable, TRUE); 767 if (ACPI_FAILURE (Status)) 768 { 769 return (Status); 770 } 771 772 DtInsertSubtable (ParentTable, Subtable); 773 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 774 775 DtPushSubtable (Subtable); 776 ParentTable = DtPeekSubtable (); 777 Count = 0; 778 779 while (*PFieldList) 780 { 781 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 782 &Subtable, TRUE); 783 if (ACPI_FAILURE (Status)) 784 { 785 return (Status); 786 } 787 788 if (!Subtable) 789 { 790 break; 791 } 792 793 DtInsertSubtable (ParentTable, Subtable); 794 Count++; 795 } 796 797 DrtmRl->ResourceCount = Count; 798 DtPopSubtable (); 799 ParentTable = DtPeekSubtable (); 800 801 /* Compile DPS */ 802 803 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 804 &Subtable, TRUE); 805 if (ACPI_FAILURE (Status)) 806 { 807 return (Status); 808 } 809 DtInsertSubtable (ParentTable, Subtable); 810 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 811 812 813 return (AE_OK); 814 } 815 816 817 /****************************************************************************** 818 * 819 * FUNCTION: DtCompileEinj 820 * 821 * PARAMETERS: List - Current field list pointer 822 * 823 * RETURN: Status 824 * 825 * DESCRIPTION: Compile EINJ. 826 * 827 *****************************************************************************/ 828 829 ACPI_STATUS 830 DtCompileEinj ( 831 void **List) 832 { 833 ACPI_STATUS Status; 834 835 836 Status = DtCompileTwoSubtables (List, 837 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 838 return (Status); 839 } 840 841 842 /****************************************************************************** 843 * 844 * FUNCTION: DtCompileErst 845 * 846 * PARAMETERS: List - Current field list pointer 847 * 848 * RETURN: Status 849 * 850 * DESCRIPTION: Compile ERST. 851 * 852 *****************************************************************************/ 853 854 ACPI_STATUS 855 DtCompileErst ( 856 void **List) 857 { 858 ACPI_STATUS Status; 859 860 861 Status = DtCompileTwoSubtables (List, 862 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 863 return (Status); 864 } 865 866 867 /****************************************************************************** 868 * 869 * FUNCTION: DtCompileGtdt 870 * 871 * PARAMETERS: List - Current field list pointer 872 * 873 * RETURN: Status 874 * 875 * DESCRIPTION: Compile GTDT. 876 * 877 *****************************************************************************/ 878 879 ACPI_STATUS 880 DtCompileGtdt ( 881 void **List) 882 { 883 ACPI_STATUS Status; 884 DT_SUBTABLE *Subtable; 885 DT_SUBTABLE *ParentTable; 886 DT_FIELD **PFieldList = (DT_FIELD **) List; 887 DT_FIELD *SubtableStart; 888 ACPI_SUBTABLE_HEADER *GtdtHeader; 889 ACPI_DMTABLE_INFO *InfoTable; 890 UINT32 GtCount; 891 892 893 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 894 &Subtable, TRUE); 895 if (ACPI_FAILURE (Status)) 896 { 897 return (Status); 898 } 899 900 ParentTable = DtPeekSubtable (); 901 DtInsertSubtable (ParentTable, Subtable); 902 903 while (*PFieldList) 904 { 905 SubtableStart = *PFieldList; 906 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 907 &Subtable, TRUE); 908 if (ACPI_FAILURE (Status)) 909 { 910 return (Status); 911 } 912 913 ParentTable = DtPeekSubtable (); 914 DtInsertSubtable (ParentTable, Subtable); 915 DtPushSubtable (Subtable); 916 917 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 918 919 switch (GtdtHeader->Type) 920 { 921 case ACPI_GTDT_TYPE_TIMER_BLOCK: 922 923 InfoTable = AcpiDmTableInfoGtdt0; 924 break; 925 926 case ACPI_GTDT_TYPE_WATCHDOG: 927 928 InfoTable = AcpiDmTableInfoGtdt1; 929 break; 930 931 default: 932 933 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 934 return (AE_ERROR); 935 } 936 937 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 938 if (ACPI_FAILURE (Status)) 939 { 940 return (Status); 941 } 942 943 ParentTable = DtPeekSubtable (); 944 DtInsertSubtable (ParentTable, Subtable); 945 946 /* 947 * Additional GT block subtable data 948 */ 949 950 switch (GtdtHeader->Type) 951 { 952 case ACPI_GTDT_TYPE_TIMER_BLOCK: 953 954 DtPushSubtable (Subtable); 955 ParentTable = DtPeekSubtable (); 956 957 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 958 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 959 960 while (GtCount) 961 { 962 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 963 &Subtable, TRUE); 964 if (ACPI_FAILURE (Status)) 965 { 966 return (Status); 967 } 968 969 DtInsertSubtable (ParentTable, Subtable); 970 GtCount--; 971 } 972 973 DtPopSubtable (); 974 break; 975 976 default: 977 978 break; 979 } 980 981 DtPopSubtable (); 982 } 983 984 return (AE_OK); 985 } 986 987 988 /****************************************************************************** 989 * 990 * FUNCTION: DtCompileFpdt 991 * 992 * PARAMETERS: List - Current field list pointer 993 * 994 * RETURN: Status 995 * 996 * DESCRIPTION: Compile FPDT. 997 * 998 *****************************************************************************/ 999 1000 ACPI_STATUS 1001 DtCompileFpdt ( 1002 void **List) 1003 { 1004 ACPI_STATUS Status; 1005 ACPI_FPDT_HEADER *FpdtHeader; 1006 DT_SUBTABLE *Subtable; 1007 DT_SUBTABLE *ParentTable; 1008 ACPI_DMTABLE_INFO *InfoTable; 1009 DT_FIELD **PFieldList = (DT_FIELD **) List; 1010 DT_FIELD *SubtableStart; 1011 1012 1013 while (*PFieldList) 1014 { 1015 SubtableStart = *PFieldList; 1016 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1017 &Subtable, TRUE); 1018 if (ACPI_FAILURE (Status)) 1019 { 1020 return (Status); 1021 } 1022 1023 ParentTable = DtPeekSubtable (); 1024 DtInsertSubtable (ParentTable, Subtable); 1025 DtPushSubtable (Subtable); 1026 1027 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1028 1029 switch (FpdtHeader->Type) 1030 { 1031 case ACPI_FPDT_TYPE_BOOT: 1032 1033 InfoTable = AcpiDmTableInfoFpdt0; 1034 break; 1035 1036 case ACPI_FPDT_TYPE_S3PERF: 1037 1038 InfoTable = AcpiDmTableInfoFpdt1; 1039 break; 1040 1041 default: 1042 1043 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1044 return (AE_ERROR); 1045 break; 1046 } 1047 1048 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1049 if (ACPI_FAILURE (Status)) 1050 { 1051 return (Status); 1052 } 1053 1054 ParentTable = DtPeekSubtable (); 1055 DtInsertSubtable (ParentTable, Subtable); 1056 DtPopSubtable (); 1057 } 1058 1059 return (AE_OK); 1060 } 1061 1062 1063 /****************************************************************************** 1064 * 1065 * FUNCTION: DtCompileHest 1066 * 1067 * PARAMETERS: List - Current field list pointer 1068 * 1069 * RETURN: Status 1070 * 1071 * DESCRIPTION: Compile HEST. 1072 * 1073 *****************************************************************************/ 1074 1075 ACPI_STATUS 1076 DtCompileHest ( 1077 void **List) 1078 { 1079 ACPI_STATUS Status; 1080 DT_SUBTABLE *Subtable; 1081 DT_SUBTABLE *ParentTable; 1082 DT_FIELD **PFieldList = (DT_FIELD **) List; 1083 DT_FIELD *SubtableStart; 1084 ACPI_DMTABLE_INFO *InfoTable; 1085 UINT16 Type; 1086 UINT32 BankCount; 1087 1088 1089 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1090 &Subtable, TRUE); 1091 if (ACPI_FAILURE (Status)) 1092 { 1093 return (Status); 1094 } 1095 1096 ParentTable = DtPeekSubtable (); 1097 DtInsertSubtable (ParentTable, Subtable); 1098 1099 while (*PFieldList) 1100 { 1101 /* Get subtable type */ 1102 1103 SubtableStart = *PFieldList; 1104 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1105 1106 switch (Type) 1107 { 1108 case ACPI_HEST_TYPE_IA32_CHECK: 1109 1110 InfoTable = AcpiDmTableInfoHest0; 1111 break; 1112 1113 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1114 1115 InfoTable = AcpiDmTableInfoHest1; 1116 break; 1117 1118 case ACPI_HEST_TYPE_IA32_NMI: 1119 1120 InfoTable = AcpiDmTableInfoHest2; 1121 break; 1122 1123 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1124 1125 InfoTable = AcpiDmTableInfoHest6; 1126 break; 1127 1128 case ACPI_HEST_TYPE_AER_ENDPOINT: 1129 1130 InfoTable = AcpiDmTableInfoHest7; 1131 break; 1132 1133 case ACPI_HEST_TYPE_AER_BRIDGE: 1134 1135 InfoTable = AcpiDmTableInfoHest8; 1136 break; 1137 1138 case ACPI_HEST_TYPE_GENERIC_ERROR: 1139 1140 InfoTable = AcpiDmTableInfoHest9; 1141 break; 1142 1143 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1144 1145 InfoTable = AcpiDmTableInfoHest10; 1146 break; 1147 1148 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1149 1150 InfoTable = AcpiDmTableInfoHest11; 1151 break; 1152 1153 default: 1154 1155 /* Cannot continue on unknown type */ 1156 1157 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1158 return (AE_ERROR); 1159 } 1160 1161 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1162 if (ACPI_FAILURE (Status)) 1163 { 1164 return (Status); 1165 } 1166 1167 DtInsertSubtable (ParentTable, Subtable); 1168 1169 /* 1170 * Additional subtable data - IA32 Error Bank(s) 1171 */ 1172 BankCount = 0; 1173 switch (Type) 1174 { 1175 case ACPI_HEST_TYPE_IA32_CHECK: 1176 1177 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1178 Subtable->Buffer))->NumHardwareBanks; 1179 break; 1180 1181 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1182 1183 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1184 Subtable->Buffer))->NumHardwareBanks; 1185 break; 1186 1187 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1188 1189 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1190 Subtable->Buffer))->NumHardwareBanks; 1191 break; 1192 1193 default: 1194 1195 break; 1196 } 1197 1198 while (BankCount) 1199 { 1200 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1201 &Subtable, TRUE); 1202 if (ACPI_FAILURE (Status)) 1203 { 1204 return (Status); 1205 } 1206 1207 DtInsertSubtable (ParentTable, Subtable); 1208 BankCount--; 1209 } 1210 } 1211 1212 return (AE_OK); 1213 } 1214 1215 1216 /****************************************************************************** 1217 * 1218 * FUNCTION: DtCompileHmat 1219 * 1220 * PARAMETERS: List - Current field list pointer 1221 * 1222 * RETURN: Status 1223 * 1224 * DESCRIPTION: Compile HMAT. 1225 * 1226 *****************************************************************************/ 1227 1228 ACPI_STATUS 1229 DtCompileHmat ( 1230 void **List) 1231 { 1232 ACPI_STATUS Status; 1233 DT_SUBTABLE *Subtable; 1234 DT_SUBTABLE *ParentTable; 1235 DT_FIELD **PFieldList = (DT_FIELD **) List; 1236 DT_FIELD *SubtableStart; 1237 DT_FIELD *EntryStart; 1238 ACPI_HMAT_STRUCTURE *HmatStruct; 1239 ACPI_HMAT_LOCALITY *HmatLocality; 1240 ACPI_HMAT_CACHE *HmatCache; 1241 ACPI_DMTABLE_INFO *InfoTable; 1242 UINT32 IntPDNumber; 1243 UINT32 TgtPDNumber; 1244 UINT64 EntryNumber; 1245 UINT16 SMBIOSHandleNumber; 1246 1247 1248 ParentTable = DtPeekSubtable (); 1249 1250 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1251 &Subtable, TRUE); 1252 if (ACPI_FAILURE (Status)) 1253 { 1254 return (Status); 1255 } 1256 DtInsertSubtable (ParentTable, Subtable); 1257 1258 while (*PFieldList) 1259 { 1260 /* Compile HMAT structure header */ 1261 1262 SubtableStart = *PFieldList; 1263 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1264 &Subtable, TRUE); 1265 if (ACPI_FAILURE (Status)) 1266 { 1267 return (Status); 1268 } 1269 DtInsertSubtable (ParentTable, Subtable); 1270 1271 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1272 HmatStruct->Length = Subtable->Length; 1273 1274 /* Compile HMAT structure body */ 1275 1276 switch (HmatStruct->Type) 1277 { 1278 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1279 1280 InfoTable = AcpiDmTableInfoHmat0; 1281 break; 1282 1283 case ACPI_HMAT_TYPE_LOCALITY: 1284 1285 InfoTable = AcpiDmTableInfoHmat1; 1286 break; 1287 1288 case ACPI_HMAT_TYPE_CACHE: 1289 1290 InfoTable = AcpiDmTableInfoHmat2; 1291 break; 1292 1293 default: 1294 1295 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 1296 return (AE_ERROR); 1297 } 1298 1299 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1300 if (ACPI_FAILURE (Status)) 1301 { 1302 return (Status); 1303 } 1304 DtInsertSubtable (ParentTable, Subtable); 1305 HmatStruct->Length += Subtable->Length; 1306 1307 /* Compile HMAT structure additionals */ 1308 1309 switch (HmatStruct->Type) 1310 { 1311 case ACPI_HMAT_TYPE_LOCALITY: 1312 1313 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 1314 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1315 1316 /* Compile initiator proximity domain list */ 1317 1318 IntPDNumber = 0; 1319 while (*PFieldList) 1320 { 1321 Status = DtCompileTable (PFieldList, 1322 AcpiDmTableInfoHmat1a, &Subtable, TRUE); 1323 if (ACPI_FAILURE (Status)) 1324 { 1325 return (Status); 1326 } 1327 if (!Subtable) 1328 { 1329 break; 1330 } 1331 DtInsertSubtable (ParentTable, Subtable); 1332 HmatStruct->Length += Subtable->Length; 1333 IntPDNumber++; 1334 } 1335 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 1336 1337 /* Compile target proximity domain list */ 1338 1339 TgtPDNumber = 0; 1340 while (*PFieldList) 1341 { 1342 Status = DtCompileTable (PFieldList, 1343 AcpiDmTableInfoHmat1b, &Subtable, TRUE); 1344 if (ACPI_FAILURE (Status)) 1345 { 1346 return (Status); 1347 } 1348 if (!Subtable) 1349 { 1350 break; 1351 } 1352 DtInsertSubtable (ParentTable, Subtable); 1353 HmatStruct->Length += Subtable->Length; 1354 TgtPDNumber++; 1355 } 1356 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 1357 1358 /* Save start of the entries for reporting errors */ 1359 1360 EntryStart = *PFieldList; 1361 1362 /* Compile latency/bandwidth entries */ 1363 1364 EntryNumber = 0; 1365 while (*PFieldList) 1366 { 1367 Status = DtCompileTable (PFieldList, 1368 AcpiDmTableInfoHmat1c, &Subtable, TRUE); 1369 if (ACPI_FAILURE (Status)) 1370 { 1371 return (Status); 1372 } 1373 if (!Subtable) 1374 { 1375 break; 1376 } 1377 DtInsertSubtable (ParentTable, Subtable); 1378 HmatStruct->Length += Subtable->Length; 1379 EntryNumber++; 1380 } 1381 1382 /* Validate number of entries */ 1383 1384 if (EntryNumber != 1385 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 1386 { 1387 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 1388 return (AE_ERROR); 1389 } 1390 break; 1391 1392 case ACPI_HMAT_TYPE_CACHE: 1393 1394 /* Compile SMBIOS handles */ 1395 1396 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 1397 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1398 SMBIOSHandleNumber = 0; 1399 while (*PFieldList) 1400 { 1401 Status = DtCompileTable (PFieldList, 1402 AcpiDmTableInfoHmat2a, &Subtable, TRUE); 1403 if (ACPI_FAILURE (Status)) 1404 { 1405 return (Status); 1406 } 1407 if (!Subtable) 1408 { 1409 break; 1410 } 1411 DtInsertSubtable (ParentTable, Subtable); 1412 HmatStruct->Length += Subtable->Length; 1413 SMBIOSHandleNumber++; 1414 } 1415 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 1416 break; 1417 1418 default: 1419 1420 break; 1421 } 1422 } 1423 1424 return (AE_OK); 1425 } 1426 1427 1428 /****************************************************************************** 1429 * 1430 * FUNCTION: DtCompileIort 1431 * 1432 * PARAMETERS: List - Current field list pointer 1433 * 1434 * RETURN: Status 1435 * 1436 * DESCRIPTION: Compile IORT. 1437 * 1438 *****************************************************************************/ 1439 1440 ACPI_STATUS 1441 DtCompileIort ( 1442 void **List) 1443 { 1444 ACPI_STATUS Status; 1445 DT_SUBTABLE *Subtable; 1446 DT_SUBTABLE *ParentTable; 1447 DT_FIELD **PFieldList = (DT_FIELD **) List; 1448 DT_FIELD *SubtableStart; 1449 ACPI_TABLE_IORT *Iort; 1450 ACPI_IORT_NODE *IortNode; 1451 ACPI_IORT_ITS_GROUP *IortItsGroup; 1452 ACPI_IORT_SMMU *IortSmmu; 1453 UINT32 NodeNumber; 1454 UINT32 NodeLength; 1455 UINT32 IdMappingNumber; 1456 UINT32 ItsNumber; 1457 UINT32 ContextIrptNumber; 1458 UINT32 PmuIrptNumber; 1459 UINT32 PaddingLength; 1460 1461 1462 ParentTable = DtPeekSubtable (); 1463 1464 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1465 &Subtable, TRUE); 1466 if (ACPI_FAILURE (Status)) 1467 { 1468 return (Status); 1469 } 1470 DtInsertSubtable (ParentTable, Subtable); 1471 1472 /* 1473 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1474 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1475 */ 1476 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1477 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1478 1479 /* 1480 * OptionalPadding - Variable-length data 1481 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1482 * Optionally allows the generic data types to be used for filling 1483 * this field. 1484 */ 1485 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1487 &Subtable, TRUE); 1488 if (ACPI_FAILURE (Status)) 1489 { 1490 return (Status); 1491 } 1492 if (Subtable) 1493 { 1494 DtInsertSubtable (ParentTable, Subtable); 1495 Iort->NodeOffset += Subtable->Length; 1496 } 1497 else 1498 { 1499 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1500 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1501 if (ACPI_FAILURE (Status)) 1502 { 1503 return (Status); 1504 } 1505 Iort->NodeOffset += PaddingLength; 1506 } 1507 1508 NodeNumber = 0; 1509 while (*PFieldList) 1510 { 1511 SubtableStart = *PFieldList; 1512 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1513 &Subtable, TRUE); 1514 if (ACPI_FAILURE (Status)) 1515 { 1516 return (Status); 1517 } 1518 1519 DtInsertSubtable (ParentTable, Subtable); 1520 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1521 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1522 1523 DtPushSubtable (Subtable); 1524 ParentTable = DtPeekSubtable (); 1525 1526 switch (IortNode->Type) 1527 { 1528 case ACPI_IORT_NODE_ITS_GROUP: 1529 1530 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1531 &Subtable, TRUE); 1532 if (ACPI_FAILURE (Status)) 1533 { 1534 return (Status); 1535 } 1536 1537 DtInsertSubtable (ParentTable, Subtable); 1538 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1539 NodeLength += Subtable->Length; 1540 1541 ItsNumber = 0; 1542 while (*PFieldList) 1543 { 1544 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1545 &Subtable, TRUE); 1546 if (ACPI_FAILURE (Status)) 1547 { 1548 return (Status); 1549 } 1550 if (!Subtable) 1551 { 1552 break; 1553 } 1554 1555 DtInsertSubtable (ParentTable, Subtable); 1556 NodeLength += Subtable->Length; 1557 ItsNumber++; 1558 } 1559 1560 IortItsGroup->ItsCount = ItsNumber; 1561 break; 1562 1563 case ACPI_IORT_NODE_NAMED_COMPONENT: 1564 1565 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 1566 &Subtable, TRUE); 1567 if (ACPI_FAILURE (Status)) 1568 { 1569 return (Status); 1570 } 1571 1572 DtInsertSubtable (ParentTable, Subtable); 1573 NodeLength += Subtable->Length; 1574 1575 /* 1576 * Padding - Variable-length data 1577 * Optionally allows the offset of the ID mappings to be used 1578 * for filling this field. 1579 */ 1580 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 1581 &Subtable, TRUE); 1582 if (ACPI_FAILURE (Status)) 1583 { 1584 return (Status); 1585 } 1586 1587 if (Subtable) 1588 { 1589 DtInsertSubtable (ParentTable, Subtable); 1590 NodeLength += Subtable->Length; 1591 } 1592 else 1593 { 1594 if (NodeLength > IortNode->MappingOffset) 1595 { 1596 return (AE_BAD_DATA); 1597 } 1598 1599 if (NodeLength < IortNode->MappingOffset) 1600 { 1601 Status = DtCompilePadding ( 1602 IortNode->MappingOffset - NodeLength, 1603 &Subtable); 1604 if (ACPI_FAILURE (Status)) 1605 { 1606 return (Status); 1607 } 1608 1609 DtInsertSubtable (ParentTable, Subtable); 1610 NodeLength = IortNode->MappingOffset; 1611 } 1612 } 1613 break; 1614 1615 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 1616 1617 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 1618 &Subtable, TRUE); 1619 if (ACPI_FAILURE (Status)) 1620 { 1621 return (Status); 1622 } 1623 1624 DtInsertSubtable (ParentTable, Subtable); 1625 NodeLength += Subtable->Length; 1626 break; 1627 1628 case ACPI_IORT_NODE_SMMU: 1629 1630 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 1631 &Subtable, TRUE); 1632 if (ACPI_FAILURE (Status)) 1633 { 1634 return (Status); 1635 } 1636 1637 DtInsertSubtable (ParentTable, Subtable); 1638 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 1639 NodeLength += Subtable->Length; 1640 1641 /* Compile global interrupt array */ 1642 1643 IortSmmu->GlobalInterruptOffset = NodeLength; 1644 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 1645 &Subtable, TRUE); 1646 if (ACPI_FAILURE (Status)) 1647 { 1648 return (Status); 1649 } 1650 1651 DtInsertSubtable (ParentTable, Subtable); 1652 NodeLength += Subtable->Length; 1653 1654 /* Compile context interrupt array */ 1655 1656 ContextIrptNumber = 0; 1657 IortSmmu->ContextInterruptOffset = NodeLength; 1658 while (*PFieldList) 1659 { 1660 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 1661 &Subtable, TRUE); 1662 if (ACPI_FAILURE (Status)) 1663 { 1664 return (Status); 1665 } 1666 1667 if (!Subtable) 1668 { 1669 break; 1670 } 1671 1672 DtInsertSubtable (ParentTable, Subtable); 1673 NodeLength += Subtable->Length; 1674 ContextIrptNumber++; 1675 } 1676 1677 IortSmmu->ContextInterruptCount = ContextIrptNumber; 1678 1679 /* Compile PMU interrupt array */ 1680 1681 PmuIrptNumber = 0; 1682 IortSmmu->PmuInterruptOffset = NodeLength; 1683 while (*PFieldList) 1684 { 1685 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 1686 &Subtable, TRUE); 1687 if (ACPI_FAILURE (Status)) 1688 { 1689 return (Status); 1690 } 1691 1692 if (!Subtable) 1693 { 1694 break; 1695 } 1696 1697 DtInsertSubtable (ParentTable, Subtable); 1698 NodeLength += Subtable->Length; 1699 PmuIrptNumber++; 1700 } 1701 1702 IortSmmu->PmuInterruptCount = PmuIrptNumber; 1703 break; 1704 1705 case ACPI_IORT_NODE_SMMU_V3: 1706 1707 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 1708 &Subtable, TRUE); 1709 if (ACPI_FAILURE (Status)) 1710 { 1711 return (Status); 1712 } 1713 1714 DtInsertSubtable (ParentTable, Subtable); 1715 NodeLength += Subtable->Length; 1716 break; 1717 1718 default: 1719 1720 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 1721 return (AE_ERROR); 1722 } 1723 1724 /* Compile Array of ID mappings */ 1725 1726 IortNode->MappingOffset = NodeLength; 1727 IdMappingNumber = 0; 1728 while (*PFieldList) 1729 { 1730 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 1731 &Subtable, TRUE); 1732 if (ACPI_FAILURE (Status)) 1733 { 1734 return (Status); 1735 } 1736 1737 if (!Subtable) 1738 { 1739 break; 1740 } 1741 1742 DtInsertSubtable (ParentTable, Subtable); 1743 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 1744 IdMappingNumber++; 1745 } 1746 1747 IortNode->MappingCount = IdMappingNumber; 1748 if (!IdMappingNumber) 1749 { 1750 IortNode->MappingOffset = 0; 1751 } 1752 1753 /* 1754 * Node length can be determined by DT_LENGTH option 1755 * IortNode->Length = NodeLength; 1756 */ 1757 DtPopSubtable (); 1758 ParentTable = DtPeekSubtable (); 1759 NodeNumber++; 1760 } 1761 1762 Iort->NodeCount = NodeNumber; 1763 return (AE_OK); 1764 } 1765 1766 1767 /****************************************************************************** 1768 * 1769 * FUNCTION: DtCompileIvrs 1770 * 1771 * PARAMETERS: List - Current field list pointer 1772 * 1773 * RETURN: Status 1774 * 1775 * DESCRIPTION: Compile IVRS. 1776 * 1777 *****************************************************************************/ 1778 1779 ACPI_STATUS 1780 DtCompileIvrs ( 1781 void **List) 1782 { 1783 ACPI_STATUS Status; 1784 DT_SUBTABLE *Subtable; 1785 DT_SUBTABLE *ParentTable; 1786 DT_FIELD **PFieldList = (DT_FIELD **) List; 1787 DT_FIELD *SubtableStart; 1788 ACPI_DMTABLE_INFO *InfoTable; 1789 ACPI_IVRS_HEADER *IvrsHeader; 1790 UINT8 EntryType; 1791 1792 1793 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 1794 &Subtable, TRUE); 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, AcpiDmTableInfoIvrsHdr, 1807 &Subtable, TRUE); 1808 if (ACPI_FAILURE (Status)) 1809 { 1810 return (Status); 1811 } 1812 1813 ParentTable = DtPeekSubtable (); 1814 DtInsertSubtable (ParentTable, Subtable); 1815 DtPushSubtable (Subtable); 1816 1817 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 1818 1819 switch (IvrsHeader->Type) 1820 { 1821 case ACPI_IVRS_TYPE_HARDWARE: 1822 1823 InfoTable = AcpiDmTableInfoIvrs0; 1824 break; 1825 1826 case ACPI_IVRS_TYPE_MEMORY1: 1827 case ACPI_IVRS_TYPE_MEMORY2: 1828 case ACPI_IVRS_TYPE_MEMORY3: 1829 1830 InfoTable = AcpiDmTableInfoIvrs1; 1831 break; 1832 1833 default: 1834 1835 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 1836 return (AE_ERROR); 1837 } 1838 1839 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1840 if (ACPI_FAILURE (Status)) 1841 { 1842 return (Status); 1843 } 1844 1845 ParentTable = DtPeekSubtable (); 1846 DtInsertSubtable (ParentTable, Subtable); 1847 1848 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 1849 { 1850 while (*PFieldList && 1851 !strcmp ((*PFieldList)->Name, "Entry Type")) 1852 { 1853 SubtableStart = *PFieldList; 1854 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 1855 1856 switch (EntryType) 1857 { 1858 /* 4-byte device entries */ 1859 1860 case ACPI_IVRS_TYPE_PAD4: 1861 case ACPI_IVRS_TYPE_ALL: 1862 case ACPI_IVRS_TYPE_SELECT: 1863 case ACPI_IVRS_TYPE_START: 1864 case ACPI_IVRS_TYPE_END: 1865 1866 InfoTable = AcpiDmTableInfoIvrs4; 1867 break; 1868 1869 /* 8-byte entries, type A */ 1870 1871 case ACPI_IVRS_TYPE_ALIAS_SELECT: 1872 case ACPI_IVRS_TYPE_ALIAS_START: 1873 1874 InfoTable = AcpiDmTableInfoIvrs8a; 1875 break; 1876 1877 /* 8-byte entries, type B */ 1878 1879 case ACPI_IVRS_TYPE_PAD8: 1880 case ACPI_IVRS_TYPE_EXT_SELECT: 1881 case ACPI_IVRS_TYPE_EXT_START: 1882 1883 InfoTable = AcpiDmTableInfoIvrs8b; 1884 break; 1885 1886 /* 8-byte entries, type C */ 1887 1888 case ACPI_IVRS_TYPE_SPECIAL: 1889 1890 InfoTable = AcpiDmTableInfoIvrs8c; 1891 break; 1892 1893 default: 1894 1895 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 1896 "IVRS Device Entry"); 1897 return (AE_ERROR); 1898 } 1899 1900 Status = DtCompileTable (PFieldList, InfoTable, 1901 &Subtable, TRUE); 1902 if (ACPI_FAILURE (Status)) 1903 { 1904 return (Status); 1905 } 1906 1907 DtInsertSubtable (ParentTable, Subtable); 1908 } 1909 } 1910 1911 DtPopSubtable (); 1912 } 1913 1914 return (AE_OK); 1915 } 1916