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