1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2023, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 /* Compile all complex data tables, signatures starting with L-Z */ 45 46 #include "aslcompiler.h" 47 48 #define _COMPONENT DT_COMPILER 49 ACPI_MODULE_NAME ("dttable2") 50 51 52 /****************************************************************************** 53 * 54 * FUNCTION: DtCompileLpit 55 * 56 * PARAMETERS: List - Current field list pointer 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Compile LPIT. 61 * 62 *****************************************************************************/ 63 64 ACPI_STATUS 65 DtCompileLpit ( 66 void **List) 67 { 68 ACPI_STATUS Status; 69 DT_SUBTABLE *Subtable; 70 DT_SUBTABLE *ParentTable; 71 DT_FIELD **PFieldList = (DT_FIELD **) List; 72 DT_FIELD *SubtableStart; 73 ACPI_DMTABLE_INFO *InfoTable; 74 ACPI_LPIT_HEADER *LpitHeader; 75 76 77 /* Note: Main table consists only of the standard ACPI table header */ 78 79 while (*PFieldList) 80 { 81 SubtableStart = *PFieldList; 82 83 /* LPIT Subtable header */ 84 85 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, 86 &Subtable); 87 if (ACPI_FAILURE (Status)) 88 { 89 return (Status); 90 } 91 92 ParentTable = DtPeekSubtable (); 93 DtInsertSubtable (ParentTable, Subtable); 94 DtPushSubtable (Subtable); 95 96 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); 97 98 switch (LpitHeader->Type) 99 { 100 case ACPI_LPIT_TYPE_NATIVE_CSTATE: 101 102 InfoTable = AcpiDmTableInfoLpit0; 103 break; 104 105 default: 106 107 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); 108 return (AE_ERROR); 109 } 110 111 /* LPIT Subtable */ 112 113 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 114 if (ACPI_FAILURE (Status)) 115 { 116 return (Status); 117 } 118 119 ParentTable = DtPeekSubtable (); 120 DtInsertSubtable (ParentTable, Subtable); 121 DtPopSubtable (); 122 } 123 124 return (AE_OK); 125 } 126 127 128 /****************************************************************************** 129 * 130 * FUNCTION: DtCompileMadt 131 * 132 * PARAMETERS: List - Current field list pointer 133 * 134 * RETURN: Status 135 * 136 * DESCRIPTION: Compile MADT. 137 * 138 *****************************************************************************/ 139 140 ACPI_STATUS 141 DtCompileMadt ( 142 void **List) 143 { 144 ACPI_STATUS Status; 145 DT_SUBTABLE *Subtable; 146 DT_SUBTABLE *ParentTable; 147 DT_FIELD **PFieldList = (DT_FIELD **) List; 148 DT_FIELD *SubtableStart; 149 ACPI_TABLE_HEADER *Table; 150 ACPI_SUBTABLE_HEADER *MadtHeader; 151 ACPI_DMTABLE_INFO *InfoTable; 152 UINT8 Revision; 153 154 155 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 156 &Subtable); 157 if (ACPI_FAILURE (Status)) 158 { 159 return (Status); 160 } 161 162 ParentTable = DtPeekSubtable (); 163 DtInsertSubtable (ParentTable, Subtable); 164 165 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 166 Revision = Table->Revision; 167 168 while (*PFieldList) 169 { 170 SubtableStart = *PFieldList; 171 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 172 &Subtable); 173 if (ACPI_FAILURE (Status)) 174 { 175 return (Status); 176 } 177 178 ParentTable = DtPeekSubtable (); 179 DtInsertSubtable (ParentTable, Subtable); 180 DtPushSubtable (Subtable); 181 182 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 183 184 switch (MadtHeader->Type) 185 { 186 case ACPI_MADT_TYPE_LOCAL_APIC: 187 188 InfoTable = AcpiDmTableInfoMadt0; 189 break; 190 191 case ACPI_MADT_TYPE_IO_APIC: 192 193 InfoTable = AcpiDmTableInfoMadt1; 194 break; 195 196 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 197 198 InfoTable = AcpiDmTableInfoMadt2; 199 break; 200 201 case ACPI_MADT_TYPE_NMI_SOURCE: 202 203 InfoTable = AcpiDmTableInfoMadt3; 204 break; 205 206 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 207 208 InfoTable = AcpiDmTableInfoMadt4; 209 break; 210 211 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 212 213 InfoTable = AcpiDmTableInfoMadt5; 214 break; 215 216 case ACPI_MADT_TYPE_IO_SAPIC: 217 218 InfoTable = AcpiDmTableInfoMadt6; 219 break; 220 221 case ACPI_MADT_TYPE_LOCAL_SAPIC: 222 223 InfoTable = AcpiDmTableInfoMadt7; 224 break; 225 226 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 227 228 InfoTable = AcpiDmTableInfoMadt8; 229 break; 230 231 case ACPI_MADT_TYPE_LOCAL_X2APIC: 232 233 InfoTable = AcpiDmTableInfoMadt9; 234 break; 235 236 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 237 238 InfoTable = AcpiDmTableInfoMadt10; 239 break; 240 241 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 242 243 if (Revision > 6) 244 InfoTable = AcpiDmTableInfoMadt11b; 245 else if (Revision == 6) 246 InfoTable = AcpiDmTableInfoMadt11a; 247 else 248 InfoTable = AcpiDmTableInfoMadt11; 249 break; 250 251 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 252 253 InfoTable = AcpiDmTableInfoMadt12; 254 break; 255 256 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 257 258 InfoTable = AcpiDmTableInfoMadt13; 259 break; 260 261 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 262 263 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt14a 264 : AcpiDmTableInfoMadt14; 265 break; 266 267 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 268 269 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt15a 270 : AcpiDmTableInfoMadt15; 271 272 break; 273 274 case ACPI_MADT_TYPE_MULTIPROC_WAKEUP: 275 276 InfoTable = AcpiDmTableInfoMadt16; 277 break; 278 279 case ACPI_MADT_TYPE_CORE_PIC: 280 281 InfoTable = AcpiDmTableInfoMadt17; 282 break; 283 284 case ACPI_MADT_TYPE_LIO_PIC: 285 286 InfoTable = AcpiDmTableInfoMadt18; 287 break; 288 289 case ACPI_MADT_TYPE_HT_PIC: 290 291 InfoTable = AcpiDmTableInfoMadt19; 292 break; 293 294 case ACPI_MADT_TYPE_EIO_PIC: 295 296 InfoTable = AcpiDmTableInfoMadt20; 297 break; 298 299 case ACPI_MADT_TYPE_MSI_PIC: 300 301 InfoTable = AcpiDmTableInfoMadt21; 302 break; 303 304 case ACPI_MADT_TYPE_BIO_PIC: 305 306 InfoTable = AcpiDmTableInfoMadt22; 307 break; 308 309 case ACPI_MADT_TYPE_LPC_PIC: 310 311 InfoTable = AcpiDmTableInfoMadt23; 312 break; 313 314 case ACPI_MADT_TYPE_RINTC: 315 316 InfoTable = AcpiDmTableInfoMadt24; 317 break; 318 319 case ACPI_MADT_TYPE_IMSIC: 320 321 InfoTable = AcpiDmTableInfoMadt25; 322 break; 323 324 case ACPI_MADT_TYPE_APLIC: 325 326 InfoTable = AcpiDmTableInfoMadt26; 327 break; 328 329 case ACPI_MADT_TYPE_PLIC: 330 331 InfoTable = AcpiDmTableInfoMadt27; 332 break; 333 334 default: 335 336 if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED) 337 { 338 InfoTable = AcpiDmTableInfoMadt128; 339 } 340 else 341 { 342 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 343 return (AE_ERROR); 344 } 345 346 break; 347 } 348 349 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 350 if (ACPI_FAILURE (Status)) 351 { 352 return (Status); 353 } 354 355 ParentTable = DtPeekSubtable (); 356 DtInsertSubtable (ParentTable, Subtable); 357 DtPopSubtable (); 358 } 359 360 return (AE_OK); 361 } 362 363 364 /****************************************************************************** 365 * 366 * FUNCTION: DtCompileMcfg 367 * 368 * PARAMETERS: List - Current field list pointer 369 * 370 * RETURN: Status 371 * 372 * DESCRIPTION: Compile MCFG. 373 * 374 *****************************************************************************/ 375 376 ACPI_STATUS 377 DtCompileMcfg ( 378 void **List) 379 { 380 ACPI_STATUS Status; 381 382 383 Status = DtCompileTwoSubtables (List, 384 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 385 return (Status); 386 } 387 388 /****************************************************************************** 389 * 390 * FUNCTION: DtCompileMpam 391 * 392 * PARAMETERS: List - Current field list pointer 393 * 394 * RETURN: Status 395 * 396 * DESCRIPTION: Compile MPAM. 397 * 398 *****************************************************************************/ 399 400 ACPI_STATUS 401 DtCompileMpam ( 402 void **List) 403 { 404 ACPI_STATUS Status; 405 DT_SUBTABLE *ParentTable; 406 DT_SUBTABLE *Subtable; 407 DT_FIELD *SubtableStart; 408 DT_FIELD **PFieldList = (DT_FIELD **) List; 409 ACPI_MPAM_MSC_NODE *MpamMscNode; 410 ACPI_MPAM_RESOURCE_NODE *MpamResourceNode; 411 UINT32 FuncDepsCount; 412 UINT32 RisLength; 413 ACPI_DMTABLE_INFO *InfoTable; 414 415 ParentTable = DtPeekSubtable (); 416 417 while (*PFieldList) 418 { 419 SubtableStart = *PFieldList; 420 421 /* Main MSC Node table */ 422 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0, 423 &Subtable); 424 if (ACPI_FAILURE (Status)) 425 { 426 return (Status); 427 } 428 429 MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer); 430 431 ParentTable = DtPeekSubtable (); 432 DtInsertSubtable (ParentTable, Subtable); 433 DtPushSubtable (Subtable); 434 435 ParentTable = DtPeekSubtable (); 436 437 /* 438 * RIS(es) per MSC node have variable lengths depending on how many RISes there and 439 * any how many functional dependencies per RIS. Calculate it in order 440 * to properly set the overall MSC length. 441 */ 442 RisLength = 0; 443 444 /* Iterate over RIS subtables per MSC node */ 445 for (UINT32 ris = 0; ris < MpamMscNode->NumResourceNodes; ris++) 446 { 447 /* Compile RIS subtable */ 448 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1, 449 &Subtable); 450 if (ACPI_FAILURE (Status)) 451 { 452 return (Status); 453 } 454 455 MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer); 456 DtInsertSubtable (ParentTable, Subtable); 457 DtPushSubtable (Subtable); 458 459 ParentTable = DtPeekSubtable (); 460 461 switch (MpamResourceNode->LocatorType) 462 { 463 case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE: 464 InfoTable = AcpiDmTableInfoMpam1A; 465 break; 466 case ACPI_MPAM_LOCATION_TYPE_MEMORY: 467 InfoTable = AcpiDmTableInfoMpam1B; 468 break; 469 case ACPI_MPAM_LOCATION_TYPE_SMMU: 470 InfoTable = AcpiDmTableInfoMpam1C; 471 break; 472 case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE: 473 InfoTable = AcpiDmTableInfoMpam1D; 474 break; 475 case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE: 476 InfoTable = AcpiDmTableInfoMpam1E; 477 break; 478 case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT: 479 InfoTable = AcpiDmTableInfoMpam1F; 480 break; 481 case ACPI_MPAM_LOCATION_TYPE_UNKNOWN: 482 InfoTable = AcpiDmTableInfoMpam1G; 483 default: 484 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type"); 485 return (AE_ERROR); 486 } 487 488 /* Compile Resource Locator Table */ 489 Status = DtCompileTable (PFieldList, InfoTable, 490 &Subtable); 491 492 if (ACPI_FAILURE (Status)) 493 { 494 return (Status); 495 } 496 497 DtInsertSubtable (ParentTable, Subtable); 498 499 /* Compile the number of functional dependencies per RIS */ 500 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps, 501 &Subtable); 502 503 if (ACPI_FAILURE (Status)) 504 { 505 return (Status); 506 } 507 508 DtInsertSubtable (ParentTable, Subtable); 509 FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 510 511 RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) + 512 FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS); 513 514 /* Iterate over functional dependencies per RIS */ 515 for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++) 516 { 517 /* Compiler functional dependencies table */ 518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2, 519 &Subtable); 520 521 if (ACPI_FAILURE (Status)) 522 { 523 return (Status); 524 } 525 526 DtInsertSubtable (ParentTable, Subtable); 527 } 528 529 DtPopSubtable (); 530 } 531 532 /* Check if the length of the MSC is correct and override with the correct length */ 533 if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength) 534 { 535 MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength); 536 DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length); 537 } 538 539 DtPopSubtable (); 540 } 541 542 return (AE_OK); 543 } 544 545 546 /****************************************************************************** 547 * 548 * FUNCTION: DtCompileMpst 549 * 550 * PARAMETERS: List - Current field list pointer 551 * 552 * RETURN: Status 553 * 554 * DESCRIPTION: Compile MPST. 555 * 556 *****************************************************************************/ 557 558 ACPI_STATUS 559 DtCompileMpst ( 560 void **List) 561 { 562 ACPI_STATUS Status; 563 DT_SUBTABLE *Subtable; 564 DT_SUBTABLE *ParentTable; 565 DT_FIELD **PFieldList = (DT_FIELD **) List; 566 ACPI_MPST_CHANNEL *MpstChannelInfo; 567 ACPI_MPST_POWER_NODE *MpstPowerNode; 568 ACPI_MPST_DATA_HDR *MpstDataHeader; 569 UINT16 SubtableCount; 570 UINT32 PowerStateCount; 571 UINT32 ComponentCount; 572 573 574 /* Main table */ 575 576 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable); 577 if (ACPI_FAILURE (Status)) 578 { 579 return (Status); 580 } 581 582 ParentTable = DtPeekSubtable (); 583 DtInsertSubtable (ParentTable, Subtable); 584 DtPushSubtable (Subtable); 585 586 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 587 SubtableCount = MpstChannelInfo->PowerNodeCount; 588 589 while (*PFieldList && SubtableCount) 590 { 591 /* Subtable: Memory Power Node(s) */ 592 593 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 594 &Subtable); 595 if (ACPI_FAILURE (Status)) 596 { 597 return (Status); 598 } 599 600 ParentTable = DtPeekSubtable (); 601 DtInsertSubtable (ParentTable, Subtable); 602 DtPushSubtable (Subtable); 603 604 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 605 PowerStateCount = MpstPowerNode->NumPowerStates; 606 ComponentCount = MpstPowerNode->NumPhysicalComponents; 607 608 ParentTable = DtPeekSubtable (); 609 610 /* Sub-subtables - Memory Power State Structure(s) */ 611 612 while (*PFieldList && PowerStateCount) 613 { 614 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 615 &Subtable); 616 if (ACPI_FAILURE (Status)) 617 { 618 return (Status); 619 } 620 621 DtInsertSubtable (ParentTable, Subtable); 622 PowerStateCount--; 623 } 624 625 /* Sub-subtables - Physical Component ID Structure(s) */ 626 627 while (*PFieldList && ComponentCount) 628 { 629 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 630 &Subtable); 631 if (ACPI_FAILURE (Status)) 632 { 633 return (Status); 634 } 635 636 DtInsertSubtable (ParentTable, Subtable); 637 ComponentCount--; 638 } 639 640 SubtableCount--; 641 DtPopSubtable (); 642 } 643 644 /* Subtable: Count of Memory Power State Characteristic structures */ 645 646 DtPopSubtable (); 647 648 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable); 649 if (ACPI_FAILURE (Status)) 650 { 651 return (Status); 652 } 653 654 ParentTable = DtPeekSubtable (); 655 DtInsertSubtable (ParentTable, Subtable); 656 DtPushSubtable (Subtable); 657 658 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 659 SubtableCount = MpstDataHeader->CharacteristicsCount; 660 661 ParentTable = DtPeekSubtable (); 662 663 /* Subtable: Memory Power State Characteristics structure(s) */ 664 665 while (*PFieldList && SubtableCount) 666 { 667 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 668 &Subtable); 669 if (ACPI_FAILURE (Status)) 670 { 671 return (Status); 672 } 673 674 DtInsertSubtable (ParentTable, Subtable); 675 SubtableCount--; 676 } 677 678 DtPopSubtable (); 679 return (AE_OK); 680 } 681 682 683 /****************************************************************************** 684 * 685 * FUNCTION: DtCompileMsct 686 * 687 * PARAMETERS: List - Current field list pointer 688 * 689 * RETURN: Status 690 * 691 * DESCRIPTION: Compile MSCT. 692 * 693 *****************************************************************************/ 694 695 ACPI_STATUS 696 DtCompileMsct ( 697 void **List) 698 { 699 ACPI_STATUS Status; 700 701 702 Status = DtCompileTwoSubtables (List, 703 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 704 return (Status); 705 } 706 707 708 /****************************************************************************** 709 * 710 * FUNCTION: DtCompileNfit 711 * 712 * PARAMETERS: List - Current field list pointer 713 * 714 * RETURN: Status 715 * 716 * DESCRIPTION: Compile NFIT. 717 * 718 *****************************************************************************/ 719 720 ACPI_STATUS 721 DtCompileNfit ( 722 void **List) 723 { 724 ACPI_STATUS Status; 725 DT_SUBTABLE *Subtable; 726 DT_SUBTABLE *ParentTable; 727 DT_FIELD **PFieldList = (DT_FIELD **) List; 728 DT_FIELD *SubtableStart; 729 ACPI_NFIT_HEADER *NfitHeader; 730 ACPI_DMTABLE_INFO *InfoTable; 731 UINT32 Count; 732 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 733 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 734 735 736 /* Main table */ 737 738 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 739 &Subtable); 740 if (ACPI_FAILURE (Status)) 741 { 742 return (Status); 743 } 744 745 ParentTable = DtPeekSubtable (); 746 DtInsertSubtable (ParentTable, Subtable); 747 DtPushSubtable (Subtable); 748 749 /* Subtables */ 750 751 while (*PFieldList) 752 { 753 SubtableStart = *PFieldList; 754 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 755 &Subtable); 756 if (ACPI_FAILURE (Status)) 757 { 758 return (Status); 759 } 760 761 ParentTable = DtPeekSubtable (); 762 DtInsertSubtable (ParentTable, Subtable); 763 DtPushSubtable (Subtable); 764 765 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 766 767 switch (NfitHeader->Type) 768 { 769 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 770 771 InfoTable = AcpiDmTableInfoNfit0; 772 break; 773 774 case ACPI_NFIT_TYPE_MEMORY_MAP: 775 776 InfoTable = AcpiDmTableInfoNfit1; 777 break; 778 779 case ACPI_NFIT_TYPE_INTERLEAVE: 780 781 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 782 InfoTable = AcpiDmTableInfoNfit2; 783 break; 784 785 case ACPI_NFIT_TYPE_SMBIOS: 786 787 InfoTable = AcpiDmTableInfoNfit3; 788 break; 789 790 case ACPI_NFIT_TYPE_CONTROL_REGION: 791 792 InfoTable = AcpiDmTableInfoNfit4; 793 break; 794 795 case ACPI_NFIT_TYPE_DATA_REGION: 796 797 InfoTable = AcpiDmTableInfoNfit5; 798 break; 799 800 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 801 802 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 803 InfoTable = AcpiDmTableInfoNfit6; 804 break; 805 806 case ACPI_NFIT_TYPE_CAPABILITIES: 807 808 InfoTable = AcpiDmTableInfoNfit7; 809 break; 810 811 default: 812 813 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 814 return (AE_ERROR); 815 } 816 817 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 818 if (ACPI_FAILURE (Status)) 819 { 820 return (Status); 821 } 822 823 ParentTable = DtPeekSubtable (); 824 DtInsertSubtable (ParentTable, Subtable); 825 DtPopSubtable (); 826 827 switch (NfitHeader->Type) 828 { 829 case ACPI_NFIT_TYPE_INTERLEAVE: 830 831 Count = 0; 832 DtPushSubtable (Subtable); 833 while (*PFieldList) 834 { 835 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 836 &Subtable); 837 if (ACPI_FAILURE (Status)) 838 { 839 return (Status); 840 } 841 842 if (!Subtable) 843 { 844 DtPopSubtable (); 845 break; 846 } 847 848 ParentTable = DtPeekSubtable (); 849 DtInsertSubtable (ParentTable, Subtable); 850 Count++; 851 } 852 853 Interleave->LineCount = Count; 854 break; 855 856 case ACPI_NFIT_TYPE_SMBIOS: 857 858 if (*PFieldList) 859 { 860 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 861 &Subtable); 862 if (ACPI_FAILURE (Status)) 863 { 864 return (Status); 865 } 866 867 if (Subtable) 868 { 869 DtInsertSubtable (ParentTable, Subtable); 870 } 871 } 872 break; 873 874 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 875 876 Count = 0; 877 DtPushSubtable (Subtable); 878 while (*PFieldList) 879 { 880 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 881 &Subtable); 882 if (ACPI_FAILURE (Status)) 883 { 884 return (Status); 885 } 886 887 if (!Subtable) 888 { 889 DtPopSubtable (); 890 break; 891 } 892 893 ParentTable = DtPeekSubtable (); 894 DtInsertSubtable (ParentTable, Subtable); 895 Count++; 896 } 897 898 Hint->HintCount = (UINT16) Count; 899 break; 900 901 default: 902 break; 903 } 904 } 905 906 return (AE_OK); 907 } 908 909 910 /****************************************************************************** 911 * 912 * FUNCTION: DtCompilePcct 913 * 914 * PARAMETERS: List - Current field list pointer 915 * 916 * RETURN: Status 917 * 918 * DESCRIPTION: Compile PCCT. 919 * 920 *****************************************************************************/ 921 922 ACPI_STATUS 923 DtCompilePcct ( 924 void **List) 925 { 926 ACPI_STATUS Status; 927 DT_SUBTABLE *Subtable; 928 DT_SUBTABLE *ParentTable; 929 DT_FIELD **PFieldList = (DT_FIELD **) List; 930 DT_FIELD *SubtableStart; 931 ACPI_SUBTABLE_HEADER *PcctHeader; 932 ACPI_DMTABLE_INFO *InfoTable; 933 934 935 /* Main table */ 936 937 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 938 &Subtable); 939 if (ACPI_FAILURE (Status)) 940 { 941 return (Status); 942 } 943 944 ParentTable = DtPeekSubtable (); 945 DtInsertSubtable (ParentTable, Subtable); 946 947 /* Subtables */ 948 949 while (*PFieldList) 950 { 951 SubtableStart = *PFieldList; 952 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 953 &Subtable); 954 if (ACPI_FAILURE (Status)) 955 { 956 return (Status); 957 } 958 959 ParentTable = DtPeekSubtable (); 960 DtInsertSubtable (ParentTable, Subtable); 961 DtPushSubtable (Subtable); 962 963 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 964 965 switch (PcctHeader->Type) 966 { 967 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 968 969 InfoTable = AcpiDmTableInfoPcct0; 970 break; 971 972 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 973 974 InfoTable = AcpiDmTableInfoPcct1; 975 break; 976 977 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: 978 979 InfoTable = AcpiDmTableInfoPcct2; 980 break; 981 982 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: 983 984 InfoTable = AcpiDmTableInfoPcct3; 985 break; 986 987 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: 988 989 InfoTable = AcpiDmTableInfoPcct4; 990 break; 991 992 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE: 993 994 InfoTable = AcpiDmTableInfoPcct5; 995 break; 996 997 default: 998 999 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 1000 return (AE_ERROR); 1001 } 1002 1003 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1004 if (ACPI_FAILURE (Status)) 1005 { 1006 return (Status); 1007 } 1008 1009 ParentTable = DtPeekSubtable (); 1010 DtInsertSubtable (ParentTable, Subtable); 1011 DtPopSubtable (); 1012 } 1013 1014 return (AE_OK); 1015 } 1016 1017 1018 /****************************************************************************** 1019 * 1020 * FUNCTION: DtCompilePdtt 1021 * 1022 * PARAMETERS: List - Current field list pointer 1023 * 1024 * RETURN: Status 1025 * 1026 * DESCRIPTION: Compile PDTT. 1027 * 1028 *****************************************************************************/ 1029 1030 ACPI_STATUS 1031 DtCompilePdtt ( 1032 void **List) 1033 { 1034 ACPI_STATUS Status; 1035 DT_SUBTABLE *Subtable; 1036 DT_SUBTABLE *ParentTable; 1037 DT_FIELD **PFieldList = (DT_FIELD **) List; 1038 ACPI_TABLE_PDTT *PdttHeader; 1039 UINT32 Count = 0; 1040 1041 1042 /* Main table */ 1043 1044 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); 1045 if (ACPI_FAILURE (Status)) 1046 { 1047 return (Status); 1048 } 1049 1050 ParentTable = DtPeekSubtable (); 1051 DtInsertSubtable (ParentTable, Subtable); 1052 1053 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); 1054 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); 1055 1056 /* There is only one type of subtable at this time, no need to decode */ 1057 1058 while (*PFieldList) 1059 { 1060 /* List of subchannel IDs, each 2 bytes */ 1061 1062 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, 1063 &Subtable); 1064 if (ACPI_FAILURE (Status)) 1065 { 1066 return (Status); 1067 } 1068 1069 DtInsertSubtable (ParentTable, Subtable); 1070 Count++; 1071 } 1072 1073 PdttHeader->TriggerCount = (UINT8) Count; 1074 return (AE_OK); 1075 } 1076 1077 1078 /****************************************************************************** 1079 * 1080 * FUNCTION: DtCompilePhat 1081 * 1082 * PARAMETERS: List - Current field list pointer 1083 * 1084 * RETURN: Status 1085 * 1086 * DESCRIPTION: Compile Phat. 1087 * 1088 *****************************************************************************/ 1089 1090 ACPI_STATUS 1091 DtCompilePhat ( 1092 void **List) 1093 { 1094 ACPI_STATUS Status = AE_OK; 1095 DT_SUBTABLE *Subtable; 1096 DT_SUBTABLE *ParentTable; 1097 DT_FIELD **PFieldList = (DT_FIELD **) List; 1098 ACPI_PHAT_HEADER *PhatHeader; 1099 ACPI_DMTABLE_INFO *Info; 1100 ACPI_PHAT_VERSION_DATA *VersionData; 1101 UINT32 DeviceDataLength; 1102 UINT32 RecordCount; 1103 DT_FIELD *DataOffsetField; 1104 DT_FIELD *DevicePathField; 1105 UINT32 TableOffset = 0; 1106 UINT32 DataOffsetValue; 1107 UINT32 i; 1108 1109 1110 /* The table consists of subtables */ 1111 1112 while (*PFieldList) 1113 { 1114 /* Compile the common subtable header */ 1115 1116 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable); 1117 if (ACPI_FAILURE (Status)) 1118 { 1119 return (Status); 1120 } 1121 1122 TableOffset += Subtable->Length; 1123 DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length); 1124 1125 ParentTable = DtPeekSubtable (); 1126 DtInsertSubtable (ParentTable, Subtable); 1127 DtPushSubtable (Subtable); 1128 1129 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer); 1130 1131 switch (PhatHeader->Type) 1132 { 1133 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1134 1135 /* Compile the middle portion of the Firmware Version Data */ 1136 1137 Info = AcpiDmTableInfoPhat0; 1138 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA); 1139 DataOffsetField = NULL; 1140 break; 1141 1142 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1143 1144 DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n", 1145 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length); 1146 1147 DataOffsetField = *PFieldList; 1148 1149 /* Walk the field list to get to the "Device-specific data Offset" field */ 1150 1151 TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA); 1152 for (i = 0; i < 3; i++) 1153 { 1154 DataOffsetField = DataOffsetField->Next; 1155 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n", 1156 TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1157 } 1158 1159 /* Convert DataOffsetField->Value (a char * string) to an integer value */ 1160 1161 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1162 1163 /* 1164 * Get the next field (Device Path): 1165 * DataOffsetField points to "Device-Specific Offset", next field is 1166 * "Device Path". 1167 */ 1168 DevicePathField = DataOffsetField->Next; 1169 1170 /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */ 1171 1172 DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2; 1173 TableOffset += DevicePathField->StringLength; 1174 1175 DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n", 1176 TableOffset, Subtable->Length, DevicePathField->StringLength); 1177 1178 /* Set the DataOffsetField to the current TableOffset */ 1179 /* Must set the DataOffsetField here (not later) */ 1180 1181 if (DataOffsetValue != 0) 1182 { 1183 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset); 1184 } 1185 1186 DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length); 1187 1188 DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: " 1189 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n", 1190 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength, 1191 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset); 1192 1193 /* Compile the middle portion of the Health Data Record */ 1194 1195 Info = AcpiDmTableInfoPhat1; 1196 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA); 1197 break; 1198 1199 default: 1200 1201 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1202 return (AE_ERROR); 1203 } 1204 1205 /* Compile either the Version Data or the Health Data */ 1206 1207 Status = DtCompileTable (PFieldList, Info, &Subtable); 1208 if (ACPI_FAILURE (Status)) 1209 { 1210 return (Status); 1211 } 1212 1213 DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n", 1214 TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length); 1215 1216 ParentTable = DtPeekSubtable (); 1217 DtInsertSubtable (ParentTable, Subtable); 1218 1219 switch (PhatHeader->Type) 1220 { 1221 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1222 1223 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, 1224 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER))); 1225 RecordCount = VersionData->ElementCount; 1226 1227 /* Compile all of the Version Elements */ 1228 1229 while (RecordCount) 1230 { 1231 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a, 1232 &Subtable); 1233 if (ACPI_FAILURE (Status)) 1234 { 1235 return (Status); 1236 } 1237 1238 ParentTable = DtPeekSubtable (); 1239 DtInsertSubtable (ParentTable, Subtable); 1240 1241 TableOffset += Subtable->Length; 1242 RecordCount--; 1243 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT); 1244 } 1245 1246 DtPopSubtable (); 1247 break; 1248 1249 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1250 1251 /* Compile the Device Path */ 1252 1253 DeviceDataLength = Subtable->Length; 1254 TableOffset += Subtable->Length; 1255 1256 DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: " 1257 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength, 1258 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value, 1259 Subtable->Length, TableOffset); 1260 1261 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable); 1262 if (ACPI_FAILURE (Status)) 1263 { 1264 return (Status); 1265 } 1266 ParentTable = DtPeekSubtable (); 1267 DtInsertSubtable (ParentTable, Subtable); 1268 1269 /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */ 1270 1271 if (!*PFieldList) 1272 { 1273 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n"); 1274 return (AE_OK); 1275 } 1276 1277 DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s" 1278 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n", 1279 DeviceDataLength, (*PFieldList)->Name, TableOffset, 1280 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length); 1281 1282 PhatHeader->Length += (UINT16) Subtable->Length; 1283 1284 /* Convert DataOffsetField->Value (a hex char * string) to an integer value */ 1285 1286 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1287 1288 DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n", 1289 DataOffsetValue, TableOffset); 1290 if (DataOffsetValue != 0) 1291 { 1292 /* Compile Device-Specific Data - only if the Data Offset is non-zero */ 1293 1294 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable); 1295 if (ACPI_FAILURE (Status)) 1296 { 1297 return (Status); 1298 } 1299 1300 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n", 1301 Subtable, TableOffset); 1302 if (Subtable) 1303 { 1304 DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: " 1305 "%X FieldName \"%s\" SubtableLength %X\n", 1306 DeviceDataLength, DataOffsetField->Name, Subtable->Length); 1307 1308 DeviceDataLength += Subtable->Length; 1309 1310 ParentTable = DtPeekSubtable (); 1311 DtInsertSubtable (ParentTable, Subtable); 1312 1313 PhatHeader->Length += (UINT16) Subtable->Length; 1314 } 1315 } 1316 1317 DtPopSubtable (); 1318 1319 DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n", 1320 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1321 break; 1322 1323 default: 1324 1325 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1326 return (AE_ERROR); 1327 } 1328 } 1329 1330 return (Status); 1331 } 1332 1333 1334 /****************************************************************************** 1335 * 1336 * FUNCTION: DtCompilePmtt 1337 * 1338 * PARAMETERS: List - Current field list pointer 1339 * 1340 * RETURN: Status 1341 * 1342 * DESCRIPTION: Compile PMTT. 1343 * 1344 *****************************************************************************/ 1345 1346 ACPI_STATUS 1347 DtCompilePmtt ( 1348 void **List) 1349 { 1350 ACPI_STATUS Status; 1351 DT_SUBTABLE *Subtable; 1352 DT_SUBTABLE *ParentTable; 1353 DT_FIELD **PFieldList = (DT_FIELD **) List; 1354 DT_FIELD *SubtableStart; 1355 UINT16 Type; 1356 1357 1358 /* Main table */ 1359 1360 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); 1361 if (ACPI_FAILURE (Status)) 1362 { 1363 return (Status); 1364 } 1365 1366 ParentTable = DtPeekSubtable (); 1367 DtInsertSubtable (ParentTable, Subtable); 1368 DtPushSubtable (Subtable); 1369 1370 /* Subtables */ 1371 1372 while (*PFieldList) 1373 { 1374 SubtableStart = *PFieldList; 1375 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1376 1377 switch (Type) 1378 { 1379 case ACPI_PMTT_TYPE_SOCKET: 1380 1381 /* Subtable: Socket Structure */ 1382 1383 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n"); 1384 1385 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 1386 &Subtable); 1387 if (ACPI_FAILURE (Status)) 1388 { 1389 return (Status); 1390 } 1391 1392 break; 1393 1394 case ACPI_PMTT_TYPE_CONTROLLER: 1395 1396 /* Subtable: Memory Controller Structure */ 1397 1398 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n"); 1399 1400 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 1401 &Subtable); 1402 if (ACPI_FAILURE (Status)) 1403 { 1404 return (Status); 1405 } 1406 1407 break; 1408 1409 case ACPI_PMTT_TYPE_DIMM: 1410 1411 /* Subtable: Physical Component (DIMM) Structure */ 1412 1413 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n"); 1414 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 1415 &Subtable); 1416 if (ACPI_FAILURE (Status)) 1417 { 1418 return (Status); 1419 } 1420 1421 break; 1422 1423 case ACPI_PMTT_TYPE_VENDOR: 1424 1425 /* Subtable: Vendor-specific Structure */ 1426 1427 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n"); 1428 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor, 1429 &Subtable); 1430 if (ACPI_FAILURE (Status)) 1431 { 1432 return (Status); 1433 } 1434 1435 break; 1436 1437 default: 1438 1439 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 1440 return (AE_ERROR); 1441 } 1442 1443 DtInsertSubtable (ParentTable, Subtable); 1444 } 1445 1446 return (Status); 1447 } 1448 1449 1450 /****************************************************************************** 1451 * 1452 * FUNCTION: DtCompilePptt 1453 * 1454 * PARAMETERS: List - Current field list pointer 1455 * 1456 * RETURN: Status 1457 * 1458 * DESCRIPTION: Compile PPTT. 1459 * 1460 *****************************************************************************/ 1461 1462 ACPI_STATUS 1463 DtCompilePptt ( 1464 void **List) 1465 { 1466 ACPI_STATUS Status; 1467 ACPI_SUBTABLE_HEADER *PpttHeader; 1468 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; 1469 DT_SUBTABLE *Subtable; 1470 DT_SUBTABLE *ParentTable; 1471 ACPI_DMTABLE_INFO *InfoTable; 1472 DT_FIELD **PFieldList = (DT_FIELD **) List; 1473 DT_FIELD *SubtableStart; 1474 ACPI_TABLE_HEADER *PpttAcpiHeader; 1475 1476 1477 ParentTable = DtPeekSubtable (); 1478 while (*PFieldList) 1479 { 1480 SubtableStart = *PFieldList; 1481 1482 /* Compile PPTT subtable header */ 1483 1484 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1485 &Subtable); 1486 if (ACPI_FAILURE (Status)) 1487 { 1488 return (Status); 1489 } 1490 DtInsertSubtable (ParentTable, Subtable); 1491 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1492 PpttHeader->Length = (UINT8)(Subtable->Length); 1493 1494 switch (PpttHeader->Type) 1495 { 1496 case ACPI_PPTT_TYPE_PROCESSOR: 1497 1498 InfoTable = AcpiDmTableInfoPptt0; 1499 break; 1500 1501 case ACPI_PPTT_TYPE_CACHE: 1502 1503 InfoTable = AcpiDmTableInfoPptt1; 1504 break; 1505 1506 case ACPI_PPTT_TYPE_ID: 1507 1508 InfoTable = AcpiDmTableInfoPptt2; 1509 break; 1510 1511 default: 1512 1513 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1514 return (AE_ERROR); 1515 } 1516 1517 /* Compile PPTT subtable body */ 1518 1519 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1520 if (ACPI_FAILURE (Status)) 1521 { 1522 return (Status); 1523 } 1524 DtInsertSubtable (ParentTable, Subtable); 1525 PpttHeader->Length += (UINT8)(Subtable->Length); 1526 1527 /* Compile PPTT subtable additional */ 1528 1529 switch (PpttHeader->Type) 1530 { 1531 case ACPI_PPTT_TYPE_PROCESSOR: 1532 1533 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1534 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1535 if (PpttProcessor) 1536 { 1537 /* Compile initiator proximity domain list */ 1538 1539 PpttProcessor->NumberOfPrivResources = 0; 1540 while (*PFieldList) 1541 { 1542 Status = DtCompileTable (PFieldList, 1543 AcpiDmTableInfoPptt0a, &Subtable); 1544 if (ACPI_FAILURE (Status)) 1545 { 1546 return (Status); 1547 } 1548 if (!Subtable) 1549 { 1550 break; 1551 } 1552 1553 DtInsertSubtable (ParentTable, Subtable); 1554 PpttHeader->Length += (UINT8)(Subtable->Length); 1555 PpttProcessor->NumberOfPrivResources++; 1556 } 1557 } 1558 break; 1559 1560 case ACPI_PPTT_TYPE_CACHE: 1561 1562 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 1563 AslGbl_RootTable->Buffer); 1564 if (PpttAcpiHeader->Revision < 3) 1565 { 1566 break; 1567 } 1568 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a, 1569 &Subtable); 1570 DtInsertSubtable (ParentTable, Subtable); 1571 PpttHeader->Length += (UINT8)(Subtable->Length); 1572 break; 1573 1574 default: 1575 1576 break; 1577 } 1578 } 1579 1580 return (AE_OK); 1581 } 1582 1583 1584 /****************************************************************************** 1585 * 1586 * FUNCTION: DtCompilePrmt 1587 * 1588 * PARAMETERS: List - Current field list pointer 1589 * 1590 * RETURN: Status 1591 * 1592 * DESCRIPTION: Compile PRMT. 1593 * 1594 *****************************************************************************/ 1595 1596 ACPI_STATUS 1597 DtCompilePrmt ( 1598 void **List) 1599 { 1600 ACPI_STATUS Status; 1601 ACPI_TABLE_PRMT_HEADER *PrmtHeader; 1602 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; 1603 DT_SUBTABLE *Subtable; 1604 DT_SUBTABLE *ParentTable; 1605 DT_FIELD **PFieldList = (DT_FIELD **) List; 1606 UINT32 i, j; 1607 1608 ParentTable = DtPeekSubtable (); 1609 1610 /* Compile PRMT subtable header */ 1611 1612 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, 1613 &Subtable); 1614 if (ACPI_FAILURE (Status)) 1615 { 1616 return (Status); 1617 } 1618 DtInsertSubtable (ParentTable, Subtable); 1619 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); 1620 1621 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) 1622 { 1623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, 1624 &Subtable); 1625 if (ACPI_FAILURE (Status)) 1626 { 1627 return (Status); 1628 } 1629 DtInsertSubtable (ParentTable, Subtable); 1630 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); 1631 1632 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) 1633 { 1634 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, 1635 &Subtable); 1636 if (ACPI_FAILURE (Status)) 1637 { 1638 return (Status); 1639 } 1640 DtInsertSubtable (ParentTable, Subtable); 1641 } 1642 } 1643 1644 return (AE_OK); 1645 } 1646 1647 1648 /****************************************************************************** 1649 * 1650 * FUNCTION: DtCompileRas2 1651 * 1652 * PARAMETERS: List - Current field list pointer 1653 * 1654 * RETURN: Status 1655 * 1656 * DESCRIPTION: Compile RAS2. 1657 * 1658 *****************************************************************************/ 1659 1660 ACPI_STATUS 1661 DtCompileRas2 ( 1662 void **List) 1663 { 1664 ACPI_STATUS Status; 1665 DT_SUBTABLE *Subtable; 1666 DT_SUBTABLE *ParentTable; 1667 DT_FIELD **PFieldList = (DT_FIELD **) List; 1668 ACPI_TABLE_RAS2 *Ras2Header; 1669 UINT32 Count = 0; 1670 1671 1672 /* Main table */ 1673 1674 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable); 1675 if (ACPI_FAILURE (Status)) 1676 { 1677 return (Status); 1678 } 1679 1680 ParentTable = DtPeekSubtable (); 1681 DtInsertSubtable (ParentTable, Subtable); 1682 1683 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer); 1684 1685 /* There is only one type of subtable at this time, no need to decode */ 1686 1687 while (*PFieldList) 1688 { 1689 /* List of RAS2 PCC descriptors, each 8 bytes */ 1690 1691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc, 1692 &Subtable); 1693 if (ACPI_FAILURE (Status)) 1694 { 1695 return (Status); 1696 } 1697 1698 DtInsertSubtable (ParentTable, Subtable); 1699 Count++; 1700 } 1701 1702 Ras2Header->NumPccDescs = (UINT8) Count; 1703 return (AE_OK); 1704 } 1705 1706 1707 /****************************************************************************** 1708 * 1709 * FUNCTION: DtCompileRgrt 1710 * 1711 * PARAMETERS: List - Current field list pointer 1712 * 1713 * RETURN: Status 1714 * 1715 * DESCRIPTION: Compile RGRT. 1716 * 1717 *****************************************************************************/ 1718 1719 ACPI_STATUS 1720 DtCompileRgrt ( 1721 void **List) 1722 { 1723 ACPI_STATUS Status; 1724 DT_SUBTABLE *Subtable; 1725 DT_SUBTABLE *ParentTable; 1726 DT_FIELD **PFieldList = (DT_FIELD **) List; 1727 1728 1729 /* Compile the main table */ 1730 1731 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, 1732 &Subtable); 1733 if (ACPI_FAILURE (Status)) 1734 { 1735 return (Status); 1736 } 1737 1738 ParentTable = DtPeekSubtable (); 1739 DtInsertSubtable (ParentTable, Subtable); 1740 1741 /* Compile the "Subtable" -- actually just the binary (PNG) image */ 1742 1743 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, 1744 &Subtable); 1745 if (ACPI_FAILURE (Status)) 1746 { 1747 return (Status); 1748 } 1749 1750 DtInsertSubtable (ParentTable, Subtable); 1751 return (AE_OK); 1752 } 1753 1754 1755 /****************************************************************************** 1756 * 1757 * FUNCTION: DtCompileRhct 1758 * 1759 * PARAMETERS: List - Current field list pointer 1760 * 1761 * RETURN: Status 1762 * 1763 * DESCRIPTION: Compile RHCT. 1764 * 1765 *****************************************************************************/ 1766 1767 ACPI_STATUS 1768 DtCompileRhct ( 1769 void **List) 1770 { 1771 ACPI_STATUS Status; 1772 ACPI_RHCT_NODE_HEADER *RhctHeader; 1773 ACPI_RHCT_HART_INFO *RhctHartInfo = NULL; 1774 DT_SUBTABLE *Subtable; 1775 DT_SUBTABLE *ParentTable; 1776 ACPI_DMTABLE_INFO *InfoTable; 1777 DT_FIELD **PFieldList = (DT_FIELD **) List; 1778 DT_FIELD *SubtableStart; 1779 1780 1781 /* Compile the main table */ 1782 1783 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct, 1784 &Subtable); 1785 if (ACPI_FAILURE (Status)) 1786 { 1787 return (Status); 1788 } 1789 1790 ParentTable = DtPeekSubtable (); 1791 while (*PFieldList) 1792 { 1793 SubtableStart = *PFieldList; 1794 1795 /* Compile RHCT subtable header */ 1796 1797 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr, 1798 &Subtable); 1799 if (ACPI_FAILURE (Status)) 1800 { 1801 return (Status); 1802 } 1803 DtInsertSubtable (ParentTable, Subtable); 1804 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer); 1805 RhctHeader->Length = (UINT16)(Subtable->Length); 1806 1807 switch (RhctHeader->Type) 1808 { 1809 case ACPI_RHCT_NODE_TYPE_ISA_STRING: 1810 1811 InfoTable = AcpiDmTableInfoRhctIsa1; 1812 break; 1813 1814 case ACPI_RHCT_NODE_TYPE_HART_INFO: 1815 1816 InfoTable = AcpiDmTableInfoRhctHartInfo1; 1817 break; 1818 1819 case ACPI_RHCT_NODE_TYPE_CMO: 1820 1821 InfoTable = AcpiDmTableInfoRhctCmo1; 1822 break; 1823 1824 case ACPI_RHCT_NODE_TYPE_MMU: 1825 1826 InfoTable = AcpiDmTableInfoRhctMmu1; 1827 break; 1828 1829 default: 1830 1831 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT"); 1832 return (AE_ERROR); 1833 } 1834 1835 /* Compile RHCT subtable body */ 1836 1837 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1838 if (ACPI_FAILURE (Status)) 1839 { 1840 return (Status); 1841 } 1842 DtInsertSubtable (ParentTable, Subtable); 1843 RhctHeader->Length += (UINT16)(Subtable->Length); 1844 1845 /* Compile RHCT subtable additionals */ 1846 1847 switch (RhctHeader->Type) 1848 { 1849 case ACPI_RHCT_NODE_TYPE_HART_INFO: 1850 1851 RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO, 1852 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER)); 1853 if (RhctHartInfo) 1854 { 1855 1856 RhctHartInfo->NumOffsets = 0; 1857 while (*PFieldList) 1858 { 1859 Status = DtCompileTable (PFieldList, 1860 AcpiDmTableInfoRhctHartInfo2, &Subtable); 1861 if (ACPI_FAILURE (Status)) 1862 { 1863 return (Status); 1864 } 1865 if (!Subtable) 1866 { 1867 break; 1868 } 1869 1870 DtInsertSubtable (ParentTable, Subtable); 1871 RhctHeader->Length += (UINT16)(Subtable->Length); 1872 RhctHartInfo->NumOffsets++; 1873 } 1874 } 1875 break; 1876 1877 default: 1878 1879 break; 1880 } 1881 } 1882 1883 return (AE_OK); 1884 } 1885 1886 1887 /****************************************************************************** 1888 * 1889 * FUNCTION: DtCompileRsdt 1890 * 1891 * PARAMETERS: List - Current field list pointer 1892 * 1893 * RETURN: Status 1894 * 1895 * DESCRIPTION: Compile RSDT. 1896 * 1897 *****************************************************************************/ 1898 1899 ACPI_STATUS 1900 DtCompileRsdt ( 1901 void **List) 1902 { 1903 DT_SUBTABLE *Subtable; 1904 DT_SUBTABLE *ParentTable; 1905 DT_FIELD *FieldList = *(DT_FIELD **) List; 1906 UINT32 Address; 1907 1908 1909 ParentTable = DtPeekSubtable (); 1910 1911 while (FieldList) 1912 { 1913 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1914 1915 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 1916 DtInsertSubtable (ParentTable, Subtable); 1917 FieldList = FieldList->Next; 1918 } 1919 1920 return (AE_OK); 1921 } 1922 1923 1924 /****************************************************************************** 1925 * 1926 * FUNCTION: DtCompileS3pt 1927 * 1928 * PARAMETERS: PFieldList - Current field list pointer 1929 * 1930 * RETURN: Status 1931 * 1932 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 1933 * 1934 *****************************************************************************/ 1935 1936 ACPI_STATUS 1937 DtCompileS3pt ( 1938 DT_FIELD **PFieldList) 1939 { 1940 ACPI_STATUS Status; 1941 ACPI_FPDT_HEADER *S3ptHeader; 1942 DT_SUBTABLE *Subtable; 1943 DT_SUBTABLE *ParentTable; 1944 ACPI_DMTABLE_INFO *InfoTable; 1945 DT_FIELD *SubtableStart; 1946 1947 1948 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 1949 &AslGbl_RootTable); 1950 if (ACPI_FAILURE (Status)) 1951 { 1952 return (Status); 1953 } 1954 1955 DtPushSubtable (AslGbl_RootTable); 1956 1957 while (*PFieldList) 1958 { 1959 SubtableStart = *PFieldList; 1960 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 1961 &Subtable); 1962 if (ACPI_FAILURE (Status)) 1963 { 1964 return (Status); 1965 } 1966 1967 ParentTable = DtPeekSubtable (); 1968 DtInsertSubtable (ParentTable, Subtable); 1969 DtPushSubtable (Subtable); 1970 1971 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1972 1973 switch (S3ptHeader->Type) 1974 { 1975 case ACPI_S3PT_TYPE_RESUME: 1976 1977 InfoTable = AcpiDmTableInfoS3pt0; 1978 break; 1979 1980 case ACPI_S3PT_TYPE_SUSPEND: 1981 1982 InfoTable = AcpiDmTableInfoS3pt1; 1983 break; 1984 1985 default: 1986 1987 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 1988 return (AE_ERROR); 1989 } 1990 1991 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1992 if (ACPI_FAILURE (Status)) 1993 { 1994 return (Status); 1995 } 1996 1997 ParentTable = DtPeekSubtable (); 1998 DtInsertSubtable (ParentTable, Subtable); 1999 DtPopSubtable (); 2000 } 2001 2002 return (AE_OK); 2003 } 2004 2005 2006 /****************************************************************************** 2007 * 2008 * FUNCTION: DtCompileSdev 2009 * 2010 * PARAMETERS: List - Current field list pointer 2011 * 2012 * RETURN: Status 2013 * 2014 * DESCRIPTION: Compile SDEV. 2015 * 2016 *****************************************************************************/ 2017 2018 ACPI_STATUS 2019 DtCompileSdev ( 2020 void **List) 2021 { 2022 ACPI_STATUS Status; 2023 ACPI_SDEV_HEADER *SdevHeader; 2024 ACPI_SDEV_HEADER *SecureComponentHeader; 2025 DT_SUBTABLE *Subtable; 2026 DT_SUBTABLE *ParentTable; 2027 ACPI_DMTABLE_INFO *InfoTable; 2028 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; 2029 DT_FIELD **PFieldList = (DT_FIELD **) List; 2030 DT_FIELD *SubtableStart; 2031 ACPI_SDEV_PCIE *Pcie = NULL; 2032 ACPI_SDEV_NAMESPACE *Namesp = NULL; 2033 UINT32 EntryCount; 2034 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; 2035 UINT16 ComponentLength = 0; 2036 2037 2038 /* Subtables */ 2039 2040 while (*PFieldList) 2041 { 2042 /* Compile common SDEV subtable header */ 2043 2044 SubtableStart = *PFieldList; 2045 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 2046 &Subtable); 2047 if (ACPI_FAILURE (Status)) 2048 { 2049 return (Status); 2050 } 2051 2052 ParentTable = DtPeekSubtable (); 2053 DtInsertSubtable (ParentTable, Subtable); 2054 DtPushSubtable (Subtable); 2055 2056 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2057 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 2058 2059 switch (SdevHeader->Type) 2060 { 2061 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2062 2063 InfoTable = AcpiDmTableInfoSdev0; 2064 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 2065 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, 2066 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); 2067 break; 2068 2069 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2070 2071 InfoTable = AcpiDmTableInfoSdev1; 2072 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 2073 break; 2074 2075 default: 2076 2077 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2078 return (AE_ERROR); 2079 } 2080 2081 /* Compile SDEV subtable body */ 2082 2083 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2084 if (ACPI_FAILURE (Status)) 2085 { 2086 return (Status); 2087 } 2088 2089 ParentTable = DtPeekSubtable (); 2090 DtInsertSubtable (ParentTable, Subtable); 2091 2092 /* Optional data fields are appended to the main subtable body */ 2093 2094 switch (SdevHeader->Type) 2095 { 2096 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2097 2098 /* 2099 * Device Id Offset will be be calculated differently depending on 2100 * the presence of secure access components. 2101 */ 2102 Namesp->DeviceIdOffset = 0; 2103 ComponentLength = 0; 2104 2105 /* If the secure access component exists, get the structures */ 2106 2107 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) 2108 { 2109 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, 2110 &Subtable); 2111 if (ACPI_FAILURE (Status)) 2112 { 2113 return (Status); 2114 } 2115 ParentTable = DtPeekSubtable (); 2116 DtInsertSubtable (ParentTable, Subtable); 2117 2118 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2119 2120 /* Compile a secure access component header */ 2121 2122 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, 2123 &Subtable); 2124 if (ACPI_FAILURE (Status)) 2125 { 2126 return (Status); 2127 } 2128 ParentTable = DtPeekSubtable (); 2129 DtInsertSubtable (ParentTable, Subtable); 2130 2131 /* Compile the secure access component */ 2132 2133 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2134 switch (SecureComponentHeader->Type) 2135 { 2136 case ACPI_SDEV_TYPE_ID_COMPONENT: 2137 2138 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; 2139 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); 2140 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); 2141 break; 2142 2143 case ACPI_SDEV_TYPE_MEM_COMPONENT: 2144 2145 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; 2146 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); 2147 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); 2148 break; 2149 2150 default: 2151 2152 /* Any other secure component types are undefined */ 2153 2154 return (AE_ERROR); 2155 } 2156 2157 Status = DtCompileTable (PFieldList, SecureComponentInfoTable, 2158 &Subtable); 2159 if (ACPI_FAILURE (Status)) 2160 { 2161 return (Status); 2162 } 2163 ParentTable = DtPeekSubtable (); 2164 DtInsertSubtable (ParentTable, Subtable); 2165 2166 SecureComponent->SecureComponentOffset = 2167 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); 2168 SecureComponent->SecureComponentLength = ComponentLength; 2169 2170 2171 /* 2172 * Add the secure component to the subtable to be added for the 2173 * the namespace subtable's length 2174 */ 2175 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2176 } 2177 2178 /* Append DeviceId namespace string */ 2179 2180 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 2181 &Subtable); 2182 if (ACPI_FAILURE (Status)) 2183 { 2184 return (Status); 2185 } 2186 2187 if (!Subtable) 2188 { 2189 break; 2190 } 2191 2192 ParentTable = DtPeekSubtable (); 2193 DtInsertSubtable (ParentTable, Subtable); 2194 2195 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); 2196 2197 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 2198 2199 /* Append Vendor data */ 2200 2201 Namesp->VendorDataLength = 0; 2202 Namesp->VendorDataOffset = 0; 2203 2204 if (*PFieldList) 2205 { 2206 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2207 &Subtable); 2208 if (ACPI_FAILURE (Status)) 2209 { 2210 return (Status); 2211 } 2212 2213 if (Subtable) 2214 { 2215 ParentTable = DtPeekSubtable (); 2216 DtInsertSubtable (ParentTable, Subtable); 2217 2218 Namesp->VendorDataOffset = 2219 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 2220 Namesp->VendorDataLength = 2221 (UINT16) Subtable->Length; 2222 2223 /* Final size of entire namespace structure */ 2224 2225 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 2226 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; 2227 } 2228 } 2229 2230 break; 2231 2232 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2233 2234 /* Append the PCIe path info first */ 2235 2236 EntryCount = 0; 2237 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 2238 { 2239 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 2240 &Subtable); 2241 if (ACPI_FAILURE (Status)) 2242 { 2243 return (Status); 2244 } 2245 2246 if (!Subtable) 2247 { 2248 DtPopSubtable (); 2249 break; 2250 } 2251 2252 ParentTable = DtPeekSubtable (); 2253 DtInsertSubtable (ParentTable, Subtable); 2254 EntryCount++; 2255 } 2256 2257 /* Path offset will point immediately after the main subtable */ 2258 2259 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 2260 Pcie->PathLength = (UINT16) 2261 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 2262 2263 /* Append the Vendor Data last */ 2264 2265 Pcie->VendorDataLength = 0; 2266 Pcie->VendorDataOffset = 0; 2267 2268 if (*PFieldList) 2269 { 2270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2271 &Subtable); 2272 if (ACPI_FAILURE (Status)) 2273 { 2274 return (Status); 2275 } 2276 2277 if (Subtable) 2278 { 2279 ParentTable = DtPeekSubtable (); 2280 DtInsertSubtable (ParentTable, Subtable); 2281 2282 Pcie->VendorDataOffset = 2283 Pcie->PathOffset + Pcie->PathLength; 2284 Pcie->VendorDataLength = (UINT16) 2285 Subtable->Length; 2286 } 2287 } 2288 2289 SdevHeader->Length = 2290 sizeof (ACPI_SDEV_PCIE) + 2291 Pcie->PathLength + Pcie->VendorDataLength; 2292 break; 2293 2294 default: 2295 2296 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2297 return (AE_ERROR); 2298 } 2299 2300 DtPopSubtable (); 2301 } 2302 2303 return (AE_OK); 2304 } 2305 2306 2307 /****************************************************************************** 2308 * 2309 * FUNCTION: DtCompileSlic 2310 * 2311 * PARAMETERS: List - Current field list pointer 2312 * 2313 * RETURN: Status 2314 * 2315 * DESCRIPTION: Compile SLIC. 2316 * 2317 *****************************************************************************/ 2318 2319 ACPI_STATUS 2320 DtCompileSlic ( 2321 void **List) 2322 { 2323 ACPI_STATUS Status; 2324 DT_SUBTABLE *Subtable; 2325 DT_SUBTABLE *ParentTable; 2326 DT_FIELD **PFieldList = (DT_FIELD **) List; 2327 2328 2329 while (*PFieldList) 2330 { 2331 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 2332 &Subtable); 2333 if (ACPI_FAILURE (Status)) 2334 { 2335 return (Status); 2336 } 2337 2338 ParentTable = DtPeekSubtable (); 2339 DtInsertSubtable (ParentTable, Subtable); 2340 DtPushSubtable (Subtable); 2341 DtPopSubtable (); 2342 } 2343 2344 return (AE_OK); 2345 } 2346 2347 2348 /****************************************************************************** 2349 * 2350 * FUNCTION: DtCompileSlit 2351 * 2352 * PARAMETERS: List - Current field list pointer 2353 * 2354 * RETURN: Status 2355 * 2356 * DESCRIPTION: Compile SLIT. 2357 * 2358 *****************************************************************************/ 2359 2360 ACPI_STATUS 2361 DtCompileSlit ( 2362 void **List) 2363 { 2364 ACPI_STATUS Status; 2365 DT_SUBTABLE *Subtable; 2366 DT_SUBTABLE *ParentTable; 2367 DT_FIELD **PFieldList = (DT_FIELD **) List; 2368 DT_FIELD *FieldList; 2369 DT_FIELD *EndOfFieldList = NULL; 2370 UINT32 Localities; 2371 UINT32 LocalityListLength; 2372 UINT8 *LocalityBuffer; 2373 2374 2375 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2376 &Subtable); 2377 if (ACPI_FAILURE (Status)) 2378 { 2379 return (Status); 2380 } 2381 2382 ParentTable = DtPeekSubtable (); 2383 DtInsertSubtable (ParentTable, Subtable); 2384 2385 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2386 LocalityBuffer = UtLocalCalloc (Localities); 2387 LocalityListLength = 0; 2388 2389 /* Compile each locality buffer */ 2390 2391 FieldList = *PFieldList; 2392 while (FieldList) 2393 { 2394 DtCompileBuffer (LocalityBuffer, 2395 FieldList->Value, FieldList, Localities); 2396 2397 LocalityListLength++; 2398 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2399 DtInsertSubtable (ParentTable, Subtable); 2400 EndOfFieldList = FieldList; 2401 FieldList = FieldList->Next; 2402 } 2403 2404 if (LocalityListLength != Localities) 2405 { 2406 sprintf(AslGbl_MsgBuffer, 2407 "Found %u entries, must match LocalityCount: %u", 2408 LocalityListLength, Localities); 2409 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 2410 ACPI_FREE (LocalityBuffer); 2411 return (AE_LIMIT); 2412 } 2413 2414 ACPI_FREE (LocalityBuffer); 2415 return (AE_OK); 2416 } 2417 2418 2419 /****************************************************************************** 2420 * 2421 * FUNCTION: DtCompileSrat 2422 * 2423 * PARAMETERS: List - Current field list pointer 2424 * 2425 * RETURN: Status 2426 * 2427 * DESCRIPTION: Compile SRAT. 2428 * 2429 *****************************************************************************/ 2430 2431 ACPI_STATUS 2432 DtCompileSrat ( 2433 void **List) 2434 { 2435 ACPI_STATUS Status; 2436 DT_SUBTABLE *Subtable; 2437 DT_SUBTABLE *ParentTable; 2438 DT_FIELD **PFieldList = (DT_FIELD **) List; 2439 DT_FIELD *SubtableStart; 2440 ACPI_SUBTABLE_HEADER *SratHeader; 2441 ACPI_DMTABLE_INFO *InfoTable; 2442 2443 2444 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 2445 &Subtable); 2446 if (ACPI_FAILURE (Status)) 2447 { 2448 return (Status); 2449 } 2450 2451 ParentTable = DtPeekSubtable (); 2452 DtInsertSubtable (ParentTable, Subtable); 2453 2454 while (*PFieldList) 2455 { 2456 SubtableStart = *PFieldList; 2457 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 2458 &Subtable); 2459 if (ACPI_FAILURE (Status)) 2460 { 2461 return (Status); 2462 } 2463 2464 ParentTable = DtPeekSubtable (); 2465 DtInsertSubtable (ParentTable, Subtable); 2466 DtPushSubtable (Subtable); 2467 2468 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2469 2470 switch (SratHeader->Type) 2471 { 2472 case ACPI_SRAT_TYPE_CPU_AFFINITY: 2473 2474 InfoTable = AcpiDmTableInfoSrat0; 2475 break; 2476 2477 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 2478 2479 InfoTable = AcpiDmTableInfoSrat1; 2480 break; 2481 2482 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 2483 2484 InfoTable = AcpiDmTableInfoSrat2; 2485 break; 2486 2487 case ACPI_SRAT_TYPE_GICC_AFFINITY: 2488 2489 InfoTable = AcpiDmTableInfoSrat3; 2490 break; 2491 2492 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 2493 2494 InfoTable = AcpiDmTableInfoSrat4; 2495 break; 2496 2497 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 2498 2499 InfoTable = AcpiDmTableInfoSrat5; 2500 break; 2501 2502 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 2503 2504 InfoTable = AcpiDmTableInfoSrat6; 2505 break; 2506 2507 case ACPI_SRAT_TYPE_RINTC_AFFINITY: 2508 2509 InfoTable = AcpiDmTableInfoSrat7; 2510 break; 2511 2512 default: 2513 2514 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 2515 return (AE_ERROR); 2516 } 2517 2518 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2519 if (ACPI_FAILURE (Status)) 2520 { 2521 return (Status); 2522 } 2523 2524 ParentTable = DtPeekSubtable (); 2525 DtInsertSubtable (ParentTable, Subtable); 2526 DtPopSubtable (); 2527 } 2528 2529 return (AE_OK); 2530 } 2531 2532 2533 /****************************************************************************** 2534 * 2535 * FUNCTION: DtCompileStao 2536 * 2537 * PARAMETERS: PFieldList - Current field list pointer 2538 * 2539 * RETURN: Status 2540 * 2541 * DESCRIPTION: Compile STAO. 2542 * 2543 *****************************************************************************/ 2544 2545 ACPI_STATUS 2546 DtCompileStao ( 2547 void **List) 2548 { 2549 DT_FIELD **PFieldList = (DT_FIELD **) List; 2550 DT_SUBTABLE *Subtable; 2551 DT_SUBTABLE *ParentTable; 2552 ACPI_STATUS Status; 2553 2554 2555 /* Compile the main table */ 2556 2557 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 2558 &Subtable); 2559 if (ACPI_FAILURE (Status)) 2560 { 2561 return (Status); 2562 } 2563 2564 ParentTable = DtPeekSubtable (); 2565 DtInsertSubtable (ParentTable, Subtable); 2566 2567 /* Compile each ASCII namestring as a subtable */ 2568 2569 while (*PFieldList) 2570 { 2571 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 2572 &Subtable); 2573 if (ACPI_FAILURE (Status)) 2574 { 2575 return (Status); 2576 } 2577 2578 ParentTable = DtPeekSubtable (); 2579 DtInsertSubtable (ParentTable, Subtable); 2580 } 2581 2582 return (AE_OK); 2583 } 2584 2585 2586 /****************************************************************************** 2587 * 2588 * FUNCTION: DtCompileSvkl 2589 * 2590 * PARAMETERS: PFieldList - Current field list pointer 2591 * 2592 * RETURN: Status 2593 * 2594 * DESCRIPTION: Compile SVKL. 2595 * 2596 * NOTES: SVKL is essentially a flat table, with a small main table and 2597 * a variable number of a single type of subtable. 2598 * 2599 *****************************************************************************/ 2600 2601 ACPI_STATUS 2602 DtCompileSvkl ( 2603 void **List) 2604 { 2605 DT_FIELD **PFieldList = (DT_FIELD **) List; 2606 DT_SUBTABLE *Subtable; 2607 DT_SUBTABLE *ParentTable; 2608 ACPI_STATUS Status; 2609 2610 2611 /* Compile the main table */ 2612 2613 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, 2614 &Subtable); 2615 if (ACPI_FAILURE (Status)) 2616 { 2617 return (Status); 2618 } 2619 2620 ParentTable = DtPeekSubtable (); 2621 DtInsertSubtable (ParentTable, Subtable); 2622 2623 /* Compile each subtable */ 2624 2625 while (*PFieldList) 2626 { 2627 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, 2628 &Subtable); 2629 if (ACPI_FAILURE (Status)) 2630 { 2631 return (Status); 2632 } 2633 2634 ParentTable = DtPeekSubtable (); 2635 DtInsertSubtable (ParentTable, Subtable); 2636 } 2637 2638 return (AE_OK); 2639 } 2640 2641 2642 /****************************************************************************** 2643 * 2644 * FUNCTION: DtCompileTcpa 2645 * 2646 * PARAMETERS: PFieldList - Current field list pointer 2647 * 2648 * RETURN: Status 2649 * 2650 * DESCRIPTION: Compile TCPA. 2651 * 2652 *****************************************************************************/ 2653 2654 ACPI_STATUS 2655 DtCompileTcpa ( 2656 void **List) 2657 { 2658 DT_FIELD **PFieldList = (DT_FIELD **) List; 2659 DT_SUBTABLE *Subtable; 2660 ACPI_TABLE_TCPA_HDR *TcpaHeader; 2661 DT_SUBTABLE *ParentTable; 2662 ACPI_STATUS Status; 2663 2664 2665 /* Compile the main table */ 2666 2667 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 2668 &Subtable); 2669 if (ACPI_FAILURE (Status)) 2670 { 2671 return (Status); 2672 } 2673 2674 ParentTable = DtPeekSubtable (); 2675 DtInsertSubtable (ParentTable, Subtable); 2676 2677 /* 2678 * Examine the PlatformClass field to determine the table type. 2679 * Either a client or server table. Only one. 2680 */ 2681 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 2682 2683 switch (TcpaHeader->PlatformClass) 2684 { 2685 case ACPI_TCPA_CLIENT_TABLE: 2686 2687 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 2688 &Subtable); 2689 break; 2690 2691 case ACPI_TCPA_SERVER_TABLE: 2692 2693 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 2694 &Subtable); 2695 break; 2696 2697 default: 2698 2699 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 2700 TcpaHeader->PlatformClass); 2701 Status = AE_ERROR; 2702 break; 2703 } 2704 2705 ParentTable = DtPeekSubtable (); 2706 DtInsertSubtable (ParentTable, Subtable); 2707 return (Status); 2708 } 2709 2710 2711 /****************************************************************************** 2712 * 2713 * FUNCTION: DtCompileTpm2Rev3 2714 * 2715 * PARAMETERS: PFieldList - Current field list pointer 2716 * 2717 * RETURN: Status 2718 * 2719 * DESCRIPTION: Compile TPM2 revision 3 2720 * 2721 *****************************************************************************/ 2722 static ACPI_STATUS 2723 DtCompileTpm2Rev3 ( 2724 void **List) 2725 { 2726 DT_FIELD **PFieldList = (DT_FIELD **) List; 2727 DT_SUBTABLE *Subtable; 2728 ACPI_TABLE_TPM23 *Tpm23Header; 2729 DT_SUBTABLE *ParentTable; 2730 ACPI_STATUS Status = AE_OK; 2731 2732 2733 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 2734 &Subtable); 2735 2736 ParentTable = DtPeekSubtable (); 2737 DtInsertSubtable (ParentTable, Subtable); 2738 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 2739 2740 /* Subtable type depends on the StartMethod */ 2741 2742 switch (Tpm23Header->StartMethod) 2743 { 2744 case ACPI_TPM23_ACPI_START_METHOD: 2745 2746 /* Subtable specific to to ARM_SMC */ 2747 2748 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 2749 &Subtable); 2750 if (ACPI_FAILURE (Status)) 2751 { 2752 return (Status); 2753 } 2754 2755 ParentTable = DtPeekSubtable (); 2756 DtInsertSubtable (ParentTable, Subtable); 2757 break; 2758 2759 default: 2760 break; 2761 } 2762 2763 return (Status); 2764 } 2765 2766 2767 /****************************************************************************** 2768 * 2769 * FUNCTION: DtCompileTpm2 2770 * 2771 * PARAMETERS: PFieldList - Current field list pointer 2772 * 2773 * RETURN: Status 2774 * 2775 * DESCRIPTION: Compile TPM2. 2776 * 2777 *****************************************************************************/ 2778 2779 ACPI_STATUS 2780 DtCompileTpm2 ( 2781 void **List) 2782 { 2783 DT_FIELD **PFieldList = (DT_FIELD **) List; 2784 DT_SUBTABLE *Subtable; 2785 ACPI_TABLE_TPM2 *Tpm2Header; 2786 DT_SUBTABLE *ParentTable; 2787 ACPI_STATUS Status = AE_OK; 2788 ACPI_TABLE_HEADER *Header; 2789 2790 2791 ParentTable = DtPeekSubtable (); 2792 2793 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2794 2795 if (Header->Revision == 3) 2796 { 2797 return (DtCompileTpm2Rev3 (List)); 2798 } 2799 2800 /* Compile the main table */ 2801 2802 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 2803 &Subtable); 2804 if (ACPI_FAILURE (Status)) 2805 { 2806 return (Status); 2807 } 2808 2809 ParentTable = DtPeekSubtable (); 2810 DtInsertSubtable (ParentTable, Subtable); 2811 2812 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 2813 2814 /* Method parameters */ 2815 /* Optional: Log area minimum length */ 2816 /* Optional: Log area start address */ 2817 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 2818 2819 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 2820 &Subtable); 2821 if (ACPI_FAILURE (Status)) 2822 { 2823 return (Status); 2824 } 2825 2826 ParentTable = DtPeekSubtable (); 2827 DtInsertSubtable (ParentTable, Subtable); 2828 2829 2830 /* Subtable type depends on the StartMethod */ 2831 2832 switch (Tpm2Header->StartMethod) 2833 { 2834 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 2835 2836 /* Subtable specific to to ARM_SMC */ 2837 2838 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 2839 &Subtable); 2840 if (ACPI_FAILURE (Status)) 2841 { 2842 return (Status); 2843 } 2844 2845 ParentTable = DtPeekSubtable (); 2846 DtInsertSubtable (ParentTable, Subtable); 2847 break; 2848 2849 case ACPI_TPM2_START_METHOD: 2850 case ACPI_TPM2_MEMORY_MAPPED: 2851 case ACPI_TPM2_COMMAND_BUFFER: 2852 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 2853 break; 2854 2855 case ACPI_TPM2_RESERVED1: 2856 case ACPI_TPM2_RESERVED3: 2857 case ACPI_TPM2_RESERVED4: 2858 case ACPI_TPM2_RESERVED5: 2859 case ACPI_TPM2_RESERVED9: 2860 case ACPI_TPM2_RESERVED10: 2861 2862 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 2863 Tpm2Header->StartMethod); 2864 Status = AE_ERROR; 2865 break; 2866 2867 case ACPI_TPM2_NOT_ALLOWED: 2868 default: 2869 2870 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 2871 Tpm2Header->StartMethod); 2872 Status = AE_ERROR; 2873 break; 2874 } 2875 2876 return (Status); 2877 } 2878 2879 2880 /****************************************************************************** 2881 * 2882 * FUNCTION: DtGetGenericTableInfo 2883 * 2884 * PARAMETERS: Name - Generic type name 2885 * 2886 * RETURN: Info entry 2887 * 2888 * DESCRIPTION: Obtain table info for a generic name entry 2889 * 2890 *****************************************************************************/ 2891 2892 ACPI_DMTABLE_INFO * 2893 DtGetGenericTableInfo ( 2894 char *Name) 2895 { 2896 ACPI_DMTABLE_INFO *Info; 2897 UINT32 i; 2898 2899 2900 if (!Name) 2901 { 2902 return (NULL); 2903 } 2904 2905 /* Search info table for name match */ 2906 2907 for (i = 0; ; i++) 2908 { 2909 Info = AcpiDmTableInfoGeneric[i]; 2910 if (Info->Opcode == ACPI_DMT_EXIT) 2911 { 2912 Info = NULL; 2913 break; 2914 } 2915 2916 /* Use caseless compare for generic keywords */ 2917 2918 if (!AcpiUtStricmp (Name, Info->Name)) 2919 { 2920 break; 2921 } 2922 } 2923 2924 return (Info); 2925 } 2926 2927 2928 /****************************************************************************** 2929 * 2930 * FUNCTION: DtCompileUefi 2931 * 2932 * PARAMETERS: List - Current field list pointer 2933 * 2934 * RETURN: Status 2935 * 2936 * DESCRIPTION: Compile UEFI. 2937 * 2938 *****************************************************************************/ 2939 2940 ACPI_STATUS 2941 DtCompileUefi ( 2942 void **List) 2943 { 2944 ACPI_STATUS Status; 2945 DT_SUBTABLE *Subtable; 2946 DT_SUBTABLE *ParentTable; 2947 DT_FIELD **PFieldList = (DT_FIELD **) List; 2948 UINT16 *DataOffset; 2949 2950 2951 /* Compile the predefined portion of the UEFI table */ 2952 2953 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 2954 &Subtable); 2955 if (ACPI_FAILURE (Status)) 2956 { 2957 return (Status); 2958 } 2959 2960 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 2961 *DataOffset = sizeof (ACPI_TABLE_UEFI); 2962 2963 ParentTable = DtPeekSubtable (); 2964 DtInsertSubtable (ParentTable, Subtable); 2965 2966 /* 2967 * Compile the "generic" portion of the UEFI table. This 2968 * part of the table is not predefined and any of the generic 2969 * operators may be used. 2970 */ 2971 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 2972 return (AE_OK); 2973 } 2974 2975 2976 /****************************************************************************** 2977 * 2978 * FUNCTION: DtCompileViot 2979 * 2980 * PARAMETERS: List - Current field list pointer 2981 * 2982 * RETURN: Status 2983 * 2984 * DESCRIPTION: Compile VIOT. 2985 * 2986 *****************************************************************************/ 2987 2988 ACPI_STATUS 2989 DtCompileViot ( 2990 void **List) 2991 { 2992 ACPI_STATUS Status; 2993 DT_SUBTABLE *Subtable; 2994 DT_SUBTABLE *ParentTable; 2995 DT_FIELD **PFieldList = (DT_FIELD **) List; 2996 DT_FIELD *SubtableStart; 2997 ACPI_TABLE_VIOT *Viot; 2998 ACPI_VIOT_HEADER *ViotHeader; 2999 ACPI_DMTABLE_INFO *InfoTable; 3000 UINT16 NodeCount; 3001 3002 ParentTable = DtPeekSubtable (); 3003 3004 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); 3005 if (ACPI_FAILURE (Status)) 3006 { 3007 return (Status); 3008 } 3009 DtInsertSubtable (ParentTable, Subtable); 3010 3011 /* 3012 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3013 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3014 */ 3015 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, 3016 sizeof (ACPI_TABLE_HEADER)); 3017 3018 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); 3019 3020 NodeCount = 0; 3021 while (*PFieldList) { 3022 SubtableStart = *PFieldList; 3023 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, 3024 &Subtable); 3025 if (ACPI_FAILURE (Status)) 3026 { 3027 return (Status); 3028 } 3029 3030 ParentTable = DtPeekSubtable (); 3031 DtInsertSubtable (ParentTable, Subtable); 3032 DtPushSubtable (Subtable); 3033 3034 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); 3035 3036 switch (ViotHeader->Type) 3037 { 3038 case ACPI_VIOT_NODE_PCI_RANGE: 3039 3040 InfoTable = AcpiDmTableInfoViot1; 3041 break; 3042 3043 case ACPI_VIOT_NODE_MMIO: 3044 3045 InfoTable = AcpiDmTableInfoViot2; 3046 break; 3047 3048 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 3049 3050 InfoTable = AcpiDmTableInfoViot3; 3051 break; 3052 3053 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 3054 3055 InfoTable = AcpiDmTableInfoViot4; 3056 break; 3057 3058 default: 3059 3060 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); 3061 return (AE_ERROR); 3062 } 3063 3064 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 3065 if (ACPI_FAILURE (Status)) 3066 { 3067 return (Status); 3068 } 3069 3070 ParentTable = DtPeekSubtable (); 3071 DtInsertSubtable (ParentTable, Subtable); 3072 DtPopSubtable (); 3073 NodeCount++; 3074 } 3075 3076 Viot->NodeCount = NodeCount; 3077 return (AE_OK); 3078 } 3079 3080 3081 /****************************************************************************** 3082 * 3083 * FUNCTION: DtCompileWdat 3084 * 3085 * PARAMETERS: List - Current field list pointer 3086 * 3087 * RETURN: Status 3088 * 3089 * DESCRIPTION: Compile WDAT. 3090 * 3091 *****************************************************************************/ 3092 3093 ACPI_STATUS 3094 DtCompileWdat ( 3095 void **List) 3096 { 3097 ACPI_STATUS Status; 3098 3099 3100 Status = DtCompileTwoSubtables (List, 3101 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 3102 return (Status); 3103 } 3104 3105 3106 /****************************************************************************** 3107 * 3108 * FUNCTION: DtCompileWpbt 3109 * 3110 * PARAMETERS: List - Current field list pointer 3111 * 3112 * RETURN: Status 3113 * 3114 * DESCRIPTION: Compile WPBT. 3115 * 3116 *****************************************************************************/ 3117 3118 ACPI_STATUS 3119 DtCompileWpbt ( 3120 void **List) 3121 { 3122 DT_FIELD **PFieldList = (DT_FIELD **) List; 3123 DT_SUBTABLE *Subtable; 3124 DT_SUBTABLE *ParentTable; 3125 ACPI_TABLE_WPBT *Table; 3126 ACPI_STATUS Status; 3127 3128 3129 /* Compile the main table */ 3130 3131 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); 3132 if (ACPI_FAILURE (Status)) 3133 { 3134 return (Status); 3135 } 3136 3137 ParentTable = DtPeekSubtable (); 3138 DtInsertSubtable (ParentTable, Subtable); 3139 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 3140 3141 /* 3142 * Exit now if there are no arguments specified. This is indicated by: 3143 * The "Command-line Arguments" field has not been specified (if specified, 3144 * it will be the last field in the field list -- after the main table). 3145 * Set the Argument Length in the main table to zero. 3146 */ 3147 if (!*PFieldList) 3148 { 3149 Table->ArgumentsLength = 0; 3150 return (AE_OK); 3151 } 3152 3153 /* Compile the argument list subtable */ 3154 3155 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); 3156 if (ACPI_FAILURE (Status)) 3157 { 3158 return (Status); 3159 } 3160 3161 /* Extract the length of the Arguments buffer, insert into main table */ 3162 3163 Table->ArgumentsLength = (UINT16) Subtable->TotalLength; 3164 DtInsertSubtable (ParentTable, Subtable); 3165 return (AE_OK); 3166 } 3167 3168 3169 /****************************************************************************** 3170 * 3171 * FUNCTION: DtCompileXsdt 3172 * 3173 * PARAMETERS: List - Current field list pointer 3174 * 3175 * RETURN: Status 3176 * 3177 * DESCRIPTION: Compile XSDT. 3178 * 3179 *****************************************************************************/ 3180 3181 ACPI_STATUS 3182 DtCompileXsdt ( 3183 void **List) 3184 { 3185 DT_SUBTABLE *Subtable; 3186 DT_SUBTABLE *ParentTable; 3187 DT_FIELD *FieldList = *(DT_FIELD **) List; 3188 UINT64 Address; 3189 3190 3191 ParentTable = DtPeekSubtable (); 3192 3193 while (FieldList) 3194 { 3195 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 3196 3197 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 3198 DtInsertSubtable (ParentTable, Subtable); 3199 FieldList = FieldList->Next; 3200 } 3201 3202 return (AE_OK); 3203 } 3204 3205 3206 /****************************************************************************** 3207 * 3208 * FUNCTION: DtCompileGeneric 3209 * 3210 * PARAMETERS: List - Current field list pointer 3211 * Name - Field name to end generic compiling 3212 * Length - Compiled table length to return 3213 * 3214 * RETURN: Status 3215 * 3216 * DESCRIPTION: Compile generic unknown table. 3217 * 3218 *****************************************************************************/ 3219 3220 ACPI_STATUS 3221 DtCompileGeneric ( 3222 void **List, 3223 char *Name, 3224 UINT32 *Length) 3225 { 3226 ACPI_STATUS Status; 3227 DT_SUBTABLE *Subtable; 3228 DT_SUBTABLE *ParentTable; 3229 DT_FIELD **PFieldList = (DT_FIELD **) List; 3230 ACPI_DMTABLE_INFO *Info; 3231 3232 3233 ParentTable = DtPeekSubtable (); 3234 3235 /* 3236 * Compile the "generic" portion of the table. This 3237 * part of the table is not predefined and any of the generic 3238 * operators may be used. 3239 */ 3240 3241 /* Find any and all labels in the entire generic portion */ 3242 3243 DtDetectAllLabels (*PFieldList); 3244 3245 /* Now we can actually compile the parse tree */ 3246 3247 if (Length && *Length) 3248 { 3249 *Length = 0; 3250 } 3251 while (*PFieldList) 3252 { 3253 if (Name && !strcmp ((*PFieldList)->Name, Name)) 3254 { 3255 break; 3256 } 3257 3258 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 3259 if (!Info) 3260 { 3261 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3262 (*PFieldList)->Name); 3263 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3264 (*PFieldList), AslGbl_MsgBuffer); 3265 3266 *PFieldList = (*PFieldList)->Next; 3267 continue; 3268 } 3269 3270 Status = DtCompileTable (PFieldList, Info, 3271 &Subtable); 3272 if (ACPI_SUCCESS (Status)) 3273 { 3274 DtInsertSubtable (ParentTable, Subtable); 3275 if (Length) 3276 { 3277 *Length += Subtable->Length; 3278 } 3279 } 3280 else 3281 { 3282 *PFieldList = (*PFieldList)->Next; 3283 3284 if (Status == AE_NOT_FOUND) 3285 { 3286 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3287 (*PFieldList)->Name); 3288 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3289 (*PFieldList), AslGbl_MsgBuffer); 3290 } 3291 } 3292 } 3293 3294 return (AE_OK); 3295 } 3296