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