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