1 /****************************************************************************** 2 * 3 * Module Name: dttable1.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 A-I */ 45 46 #include "aslcompiler.h" 47 48 #define _COMPONENT DT_COMPILER 49 ACPI_MODULE_NAME ("dttable1") 50 51 52 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 53 { 54 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 55 {ACPI_DMT_EXIT, 0, NULL, 0} 56 }; 57 58 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 59 { 60 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 61 {ACPI_DMT_EXIT, 0, NULL, 0} 62 }; 63 64 65 /****************************************************************************** 66 * 67 * FUNCTION: DtCompileAest 68 * 69 * PARAMETERS: List - Current field list pointer 70 * 71 * RETURN: Status 72 * 73 * DESCRIPTION: Compile AEST. 74 * 75 * NOTE: Assumes the following table structure: 76 * For all AEST Error Nodes: 77 * 1) An AEST Error Node, followed immediately by: 78 * 2) Any node-specific data 79 * 3) An Interface Structure (one) 80 * 4) A list (array) of Interrupt Structures, the count as specified 81 * in the NodeInterruptCount field of the Error Node header. 82 * 83 * AEST - ARM Error Source table. Conforms to: 84 * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020 85 * 86 *****************************************************************************/ 87 88 ACPI_STATUS 89 DtCompileAest ( 90 void **List) 91 { 92 ACPI_AEST_HEADER *ErrorNodeHeader; 93 ACPI_AEST_PROCESSOR *AestProcessor; 94 DT_SUBTABLE *Subtable; 95 DT_SUBTABLE *ParentTable; 96 ACPI_DMTABLE_INFO *InfoTable; 97 ACPI_STATUS Status; 98 UINT32 i; 99 UINT32 Offset; 100 DT_FIELD **PFieldList = (DT_FIELD **) List; 101 102 103 while (*PFieldList) 104 { 105 /* Compile the common error node header */ 106 107 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr, 108 &Subtable); 109 if (ACPI_FAILURE (Status)) 110 { 111 return (Status); 112 } 113 114 ParentTable = DtPeekSubtable (); 115 DtInsertSubtable (ParentTable, Subtable); 116 117 /* Everything past the error node header will be a subtable */ 118 119 DtPushSubtable (Subtable); 120 121 /* 122 * Compile the node-specific structure (Based on the error 123 * node header Type field) 124 */ 125 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer); 126 127 /* Point past the common error node header */ 128 129 Offset = sizeof (ACPI_AEST_HEADER); 130 ErrorNodeHeader->NodeSpecificOffset = Offset; 131 132 /* Decode the error node type */ 133 134 switch (ErrorNodeHeader->Type) 135 { 136 case ACPI_AEST_PROCESSOR_ERROR_NODE: 137 138 InfoTable = AcpiDmTableInfoAestProcError; 139 break; 140 141 case ACPI_AEST_MEMORY_ERROR_NODE: 142 143 InfoTable = AcpiDmTableInfoAestMemError; 144 break; 145 146 case ACPI_AEST_SMMU_ERROR_NODE: 147 148 InfoTable = AcpiDmTableInfoAestSmmuError; 149 break; 150 151 case ACPI_AEST_VENDOR_ERROR_NODE: 152 153 InfoTable = AcpiDmTableInfoAestVendorError; 154 break; 155 156 case ACPI_AEST_GIC_ERROR_NODE: 157 158 InfoTable = AcpiDmTableInfoAestGicError; 159 break; 160 161 /* Error case below */ 162 default: 163 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n", 164 ErrorNodeHeader->Type); 165 return (AE_ERROR); 166 } 167 168 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 169 if (ACPI_FAILURE (Status)) 170 { 171 return (Status); 172 } 173 174 /* Point past the node-specific structure */ 175 176 Offset += Subtable->Length; 177 ErrorNodeHeader->NodeInterfaceOffset = Offset; 178 179 ParentTable = DtPeekSubtable (); 180 DtInsertSubtable (ParentTable, Subtable); 181 182 /* Compile any additional node-specific substructures */ 183 184 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE) 185 { 186 /* 187 * Special handling for PROCESSOR_ERROR_NODE subtables 188 * (to handle the Resource Substructure via the ResourceType 189 * field). 190 */ 191 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, 192 Subtable->Buffer); 193 194 switch (AestProcessor->ResourceType) 195 { 196 case ACPI_AEST_CACHE_RESOURCE: 197 198 InfoTable = AcpiDmTableInfoAestCacheRsrc; 199 break; 200 201 case ACPI_AEST_TLB_RESOURCE: 202 203 InfoTable = AcpiDmTableInfoAestTlbRsrc; 204 break; 205 206 case ACPI_AEST_GENERIC_RESOURCE: 207 208 InfoTable = AcpiDmTableInfoAestGenRsrc; 209 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n", 210 AestProcessor->ResourceType); 211 return (AE_ERROR); 212 213 /* Error case below */ 214 default: 215 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n", 216 AestProcessor->ResourceType); 217 return (AE_ERROR); 218 } 219 220 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 221 if (ACPI_FAILURE (Status)) 222 { 223 return (Status); 224 } 225 226 /* Point past the resource substructure subtable */ 227 228 Offset += Subtable->Length; 229 ErrorNodeHeader->NodeInterfaceOffset = Offset; 230 231 ParentTable = DtPeekSubtable (); 232 DtInsertSubtable (ParentTable, Subtable); 233 } 234 235 /* Compile the (required) node interface structure */ 236 237 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface, 238 &Subtable); 239 if (ACPI_FAILURE (Status)) 240 { 241 return (Status); 242 } 243 244 ErrorNodeHeader->NodeInterruptOffset = 0; 245 ParentTable = DtPeekSubtable (); 246 DtInsertSubtable (ParentTable, Subtable); 247 248 /* Compile each of the node interrupt structures */ 249 250 if (ErrorNodeHeader->NodeInterruptCount) 251 { 252 /* Point to the first interrupt structure */ 253 254 Offset += Subtable->Length; 255 ErrorNodeHeader->NodeInterruptOffset = Offset; 256 } 257 258 /* Compile each of the interrupt structures */ 259 260 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++) 261 { 262 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt, 263 &Subtable); 264 if (ACPI_FAILURE (Status)) 265 { 266 return (Status); 267 } 268 269 ParentTable = DtPeekSubtable (); 270 DtInsertSubtable (ParentTable, Subtable); 271 } 272 273 /* Prepare for the next AEST Error node */ 274 275 DtPopSubtable (); 276 } 277 278 return (AE_OK); 279 } 280 281 282 /****************************************************************************** 283 * 284 * FUNCTION: DtCompileApmt 285 * 286 * PARAMETERS: List - Current field list pointer 287 * 288 * RETURN: Status 289 * 290 * DESCRIPTION: Compile APMT. 291 * 292 *****************************************************************************/ 293 294 ACPI_STATUS 295 DtCompileApmt ( 296 void **List) 297 { 298 ACPI_STATUS Status; 299 ACPI_TABLE_HEADER *Header; 300 ACPI_APMT_NODE *ApmtNode; 301 ACPI_APMT_NODE *PeerApmtNode; 302 DT_SUBTABLE *Subtable; 303 DT_SUBTABLE *PeerSubtable; 304 DT_SUBTABLE *ParentTable; 305 DT_FIELD **PFieldList = (DT_FIELD**)List; 306 DT_FIELD *SubtableStart; 307 UINT32 CurLength; 308 char MsgBuffer[64] = ""; 309 310 ParentTable = DtPeekSubtable(); 311 312 Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer); 313 314 CurLength = sizeof(ACPI_TABLE_HEADER); 315 316 /* Walk the parse tree */ 317 318 while (*PFieldList) 319 { 320 /* APMT Node Subtable */ 321 322 SubtableStart = *PFieldList; 323 324 Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable); 325 326 if (ACPI_FAILURE(Status)) 327 { 328 return (Status); 329 } 330 331 ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer); 332 333 if (ApmtNode->Length != sizeof(ACPI_APMT_NODE)) 334 { 335 DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT"); 336 return (AE_ERROR); 337 } 338 339 if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT) 340 { 341 snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type); 342 DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer); 343 return (AE_ERROR); 344 } 345 346 PeerSubtable = DtGetNextSubtable(ParentTable, NULL); 347 348 /* Validate the node id needs to be unique. */ 349 while(PeerSubtable) 350 { 351 PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer); 352 if (PeerApmtNode->Id == ApmtNode->Id) 353 { 354 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id); 355 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer); 356 return (AE_ERROR); 357 } 358 359 PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable); 360 } 361 362 CurLength += ApmtNode->Length; 363 364 DtInsertSubtable(ParentTable, Subtable); 365 } 366 367 if (Header->Length != CurLength) 368 { 369 snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)", 370 Header->Length, CurLength); 371 DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer); 372 return (AE_ERROR); 373 } 374 375 return (AE_OK); 376 } 377 378 /****************************************************************************** 379 * 380 * FUNCTION: DtCompileAsf 381 * 382 * PARAMETERS: List - Current field list pointer 383 * 384 * RETURN: Status 385 * 386 * DESCRIPTION: Compile ASF!. 387 * 388 *****************************************************************************/ 389 390 ACPI_STATUS 391 DtCompileAsf ( 392 void **List) 393 { 394 ACPI_ASF_INFO *AsfTable; 395 DT_SUBTABLE *Subtable; 396 DT_SUBTABLE *ParentTable; 397 ACPI_DMTABLE_INFO *InfoTable; 398 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 399 UINT32 DataCount = 0; 400 ACPI_STATUS Status; 401 UINT32 i; 402 DT_FIELD **PFieldList = (DT_FIELD **) List; 403 DT_FIELD *SubtableStart; 404 405 406 while (*PFieldList) 407 { 408 SubtableStart = *PFieldList; 409 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 410 &Subtable); 411 if (ACPI_FAILURE (Status)) 412 { 413 return (Status); 414 } 415 416 ParentTable = DtPeekSubtable (); 417 DtInsertSubtable (ParentTable, Subtable); 418 DtPushSubtable (Subtable); 419 420 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 421 422 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 423 { 424 case ACPI_ASF_TYPE_INFO: 425 426 InfoTable = AcpiDmTableInfoAsf0; 427 break; 428 429 case ACPI_ASF_TYPE_ALERT: 430 431 InfoTable = AcpiDmTableInfoAsf1; 432 break; 433 434 case ACPI_ASF_TYPE_CONTROL: 435 436 InfoTable = AcpiDmTableInfoAsf2; 437 break; 438 439 case ACPI_ASF_TYPE_BOOT: 440 441 InfoTable = AcpiDmTableInfoAsf3; 442 break; 443 444 case ACPI_ASF_TYPE_ADDRESS: 445 446 InfoTable = AcpiDmTableInfoAsf4; 447 break; 448 449 default: 450 451 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 452 return (AE_ERROR); 453 } 454 455 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 456 if (ACPI_FAILURE (Status)) 457 { 458 return (Status); 459 } 460 461 ParentTable = DtPeekSubtable (); 462 DtInsertSubtable (ParentTable, Subtable); 463 464 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 465 { 466 case ACPI_ASF_TYPE_INFO: 467 468 DataInfoTable = NULL; 469 break; 470 471 case ACPI_ASF_TYPE_ALERT: 472 473 DataInfoTable = AcpiDmTableInfoAsf1a; 474 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 475 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 476 sizeof (ACPI_ASF_HEADER)))->Alerts; 477 break; 478 479 case ACPI_ASF_TYPE_CONTROL: 480 481 DataInfoTable = AcpiDmTableInfoAsf2a; 482 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 483 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 484 sizeof (ACPI_ASF_HEADER)))->Controls; 485 break; 486 487 case ACPI_ASF_TYPE_BOOT: 488 489 DataInfoTable = NULL; 490 break; 491 492 case ACPI_ASF_TYPE_ADDRESS: 493 494 DataInfoTable = TableInfoAsfAddress; 495 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 496 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 497 sizeof (ACPI_ASF_HEADER)))->Devices; 498 break; 499 500 default: 501 502 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 503 return (AE_ERROR); 504 } 505 506 if (DataInfoTable) 507 { 508 switch (AsfTable->Header.Type & 0x7F) 509 { 510 case ACPI_ASF_TYPE_ADDRESS: 511 512 while (DataCount > 0) 513 { 514 Status = DtCompileTable (PFieldList, DataInfoTable, 515 &Subtable); 516 if (ACPI_FAILURE (Status)) 517 { 518 return (Status); 519 } 520 521 DtInsertSubtable (ParentTable, Subtable); 522 DataCount = DataCount - Subtable->Length; 523 } 524 break; 525 526 default: 527 528 for (i = 0; i < DataCount; i++) 529 { 530 Status = DtCompileTable (PFieldList, DataInfoTable, 531 &Subtable); 532 if (ACPI_FAILURE (Status)) 533 { 534 return (Status); 535 } 536 537 DtInsertSubtable (ParentTable, Subtable); 538 } 539 break; 540 } 541 } 542 543 DtPopSubtable (); 544 } 545 546 return (AE_OK); 547 } 548 549 550 /****************************************************************************** 551 * 552 * FUNCTION: DtCompileCedt 553 * 554 * PARAMETERS: List - Current field list pointer 555 * 556 * RETURN: Status 557 * 558 * DESCRIPTION: Compile CEDT. 559 * 560 *****************************************************************************/ 561 562 ACPI_STATUS 563 DtCompileCedt ( 564 void **List) 565 { 566 ACPI_STATUS Status; 567 DT_SUBTABLE *Subtable; 568 DT_SUBTABLE *ParentTable; 569 DT_FIELD **PFieldList = (DT_FIELD **) List; 570 ACPI_CEDT_HEADER *CedtHeader; 571 DT_FIELD *SubtableStart; 572 573 574 /* Walk the parse tree */ 575 576 while (*PFieldList) 577 { 578 /* if CFMWS and has more than one target, then set to zero later */ 579 580 int InsertFlag = 1; 581 SubtableStart = *PFieldList; 582 583 /* CEDT Header */ 584 585 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr, 586 &Subtable); 587 if (ACPI_FAILURE (Status)) 588 { 589 return (Status); 590 } 591 592 ParentTable = DtPeekSubtable (); 593 DtInsertSubtable (ParentTable, Subtable); 594 DtPushSubtable (Subtable); 595 596 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer); 597 598 switch (CedtHeader->Type) 599 { 600 case ACPI_CEDT_TYPE_CHBS: 601 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable); 602 if (ACPI_FAILURE (Status)) 603 { 604 return (Status); 605 } 606 break; 607 case ACPI_CEDT_TYPE_CFMWS: { 608 unsigned char *dump; 609 unsigned int idx, offset, max = 0; 610 611 /* Compile table with first "Interleave target" */ 612 613 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable); 614 if (ACPI_FAILURE (Status)) 615 { 616 return (Status); 617 } 618 619 /* Look in buffer for the number of targets */ 620 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays); 621 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */ 622 max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */ 623 if (max > 8) max=1; /* Error in encoding Interleaving Ways. */ 624 if (max == 1) /* if only one target, then break here. */ 625 break; /* break if only one target. */ 626 627 /* We need to add more interleave targets, so write the current Subtable. */ 628 629 ParentTable = DtPeekSubtable (); 630 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt1 table so we can put in */ 631 DtPushSubtable (Subtable); /* the targets > the first. */ 632 633 /* Now, find out all interleave targets beyond the first. */ 634 635 for (idx = 1; idx < max; idx++) { 636 ParentTable = DtPeekSubtable (); 637 638 if (*PFieldList) 639 { 640 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable); 641 if (ACPI_FAILURE (Status)) 642 { 643 return (Status); 644 } 645 if (Subtable) 646 { 647 DtInsertSubtable (ParentTable, Subtable); /* got a target, so insert table. */ 648 InsertFlag = 0; 649 } 650 } 651 } 652 653 DtPopSubtable (); 654 ParentTable = DtPeekSubtable (); 655 break; 656 } 657 658 default: 659 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT"); 660 return (AE_ERROR); 661 } 662 663 ParentTable = DtPeekSubtable (); 664 if (InsertFlag == 1) { 665 DtInsertSubtable (ParentTable, Subtable); 666 } 667 DtPopSubtable (); 668 } 669 670 return (AE_OK); 671 } 672 673 674 /****************************************************************************** 675 * 676 * FUNCTION: DtCompileCpep 677 * 678 * PARAMETERS: List - Current field list pointer 679 * 680 * RETURN: Status 681 * 682 * DESCRIPTION: Compile CPEP. 683 * 684 *****************************************************************************/ 685 686 ACPI_STATUS 687 DtCompileCpep ( 688 void **List) 689 { 690 ACPI_STATUS Status; 691 692 693 Status = DtCompileTwoSubtables (List, 694 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 695 return (Status); 696 } 697 698 699 /****************************************************************************** 700 * 701 * FUNCTION: DtCompileCsrt 702 * 703 * PARAMETERS: List - Current field list pointer 704 * 705 * RETURN: Status 706 * 707 * DESCRIPTION: Compile CSRT. 708 * 709 *****************************************************************************/ 710 711 ACPI_STATUS 712 DtCompileCsrt ( 713 void **List) 714 { 715 ACPI_STATUS Status = AE_OK; 716 DT_SUBTABLE *Subtable; 717 DT_SUBTABLE *ParentTable; 718 DT_FIELD **PFieldList = (DT_FIELD **) List; 719 UINT32 DescriptorCount; 720 UINT32 GroupLength; 721 722 723 /* Subtables (Resource Groups) */ 724 725 ParentTable = DtPeekSubtable (); 726 while (*PFieldList) 727 { 728 /* Resource group subtable */ 729 730 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 731 &Subtable); 732 if (ACPI_FAILURE (Status)) 733 { 734 return (Status); 735 } 736 737 /* Compute the number of resource descriptors */ 738 739 GroupLength = 740 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 741 Subtable->Buffer))->Length - 742 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 743 Subtable->Buffer))->SharedInfoLength - 744 sizeof (ACPI_CSRT_GROUP); 745 746 DescriptorCount = (GroupLength / 747 sizeof (ACPI_CSRT_DESCRIPTOR)); 748 749 DtInsertSubtable (ParentTable, Subtable); 750 DtPushSubtable (Subtable); 751 ParentTable = DtPeekSubtable (); 752 753 /* Shared info subtable (One per resource group) */ 754 755 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 756 &Subtable); 757 if (ACPI_FAILURE (Status)) 758 { 759 return (Status); 760 } 761 762 DtInsertSubtable (ParentTable, Subtable); 763 764 /* Sub-Subtables (Resource Descriptors) */ 765 766 while (*PFieldList && DescriptorCount) 767 { 768 769 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 770 &Subtable); 771 if (ACPI_FAILURE (Status)) 772 { 773 return (Status); 774 } 775 776 DtInsertSubtable (ParentTable, Subtable); 777 778 DtPushSubtable (Subtable); 779 ParentTable = DtPeekSubtable (); 780 if (*PFieldList) 781 { 782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 783 &Subtable); 784 if (ACPI_FAILURE (Status)) 785 { 786 return (Status); 787 } 788 if (Subtable) 789 { 790 DtInsertSubtable (ParentTable, Subtable); 791 } 792 } 793 794 DtPopSubtable (); 795 ParentTable = DtPeekSubtable (); 796 DescriptorCount--; 797 } 798 799 DtPopSubtable (); 800 ParentTable = DtPeekSubtable (); 801 } 802 803 return (Status); 804 } 805 806 807 /****************************************************************************** 808 * 809 * FUNCTION: DtCompileDbg2 810 * 811 * PARAMETERS: List - Current field list pointer 812 * 813 * RETURN: Status 814 * 815 * DESCRIPTION: Compile DBG2. 816 * 817 *****************************************************************************/ 818 819 ACPI_STATUS 820 DtCompileDbg2 ( 821 void **List) 822 { 823 ACPI_STATUS Status; 824 DT_SUBTABLE *Subtable; 825 DT_SUBTABLE *ParentTable; 826 DT_FIELD **PFieldList = (DT_FIELD **) List; 827 UINT32 SubtableCount; 828 ACPI_DBG2_HEADER *Dbg2Header; 829 ACPI_DBG2_DEVICE *DeviceInfo; 830 UINT16 CurrentOffset; 831 UINT32 i; 832 833 834 /* Main table */ 835 836 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable); 837 if (ACPI_FAILURE (Status)) 838 { 839 return (Status); 840 } 841 842 ParentTable = DtPeekSubtable (); 843 DtInsertSubtable (ParentTable, Subtable); 844 845 /* Main table fields */ 846 847 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 848 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 849 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 850 851 SubtableCount = Dbg2Header->InfoCount; 852 DtPushSubtable (Subtable); 853 854 /* Process all Device Information subtables (Count = InfoCount) */ 855 856 while (*PFieldList && SubtableCount) 857 { 858 /* Subtable: Debug Device Information */ 859 860 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 861 &Subtable); 862 if (ACPI_FAILURE (Status)) 863 { 864 return (Status); 865 } 866 867 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 868 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 869 870 ParentTable = DtPeekSubtable (); 871 DtInsertSubtable (ParentTable, Subtable); 872 DtPushSubtable (Subtable); 873 874 ParentTable = DtPeekSubtable (); 875 876 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 877 878 DeviceInfo->BaseAddressOffset = CurrentOffset; 879 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 880 { 881 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 882 &Subtable); 883 if (ACPI_FAILURE (Status)) 884 { 885 return (Status); 886 } 887 888 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 889 DtInsertSubtable (ParentTable, Subtable); 890 } 891 892 /* AddressSize array (Required, size = RegisterCount) */ 893 894 DeviceInfo->AddressSizeOffset = CurrentOffset; 895 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 896 { 897 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 898 &Subtable); 899 if (ACPI_FAILURE (Status)) 900 { 901 return (Status); 902 } 903 904 CurrentOffset += (UINT16) sizeof (UINT32); 905 DtInsertSubtable (ParentTable, Subtable); 906 } 907 908 /* NamespaceString device identifier (Required, size = NamePathLength) */ 909 910 DeviceInfo->NamepathOffset = CurrentOffset; 911 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 912 &Subtable); 913 if (ACPI_FAILURE (Status)) 914 { 915 return (Status); 916 } 917 918 /* Update the device info header */ 919 920 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 921 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 922 DtInsertSubtable (ParentTable, Subtable); 923 924 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 925 926 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 927 &Subtable); 928 if (Status == AE_END_OF_TABLE) 929 { 930 /* optional field was not found and we're at the end of the file */ 931 932 goto subtableDone; 933 } 934 else if (ACPI_FAILURE (Status)) 935 { 936 return (Status); 937 } 938 939 /* Update the device info header (zeros if no OEM data present) */ 940 941 DeviceInfo->OemDataOffset = 0; 942 DeviceInfo->OemDataLength = 0; 943 944 /* Optional subtable (OemData) */ 945 946 if (Subtable && Subtable->Length) 947 { 948 DeviceInfo->OemDataOffset = CurrentOffset; 949 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 950 951 DtInsertSubtable (ParentTable, Subtable); 952 } 953 subtableDone: 954 SubtableCount--; 955 DtPopSubtable (); /* Get next Device Information subtable */ 956 } 957 958 DtPopSubtable (); 959 return (AE_OK); 960 } 961 962 963 /****************************************************************************** 964 * 965 * FUNCTION: DtCompileDmar 966 * 967 * PARAMETERS: List - Current field list pointer 968 * 969 * RETURN: Status 970 * 971 * DESCRIPTION: Compile DMAR. 972 * 973 *****************************************************************************/ 974 975 ACPI_STATUS 976 DtCompileDmar ( 977 void **List) 978 { 979 ACPI_STATUS Status; 980 DT_SUBTABLE *Subtable; 981 DT_SUBTABLE *ParentTable; 982 DT_FIELD **PFieldList = (DT_FIELD **) List; 983 DT_FIELD *SubtableStart; 984 ACPI_DMTABLE_INFO *InfoTable; 985 ACPI_DMAR_HEADER *DmarHeader; 986 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 987 UINT32 DeviceScopeLength; 988 UINT32 PciPathLength; 989 990 991 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 992 if (ACPI_FAILURE (Status)) 993 { 994 return (Status); 995 } 996 997 ParentTable = DtPeekSubtable (); 998 DtInsertSubtable (ParentTable, Subtable); 999 DtPushSubtable (Subtable); 1000 1001 while (*PFieldList) 1002 { 1003 /* DMAR Header */ 1004 1005 SubtableStart = *PFieldList; 1006 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 1007 &Subtable); 1008 if (ACPI_FAILURE (Status)) 1009 { 1010 return (Status); 1011 } 1012 1013 ParentTable = DtPeekSubtable (); 1014 DtInsertSubtable (ParentTable, Subtable); 1015 DtPushSubtable (Subtable); 1016 1017 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 1018 1019 switch (DmarHeader->Type) 1020 { 1021 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1022 1023 InfoTable = AcpiDmTableInfoDmar0; 1024 break; 1025 1026 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1027 1028 InfoTable = AcpiDmTableInfoDmar1; 1029 break; 1030 1031 case ACPI_DMAR_TYPE_ROOT_ATS: 1032 1033 InfoTable = AcpiDmTableInfoDmar2; 1034 break; 1035 1036 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1037 1038 InfoTable = AcpiDmTableInfoDmar3; 1039 break; 1040 1041 case ACPI_DMAR_TYPE_NAMESPACE: 1042 1043 InfoTable = AcpiDmTableInfoDmar4; 1044 break; 1045 1046 case ACPI_DMAR_TYPE_SATC: 1047 1048 InfoTable = AcpiDmTableInfoDmar5; 1049 break; 1050 1051 default: 1052 1053 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 1054 return (AE_ERROR); 1055 } 1056 1057 /* DMAR Subtable */ 1058 1059 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1060 if (ACPI_FAILURE (Status)) 1061 { 1062 return (Status); 1063 } 1064 1065 ParentTable = DtPeekSubtable (); 1066 DtInsertSubtable (ParentTable, Subtable); 1067 1068 /* 1069 * Optional Device Scope subtables 1070 */ 1071 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 1072 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 1073 { 1074 /* These types do not support device scopes */ 1075 1076 DtPopSubtable (); 1077 continue; 1078 } 1079 1080 DtPushSubtable (Subtable); 1081 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 1082 ParentTable->Length; 1083 while (DeviceScopeLength) 1084 { 1085 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 1086 &Subtable); 1087 if (Status == AE_NOT_FOUND) 1088 { 1089 break; 1090 } 1091 1092 ParentTable = DtPeekSubtable (); 1093 DtInsertSubtable (ParentTable, Subtable); 1094 DtPushSubtable (Subtable); 1095 1096 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 1097 1098 /* Optional PCI Paths */ 1099 1100 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 1101 while (PciPathLength) 1102 { 1103 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 1104 &Subtable); 1105 if (Status == AE_NOT_FOUND) 1106 { 1107 DtPopSubtable (); 1108 break; 1109 } 1110 1111 ParentTable = DtPeekSubtable (); 1112 DtInsertSubtable (ParentTable, Subtable); 1113 PciPathLength -= Subtable->Length; 1114 } 1115 1116 DtPopSubtable (); 1117 DeviceScopeLength -= DmarDeviceScope->Length; 1118 } 1119 1120 DtPopSubtable (); 1121 DtPopSubtable (); 1122 } 1123 1124 return (AE_OK); 1125 } 1126 1127 1128 /****************************************************************************** 1129 * 1130 * FUNCTION: DtCompileDrtm 1131 * 1132 * PARAMETERS: List - Current field list pointer 1133 * 1134 * RETURN: Status 1135 * 1136 * DESCRIPTION: Compile DRTM. 1137 * 1138 *****************************************************************************/ 1139 1140 ACPI_STATUS 1141 DtCompileDrtm ( 1142 void **List) 1143 { 1144 ACPI_STATUS Status; 1145 DT_SUBTABLE *Subtable; 1146 DT_SUBTABLE *ParentTable; 1147 DT_FIELD **PFieldList = (DT_FIELD **) List; 1148 UINT32 Count; 1149 /* ACPI_TABLE_DRTM *Drtm; */ 1150 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1151 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1152 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1153 1154 1155 ParentTable = DtPeekSubtable (); 1156 1157 /* Compile DRTM header */ 1158 1159 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1160 &Subtable); 1161 if (ACPI_FAILURE (Status)) 1162 { 1163 return (Status); 1164 } 1165 DtInsertSubtable (ParentTable, Subtable); 1166 1167 /* 1168 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1169 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1170 */ 1171 #if 0 1172 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1173 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1174 #endif 1175 /* Compile VTL */ 1176 1177 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1178 &Subtable); 1179 if (ACPI_FAILURE (Status)) 1180 { 1181 return (Status); 1182 } 1183 1184 DtInsertSubtable (ParentTable, Subtable); 1185 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1186 1187 DtPushSubtable (Subtable); 1188 ParentTable = DtPeekSubtable (); 1189 Count = 0; 1190 1191 while (*PFieldList) 1192 { 1193 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1194 &Subtable); 1195 if (ACPI_FAILURE (Status)) 1196 { 1197 return (Status); 1198 } 1199 if (!Subtable) 1200 { 1201 break; 1202 } 1203 DtInsertSubtable (ParentTable, Subtable); 1204 Count++; 1205 } 1206 1207 DrtmVtl->ValidatedTableCount = Count; 1208 DtPopSubtable (); 1209 ParentTable = DtPeekSubtable (); 1210 1211 /* Compile RL */ 1212 1213 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1214 &Subtable); 1215 if (ACPI_FAILURE (Status)) 1216 { 1217 return (Status); 1218 } 1219 1220 DtInsertSubtable (ParentTable, Subtable); 1221 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1222 1223 DtPushSubtable (Subtable); 1224 ParentTable = DtPeekSubtable (); 1225 Count = 0; 1226 1227 while (*PFieldList) 1228 { 1229 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1230 &Subtable); 1231 if (ACPI_FAILURE (Status)) 1232 { 1233 return (Status); 1234 } 1235 1236 if (!Subtable) 1237 { 1238 break; 1239 } 1240 1241 DtInsertSubtable (ParentTable, Subtable); 1242 Count++; 1243 } 1244 1245 DrtmRl->ResourceCount = Count; 1246 DtPopSubtable (); 1247 ParentTable = DtPeekSubtable (); 1248 1249 /* Compile DPS */ 1250 1251 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1252 &Subtable); 1253 if (ACPI_FAILURE (Status)) 1254 { 1255 return (Status); 1256 } 1257 DtInsertSubtable (ParentTable, Subtable); 1258 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1259 1260 1261 return (AE_OK); 1262 } 1263 1264 1265 /****************************************************************************** 1266 * 1267 * FUNCTION: DtCompileEinj 1268 * 1269 * PARAMETERS: List - Current field list pointer 1270 * 1271 * RETURN: Status 1272 * 1273 * DESCRIPTION: Compile EINJ. 1274 * 1275 *****************************************************************************/ 1276 1277 ACPI_STATUS 1278 DtCompileEinj ( 1279 void **List) 1280 { 1281 ACPI_STATUS Status; 1282 1283 1284 Status = DtCompileTwoSubtables (List, 1285 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1286 return (Status); 1287 } 1288 1289 1290 /****************************************************************************** 1291 * 1292 * FUNCTION: DtCompileErst 1293 * 1294 * PARAMETERS: List - Current field list pointer 1295 * 1296 * RETURN: Status 1297 * 1298 * DESCRIPTION: Compile ERST. 1299 * 1300 *****************************************************************************/ 1301 1302 ACPI_STATUS 1303 DtCompileErst ( 1304 void **List) 1305 { 1306 ACPI_STATUS Status; 1307 1308 1309 Status = DtCompileTwoSubtables (List, 1310 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 1311 return (Status); 1312 } 1313 1314 1315 /****************************************************************************** 1316 * 1317 * FUNCTION: DtCompileGtdt 1318 * 1319 * PARAMETERS: List - Current field list pointer 1320 * 1321 * RETURN: Status 1322 * 1323 * DESCRIPTION: Compile GTDT. 1324 * 1325 *****************************************************************************/ 1326 1327 ACPI_STATUS 1328 DtCompileGtdt ( 1329 void **List) 1330 { 1331 ACPI_STATUS Status; 1332 DT_SUBTABLE *Subtable; 1333 DT_SUBTABLE *ParentTable; 1334 DT_FIELD **PFieldList = (DT_FIELD **) List; 1335 DT_FIELD *SubtableStart; 1336 ACPI_SUBTABLE_HEADER *GtdtHeader; 1337 ACPI_DMTABLE_INFO *InfoTable; 1338 UINT32 GtCount; 1339 ACPI_TABLE_HEADER *Header; 1340 1341 1342 ParentTable = DtPeekSubtable (); 1343 1344 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1345 1346 /* Compile the main table */ 1347 1348 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1349 &Subtable); 1350 if (ACPI_FAILURE (Status)) 1351 { 1352 return (Status); 1353 } 1354 1355 /* GTDT revision 3 later contains 2 extra fields before subtables */ 1356 1357 if (Header->Revision > 2) 1358 { 1359 ParentTable = DtPeekSubtable (); 1360 DtInsertSubtable (ParentTable, Subtable); 1361 1362 Status = DtCompileTable (PFieldList, 1363 AcpiDmTableInfoGtdtEl2, &Subtable); 1364 if (ACPI_FAILURE (Status)) 1365 { 1366 return (Status); 1367 } 1368 } 1369 1370 ParentTable = DtPeekSubtable (); 1371 DtInsertSubtable (ParentTable, Subtable); 1372 1373 while (*PFieldList) 1374 { 1375 SubtableStart = *PFieldList; 1376 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1377 &Subtable); 1378 if (ACPI_FAILURE (Status)) 1379 { 1380 return (Status); 1381 } 1382 1383 ParentTable = DtPeekSubtable (); 1384 DtInsertSubtable (ParentTable, Subtable); 1385 DtPushSubtable (Subtable); 1386 1387 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1388 1389 switch (GtdtHeader->Type) 1390 { 1391 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1392 1393 InfoTable = AcpiDmTableInfoGtdt0; 1394 break; 1395 1396 case ACPI_GTDT_TYPE_WATCHDOG: 1397 1398 InfoTable = AcpiDmTableInfoGtdt1; 1399 break; 1400 1401 default: 1402 1403 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1404 return (AE_ERROR); 1405 } 1406 1407 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1408 if (ACPI_FAILURE (Status)) 1409 { 1410 return (Status); 1411 } 1412 1413 ParentTable = DtPeekSubtable (); 1414 DtInsertSubtable (ParentTable, Subtable); 1415 1416 /* 1417 * Additional GT block subtable data 1418 */ 1419 1420 switch (GtdtHeader->Type) 1421 { 1422 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1423 1424 DtPushSubtable (Subtable); 1425 ParentTable = DtPeekSubtable (); 1426 1427 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1428 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1429 1430 while (GtCount) 1431 { 1432 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1433 &Subtable); 1434 if (ACPI_FAILURE (Status)) 1435 { 1436 return (Status); 1437 } 1438 1439 DtInsertSubtable (ParentTable, Subtable); 1440 GtCount--; 1441 } 1442 1443 DtPopSubtable (); 1444 break; 1445 1446 default: 1447 1448 break; 1449 } 1450 1451 DtPopSubtable (); 1452 } 1453 1454 return (AE_OK); 1455 } 1456 1457 1458 /****************************************************************************** 1459 * 1460 * FUNCTION: DtCompileFpdt 1461 * 1462 * PARAMETERS: List - Current field list pointer 1463 * 1464 * RETURN: Status 1465 * 1466 * DESCRIPTION: Compile FPDT. 1467 * 1468 *****************************************************************************/ 1469 1470 ACPI_STATUS 1471 DtCompileFpdt ( 1472 void **List) 1473 { 1474 ACPI_STATUS Status; 1475 ACPI_FPDT_HEADER *FpdtHeader; 1476 DT_SUBTABLE *Subtable; 1477 DT_SUBTABLE *ParentTable; 1478 ACPI_DMTABLE_INFO *InfoTable; 1479 DT_FIELD **PFieldList = (DT_FIELD **) List; 1480 DT_FIELD *SubtableStart; 1481 1482 1483 while (*PFieldList) 1484 { 1485 SubtableStart = *PFieldList; 1486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1487 &Subtable); 1488 if (ACPI_FAILURE (Status)) 1489 { 1490 return (Status); 1491 } 1492 1493 ParentTable = DtPeekSubtable (); 1494 DtInsertSubtable (ParentTable, Subtable); 1495 DtPushSubtable (Subtable); 1496 1497 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1498 1499 switch (FpdtHeader->Type) 1500 { 1501 case ACPI_FPDT_TYPE_BOOT: 1502 1503 InfoTable = AcpiDmTableInfoFpdt0; 1504 break; 1505 1506 case ACPI_FPDT_TYPE_S3PERF: 1507 1508 InfoTable = AcpiDmTableInfoFpdt1; 1509 break; 1510 1511 default: 1512 1513 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1514 return (AE_ERROR); 1515 break; 1516 } 1517 1518 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1519 if (ACPI_FAILURE (Status)) 1520 { 1521 return (Status); 1522 } 1523 1524 ParentTable = DtPeekSubtable (); 1525 DtInsertSubtable (ParentTable, Subtable); 1526 DtPopSubtable (); 1527 } 1528 1529 return (AE_OK); 1530 } 1531 1532 1533 /****************************************************************************** 1534 * 1535 * FUNCTION: DtCompileHest 1536 * 1537 * PARAMETERS: List - Current field list pointer 1538 * 1539 * RETURN: Status 1540 * 1541 * DESCRIPTION: Compile HEST. 1542 * 1543 *****************************************************************************/ 1544 1545 ACPI_STATUS 1546 DtCompileHest ( 1547 void **List) 1548 { 1549 ACPI_STATUS Status; 1550 DT_SUBTABLE *Subtable; 1551 DT_SUBTABLE *ParentTable; 1552 DT_FIELD **PFieldList = (DT_FIELD **) List; 1553 DT_FIELD *SubtableStart; 1554 ACPI_DMTABLE_INFO *InfoTable; 1555 UINT16 Type; 1556 UINT32 BankCount; 1557 1558 1559 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1560 &Subtable); 1561 if (ACPI_FAILURE (Status)) 1562 { 1563 return (Status); 1564 } 1565 1566 ParentTable = DtPeekSubtable (); 1567 DtInsertSubtable (ParentTable, Subtable); 1568 1569 while (*PFieldList) 1570 { 1571 /* Get subtable type */ 1572 1573 SubtableStart = *PFieldList; 1574 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1575 1576 switch (Type) 1577 { 1578 case ACPI_HEST_TYPE_IA32_CHECK: 1579 1580 InfoTable = AcpiDmTableInfoHest0; 1581 break; 1582 1583 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1584 1585 InfoTable = AcpiDmTableInfoHest1; 1586 break; 1587 1588 case ACPI_HEST_TYPE_IA32_NMI: 1589 1590 InfoTable = AcpiDmTableInfoHest2; 1591 break; 1592 1593 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1594 1595 InfoTable = AcpiDmTableInfoHest6; 1596 break; 1597 1598 case ACPI_HEST_TYPE_AER_ENDPOINT: 1599 1600 InfoTable = AcpiDmTableInfoHest7; 1601 break; 1602 1603 case ACPI_HEST_TYPE_AER_BRIDGE: 1604 1605 InfoTable = AcpiDmTableInfoHest8; 1606 break; 1607 1608 case ACPI_HEST_TYPE_GENERIC_ERROR: 1609 1610 InfoTable = AcpiDmTableInfoHest9; 1611 break; 1612 1613 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1614 1615 InfoTable = AcpiDmTableInfoHest10; 1616 break; 1617 1618 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1619 1620 InfoTable = AcpiDmTableInfoHest11; 1621 break; 1622 1623 default: 1624 1625 /* Cannot continue on unknown type */ 1626 1627 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1628 return (AE_ERROR); 1629 } 1630 1631 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1632 if (ACPI_FAILURE (Status)) 1633 { 1634 return (Status); 1635 } 1636 1637 DtInsertSubtable (ParentTable, Subtable); 1638 1639 /* 1640 * Additional subtable data - IA32 Error Bank(s) 1641 */ 1642 BankCount = 0; 1643 switch (Type) 1644 { 1645 case ACPI_HEST_TYPE_IA32_CHECK: 1646 1647 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1648 Subtable->Buffer))->NumHardwareBanks; 1649 break; 1650 1651 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1652 1653 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1654 Subtable->Buffer))->NumHardwareBanks; 1655 break; 1656 1657 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1658 1659 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1660 Subtable->Buffer))->NumHardwareBanks; 1661 break; 1662 1663 default: 1664 1665 break; 1666 } 1667 1668 while (BankCount) 1669 { 1670 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1671 &Subtable); 1672 if (ACPI_FAILURE (Status)) 1673 { 1674 return (Status); 1675 } 1676 1677 DtInsertSubtable (ParentTable, Subtable); 1678 BankCount--; 1679 } 1680 } 1681 1682 return (AE_OK); 1683 } 1684 1685 1686 /****************************************************************************** 1687 * 1688 * FUNCTION: DtCompileHmat 1689 * 1690 * PARAMETERS: List - Current field list pointer 1691 * 1692 * RETURN: Status 1693 * 1694 * DESCRIPTION: Compile HMAT. 1695 * 1696 *****************************************************************************/ 1697 1698 ACPI_STATUS 1699 DtCompileHmat ( 1700 void **List) 1701 { 1702 ACPI_STATUS Status; 1703 DT_SUBTABLE *Subtable; 1704 DT_SUBTABLE *ParentTable; 1705 DT_FIELD **PFieldList = (DT_FIELD **) List; 1706 DT_FIELD *SubtableStart; 1707 DT_FIELD *EntryStart; 1708 ACPI_HMAT_STRUCTURE *HmatStruct; 1709 ACPI_HMAT_LOCALITY *HmatLocality; 1710 ACPI_HMAT_CACHE *HmatCache; 1711 ACPI_DMTABLE_INFO *InfoTable; 1712 UINT32 IntPDNumber; 1713 UINT32 TgtPDNumber; 1714 UINT64 EntryNumber; 1715 UINT16 SMBIOSHandleNumber; 1716 1717 1718 ParentTable = DtPeekSubtable (); 1719 1720 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1721 &Subtable); 1722 if (ACPI_FAILURE (Status)) 1723 { 1724 return (Status); 1725 } 1726 DtInsertSubtable (ParentTable, Subtable); 1727 1728 while (*PFieldList) 1729 { 1730 /* Compile HMAT structure header */ 1731 1732 SubtableStart = *PFieldList; 1733 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1734 &Subtable); 1735 if (ACPI_FAILURE (Status)) 1736 { 1737 return (Status); 1738 } 1739 DtInsertSubtable (ParentTable, Subtable); 1740 1741 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1742 HmatStruct->Length = Subtable->Length; 1743 1744 /* Compile HMAT structure body */ 1745 1746 switch (HmatStruct->Type) 1747 { 1748 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1749 1750 InfoTable = AcpiDmTableInfoHmat0; 1751 break; 1752 1753 case ACPI_HMAT_TYPE_LOCALITY: 1754 1755 InfoTable = AcpiDmTableInfoHmat1; 1756 break; 1757 1758 case ACPI_HMAT_TYPE_CACHE: 1759 1760 InfoTable = AcpiDmTableInfoHmat2; 1761 break; 1762 1763 default: 1764 1765 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 1766 return (AE_ERROR); 1767 } 1768 1769 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1770 if (ACPI_FAILURE (Status)) 1771 { 1772 return (Status); 1773 } 1774 DtInsertSubtable (ParentTable, Subtable); 1775 HmatStruct->Length += Subtable->Length; 1776 1777 /* Compile HMAT structure additionals */ 1778 1779 switch (HmatStruct->Type) 1780 { 1781 case ACPI_HMAT_TYPE_LOCALITY: 1782 1783 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 1784 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1785 1786 /* Compile initiator proximity domain list */ 1787 1788 IntPDNumber = 0; 1789 while (*PFieldList) 1790 { 1791 Status = DtCompileTable (PFieldList, 1792 AcpiDmTableInfoHmat1a, &Subtable); 1793 if (ACPI_FAILURE (Status)) 1794 { 1795 return (Status); 1796 } 1797 if (!Subtable) 1798 { 1799 break; 1800 } 1801 DtInsertSubtable (ParentTable, Subtable); 1802 HmatStruct->Length += Subtable->Length; 1803 IntPDNumber++; 1804 } 1805 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 1806 1807 /* Compile target proximity domain list */ 1808 1809 TgtPDNumber = 0; 1810 while (*PFieldList) 1811 { 1812 Status = DtCompileTable (PFieldList, 1813 AcpiDmTableInfoHmat1b, &Subtable); 1814 if (ACPI_FAILURE (Status)) 1815 { 1816 return (Status); 1817 } 1818 if (!Subtable) 1819 { 1820 break; 1821 } 1822 DtInsertSubtable (ParentTable, Subtable); 1823 HmatStruct->Length += Subtable->Length; 1824 TgtPDNumber++; 1825 } 1826 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 1827 1828 /* Save start of the entries for reporting errors */ 1829 1830 EntryStart = *PFieldList; 1831 1832 /* Compile latency/bandwidth entries */ 1833 1834 EntryNumber = 0; 1835 while (*PFieldList) 1836 { 1837 Status = DtCompileTable (PFieldList, 1838 AcpiDmTableInfoHmat1c, &Subtable); 1839 if (ACPI_FAILURE (Status)) 1840 { 1841 return (Status); 1842 } 1843 if (!Subtable) 1844 { 1845 break; 1846 } 1847 DtInsertSubtable (ParentTable, Subtable); 1848 HmatStruct->Length += Subtable->Length; 1849 EntryNumber++; 1850 } 1851 1852 /* Validate number of entries */ 1853 1854 if (EntryNumber != 1855 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 1856 { 1857 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 1858 return (AE_ERROR); 1859 } 1860 break; 1861 1862 case ACPI_HMAT_TYPE_CACHE: 1863 1864 /* Compile SMBIOS handles */ 1865 1866 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 1867 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1868 SMBIOSHandleNumber = 0; 1869 while (*PFieldList) 1870 { 1871 Status = DtCompileTable (PFieldList, 1872 AcpiDmTableInfoHmat2a, &Subtable); 1873 if (ACPI_FAILURE (Status)) 1874 { 1875 return (Status); 1876 } 1877 if (!Subtable) 1878 { 1879 break; 1880 } 1881 DtInsertSubtable (ParentTable, Subtable); 1882 HmatStruct->Length += Subtable->Length; 1883 SMBIOSHandleNumber++; 1884 } 1885 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 1886 break; 1887 1888 default: 1889 1890 break; 1891 } 1892 } 1893 1894 return (AE_OK); 1895 } 1896 1897 1898 /****************************************************************************** 1899 * 1900 * FUNCTION: DtCompileIort 1901 * 1902 * PARAMETERS: List - Current field list pointer 1903 * 1904 * RETURN: Status 1905 * 1906 * DESCRIPTION: Compile IORT. 1907 * 1908 *****************************************************************************/ 1909 1910 ACPI_STATUS 1911 DtCompileIort ( 1912 void **List) 1913 { 1914 ACPI_STATUS Status; 1915 DT_SUBTABLE *Subtable; 1916 DT_SUBTABLE *ParentTable; 1917 DT_FIELD **PFieldList = (DT_FIELD **) List; 1918 DT_FIELD *SubtableStart; 1919 ACPI_TABLE_HEADER *Table; 1920 ACPI_TABLE_IORT *Iort; 1921 ACPI_IORT_NODE *IortNode; 1922 ACPI_IORT_ITS_GROUP *IortItsGroup; 1923 ACPI_IORT_SMMU *IortSmmu; 1924 ACPI_IORT_RMR *IortRmr; 1925 UINT32 NodeNumber; 1926 UINT32 NodeLength; 1927 UINT32 IdMappingNumber; 1928 UINT32 ItsNumber; 1929 UINT32 ContextIrptNumber; 1930 UINT32 PmuIrptNumber; 1931 UINT32 PaddingLength; 1932 UINT8 Revision; 1933 UINT32 RmrCount; 1934 1935 1936 ParentTable = DtPeekSubtable (); 1937 1938 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1939 &Subtable); 1940 if (ACPI_FAILURE (Status)) 1941 { 1942 return (Status); 1943 } 1944 DtInsertSubtable (ParentTable, Subtable); 1945 1946 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1947 Revision = Table->Revision; 1948 1949 /* IORT Revisions E, E.a & E.c have known issues and are not supported */ 1950 1951 if (Revision == 1 || Revision == 2 || Revision == 4) 1952 { 1953 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 1954 return (AE_ERROR); 1955 } 1956 1957 /* 1958 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1959 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1960 */ 1961 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1962 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1963 1964 /* 1965 * OptionalPadding - Variable-length data 1966 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1967 * Optionally allows the generic data types to be used for filling 1968 * this field. 1969 */ 1970 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1971 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1972 &Subtable); 1973 if (ACPI_FAILURE (Status)) 1974 { 1975 return (Status); 1976 } 1977 if (Subtable) 1978 { 1979 DtInsertSubtable (ParentTable, Subtable); 1980 Iort->NodeOffset += Subtable->Length; 1981 } 1982 else 1983 { 1984 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1985 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1986 if (ACPI_FAILURE (Status)) 1987 { 1988 return (Status); 1989 } 1990 Iort->NodeOffset += PaddingLength; 1991 } 1992 1993 NodeNumber = 0; 1994 while (*PFieldList) 1995 { 1996 SubtableStart = *PFieldList; 1997 if (Revision == 0) 1998 { 1999 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 2000 &Subtable); 2001 } 2002 else if (Revision >= 3) 2003 { 2004 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 2005 &Subtable); 2006 } 2007 2008 if (ACPI_FAILURE (Status)) 2009 { 2010 return (Status); 2011 } 2012 2013 DtInsertSubtable (ParentTable, Subtable); 2014 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 2015 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 2016 2017 DtPushSubtable (Subtable); 2018 ParentTable = DtPeekSubtable (); 2019 2020 switch (IortNode->Type) 2021 { 2022 case ACPI_IORT_NODE_ITS_GROUP: 2023 2024 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 2025 &Subtable); 2026 if (ACPI_FAILURE (Status)) 2027 { 2028 return (Status); 2029 } 2030 2031 DtInsertSubtable (ParentTable, Subtable); 2032 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 2033 NodeLength += Subtable->Length; 2034 2035 ItsNumber = 0; 2036 while (*PFieldList) 2037 { 2038 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 2039 &Subtable); 2040 if (ACPI_FAILURE (Status)) 2041 { 2042 return (Status); 2043 } 2044 if (!Subtable) 2045 { 2046 break; 2047 } 2048 2049 DtInsertSubtable (ParentTable, Subtable); 2050 NodeLength += Subtable->Length; 2051 ItsNumber++; 2052 } 2053 2054 IortItsGroup->ItsCount = ItsNumber; 2055 break; 2056 2057 case ACPI_IORT_NODE_NAMED_COMPONENT: 2058 2059 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 2060 &Subtable); 2061 if (ACPI_FAILURE (Status)) 2062 { 2063 return (Status); 2064 } 2065 2066 DtInsertSubtable (ParentTable, Subtable); 2067 NodeLength += Subtable->Length; 2068 2069 /* 2070 * Padding - Variable-length data 2071 * Optionally allows the offset of the ID mappings to be used 2072 * for filling this field. 2073 */ 2074 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 2075 &Subtable); 2076 if (ACPI_FAILURE (Status)) 2077 { 2078 return (Status); 2079 } 2080 2081 if (Subtable) 2082 { 2083 DtInsertSubtable (ParentTable, Subtable); 2084 NodeLength += Subtable->Length; 2085 } 2086 else 2087 { 2088 if (NodeLength > IortNode->MappingOffset) 2089 { 2090 return (AE_BAD_DATA); 2091 } 2092 2093 if (NodeLength < IortNode->MappingOffset) 2094 { 2095 Status = DtCompilePadding ( 2096 IortNode->MappingOffset - NodeLength, 2097 &Subtable); 2098 if (ACPI_FAILURE (Status)) 2099 { 2100 return (Status); 2101 } 2102 2103 DtInsertSubtable (ParentTable, Subtable); 2104 NodeLength = IortNode->MappingOffset; 2105 } 2106 } 2107 break; 2108 2109 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 2110 2111 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 2112 &Subtable); 2113 if (ACPI_FAILURE (Status)) 2114 { 2115 return (Status); 2116 } 2117 2118 DtInsertSubtable (ParentTable, Subtable); 2119 NodeLength += Subtable->Length; 2120 break; 2121 2122 case ACPI_IORT_NODE_SMMU: 2123 2124 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 2125 &Subtable); 2126 if (ACPI_FAILURE (Status)) 2127 { 2128 return (Status); 2129 } 2130 2131 DtInsertSubtable (ParentTable, Subtable); 2132 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 2133 NodeLength += Subtable->Length; 2134 2135 /* Compile global interrupt array */ 2136 2137 IortSmmu->GlobalInterruptOffset = NodeLength; 2138 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 2139 &Subtable); 2140 if (ACPI_FAILURE (Status)) 2141 { 2142 return (Status); 2143 } 2144 2145 DtInsertSubtable (ParentTable, Subtable); 2146 NodeLength += Subtable->Length; 2147 2148 /* Compile context interrupt array */ 2149 2150 ContextIrptNumber = 0; 2151 IortSmmu->ContextInterruptOffset = NodeLength; 2152 while (*PFieldList) 2153 { 2154 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2155 &Subtable); 2156 if (ACPI_FAILURE (Status)) 2157 { 2158 return (Status); 2159 } 2160 2161 if (!Subtable) 2162 { 2163 break; 2164 } 2165 2166 DtInsertSubtable (ParentTable, Subtable); 2167 NodeLength += Subtable->Length; 2168 ContextIrptNumber++; 2169 } 2170 2171 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2172 2173 /* Compile PMU interrupt array */ 2174 2175 PmuIrptNumber = 0; 2176 IortSmmu->PmuInterruptOffset = NodeLength; 2177 while (*PFieldList) 2178 { 2179 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2180 &Subtable); 2181 if (ACPI_FAILURE (Status)) 2182 { 2183 return (Status); 2184 } 2185 2186 if (!Subtable) 2187 { 2188 break; 2189 } 2190 2191 DtInsertSubtable (ParentTable, Subtable); 2192 NodeLength += Subtable->Length; 2193 PmuIrptNumber++; 2194 } 2195 2196 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2197 break; 2198 2199 case ACPI_IORT_NODE_SMMU_V3: 2200 2201 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2202 &Subtable); 2203 if (ACPI_FAILURE (Status)) 2204 { 2205 return (Status); 2206 } 2207 2208 DtInsertSubtable (ParentTable, Subtable); 2209 NodeLength += Subtable->Length; 2210 break; 2211 2212 case ACPI_IORT_NODE_PMCG: 2213 2214 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2215 &Subtable); 2216 if (ACPI_FAILURE (Status)) 2217 { 2218 return (Status); 2219 } 2220 2221 DtInsertSubtable (ParentTable, Subtable); 2222 NodeLength += Subtable->Length; 2223 break; 2224 2225 case ACPI_IORT_NODE_RMR: 2226 2227 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2228 &Subtable); 2229 if (ACPI_FAILURE (Status)) 2230 { 2231 return (Status); 2232 } 2233 2234 DtInsertSubtable (ParentTable, Subtable); 2235 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2236 NodeLength += Subtable->Length; 2237 2238 /* Compile RMR Descriptors */ 2239 2240 RmrCount = 0; 2241 IortRmr->RmrOffset = NodeLength; 2242 while (*PFieldList) 2243 { 2244 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2245 &Subtable); 2246 if (ACPI_FAILURE (Status)) 2247 { 2248 return (Status); 2249 } 2250 2251 if (!Subtable) 2252 { 2253 break; 2254 } 2255 2256 DtInsertSubtable (ParentTable, Subtable); 2257 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2258 RmrCount++; 2259 } 2260 2261 IortRmr->RmrCount = RmrCount; 2262 break; 2263 2264 default: 2265 2266 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 2267 return (AE_ERROR); 2268 } 2269 2270 /* Compile Array of ID mappings */ 2271 2272 IortNode->MappingOffset = NodeLength; 2273 IdMappingNumber = 0; 2274 while (*PFieldList) 2275 { 2276 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 2277 &Subtable); 2278 if (ACPI_FAILURE (Status)) 2279 { 2280 return (Status); 2281 } 2282 2283 if (!Subtable) 2284 { 2285 break; 2286 } 2287 2288 DtInsertSubtable (ParentTable, Subtable); 2289 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 2290 IdMappingNumber++; 2291 } 2292 2293 IortNode->MappingCount = IdMappingNumber; 2294 if (!IdMappingNumber) 2295 { 2296 IortNode->MappingOffset = 0; 2297 } 2298 2299 /* 2300 * Node length can be determined by DT_LENGTH option 2301 * IortNode->Length = NodeLength; 2302 */ 2303 DtPopSubtable (); 2304 ParentTable = DtPeekSubtable (); 2305 NodeNumber++; 2306 } 2307 2308 Iort->NodeCount = NodeNumber; 2309 return (AE_OK); 2310 } 2311 2312 2313 /****************************************************************************** 2314 * 2315 * FUNCTION: DtCompileIvrs 2316 * 2317 * PARAMETERS: List - Current field list pointer 2318 * 2319 * RETURN: Status 2320 * 2321 * DESCRIPTION: Compile IVRS. Notes: 2322 * The IVRS is essentially a flat table, with the following 2323 * structure: 2324 * <Main ACPI Table Header> 2325 * <Main subtable - virtualization info> 2326 * <IVHD> 2327 * <Device Entries> 2328 * ... 2329 * <IVHD> 2330 * <Device Entries> 2331 * <IVMD> 2332 * ... 2333 * 2334 *****************************************************************************/ 2335 2336 ACPI_STATUS 2337 DtCompileIvrs ( 2338 void **List) 2339 { 2340 ACPI_STATUS Status; 2341 DT_SUBTABLE *Subtable; 2342 DT_SUBTABLE *ParentTable; 2343 DT_SUBTABLE *MainSubtable; 2344 DT_FIELD **PFieldList = (DT_FIELD **) List; 2345 DT_FIELD *SubtableStart; 2346 ACPI_DMTABLE_INFO *InfoTable = NULL; 2347 UINT8 SubtableType; 2348 UINT8 Temp64[16]; 2349 UINT8 Temp8; 2350 2351 2352 /* Main table */ 2353 2354 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 2355 &Subtable); 2356 if (ACPI_FAILURE (Status)) 2357 { 2358 return (Status); 2359 } 2360 2361 ParentTable = DtPeekSubtable (); 2362 DtInsertSubtable (ParentTable, Subtable); 2363 DtPushSubtable (Subtable); 2364 2365 /* Save a pointer to the main subtable */ 2366 2367 MainSubtable = Subtable; 2368 2369 while (*PFieldList) 2370 { 2371 SubtableStart = *PFieldList; 2372 2373 /* Compile the SubtableType integer */ 2374 2375 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 2376 2377 switch (SubtableType) 2378 { 2379 2380 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 2381 2382 case ACPI_IVRS_TYPE_HARDWARE1: 2383 2384 InfoTable = AcpiDmTableInfoIvrsHware1; 2385 break; 2386 2387 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 2388 2389 case ACPI_IVRS_TYPE_HARDWARE2: 2390 case ACPI_IVRS_TYPE_HARDWARE3: 2391 2392 InfoTable = AcpiDmTableInfoIvrsHware23; 2393 break; 2394 2395 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 2396 2397 case ACPI_IVRS_TYPE_MEMORY1: 2398 case ACPI_IVRS_TYPE_MEMORY2: 2399 case ACPI_IVRS_TYPE_MEMORY3: 2400 2401 InfoTable = AcpiDmTableInfoIvrsMemory; 2402 break; 2403 2404 /* 4-byte device entries */ 2405 2406 case ACPI_IVRS_TYPE_PAD4: 2407 case ACPI_IVRS_TYPE_ALL: 2408 case ACPI_IVRS_TYPE_SELECT: 2409 case ACPI_IVRS_TYPE_START: 2410 case ACPI_IVRS_TYPE_END: 2411 2412 InfoTable = AcpiDmTableInfoIvrs4; 2413 break; 2414 2415 /* 8-byte device entries, type A */ 2416 2417 case ACPI_IVRS_TYPE_ALIAS_SELECT: 2418 case ACPI_IVRS_TYPE_ALIAS_START: 2419 2420 InfoTable = AcpiDmTableInfoIvrs8a; 2421 break; 2422 2423 /* 8-byte device entries, type B */ 2424 2425 case ACPI_IVRS_TYPE_EXT_SELECT: 2426 case ACPI_IVRS_TYPE_EXT_START: 2427 2428 InfoTable = AcpiDmTableInfoIvrs8b; 2429 break; 2430 2431 /* 8-byte device entries, type C */ 2432 2433 case ACPI_IVRS_TYPE_SPECIAL: 2434 2435 InfoTable = AcpiDmTableInfoIvrs8c; 2436 break; 2437 2438 /* Variable device entries, type F0h */ 2439 2440 case ACPI_IVRS_TYPE_HID: 2441 2442 InfoTable = AcpiDmTableInfoIvrsHid; 2443 break; 2444 2445 default: 2446 2447 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 2448 "IVRS Device Entry"); 2449 return (AE_ERROR); 2450 } 2451 2452 /* Compile the InfoTable from above */ 2453 2454 Status = DtCompileTable (PFieldList, InfoTable, 2455 &Subtable); 2456 if (ACPI_FAILURE (Status)) 2457 { 2458 return (Status); 2459 } 2460 2461 ParentTable = DtPeekSubtable (); 2462 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 2463 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 2464 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 2465 SubtableType != ACPI_IVRS_TYPE_HID && 2466 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 2467 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 2468 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 2469 { 2470 if (ParentTable) 2471 DtInsertSubtable (ParentTable, Subtable); 2472 } 2473 2474 switch (SubtableType) 2475 { 2476 case ACPI_IVRS_TYPE_HARDWARE1: 2477 case ACPI_IVRS_TYPE_HARDWARE2: 2478 case ACPI_IVRS_TYPE_HARDWARE3: 2479 case ACPI_IVRS_TYPE_MEMORY1: 2480 case ACPI_IVRS_TYPE_MEMORY2: 2481 case ACPI_IVRS_TYPE_MEMORY3: 2482 2483 /* Insert these IVHDs/IVMDs at the root subtable */ 2484 2485 DtInsertSubtable (MainSubtable, Subtable); 2486 DtPushSubtable (Subtable); 2487 ParentTable = MainSubtable; 2488 break; 2489 2490 case ACPI_IVRS_TYPE_HID: 2491 2492 /* Special handling for the HID named device entry (0xF0) */ 2493 2494 if (ParentTable) 2495 { 2496 DtInsertSubtable (ParentTable, Subtable); 2497 } 2498 2499 /* 2500 * Process the HID value. First, get the HID value as a string. 2501 */ 2502 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2503 2504 /* 2505 * Determine if the HID is an integer or a string. 2506 * An integer is defined to be 32 bits, with the upper 32 bits 2507 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 2508 * integer or a character string. If an integer, the lower 2509 * 4 bytes of the field contain the integer and the upper 2510 * 4 bytes are padded with 0". 2511 */ 2512 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2513 { 2514 /* Compile the HID value as an integer */ 2515 2516 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2517 2518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 2519 &Subtable); 2520 if (ACPI_FAILURE (Status)) 2521 { 2522 return (Status); 2523 } 2524 } 2525 else 2526 { 2527 /* Compile the HID value as a string */ 2528 2529 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 2530 &Subtable); 2531 if (ACPI_FAILURE (Status)) 2532 { 2533 return (Status); 2534 } 2535 } 2536 2537 DtInsertSubtable (ParentTable, Subtable); 2538 2539 /* 2540 * Process the CID value. First, get the CID value as a string. 2541 */ 2542 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2543 2544 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2545 { 2546 /* Compile the CID value as an integer */ 2547 2548 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2549 2550 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 2551 &Subtable); 2552 if (ACPI_FAILURE (Status)) 2553 { 2554 return (Status); 2555 } 2556 } 2557 else 2558 { 2559 /* Compile the CID value as a string */ 2560 2561 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 2562 &Subtable); 2563 if (ACPI_FAILURE (Status)) 2564 { 2565 return (Status); 2566 } 2567 } 2568 2569 DtInsertSubtable (ParentTable, Subtable); 2570 2571 /* 2572 * Process the UID value. First, get and decode the "UID Format" field (Integer). 2573 */ 2574 if (!*PFieldList) 2575 { 2576 return (AE_OK); 2577 } 2578 2579 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 2580 2581 switch (Temp8) 2582 { 2583 case ACPI_IVRS_UID_NOT_PRESENT: 2584 break; 2585 2586 case ACPI_IVRS_UID_IS_INTEGER: 2587 2588 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 2589 &Subtable); 2590 if (ACPI_FAILURE (Status)) 2591 { 2592 return (Status); 2593 } 2594 DtInsertSubtable (ParentTable, Subtable); 2595 break; 2596 2597 case ACPI_IVRS_UID_IS_STRING: 2598 2599 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 2600 &Subtable); 2601 if (ACPI_FAILURE (Status)) 2602 { 2603 return (Status); 2604 } 2605 DtInsertSubtable (ParentTable, Subtable); 2606 break; 2607 2608 default: 2609 2610 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 2611 "IVRS Device Entry"); 2612 return (AE_ERROR); 2613 } 2614 2615 default: 2616 2617 /* All other subtable types come through here */ 2618 break; 2619 } 2620 } 2621 2622 return (AE_OK); 2623 } 2624