1 /****************************************************************************** 2 * 3 * Module Name: dttable1.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 491 if (Status == AE_END_OF_TABLE) 492 { 493 /* optional field was not found and we're at the end of the file */ 494 495 goto subtableDone; 496 } 497 else if (ACPI_FAILURE (Status)) 498 { 499 return (Status); 500 } 501 502 /* Update the device info header (zeros if no OEM data present) */ 503 504 DeviceInfo->OemDataOffset = 0; 505 DeviceInfo->OemDataLength = 0; 506 507 /* Optional subtable (OemData) */ 508 509 if (Subtable && Subtable->Length) 510 { 511 DeviceInfo->OemDataOffset = CurrentOffset; 512 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 513 514 DtInsertSubtable (ParentTable, Subtable); 515 } 516 subtableDone: 517 SubtableCount--; 518 DtPopSubtable (); /* Get next Device Information subtable */ 519 } 520 521 DtPopSubtable (); 522 return (AE_OK); 523 } 524 525 526 /****************************************************************************** 527 * 528 * FUNCTION: DtCompileDmar 529 * 530 * PARAMETERS: List - Current field list pointer 531 * 532 * RETURN: Status 533 * 534 * DESCRIPTION: Compile DMAR. 535 * 536 *****************************************************************************/ 537 538 ACPI_STATUS 539 DtCompileDmar ( 540 void **List) 541 { 542 ACPI_STATUS Status; 543 DT_SUBTABLE *Subtable; 544 DT_SUBTABLE *ParentTable; 545 DT_FIELD **PFieldList = (DT_FIELD **) List; 546 DT_FIELD *SubtableStart; 547 ACPI_DMTABLE_INFO *InfoTable; 548 ACPI_DMAR_HEADER *DmarHeader; 549 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 550 UINT32 DeviceScopeLength; 551 UINT32 PciPathLength; 552 553 554 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 555 if (ACPI_FAILURE (Status)) 556 { 557 return (Status); 558 } 559 560 ParentTable = DtPeekSubtable (); 561 DtInsertSubtable (ParentTable, Subtable); 562 DtPushSubtable (Subtable); 563 564 while (*PFieldList) 565 { 566 /* DMAR Header */ 567 568 SubtableStart = *PFieldList; 569 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 570 &Subtable); 571 if (ACPI_FAILURE (Status)) 572 { 573 return (Status); 574 } 575 576 ParentTable = DtPeekSubtable (); 577 DtInsertSubtable (ParentTable, Subtable); 578 DtPushSubtable (Subtable); 579 580 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 581 582 switch (DmarHeader->Type) 583 { 584 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 585 586 InfoTable = AcpiDmTableInfoDmar0; 587 break; 588 589 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 590 591 InfoTable = AcpiDmTableInfoDmar1; 592 break; 593 594 case ACPI_DMAR_TYPE_ROOT_ATS: 595 596 InfoTable = AcpiDmTableInfoDmar2; 597 break; 598 599 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 600 601 InfoTable = AcpiDmTableInfoDmar3; 602 break; 603 604 case ACPI_DMAR_TYPE_NAMESPACE: 605 606 InfoTable = AcpiDmTableInfoDmar4; 607 break; 608 609 default: 610 611 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 612 return (AE_ERROR); 613 } 614 615 /* DMAR Subtable */ 616 617 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 618 if (ACPI_FAILURE (Status)) 619 { 620 return (Status); 621 } 622 623 ParentTable = DtPeekSubtable (); 624 DtInsertSubtable (ParentTable, Subtable); 625 626 /* 627 * Optional Device Scope subtables 628 */ 629 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 630 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 631 { 632 /* These types do not support device scopes */ 633 634 DtPopSubtable (); 635 continue; 636 } 637 638 DtPushSubtable (Subtable); 639 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 640 ParentTable->Length; 641 while (DeviceScopeLength) 642 { 643 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 644 &Subtable); 645 if (Status == AE_NOT_FOUND) 646 { 647 break; 648 } 649 650 ParentTable = DtPeekSubtable (); 651 DtInsertSubtable (ParentTable, Subtable); 652 DtPushSubtable (Subtable); 653 654 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 655 656 /* Optional PCI Paths */ 657 658 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 659 while (PciPathLength) 660 { 661 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 662 &Subtable); 663 if (Status == AE_NOT_FOUND) 664 { 665 DtPopSubtable (); 666 break; 667 } 668 669 ParentTable = DtPeekSubtable (); 670 DtInsertSubtable (ParentTable, Subtable); 671 PciPathLength -= Subtable->Length; 672 } 673 674 DtPopSubtable (); 675 DeviceScopeLength -= DmarDeviceScope->Length; 676 } 677 678 DtPopSubtable (); 679 DtPopSubtable (); 680 } 681 682 return (AE_OK); 683 } 684 685 686 /****************************************************************************** 687 * 688 * FUNCTION: DtCompileDrtm 689 * 690 * PARAMETERS: List - Current field list pointer 691 * 692 * RETURN: Status 693 * 694 * DESCRIPTION: Compile DRTM. 695 * 696 *****************************************************************************/ 697 698 ACPI_STATUS 699 DtCompileDrtm ( 700 void **List) 701 { 702 ACPI_STATUS Status; 703 DT_SUBTABLE *Subtable; 704 DT_SUBTABLE *ParentTable; 705 DT_FIELD **PFieldList = (DT_FIELD **) List; 706 UINT32 Count; 707 /* ACPI_TABLE_DRTM *Drtm; */ 708 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 709 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 710 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 711 712 713 ParentTable = DtPeekSubtable (); 714 715 /* Compile DRTM header */ 716 717 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 718 &Subtable); 719 if (ACPI_FAILURE (Status)) 720 { 721 return (Status); 722 } 723 DtInsertSubtable (ParentTable, Subtable); 724 725 /* 726 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care 727 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 728 */ 729 #if 0 730 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 731 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 732 #endif 733 /* Compile VTL */ 734 735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 736 &Subtable); 737 if (ACPI_FAILURE (Status)) 738 { 739 return (Status); 740 } 741 742 DtInsertSubtable (ParentTable, Subtable); 743 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 744 745 DtPushSubtable (Subtable); 746 ParentTable = DtPeekSubtable (); 747 Count = 0; 748 749 while (*PFieldList) 750 { 751 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 752 &Subtable); 753 if (ACPI_FAILURE (Status)) 754 { 755 return (Status); 756 } 757 if (!Subtable) 758 { 759 break; 760 } 761 DtInsertSubtable (ParentTable, Subtable); 762 Count++; 763 } 764 765 DrtmVtl->ValidatedTableCount = Count; 766 DtPopSubtable (); 767 ParentTable = DtPeekSubtable (); 768 769 /* Compile RL */ 770 771 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 772 &Subtable); 773 if (ACPI_FAILURE (Status)) 774 { 775 return (Status); 776 } 777 778 DtInsertSubtable (ParentTable, Subtable); 779 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 780 781 DtPushSubtable (Subtable); 782 ParentTable = DtPeekSubtable (); 783 Count = 0; 784 785 while (*PFieldList) 786 { 787 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 788 &Subtable); 789 if (ACPI_FAILURE (Status)) 790 { 791 return (Status); 792 } 793 794 if (!Subtable) 795 { 796 break; 797 } 798 799 DtInsertSubtable (ParentTable, Subtable); 800 Count++; 801 } 802 803 DrtmRl->ResourceCount = Count; 804 DtPopSubtable (); 805 ParentTable = DtPeekSubtable (); 806 807 /* Compile DPS */ 808 809 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 810 &Subtable); 811 if (ACPI_FAILURE (Status)) 812 { 813 return (Status); 814 } 815 DtInsertSubtable (ParentTable, Subtable); 816 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 817 818 819 return (AE_OK); 820 } 821 822 823 /****************************************************************************** 824 * 825 * FUNCTION: DtCompileEinj 826 * 827 * PARAMETERS: List - Current field list pointer 828 * 829 * RETURN: Status 830 * 831 * DESCRIPTION: Compile EINJ. 832 * 833 *****************************************************************************/ 834 835 ACPI_STATUS 836 DtCompileEinj ( 837 void **List) 838 { 839 ACPI_STATUS Status; 840 841 842 Status = DtCompileTwoSubtables (List, 843 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 844 return (Status); 845 } 846 847 848 /****************************************************************************** 849 * 850 * FUNCTION: DtCompileErst 851 * 852 * PARAMETERS: List - Current field list pointer 853 * 854 * RETURN: Status 855 * 856 * DESCRIPTION: Compile ERST. 857 * 858 *****************************************************************************/ 859 860 ACPI_STATUS 861 DtCompileErst ( 862 void **List) 863 { 864 ACPI_STATUS Status; 865 866 867 Status = DtCompileTwoSubtables (List, 868 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 869 return (Status); 870 } 871 872 873 /****************************************************************************** 874 * 875 * FUNCTION: DtCompileGtdt 876 * 877 * PARAMETERS: List - Current field list pointer 878 * 879 * RETURN: Status 880 * 881 * DESCRIPTION: Compile GTDT. 882 * 883 *****************************************************************************/ 884 885 ACPI_STATUS 886 DtCompileGtdt ( 887 void **List) 888 { 889 ACPI_STATUS Status; 890 DT_SUBTABLE *Subtable; 891 DT_SUBTABLE *ParentTable; 892 DT_FIELD **PFieldList = (DT_FIELD **) List; 893 DT_FIELD *SubtableStart; 894 ACPI_SUBTABLE_HEADER *GtdtHeader; 895 ACPI_DMTABLE_INFO *InfoTable; 896 UINT32 GtCount; 897 898 899 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 900 &Subtable); 901 if (ACPI_FAILURE (Status)) 902 { 903 return (Status); 904 } 905 906 ParentTable = DtPeekSubtable (); 907 DtInsertSubtable (ParentTable, Subtable); 908 909 while (*PFieldList) 910 { 911 SubtableStart = *PFieldList; 912 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 913 &Subtable); 914 if (ACPI_FAILURE (Status)) 915 { 916 return (Status); 917 } 918 919 ParentTable = DtPeekSubtable (); 920 DtInsertSubtable (ParentTable, Subtable); 921 DtPushSubtable (Subtable); 922 923 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 924 925 switch (GtdtHeader->Type) 926 { 927 case ACPI_GTDT_TYPE_TIMER_BLOCK: 928 929 InfoTable = AcpiDmTableInfoGtdt0; 930 break; 931 932 case ACPI_GTDT_TYPE_WATCHDOG: 933 934 InfoTable = AcpiDmTableInfoGtdt1; 935 break; 936 937 default: 938 939 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 940 return (AE_ERROR); 941 } 942 943 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 944 if (ACPI_FAILURE (Status)) 945 { 946 return (Status); 947 } 948 949 ParentTable = DtPeekSubtable (); 950 DtInsertSubtable (ParentTable, Subtable); 951 952 /* 953 * Additional GT block subtable data 954 */ 955 956 switch (GtdtHeader->Type) 957 { 958 case ACPI_GTDT_TYPE_TIMER_BLOCK: 959 960 DtPushSubtable (Subtable); 961 ParentTable = DtPeekSubtable (); 962 963 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 964 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 965 966 while (GtCount) 967 { 968 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 969 &Subtable); 970 if (ACPI_FAILURE (Status)) 971 { 972 return (Status); 973 } 974 975 DtInsertSubtable (ParentTable, Subtable); 976 GtCount--; 977 } 978 979 DtPopSubtable (); 980 break; 981 982 default: 983 984 break; 985 } 986 987 DtPopSubtable (); 988 } 989 990 return (AE_OK); 991 } 992 993 994 /****************************************************************************** 995 * 996 * FUNCTION: DtCompileFpdt 997 * 998 * PARAMETERS: List - Current field list pointer 999 * 1000 * RETURN: Status 1001 * 1002 * DESCRIPTION: Compile FPDT. 1003 * 1004 *****************************************************************************/ 1005 1006 ACPI_STATUS 1007 DtCompileFpdt ( 1008 void **List) 1009 { 1010 ACPI_STATUS Status; 1011 ACPI_FPDT_HEADER *FpdtHeader; 1012 DT_SUBTABLE *Subtable; 1013 DT_SUBTABLE *ParentTable; 1014 ACPI_DMTABLE_INFO *InfoTable; 1015 DT_FIELD **PFieldList = (DT_FIELD **) List; 1016 DT_FIELD *SubtableStart; 1017 1018 1019 while (*PFieldList) 1020 { 1021 SubtableStart = *PFieldList; 1022 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1023 &Subtable); 1024 if (ACPI_FAILURE (Status)) 1025 { 1026 return (Status); 1027 } 1028 1029 ParentTable = DtPeekSubtable (); 1030 DtInsertSubtable (ParentTable, Subtable); 1031 DtPushSubtable (Subtable); 1032 1033 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1034 1035 switch (FpdtHeader->Type) 1036 { 1037 case ACPI_FPDT_TYPE_BOOT: 1038 1039 InfoTable = AcpiDmTableInfoFpdt0; 1040 break; 1041 1042 case ACPI_FPDT_TYPE_S3PERF: 1043 1044 InfoTable = AcpiDmTableInfoFpdt1; 1045 break; 1046 1047 default: 1048 1049 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1050 return (AE_ERROR); 1051 break; 1052 } 1053 1054 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1055 if (ACPI_FAILURE (Status)) 1056 { 1057 return (Status); 1058 } 1059 1060 ParentTable = DtPeekSubtable (); 1061 DtInsertSubtable (ParentTable, Subtable); 1062 DtPopSubtable (); 1063 } 1064 1065 return (AE_OK); 1066 } 1067 1068 1069 /****************************************************************************** 1070 * 1071 * FUNCTION: DtCompileHest 1072 * 1073 * PARAMETERS: List - Current field list pointer 1074 * 1075 * RETURN: Status 1076 * 1077 * DESCRIPTION: Compile HEST. 1078 * 1079 *****************************************************************************/ 1080 1081 ACPI_STATUS 1082 DtCompileHest ( 1083 void **List) 1084 { 1085 ACPI_STATUS Status; 1086 DT_SUBTABLE *Subtable; 1087 DT_SUBTABLE *ParentTable; 1088 DT_FIELD **PFieldList = (DT_FIELD **) List; 1089 DT_FIELD *SubtableStart; 1090 ACPI_DMTABLE_INFO *InfoTable; 1091 UINT16 Type; 1092 UINT32 BankCount; 1093 1094 1095 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1096 &Subtable); 1097 if (ACPI_FAILURE (Status)) 1098 { 1099 return (Status); 1100 } 1101 1102 ParentTable = DtPeekSubtable (); 1103 DtInsertSubtable (ParentTable, Subtable); 1104 1105 while (*PFieldList) 1106 { 1107 /* Get subtable type */ 1108 1109 SubtableStart = *PFieldList; 1110 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1111 1112 switch (Type) 1113 { 1114 case ACPI_HEST_TYPE_IA32_CHECK: 1115 1116 InfoTable = AcpiDmTableInfoHest0; 1117 break; 1118 1119 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1120 1121 InfoTable = AcpiDmTableInfoHest1; 1122 break; 1123 1124 case ACPI_HEST_TYPE_IA32_NMI: 1125 1126 InfoTable = AcpiDmTableInfoHest2; 1127 break; 1128 1129 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1130 1131 InfoTable = AcpiDmTableInfoHest6; 1132 break; 1133 1134 case ACPI_HEST_TYPE_AER_ENDPOINT: 1135 1136 InfoTable = AcpiDmTableInfoHest7; 1137 break; 1138 1139 case ACPI_HEST_TYPE_AER_BRIDGE: 1140 1141 InfoTable = AcpiDmTableInfoHest8; 1142 break; 1143 1144 case ACPI_HEST_TYPE_GENERIC_ERROR: 1145 1146 InfoTable = AcpiDmTableInfoHest9; 1147 break; 1148 1149 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1150 1151 InfoTable = AcpiDmTableInfoHest10; 1152 break; 1153 1154 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1155 1156 InfoTable = AcpiDmTableInfoHest11; 1157 break; 1158 1159 default: 1160 1161 /* Cannot continue on unknown type */ 1162 1163 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1164 return (AE_ERROR); 1165 } 1166 1167 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1168 if (ACPI_FAILURE (Status)) 1169 { 1170 return (Status); 1171 } 1172 1173 DtInsertSubtable (ParentTable, Subtable); 1174 1175 /* 1176 * Additional subtable data - IA32 Error Bank(s) 1177 */ 1178 BankCount = 0; 1179 switch (Type) 1180 { 1181 case ACPI_HEST_TYPE_IA32_CHECK: 1182 1183 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1184 Subtable->Buffer))->NumHardwareBanks; 1185 break; 1186 1187 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1188 1189 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1190 Subtable->Buffer))->NumHardwareBanks; 1191 break; 1192 1193 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1194 1195 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1196 Subtable->Buffer))->NumHardwareBanks; 1197 break; 1198 1199 default: 1200 1201 break; 1202 } 1203 1204 while (BankCount) 1205 { 1206 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1207 &Subtable); 1208 if (ACPI_FAILURE (Status)) 1209 { 1210 return (Status); 1211 } 1212 1213 DtInsertSubtable (ParentTable, Subtable); 1214 BankCount--; 1215 } 1216 } 1217 1218 return (AE_OK); 1219 } 1220 1221 1222 /****************************************************************************** 1223 * 1224 * FUNCTION: DtCompileHmat 1225 * 1226 * PARAMETERS: List - Current field list pointer 1227 * 1228 * RETURN: Status 1229 * 1230 * DESCRIPTION: Compile HMAT. 1231 * 1232 *****************************************************************************/ 1233 1234 ACPI_STATUS 1235 DtCompileHmat ( 1236 void **List) 1237 { 1238 ACPI_STATUS Status; 1239 DT_SUBTABLE *Subtable; 1240 DT_SUBTABLE *ParentTable; 1241 DT_FIELD **PFieldList = (DT_FIELD **) List; 1242 DT_FIELD *SubtableStart; 1243 DT_FIELD *EntryStart; 1244 ACPI_HMAT_STRUCTURE *HmatStruct; 1245 ACPI_HMAT_LOCALITY *HmatLocality; 1246 ACPI_HMAT_CACHE *HmatCache; 1247 ACPI_DMTABLE_INFO *InfoTable; 1248 UINT32 IntPDNumber; 1249 UINT32 TgtPDNumber; 1250 UINT64 EntryNumber; 1251 UINT16 SMBIOSHandleNumber; 1252 1253 1254 ParentTable = DtPeekSubtable (); 1255 1256 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1257 &Subtable); 1258 if (ACPI_FAILURE (Status)) 1259 { 1260 return (Status); 1261 } 1262 DtInsertSubtable (ParentTable, Subtable); 1263 1264 while (*PFieldList) 1265 { 1266 /* Compile HMAT structure header */ 1267 1268 SubtableStart = *PFieldList; 1269 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1270 &Subtable); 1271 if (ACPI_FAILURE (Status)) 1272 { 1273 return (Status); 1274 } 1275 DtInsertSubtable (ParentTable, Subtable); 1276 1277 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1278 HmatStruct->Length = Subtable->Length; 1279 1280 /* Compile HMAT structure body */ 1281 1282 switch (HmatStruct->Type) 1283 { 1284 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1285 1286 InfoTable = AcpiDmTableInfoHmat0; 1287 break; 1288 1289 case ACPI_HMAT_TYPE_LOCALITY: 1290 1291 InfoTable = AcpiDmTableInfoHmat1; 1292 break; 1293 1294 case ACPI_HMAT_TYPE_CACHE: 1295 1296 InfoTable = AcpiDmTableInfoHmat2; 1297 break; 1298 1299 default: 1300 1301 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 1302 return (AE_ERROR); 1303 } 1304 1305 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1306 if (ACPI_FAILURE (Status)) 1307 { 1308 return (Status); 1309 } 1310 DtInsertSubtable (ParentTable, Subtable); 1311 HmatStruct->Length += Subtable->Length; 1312 1313 /* Compile HMAT structure additionals */ 1314 1315 switch (HmatStruct->Type) 1316 { 1317 case ACPI_HMAT_TYPE_LOCALITY: 1318 1319 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 1320 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1321 1322 /* Compile initiator proximity domain list */ 1323 1324 IntPDNumber = 0; 1325 while (*PFieldList) 1326 { 1327 Status = DtCompileTable (PFieldList, 1328 AcpiDmTableInfoHmat1a, &Subtable); 1329 if (ACPI_FAILURE (Status)) 1330 { 1331 return (Status); 1332 } 1333 if (!Subtable) 1334 { 1335 break; 1336 } 1337 DtInsertSubtable (ParentTable, Subtable); 1338 HmatStruct->Length += Subtable->Length; 1339 IntPDNumber++; 1340 } 1341 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 1342 1343 /* Compile target proximity domain list */ 1344 1345 TgtPDNumber = 0; 1346 while (*PFieldList) 1347 { 1348 Status = DtCompileTable (PFieldList, 1349 AcpiDmTableInfoHmat1b, &Subtable); 1350 if (ACPI_FAILURE (Status)) 1351 { 1352 return (Status); 1353 } 1354 if (!Subtable) 1355 { 1356 break; 1357 } 1358 DtInsertSubtable (ParentTable, Subtable); 1359 HmatStruct->Length += Subtable->Length; 1360 TgtPDNumber++; 1361 } 1362 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 1363 1364 /* Save start of the entries for reporting errors */ 1365 1366 EntryStart = *PFieldList; 1367 1368 /* Compile latency/bandwidth entries */ 1369 1370 EntryNumber = 0; 1371 while (*PFieldList) 1372 { 1373 Status = DtCompileTable (PFieldList, 1374 AcpiDmTableInfoHmat1c, &Subtable); 1375 if (ACPI_FAILURE (Status)) 1376 { 1377 return (Status); 1378 } 1379 if (!Subtable) 1380 { 1381 break; 1382 } 1383 DtInsertSubtable (ParentTable, Subtable); 1384 HmatStruct->Length += Subtable->Length; 1385 EntryNumber++; 1386 } 1387 1388 /* Validate number of entries */ 1389 1390 if (EntryNumber != 1391 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 1392 { 1393 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 1394 return (AE_ERROR); 1395 } 1396 break; 1397 1398 case ACPI_HMAT_TYPE_CACHE: 1399 1400 /* Compile SMBIOS handles */ 1401 1402 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 1403 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1404 SMBIOSHandleNumber = 0; 1405 while (*PFieldList) 1406 { 1407 Status = DtCompileTable (PFieldList, 1408 AcpiDmTableInfoHmat2a, &Subtable); 1409 if (ACPI_FAILURE (Status)) 1410 { 1411 return (Status); 1412 } 1413 if (!Subtable) 1414 { 1415 break; 1416 } 1417 DtInsertSubtable (ParentTable, Subtable); 1418 HmatStruct->Length += Subtable->Length; 1419 SMBIOSHandleNumber++; 1420 } 1421 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 1422 break; 1423 1424 default: 1425 1426 break; 1427 } 1428 } 1429 1430 return (AE_OK); 1431 } 1432 1433 1434 /****************************************************************************** 1435 * 1436 * FUNCTION: DtCompileIort 1437 * 1438 * PARAMETERS: List - Current field list pointer 1439 * 1440 * RETURN: Status 1441 * 1442 * DESCRIPTION: Compile IORT. 1443 * 1444 *****************************************************************************/ 1445 1446 ACPI_STATUS 1447 DtCompileIort ( 1448 void **List) 1449 { 1450 ACPI_STATUS Status; 1451 DT_SUBTABLE *Subtable; 1452 DT_SUBTABLE *ParentTable; 1453 DT_FIELD **PFieldList = (DT_FIELD **) List; 1454 DT_FIELD *SubtableStart; 1455 ACPI_TABLE_IORT *Iort; 1456 ACPI_IORT_NODE *IortNode; 1457 ACPI_IORT_ITS_GROUP *IortItsGroup; 1458 ACPI_IORT_SMMU *IortSmmu; 1459 UINT32 NodeNumber; 1460 UINT32 NodeLength; 1461 UINT32 IdMappingNumber; 1462 UINT32 ItsNumber; 1463 UINT32 ContextIrptNumber; 1464 UINT32 PmuIrptNumber; 1465 UINT32 PaddingLength; 1466 1467 1468 ParentTable = DtPeekSubtable (); 1469 1470 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1471 &Subtable); 1472 if (ACPI_FAILURE (Status)) 1473 { 1474 return (Status); 1475 } 1476 DtInsertSubtable (ParentTable, Subtable); 1477 1478 /* 1479 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1480 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1481 */ 1482 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1483 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1484 1485 /* 1486 * OptionalPadding - Variable-length data 1487 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1488 * Optionally allows the generic data types to be used for filling 1489 * this field. 1490 */ 1491 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1492 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1493 &Subtable); 1494 if (ACPI_FAILURE (Status)) 1495 { 1496 return (Status); 1497 } 1498 if (Subtable) 1499 { 1500 DtInsertSubtable (ParentTable, Subtable); 1501 Iort->NodeOffset += Subtable->Length; 1502 } 1503 else 1504 { 1505 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1506 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1507 if (ACPI_FAILURE (Status)) 1508 { 1509 return (Status); 1510 } 1511 Iort->NodeOffset += PaddingLength; 1512 } 1513 1514 NodeNumber = 0; 1515 while (*PFieldList) 1516 { 1517 SubtableStart = *PFieldList; 1518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1519 &Subtable); 1520 if (ACPI_FAILURE (Status)) 1521 { 1522 return (Status); 1523 } 1524 1525 DtInsertSubtable (ParentTable, Subtable); 1526 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1527 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1528 1529 DtPushSubtable (Subtable); 1530 ParentTable = DtPeekSubtable (); 1531 1532 switch (IortNode->Type) 1533 { 1534 case ACPI_IORT_NODE_ITS_GROUP: 1535 1536 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1537 &Subtable); 1538 if (ACPI_FAILURE (Status)) 1539 { 1540 return (Status); 1541 } 1542 1543 DtInsertSubtable (ParentTable, Subtable); 1544 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1545 NodeLength += Subtable->Length; 1546 1547 ItsNumber = 0; 1548 while (*PFieldList) 1549 { 1550 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1551 &Subtable); 1552 if (ACPI_FAILURE (Status)) 1553 { 1554 return (Status); 1555 } 1556 if (!Subtable) 1557 { 1558 break; 1559 } 1560 1561 DtInsertSubtable (ParentTable, Subtable); 1562 NodeLength += Subtable->Length; 1563 ItsNumber++; 1564 } 1565 1566 IortItsGroup->ItsCount = ItsNumber; 1567 break; 1568 1569 case ACPI_IORT_NODE_NAMED_COMPONENT: 1570 1571 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 1572 &Subtable); 1573 if (ACPI_FAILURE (Status)) 1574 { 1575 return (Status); 1576 } 1577 1578 DtInsertSubtable (ParentTable, Subtable); 1579 NodeLength += Subtable->Length; 1580 1581 /* 1582 * Padding - Variable-length data 1583 * Optionally allows the offset of the ID mappings to be used 1584 * for filling this field. 1585 */ 1586 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 1587 &Subtable); 1588 if (ACPI_FAILURE (Status)) 1589 { 1590 return (Status); 1591 } 1592 1593 if (Subtable) 1594 { 1595 DtInsertSubtable (ParentTable, Subtable); 1596 NodeLength += Subtable->Length; 1597 } 1598 else 1599 { 1600 if (NodeLength > IortNode->MappingOffset) 1601 { 1602 return (AE_BAD_DATA); 1603 } 1604 1605 if (NodeLength < IortNode->MappingOffset) 1606 { 1607 Status = DtCompilePadding ( 1608 IortNode->MappingOffset - NodeLength, 1609 &Subtable); 1610 if (ACPI_FAILURE (Status)) 1611 { 1612 return (Status); 1613 } 1614 1615 DtInsertSubtable (ParentTable, Subtable); 1616 NodeLength = IortNode->MappingOffset; 1617 } 1618 } 1619 break; 1620 1621 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 1622 1623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 1624 &Subtable); 1625 if (ACPI_FAILURE (Status)) 1626 { 1627 return (Status); 1628 } 1629 1630 DtInsertSubtable (ParentTable, Subtable); 1631 NodeLength += Subtable->Length; 1632 break; 1633 1634 case ACPI_IORT_NODE_SMMU: 1635 1636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 1637 &Subtable); 1638 if (ACPI_FAILURE (Status)) 1639 { 1640 return (Status); 1641 } 1642 1643 DtInsertSubtable (ParentTable, Subtable); 1644 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 1645 NodeLength += Subtable->Length; 1646 1647 /* Compile global interrupt array */ 1648 1649 IortSmmu->GlobalInterruptOffset = NodeLength; 1650 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 1651 &Subtable); 1652 if (ACPI_FAILURE (Status)) 1653 { 1654 return (Status); 1655 } 1656 1657 DtInsertSubtable (ParentTable, Subtable); 1658 NodeLength += Subtable->Length; 1659 1660 /* Compile context interrupt array */ 1661 1662 ContextIrptNumber = 0; 1663 IortSmmu->ContextInterruptOffset = NodeLength; 1664 while (*PFieldList) 1665 { 1666 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 1667 &Subtable); 1668 if (ACPI_FAILURE (Status)) 1669 { 1670 return (Status); 1671 } 1672 1673 if (!Subtable) 1674 { 1675 break; 1676 } 1677 1678 DtInsertSubtable (ParentTable, Subtable); 1679 NodeLength += Subtable->Length; 1680 ContextIrptNumber++; 1681 } 1682 1683 IortSmmu->ContextInterruptCount = ContextIrptNumber; 1684 1685 /* Compile PMU interrupt array */ 1686 1687 PmuIrptNumber = 0; 1688 IortSmmu->PmuInterruptOffset = NodeLength; 1689 while (*PFieldList) 1690 { 1691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 1692 &Subtable); 1693 if (ACPI_FAILURE (Status)) 1694 { 1695 return (Status); 1696 } 1697 1698 if (!Subtable) 1699 { 1700 break; 1701 } 1702 1703 DtInsertSubtable (ParentTable, Subtable); 1704 NodeLength += Subtable->Length; 1705 PmuIrptNumber++; 1706 } 1707 1708 IortSmmu->PmuInterruptCount = PmuIrptNumber; 1709 break; 1710 1711 case ACPI_IORT_NODE_SMMU_V3: 1712 1713 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 1714 &Subtable); 1715 if (ACPI_FAILURE (Status)) 1716 { 1717 return (Status); 1718 } 1719 1720 DtInsertSubtable (ParentTable, Subtable); 1721 NodeLength += Subtable->Length; 1722 break; 1723 1724 default: 1725 1726 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 1727 return (AE_ERROR); 1728 } 1729 1730 /* Compile Array of ID mappings */ 1731 1732 IortNode->MappingOffset = NodeLength; 1733 IdMappingNumber = 0; 1734 while (*PFieldList) 1735 { 1736 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 1737 &Subtable); 1738 if (ACPI_FAILURE (Status)) 1739 { 1740 return (Status); 1741 } 1742 1743 if (!Subtable) 1744 { 1745 break; 1746 } 1747 1748 DtInsertSubtable (ParentTable, Subtable); 1749 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 1750 IdMappingNumber++; 1751 } 1752 1753 IortNode->MappingCount = IdMappingNumber; 1754 if (!IdMappingNumber) 1755 { 1756 IortNode->MappingOffset = 0; 1757 } 1758 1759 /* 1760 * Node length can be determined by DT_LENGTH option 1761 * IortNode->Length = NodeLength; 1762 */ 1763 DtPopSubtable (); 1764 ParentTable = DtPeekSubtable (); 1765 NodeNumber++; 1766 } 1767 1768 Iort->NodeCount = NodeNumber; 1769 return (AE_OK); 1770 } 1771 1772 1773 /****************************************************************************** 1774 * 1775 * FUNCTION: DtCompileIvrs 1776 * 1777 * PARAMETERS: List - Current field list pointer 1778 * 1779 * RETURN: Status 1780 * 1781 * DESCRIPTION: Compile IVRS. 1782 * 1783 *****************************************************************************/ 1784 1785 ACPI_STATUS 1786 DtCompileIvrs ( 1787 void **List) 1788 { 1789 ACPI_STATUS Status; 1790 DT_SUBTABLE *Subtable; 1791 DT_SUBTABLE *ParentTable; 1792 DT_FIELD **PFieldList = (DT_FIELD **) List; 1793 DT_FIELD *SubtableStart; 1794 ACPI_DMTABLE_INFO *InfoTable; 1795 ACPI_IVRS_HEADER *IvrsHeader; 1796 UINT8 EntryType; 1797 1798 1799 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 1800 &Subtable); 1801 if (ACPI_FAILURE (Status)) 1802 { 1803 return (Status); 1804 } 1805 1806 ParentTable = DtPeekSubtable (); 1807 DtInsertSubtable (ParentTable, Subtable); 1808 1809 while (*PFieldList) 1810 { 1811 SubtableStart = *PFieldList; 1812 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 1813 &Subtable); 1814 if (ACPI_FAILURE (Status)) 1815 { 1816 return (Status); 1817 } 1818 1819 ParentTable = DtPeekSubtable (); 1820 DtInsertSubtable (ParentTable, Subtable); 1821 DtPushSubtable (Subtable); 1822 1823 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 1824 1825 switch (IvrsHeader->Type) 1826 { 1827 case ACPI_IVRS_TYPE_HARDWARE: 1828 1829 InfoTable = AcpiDmTableInfoIvrs0; 1830 break; 1831 1832 case ACPI_IVRS_TYPE_MEMORY1: 1833 case ACPI_IVRS_TYPE_MEMORY2: 1834 case ACPI_IVRS_TYPE_MEMORY3: 1835 1836 InfoTable = AcpiDmTableInfoIvrs1; 1837 break; 1838 1839 default: 1840 1841 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 1842 return (AE_ERROR); 1843 } 1844 1845 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1846 if (ACPI_FAILURE (Status)) 1847 { 1848 return (Status); 1849 } 1850 1851 ParentTable = DtPeekSubtable (); 1852 DtInsertSubtable (ParentTable, Subtable); 1853 1854 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 1855 { 1856 while (*PFieldList && 1857 !strcmp ((*PFieldList)->Name, "Entry Type")) 1858 { 1859 SubtableStart = *PFieldList; 1860 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 1861 1862 switch (EntryType) 1863 { 1864 /* 4-byte device entries */ 1865 1866 case ACPI_IVRS_TYPE_PAD4: 1867 case ACPI_IVRS_TYPE_ALL: 1868 case ACPI_IVRS_TYPE_SELECT: 1869 case ACPI_IVRS_TYPE_START: 1870 case ACPI_IVRS_TYPE_END: 1871 1872 InfoTable = AcpiDmTableInfoIvrs4; 1873 break; 1874 1875 /* 8-byte entries, type A */ 1876 1877 case ACPI_IVRS_TYPE_ALIAS_SELECT: 1878 case ACPI_IVRS_TYPE_ALIAS_START: 1879 1880 InfoTable = AcpiDmTableInfoIvrs8a; 1881 break; 1882 1883 /* 8-byte entries, type B */ 1884 1885 case ACPI_IVRS_TYPE_PAD8: 1886 case ACPI_IVRS_TYPE_EXT_SELECT: 1887 case ACPI_IVRS_TYPE_EXT_START: 1888 1889 InfoTable = AcpiDmTableInfoIvrs8b; 1890 break; 1891 1892 /* 8-byte entries, type C */ 1893 1894 case ACPI_IVRS_TYPE_SPECIAL: 1895 1896 InfoTable = AcpiDmTableInfoIvrs8c; 1897 break; 1898 1899 default: 1900 1901 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 1902 "IVRS Device Entry"); 1903 return (AE_ERROR); 1904 } 1905 1906 Status = DtCompileTable (PFieldList, InfoTable, 1907 &Subtable); 1908 if (ACPI_FAILURE (Status)) 1909 { 1910 return (Status); 1911 } 1912 1913 DtInsertSubtable (ParentTable, Subtable); 1914 } 1915 } 1916 1917 DtPopSubtable (); 1918 } 1919 1920 return (AE_OK); 1921 } 1922