1 /** @file 2 Update the _PRT and _PRW method for pci devices 3 4 Copyright (c) 2013-2016 Intel Corporation. 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 15 **/ 16 #include "AcpiPlatform.h" 17 18 PCI_DEVICE_INFO *mQNCPciInfo = NULL; 19 20 /** 21 Init Pci Device Structure 22 @param mConfigData - Pointer of Pci Device information Structure 23 24 **/ 25 VOID 26 InitPciDeviceInfoStructure ( 27 PCI_DEVICE_SETTING *mConfigData 28 ) 29 { 30 // 31 // Return 0 given that function unsupported. 32 // Would need to parse ACPI tables and build mQNCPciInfo above 33 // with found _PRT & _PRW methods for PCI devices. 34 // 35 mConfigData->PciDeviceInfoNumber = 0; 36 } 37 38 /** 39 return Integer value. 40 41 @param Data - AML data buffer 42 @param Integer - integer value. 43 44 @return Data size processed. 45 **/ 46 UINTN 47 SdtGetInteger ( 48 IN UINT8 *Data, 49 OUT UINT64 *Integer 50 ) 51 { 52 *Integer = 0; 53 switch (*Data) { 54 case AML_ZERO_OP: 55 return 1; 56 case AML_ONE_OP: 57 *Integer = 1; 58 return 1; 59 case AML_ONES_OP: 60 *Integer = (UINTN)-1; 61 return 1; 62 case AML_BYTE_PREFIX: 63 CopyMem (Integer, Data + 1, sizeof(UINT8)); 64 return 1 + sizeof(UINT8); 65 case AML_WORD_PREFIX: 66 CopyMem (Integer, Data + 1, sizeof(UINT16)); 67 return 1 + sizeof(UINT16); 68 case AML_DWORD_PREFIX: 69 CopyMem (Integer, Data + 1, sizeof(UINT32)); 70 return 1 + sizeof(UINT32); 71 case AML_QWORD_PREFIX: 72 CopyMem (Integer, Data + 1, sizeof(UINT64)); 73 return 1 + sizeof(UINT64); 74 default: 75 // Something wrong 76 ASSERT (FALSE); 77 return 1; 78 } 79 } 80 81 82 /** 83 Check if this handle has expected opcode. 84 85 @param AcpiSdt Pointer to Acpi SDT protocol 86 @param Handle ACPI handle 87 @param OpCode Expected OpCode 88 @param SubOpCode Expected SubOpCode 89 90 @retval TRUE This handle has expected opcode 91 @retval FALSE This handle does not have expected opcode 92 **/ 93 BOOLEAN 94 SdtIsThisTypeObject ( 95 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 96 IN EFI_ACPI_HANDLE Handle, 97 IN UINT8 OpCode, 98 IN UINT8 SubOpCode 99 ) 100 { 101 EFI_STATUS Status; 102 EFI_ACPI_DATA_TYPE DataType; 103 UINT8 *Data; 104 UINTN DataSize; 105 106 Status = AcpiSdt->GetOption (Handle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 107 ASSERT_EFI_ERROR (Status); 108 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 109 110 if (OpCode == AML_EXT_OP) { 111 if (Data[1] == SubOpCode) { 112 return TRUE; 113 } 114 } else { 115 if (Data[0] == OpCode) { 116 return TRUE; 117 } 118 } 119 return FALSE; 120 } 121 122 /** 123 Check if this handle has expected name and name value. 124 125 @param AcpiSdt Pointer to Acpi SDT protocol 126 @param Handle ACPI handle 127 @param Name Expected name 128 @param Value Expected name value 129 130 @retval TRUE This handle has expected name and name value. 131 @retval FALSE This handle does not have expected name and name value. 132 **/ 133 BOOLEAN 134 SdtIsNameIntegerValueEqual ( 135 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 136 IN EFI_ACPI_HANDLE Handle, 137 IN CHAR8 *Name, 138 IN UINT64 Value 139 ) 140 { 141 EFI_STATUS Status; 142 EFI_ACPI_DATA_TYPE DataType; 143 UINT8 *Data; 144 UINTN DataSize; 145 UINT64 Integer; 146 147 Status = AcpiSdt->GetOption (Handle, 1, &DataType, (CONST VOID **)&Data, &DataSize); 148 ASSERT_EFI_ERROR (Status); 149 ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING); 150 151 if (CompareMem (Data, Name, 4) != 0) { 152 return FALSE; 153 } 154 155 // 156 // Name match check object 157 // 158 Status = AcpiSdt->GetOption (Handle, 2, &DataType, (CONST VOID **)&Data, &DataSize); 159 ASSERT_EFI_ERROR (Status); 160 161 Integer = 0; 162 SdtGetInteger (Data, &Integer); 163 if (Integer != Value) { 164 return FALSE; 165 } 166 167 // All match 168 return TRUE; 169 } 170 171 /** 172 Check if this handle's children has expected name and name value. 173 174 @param AcpiSdt Pointer to Acpi SDT protocol 175 @param ParentHandle ACPI parent handle 176 @param Name Expected name 177 @param Value Expected name value 178 179 @retval TRUE This handle's children has expected name and name value. 180 @retval FALSE This handle's children does not have expected name and name value. 181 **/ 182 BOOLEAN 183 SdtCheckNameIntegerValue ( 184 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 185 IN EFI_ACPI_HANDLE ParentHandle, 186 IN CHAR8 *Name, 187 IN UINT64 Value 188 ) 189 { 190 EFI_ACPI_HANDLE PreviousHandle; 191 EFI_ACPI_HANDLE Handle; 192 EFI_STATUS Status; 193 194 Handle = NULL; 195 while (TRUE) { 196 PreviousHandle = Handle; 197 Status = AcpiSdt->GetChild (ParentHandle, &Handle); 198 ASSERT_EFI_ERROR (Status); 199 200 if (PreviousHandle != NULL) { 201 Status = AcpiSdt->Close (PreviousHandle); 202 ASSERT_EFI_ERROR (Status); 203 } 204 205 // 206 // Done 207 // 208 if (Handle == NULL) { 209 return FALSE; 210 } 211 212 // 213 // Check this name 214 // 215 if (SdtIsThisTypeObject (AcpiSdt, Handle, AML_NAME_OP, 0)) { 216 if (SdtIsNameIntegerValueEqual (AcpiSdt, Handle, Name, Value)) { 217 return TRUE; 218 } 219 } 220 } 221 222 // 223 // Should not run here 224 // 225 } 226 227 /** 228 Convert the pci address from VPD (bus,dev,fun) into the address that acpi table 229 can recognize. 230 231 @param PciAddress Pci address from VPD 232 233 @retval return the address that acpi table can recognize 234 **/ 235 UINT32 236 SdtConvertToAcpiPciAdress ( 237 IN UINT32 PciAddress 238 ) 239 { 240 UINT32 ReturnAddress; 241 242 ReturnAddress = ((PciAddress & 0x0000FF00) << 8) | (PciAddress & 0x000000FF); 243 244 if ((PciAddress & 0x000000FF) == 0x000000FF) 245 ReturnAddress |= 0x0000FFFF; 246 247 return ReturnAddress; 248 } 249 250 /** 251 return AML NameString size. 252 253 @param Buffer - AML name string 254 255 @return AML name string size 256 **/ 257 UINTN 258 SdtGetNameStringSize ( 259 IN UINT8 *Buffer 260 ) 261 { 262 UINTN SegCount; 263 UINTN Length; 264 265 Length = 0; 266 267 // 268 // Parse root or prefix 269 // 270 if (*Buffer == AML_ROOT_CHAR) { 271 // 272 // RootChar 273 // 274 Buffer ++; 275 Length ++; 276 } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { 277 // 278 // ParentPrefixChar 279 // 280 Buffer ++; 281 Length ++; 282 while (*Buffer == AML_PARENT_PREFIX_CHAR) { 283 Buffer ++; 284 Length ++; 285 } 286 } 287 288 // 289 // Parse name segment 290 // 291 if (*Buffer == AML_DUAL_NAME_PREFIX) { 292 // 293 // DualName 294 // 295 Buffer ++; 296 Length ++; 297 SegCount = 2; 298 } else if (*Buffer == AML_MULTI_NAME_PREFIX) { 299 // 300 // MultiName 301 // 302 Buffer ++; 303 Length ++; 304 SegCount = *Buffer; 305 Buffer ++; 306 Length ++; 307 } else if (*Buffer == 0) { 308 // 309 // NULL Name 310 // 311 SegCount = 0; 312 Length ++; 313 } else { 314 // 315 // NameSeg 316 // 317 SegCount = 1; 318 } 319 320 Buffer += 4 * SegCount; 321 Length += 4 * SegCount; 322 323 return Length; 324 } 325 326 /** 327 The routine to check if this device is PCI root bridge. 328 329 @param AcpiSdt Pointer to Acpi SDT protocol 330 @param DeviceHandle ACPI device handle 331 @param Context Context info - not used here 332 333 @retval TRUE This is PCI root bridge 334 @retval FALSE This is not PCI root bridge 335 **/ 336 BOOLEAN 337 SdtFindRootBridgeHandle ( 338 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 339 IN EFI_ACPI_HANDLE CheckHandle, 340 IN VOID *Context 341 ) 342 { 343 BOOLEAN Result; 344 EFI_ACPI_DATA_TYPE DataType; 345 UINT8 *Data; 346 UINTN DataSize; 347 EFI_STATUS Status; 348 349 if (!SdtIsThisTypeObject (AcpiSdt, CheckHandle, AML_EXT_OP, AML_EXT_DEVICE_OP)) 350 return FALSE; 351 352 Result = SdtCheckNameIntegerValue (AcpiSdt,CheckHandle, "_HID", (UINT64)0x080AD041); // PNP0A08 353 if (!Result) { 354 Result = SdtCheckNameIntegerValue (AcpiSdt, CheckHandle, "_CID", (UINT64)0x030AD041); // PNP0A03 355 if (!Result) { 356 return Result; 357 } 358 } 359 360 // 361 // Found 362 // 363 Status = AcpiSdt->GetOption (CheckHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize); 364 ASSERT_EFI_ERROR (Status); 365 ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING); 366 367 return Result; 368 } 369 370 371 /** 372 The routine to check if this device is wanted. 373 374 @param AcpiSdt Pointer to Acpi SDT protocol 375 @param DeviceHandle ACPI device handle 376 @param Context Context info - not used here 377 378 @retval TRUE This is PCI device wanted 379 @retval FALSE This is not PCI device wanted 380 **/ 381 BOOLEAN 382 SdtFindPciDeviceHandle ( 383 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 384 IN EFI_ACPI_HANDLE CheckHandle, 385 IN VOID *Context 386 ) 387 { 388 BOOLEAN Result; 389 EFI_ACPI_DATA_TYPE DataType; 390 UINT8 *Data; 391 UINTN DataSize; 392 EFI_STATUS Status; 393 394 if (!SdtIsThisTypeObject (AcpiSdt, CheckHandle, AML_EXT_OP, AML_EXT_DEVICE_OP)) 395 return FALSE; 396 397 Result = SdtCheckNameIntegerValue (AcpiSdt,CheckHandle, "_ADR", (UINT64)*(UINT32 *)Context); 398 if (!Result) { 399 return Result; 400 } 401 402 // 403 // Found 404 // 405 Status = AcpiSdt->GetOption (CheckHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize); 406 ASSERT_EFI_ERROR (Status); 407 ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING); 408 409 return Result; 410 } 411 412 /** 413 Go through the parent handle and find the handle which pass CheckHandleInfo. 414 415 @param AcpiSdt Pointer to Acpi SDT protocol 416 @param ParentHandle ACPI parent handle 417 @param CheckHandleInfo The callback routine to check if this handle meet the requirement 418 @param Context The context of CheckHandleInfo 419 420 @return the handle which is first one can pass CheckHandleInfo. 421 **/ 422 EFI_ACPI_HANDLE 423 SdtGetHandleByScanAllChilds ( 424 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 425 IN EFI_ACPI_HANDLE ParentHandle, 426 IN CHECK_HANDLE_INFO CheckHandleInfo, 427 IN VOID *Context 428 ) 429 { 430 EFI_ACPI_HANDLE PreviousHandle; 431 EFI_ACPI_HANDLE Handle; 432 EFI_STATUS Status; 433 EFI_ACPI_HANDLE ReturnHandle; 434 435 // 436 // Use deep first algo to enumerate all ACPI object 437 // 438 Handle = NULL; 439 while (TRUE) { 440 PreviousHandle = Handle; 441 Status = AcpiSdt->GetChild (ParentHandle, &Handle); 442 ASSERT_EFI_ERROR (Status); 443 444 if (PreviousHandle != NULL) { 445 Status = AcpiSdt->Close (PreviousHandle); 446 ASSERT_EFI_ERROR (Status); 447 } 448 449 // 450 // Done 451 // 452 if (Handle == NULL) { 453 return NULL; 454 } 455 456 // 457 // Check this handle 458 // 459 if (CheckHandleInfo (AcpiSdt, Handle, Context)) { 460 return Handle; 461 } 462 463 // 464 // Enumerate 465 // 466 ReturnHandle = SdtGetHandleByScanAllChilds (AcpiSdt, Handle, CheckHandleInfo, Context); 467 if (ReturnHandle != NULL) { 468 return ReturnHandle; 469 } 470 } 471 472 // 473 // Should not run here 474 // 475 } 476 477 478 /** 479 Check whether the INTx package is matched 480 481 @param AcpiSdt Pointer to Acpi SDT protocol 482 @param INTxPkgHandle ACPI INTx package handle 483 @param PciAddress Acpi pci address 484 @param INTx Index of INTx pin 485 @param IsAPIC Tell whether the returned INTx package is for APIC or not 486 487 @retval TRUE the INTx package is matched 488 @retval FALSE the INTx package is not matched 489 490 **/ 491 BOOLEAN 492 SdtCheckINTxPkgIsMatch ( 493 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 494 IN EFI_ACPI_HANDLE INTxPkgHandle, 495 IN UINT32 PciAddress, 496 IN UINT8 INTx, 497 IN BOOLEAN *IsAPIC 498 ) 499 { 500 EFI_ACPI_HANDLE PreviousHandle; 501 EFI_STATUS Status; 502 EFI_ACPI_HANDLE MemberHandle; 503 EFI_ACPI_DATA_TYPE DataType; 504 UINT8 *Data; 505 UINTN DataSize; 506 UINT64 CurrentPciAddress; 507 UINT64 CurrentINTx; 508 UINTN ChildSize; 509 510 511 // 512 // Check the pci address 513 // 514 MemberHandle = NULL; 515 Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle); 516 ASSERT_EFI_ERROR (Status); 517 ASSERT (MemberHandle != NULL); 518 519 Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 520 ASSERT_EFI_ERROR (Status); 521 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 522 523 CurrentPciAddress = 0; 524 SdtGetInteger (Data, &CurrentPciAddress); 525 526 if (CurrentPciAddress != PciAddress) { 527 528 Status = AcpiSdt->Close (MemberHandle); 529 ASSERT_EFI_ERROR (Status); 530 return FALSE; 531 } 532 533 // 534 // Check the pci interrupt pin 535 // 536 PreviousHandle = MemberHandle; 537 Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle); 538 ASSERT_EFI_ERROR (Status); 539 ASSERT (MemberHandle != NULL); 540 541 if (PreviousHandle != NULL) { 542 Status = AcpiSdt->Close (PreviousHandle); 543 ASSERT_EFI_ERROR (Status); 544 } 545 546 Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 547 ASSERT_EFI_ERROR (Status); 548 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 549 550 CurrentINTx = 0; 551 ChildSize = SdtGetInteger (Data, &CurrentINTx); 552 553 Status = AcpiSdt->Close (MemberHandle); 554 ASSERT_EFI_ERROR (Status); 555 556 if (CurrentINTx != INTx) 557 return FALSE; 558 559 Data += ChildSize; 560 561 if (*Data == AML_BYTE_PREFIX) 562 Data += 1; 563 564 // 565 // Check the pci interrupt source 566 // 567 if (*Data != 0) 568 *IsAPIC = FALSE; 569 else 570 *IsAPIC = TRUE; 571 572 return TRUE; 573 } 574 575 576 577 578 /** 579 Get the wanted INTx package inside the parent package 580 581 @param AcpiSdt Pointer to Acpi SDT protocol 582 @param ParentPkgHandle ACPI parent package handle 583 @param PciAddress Acpi pci address 584 @param INTx Index of INTx pin 585 @param INTxPkgHandle ACPI INTx package handle 586 @param IsAPIC Tell whether the returned INTx package is for APIC or not 587 588 **/ 589 VOID 590 SdtGetINTxPkgHandle ( 591 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 592 IN EFI_ACPI_HANDLE ParentPkgHandle, 593 IN UINT32 PciAddress, 594 IN UINT8 INTx, 595 IN EFI_ACPI_HANDLE *INTxPkgHandle, 596 IN BOOLEAN *IsAPIC 597 ) 598 { 599 EFI_ACPI_HANDLE PreviousHandle; 600 EFI_STATUS Status; 601 EFI_ACPI_HANDLE ChildPkgHandle; 602 603 ChildPkgHandle = NULL; 604 while (TRUE) { 605 PreviousHandle = ChildPkgHandle; 606 Status = AcpiSdt->GetChild (ParentPkgHandle, &ChildPkgHandle); 607 ASSERT_EFI_ERROR (Status); 608 609 if (PreviousHandle != NULL) { 610 Status = AcpiSdt->Close (PreviousHandle); 611 ASSERT_EFI_ERROR (Status); 612 } 613 614 if (ChildPkgHandle == NULL) { 615 break; 616 } 617 618 if (SdtCheckINTxPkgIsMatch(AcpiSdt, ChildPkgHandle, PciAddress, INTx, IsAPIC)) { 619 *INTxPkgHandle = ChildPkgHandle; 620 return; 621 } 622 } 623 624 return; 625 } 626 627 /** 628 Update the INTx package with the correct pirq value 629 630 @param AcpiSdt Pointer to Acpi SDT protocol 631 @param INTxPkgHandle ACPI INTx package handle 632 @param PirqValue Correct pirq value 633 @param IsAPIC Tell whether the INTx package is for APIC or not 634 635 **/ 636 VOID 637 SdtUpdateINTxPkg ( 638 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 639 IN EFI_ACPI_HANDLE INTxPkgHandle, 640 IN UINT8 PirqValue, 641 IN BOOLEAN IsAPIC 642 ) 643 { 644 EFI_ACPI_HANDLE PreviousHandle; 645 EFI_STATUS Status; 646 EFI_ACPI_HANDLE MemberHandle; 647 EFI_ACPI_DATA_TYPE DataType; 648 UINT8 *Data; 649 UINTN DataSize; 650 UINT64 TempValue; 651 UINTN ChildSize; 652 653 654 // 655 // Check the pci address 656 // 657 MemberHandle = NULL; 658 Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle); 659 ASSERT_EFI_ERROR (Status); 660 ASSERT (MemberHandle != NULL); 661 662 // 663 // Check the pci interrupt pin 664 // 665 PreviousHandle = MemberHandle; 666 Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle); 667 ASSERT_EFI_ERROR (Status); 668 ASSERT (MemberHandle != NULL); 669 670 if (PreviousHandle != NULL) { 671 Status = AcpiSdt->Close (PreviousHandle); 672 ASSERT_EFI_ERROR (Status); 673 } 674 675 Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 676 ASSERT_EFI_ERROR (Status); 677 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 678 679 ChildSize = SdtGetInteger (Data, &TempValue); 680 681 Status = AcpiSdt->Close (MemberHandle); 682 ASSERT_EFI_ERROR (Status); 683 684 Data += ChildSize; 685 686 // 687 // update the pci interrupt source or source index 688 // 689 if (!IsAPIC) { 690 ChildSize = SdtGetNameStringSize (Data); 691 Data += (ChildSize - 1); 692 693 PirqValue += 0x40; // change to ascii char 694 if (*Data != PirqValue) 695 *Data = PirqValue; 696 } else { 697 698 ChildSize = SdtGetInteger (Data, &TempValue); 699 Data += ChildSize; 700 701 Data += 1; 702 703 if (*Data != PirqValue) 704 *Data = PirqValue; 705 } 706 } 707 708 /** 709 Check every child package inside this interested parent package for update PRT 710 711 @param AcpiSdt Pointer to Acpi SDT protocol 712 @param ParentPkgHandle ACPI parent package handle 713 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 714 715 **/ 716 VOID 717 SdtCheckParentPackage ( 718 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 719 IN EFI_ACPI_HANDLE ParentPkgHandle, 720 IN PCI_DEVICE_INFO *PciDeviceInfo 721 ) 722 { 723 EFI_ACPI_HANDLE INTAPkgHandle; 724 EFI_ACPI_HANDLE INTBPkgHandle; 725 EFI_ACPI_HANDLE INTCPkgHandle; 726 EFI_ACPI_HANDLE INTDPkgHandle; 727 UINT32 PciAddress = 0; 728 BOOLEAN IsAllFunctions = FALSE; 729 UINT8 IsAPIC = 0; 730 EFI_STATUS Status; 731 732 INTAPkgHandle = INTBPkgHandle = INTCPkgHandle = INTDPkgHandle = NULL; 733 734 PciAddress = SdtConvertToAcpiPciAdress(PciDeviceInfo->DeviceAddress); 735 736 if ((PciAddress & 0xFFFF) == 0xFFFF) { 737 IsAllFunctions = TRUE; 738 } else { 739 IsAllFunctions = FALSE; 740 PciAddress = (PciAddress | 0xFFFF); 741 } 742 743 SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 0, &INTAPkgHandle, (BOOLEAN *)&IsAPIC); 744 SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 1, &INTBPkgHandle, (BOOLEAN *)&IsAPIC); 745 SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 2, &INTCPkgHandle, (BOOLEAN *)&IsAPIC); 746 SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 3, &INTDPkgHandle, (BOOLEAN *)&IsAPIC); 747 748 // 749 // Check INTA 750 // 751 if ((PciDeviceInfo->INTA[IsAPIC] != 0xFF) && (INTAPkgHandle != NULL)) { 752 // 753 // Find INTA package and there is valid INTA update item, update it 754 // 755 SdtUpdateINTxPkg (AcpiSdt, INTAPkgHandle, (PciDeviceInfo->INTA[IsAPIC]), IsAPIC); 756 } else if ((PciDeviceInfo->INTA[IsAPIC] != 0xFF) && (INTAPkgHandle == NULL)) { 757 // 758 // There is valid INTA update item, but no INA package exist, should add it 759 // 760 DEBUG ((EFI_D_ERROR, "\n\nShould add INTA item for this device(0x%x)\n\n", PciAddress)); 761 762 } else if ((PciDeviceInfo->INTA[IsAPIC] == 0xFF) && (INTAPkgHandle != NULL) && IsAllFunctions) { 763 // 764 // For all functions senario, if there is invalid INTA update item, but INTA package does exist, should delete it 765 // 766 DEBUG ((EFI_D_ERROR, "\n\nShould remove INTA item for this device(0x%x)\n\n", PciAddress)); 767 768 } 769 770 // 771 // Check INTB 772 // 773 if ((PciDeviceInfo->INTB[IsAPIC] != 0xFF) && (INTBPkgHandle != NULL)) { 774 // 775 // Find INTB package and there is valid INTB update item, update it 776 // 777 SdtUpdateINTxPkg (AcpiSdt, INTBPkgHandle, (PciDeviceInfo->INTB[IsAPIC]), IsAPIC); 778 } else if ((PciDeviceInfo->INTB[IsAPIC] != 0xFF) && (INTBPkgHandle == NULL)) { 779 // 780 // There is valid INTB update item, but no INTB package exist, should add it 781 // 782 DEBUG ((EFI_D_ERROR, "\n\nShould add INTB item for this device(0x%x)\n\n", PciAddress)); 783 784 } else if ((PciDeviceInfo->INTB[IsAPIC] == 0xFF) && (INTBPkgHandle != NULL) && IsAllFunctions) { 785 // 786 // For all functions senario, if there is invalid INTB update item, but INTB package does exist, should delete it 787 // 788 DEBUG ((EFI_D_ERROR, "\n\nShould remove INTB item for this device(0x%x)\n\n", PciAddress)); 789 790 } 791 792 // 793 // Check INTC 794 // 795 if ((PciDeviceInfo->INTC[IsAPIC] != 0xFF) && (INTCPkgHandle != NULL)) { 796 // 797 // Find INTC package and there is valid INTC update item, update it 798 // 799 SdtUpdateINTxPkg (AcpiSdt, INTCPkgHandle, (PciDeviceInfo->INTC[IsAPIC]), IsAPIC); 800 } else if ((PciDeviceInfo->INTC[IsAPIC] != 0xFF) && (INTCPkgHandle == NULL)) { 801 // 802 // There is valid INTC update item, but no INTC package exist, should add it 803 // 804 DEBUG ((EFI_D_ERROR, "\n\nShould add INTC item for this device(0x%x)\n\n", PciAddress)); 805 806 } else if ((PciDeviceInfo->INTC[IsAPIC] == 0xFF) && (INTCPkgHandle != NULL) && IsAllFunctions) { 807 // 808 // For all functions senario, if there is invalid INTC update item, but INTC package does exist, should delete it 809 // 810 DEBUG ((EFI_D_ERROR, "\n\nShould remove INTC item for this device(0x%x)\n\n", PciAddress)); 811 } 812 813 // 814 // Check INTD 815 // 816 if ((PciDeviceInfo->INTD[IsAPIC] != 0xFF) && (INTDPkgHandle != NULL)) { 817 // 818 // Find INTD package and there is valid INTD update item, update it 819 // 820 SdtUpdateINTxPkg (AcpiSdt, INTDPkgHandle, (PciDeviceInfo->INTD[IsAPIC]), IsAPIC); 821 } else if ((PciDeviceInfo->INTD[IsAPIC] != 0xFF) && (INTDPkgHandle == NULL)) { 822 // 823 // There is valid INTD update item, but no INTD package exist, should add it 824 // 825 DEBUG ((EFI_D_ERROR, "\n\nShould add INTD item for this device(0x%x)\n\n", PciAddress)); 826 827 } else if ((PciDeviceInfo->INTD[IsAPIC] == 0xFF) && (INTDPkgHandle != NULL) && IsAllFunctions) { 828 // 829 // For all functions senario, if there is invalid INTD update item, but INTD package does exist, should delete it 830 // 831 DEBUG ((EFI_D_ERROR, "\n\nShould remove INTD item for this device(0x%x)\n\n", PciAddress)); 832 } 833 834 835 if (INTAPkgHandle != NULL) { 836 Status = AcpiSdt->Close (INTAPkgHandle); 837 ASSERT_EFI_ERROR (Status); 838 } 839 840 if (INTBPkgHandle != NULL) { 841 Status = AcpiSdt->Close (INTBPkgHandle); 842 ASSERT_EFI_ERROR (Status); 843 } 844 845 if (INTCPkgHandle != NULL) { 846 Status = AcpiSdt->Close (INTCPkgHandle); 847 ASSERT_EFI_ERROR (Status); 848 } 849 850 if (INTDPkgHandle != NULL) { 851 Status = AcpiSdt->Close (INTDPkgHandle); 852 ASSERT_EFI_ERROR (Status); 853 } 854 855 return; 856 } 857 858 /** 859 Check every return package for update PRT 860 861 @param AcpiSdt Pointer to Acpi SDT protocol 862 @param ParentHandle ACPI pci device handle 863 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 864 865 **/ 866 VOID 867 SdtCheckReturnPackage ( 868 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 869 IN EFI_ACPI_HANDLE MethodHandle, 870 IN PCI_DEVICE_INFO *PciDeviceInfo 871 ) 872 { 873 EFI_ACPI_HANDLE PreviousHandle; 874 EFI_ACPI_HANDLE ReturnHandle; 875 EFI_ACPI_HANDLE PackageHandle; 876 EFI_ACPI_HANDLE NamePkgHandle; 877 EFI_STATUS Status; 878 EFI_ACPI_DATA_TYPE DataType; 879 UINT8 *Data; 880 UINTN DataSize; 881 CHAR8 NameStr[128]; 882 883 ReturnHandle = NULL; 884 while (TRUE) { 885 PreviousHandle = ReturnHandle; 886 Status = AcpiSdt->GetChild (MethodHandle, &ReturnHandle); 887 ASSERT_EFI_ERROR (Status); 888 889 if (PreviousHandle != NULL) { 890 Status = AcpiSdt->Close (PreviousHandle); 891 ASSERT_EFI_ERROR (Status); 892 } 893 894 if (ReturnHandle == NULL) { 895 break; 896 } 897 898 Status = AcpiSdt->GetOption (ReturnHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 899 ASSERT_EFI_ERROR (Status); 900 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 901 902 if (*Data == AML_RETURN_OP) { 903 // 904 // Find the return method handle, then look for the returned package data 905 // 906 Status = AcpiSdt->GetOption (ReturnHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize); 907 ASSERT_EFI_ERROR (Status); 908 909 910 if (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING) { 911 ZeroMem (NameStr, 128); 912 AsciiStrCpy (NameStr, "\\_SB."); 913 DataSize = SdtGetNameStringSize (Data); 914 AsciiStrnCat (NameStr, (CHAR8 *)Data, DataSize); 915 916 NamePkgHandle = NULL; 917 Status = AcpiSdt->FindPath (mDsdtHandle, NameStr, &NamePkgHandle); 918 ASSERT_EFI_ERROR (Status); 919 ASSERT (NamePkgHandle != NULL); 920 921 Status = AcpiSdt->GetOption (NamePkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 922 ASSERT_EFI_ERROR (Status); 923 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 924 ASSERT (*Data == AML_NAME_OP); 925 926 Status = AcpiSdt->GetOption (NamePkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize); 927 ASSERT_EFI_ERROR (Status); 928 ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD); 929 } 930 931 ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD); 932 933 // 934 // Get the parent package handle 935 // 936 PackageHandle = NULL; 937 Status = AcpiSdt->Open (Data, &PackageHandle); 938 ASSERT_EFI_ERROR (Status); 939 940 // 941 // Check the parent package for update pci routing 942 // 943 SdtCheckParentPackage (AcpiSdt, PackageHandle, PciDeviceInfo); 944 945 Status = AcpiSdt->Close (PackageHandle); 946 ASSERT_EFI_ERROR (Status); 947 948 Status = AcpiSdt->Close (ReturnHandle); 949 ASSERT_EFI_ERROR (Status); 950 951 break; 952 } 953 954 // 955 // Not ReturnOp, search it as parent 956 // 957 SdtCheckReturnPackage (AcpiSdt, ReturnHandle, PciDeviceInfo); 958 } 959 960 // 961 // Done 962 // 963 return; 964 965 } 966 967 /** 968 update interrupt info inside the PRT method for the given pci device handle 969 970 @param AcpiSdt Pointer to Acpi SDT protocol 971 @param PciHandle ACPI pci device handle 972 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 973 974 **/ 975 EFI_STATUS 976 SdtUpdatePrtMethod ( 977 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 978 IN EFI_ACPI_HANDLE PciHandle, 979 IN PCI_DEVICE_INFO *PciDeviceInfo 980 ) 981 { 982 EFI_STATUS Status; 983 EFI_ACPI_HANDLE PrtMethodHandle; 984 985 // 986 // Find the PRT method under this pci device 987 // 988 PrtMethodHandle = NULL; 989 Status = AcpiSdt->FindPath (PciHandle, "_PRT", &PrtMethodHandle); 990 991 if (EFI_ERROR (Status)) { 992 return EFI_INVALID_PARAMETER; 993 } 994 995 if (PrtMethodHandle == NULL) { 996 return EFI_INVALID_PARAMETER; 997 } 998 999 SdtCheckReturnPackage(AcpiSdt, PrtMethodHandle, PciDeviceInfo); 1000 1001 Status = AcpiSdt->Close (PrtMethodHandle); 1002 ASSERT_EFI_ERROR (Status); 1003 1004 return Status; 1005 } 1006 1007 1008 /** 1009 Update the package inside name op with correct wakeup resources 1010 1011 @param AcpiSdt Pointer to Acpi SDT protocol 1012 @param InPkgHandle ACPI inside package handle 1013 @param GPEPin Correct gpe pin 1014 @param SxNum Correct system state the device can wake up from 1015 1016 **/ 1017 VOID 1018 SdtUpdatePackageInName ( 1019 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 1020 IN EFI_ACPI_HANDLE INTxPkgHandle, 1021 IN UINT8 GPEPin, 1022 IN UINT8 SxNum 1023 ) 1024 { 1025 EFI_ACPI_HANDLE PreviousHandle; 1026 EFI_STATUS Status; 1027 EFI_ACPI_HANDLE MemberHandle; 1028 EFI_ACPI_DATA_TYPE DataType; 1029 UINT8 *Data; 1030 UINTN DataSize; 1031 1032 // 1033 // Check the gpe pin 1034 // 1035 MemberHandle = NULL; 1036 Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle); 1037 ASSERT_EFI_ERROR (Status); 1038 ASSERT (MemberHandle != NULL); 1039 1040 Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 1041 ASSERT_EFI_ERROR (Status); 1042 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 1043 1044 // 1045 // Skip byte prefix 1046 // 1047 Data += 1; 1048 1049 if (*Data != GPEPin) { 1050 1051 *Data = GPEPin; 1052 } 1053 1054 // 1055 // Check the sx number 1056 // 1057 PreviousHandle = MemberHandle; 1058 Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle); 1059 ASSERT_EFI_ERROR (Status); 1060 ASSERT (MemberHandle != NULL); 1061 1062 if (PreviousHandle != NULL) { 1063 Status = AcpiSdt->Close (PreviousHandle); 1064 ASSERT_EFI_ERROR (Status); 1065 } 1066 1067 Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 1068 ASSERT_EFI_ERROR (Status); 1069 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 1070 1071 // 1072 // Skip byte prefix 1073 // 1074 Data += 1; 1075 1076 if (*Data != SxNum) { 1077 1078 *Data = SxNum; 1079 } 1080 1081 Status = AcpiSdt->Close (MemberHandle); 1082 ASSERT_EFI_ERROR (Status); 1083 1084 } 1085 1086 /** 1087 Check the name package belonged to PRW 1088 1089 @param AcpiSdt Pointer to Acpi SDT protocol 1090 @param PrwPkgHandle ACPI PRW package handle 1091 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 1092 1093 **/ 1094 VOID 1095 SdtCheckNamePackage ( 1096 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 1097 IN EFI_ACPI_HANDLE PrwPkgHandle, 1098 IN PCI_DEVICE_INFO *PciDeviceInfo 1099 ) 1100 { 1101 EFI_ACPI_HANDLE InPkgHandle; 1102 EFI_STATUS Status; 1103 EFI_ACPI_DATA_TYPE DataType; 1104 UINT8 *Data; 1105 UINTN DataSize; 1106 1107 Status = AcpiSdt->GetOption (PrwPkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize); 1108 ASSERT_EFI_ERROR (Status); 1109 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); 1110 ASSERT (*Data == AML_NAME_OP); 1111 1112 Status = AcpiSdt->GetOption (PrwPkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize); 1113 ASSERT_EFI_ERROR (Status); 1114 ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD); 1115 1116 // 1117 // Get the inside package handle 1118 // 1119 InPkgHandle = NULL; 1120 Status = AcpiSdt->Open (Data, &InPkgHandle); 1121 ASSERT_EFI_ERROR (Status); 1122 1123 // 1124 // update the package in name op for wakeup info 1125 // 1126 if ((PciDeviceInfo->GPEPin != 0xFF) && (PciDeviceInfo->SxNum != 0xFF)) 1127 SdtUpdatePackageInName (AcpiSdt, InPkgHandle, PciDeviceInfo->GPEPin, PciDeviceInfo->SxNum); 1128 1129 Status = AcpiSdt->Close (InPkgHandle); 1130 ASSERT_EFI_ERROR (Status); 1131 1132 return; 1133 1134 } 1135 1136 /** 1137 update wakeup info inside the PRW method for the given pci device handle 1138 1139 @param AcpiSdt Pointer to Acpi SDT protocol 1140 @param PciHandle ACPI pci device handle 1141 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 1142 1143 **/ 1144 EFI_STATUS 1145 SdtUpdatePrwPackage ( 1146 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 1147 IN EFI_ACPI_HANDLE PciHandle, 1148 IN PCI_DEVICE_INFO *PciDeviceInfo 1149 ) 1150 { 1151 EFI_STATUS Status; 1152 EFI_ACPI_HANDLE PrwPkgHandle; 1153 1154 // 1155 // Find the PRT method under this pci device 1156 // 1157 PrwPkgHandle = NULL; 1158 Status = AcpiSdt->FindPath (PciHandle, "_PRW", &PrwPkgHandle); 1159 1160 if (EFI_ERROR (Status)) { 1161 return EFI_INVALID_PARAMETER; 1162 } 1163 1164 if (PrwPkgHandle == NULL) { 1165 return EFI_INVALID_PARAMETER; 1166 } 1167 1168 SdtCheckNamePackage(AcpiSdt, PrwPkgHandle, PciDeviceInfo); 1169 1170 Status = AcpiSdt->Close (PrwPkgHandle); 1171 ASSERT_EFI_ERROR (Status); 1172 1173 return Status; 1174 } 1175 1176 /** 1177 update pci routing information in acpi table based on pcd settings 1178 1179 @param AcpiSdt Pointer to Acpi SDT protocol 1180 @param PciRootHandle ACPI root bridge handle 1181 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 1182 1183 **/ 1184 EFI_STATUS 1185 SdtUpdatePciRouting ( 1186 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 1187 IN EFI_ACPI_HANDLE PciRootHandle, 1188 IN PCI_DEVICE_INFO *PciDeviceInfo 1189 ) 1190 { 1191 EFI_STATUS Status; 1192 EFI_ACPI_HANDLE PciBridgeHandle; 1193 UINT32 PciAddress; 1194 1195 1196 PciBridgeHandle = NULL; 1197 if (PciDeviceInfo->BridgeAddress == 0x00000000) { 1198 // 1199 // Its bridge is the host root bridge 1200 // 1201 PciBridgeHandle = PciRootHandle; 1202 1203 } else { 1204 1205 // 1206 // Its bridge is just a pci device under the host bridge 1207 // 1208 1209 // 1210 // Conver the bridge address into one that acpi table can recognize 1211 // 1212 PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->BridgeAddress); 1213 1214 // 1215 // Scan the whole table to find the pci device 1216 // 1217 PciBridgeHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciRootHandle, SdtFindPciDeviceHandle, &PciAddress); 1218 if (PciBridgeHandle == NULL) { 1219 1220 return EFI_INVALID_PARAMETER; 1221 } 1222 } 1223 1224 Status = SdtUpdatePrtMethod(AcpiSdt, PciBridgeHandle, PciDeviceInfo); 1225 1226 if (PciDeviceInfo->BridgeAddress != 0x00000000) { 1227 Status = AcpiSdt->Close (PciBridgeHandle); 1228 ASSERT_EFI_ERROR (Status); 1229 } 1230 1231 return Status; 1232 } 1233 1234 1235 /** 1236 update power resource wake up information in acpi table based on pcd settings 1237 1238 @param AcpiSdt Pointer to Acpi SDT protocol 1239 @param PciRootHandle ACPI root bridge handle 1240 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 1241 1242 **/ 1243 EFI_STATUS 1244 SdtUpdatePowerWake ( 1245 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 1246 IN EFI_ACPI_HANDLE PciRootHandle, 1247 IN PCI_DEVICE_INFO *PciDeviceInfo 1248 ) 1249 { 1250 EFI_STATUS Status; 1251 EFI_ACPI_HANDLE PciBridgeHandle; 1252 EFI_ACPI_HANDLE PciDeviceHandle; 1253 UINT32 PciAddress; 1254 1255 PciBridgeHandle = NULL; 1256 if (PciDeviceInfo->BridgeAddress == 0x00000000) { 1257 // 1258 // Its bridge is the host root bridge 1259 // 1260 PciBridgeHandle = PciRootHandle; 1261 1262 } else { 1263 1264 // 1265 // Its bridge is just a pci device under the host bridge 1266 // 1267 1268 // 1269 // Conver the bridge address into one that acpi table can recognize 1270 // 1271 PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->BridgeAddress); 1272 1273 // 1274 // Scan the whole table to find the pci device 1275 // 1276 PciBridgeHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciRootHandle, SdtFindPciDeviceHandle, &PciAddress); 1277 1278 if (PciBridgeHandle == NULL) { 1279 1280 Status = AcpiSdt->Close (PciRootHandle); 1281 ASSERT_EFI_ERROR (Status); 1282 1283 return EFI_INVALID_PARAMETER; 1284 } 1285 } 1286 1287 PciDeviceHandle = NULL; 1288 1289 // 1290 // Conver the device address into one that acpi table can recognize 1291 // 1292 PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->DeviceAddress); 1293 1294 // 1295 // Scan the whole table to find the pci device 1296 // 1297 PciDeviceHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciBridgeHandle, SdtFindPciDeviceHandle, &PciAddress); 1298 1299 if (PciDeviceHandle == NULL) { 1300 if (PciDeviceInfo->BridgeAddress != 0x00000000) { 1301 Status = AcpiSdt->Close (PciBridgeHandle); 1302 ASSERT_EFI_ERROR (Status); 1303 } 1304 1305 return EFI_INVALID_PARAMETER; 1306 } 1307 1308 Status = SdtUpdatePrwPackage(AcpiSdt, PciDeviceHandle, PciDeviceInfo); 1309 1310 Status = AcpiSdt->Close (PciDeviceHandle); 1311 ASSERT_EFI_ERROR (Status); 1312 1313 if (PciDeviceInfo->BridgeAddress != 0x00000000) { 1314 Status = AcpiSdt->Close (PciBridgeHandle); 1315 ASSERT_EFI_ERROR (Status); 1316 } 1317 1318 return Status; 1319 } 1320 1321 1322 /** 1323 Get the root bridge handle by scanning the acpi table 1324 1325 @param AcpiSdt Pointer to Acpi SDT protocol 1326 @param DsdtHandle ACPI root handle 1327 1328 @retval EFI_ACPI_HANDLE the handle of the root bridge 1329 **/ 1330 EFI_ACPI_HANDLE 1331 SdtGetRootBridgeHandle ( 1332 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt, 1333 IN EFI_ACPI_HANDLE DsdtHandle 1334 ) 1335 { 1336 EFI_ACPI_HANDLE PciRootHandle; 1337 1338 // 1339 // Scan the whole table to find the root bridge 1340 // 1341 PciRootHandle = NULL; 1342 PciRootHandle = SdtGetHandleByScanAllChilds(AcpiSdt, DsdtHandle, SdtFindRootBridgeHandle, NULL); 1343 ASSERT (PciRootHandle != NULL); 1344 1345 return PciRootHandle; 1346 } 1347 1348 1349 /** 1350 Check input Pci device info is changed from the default values 1351 @param PciDeviceInfo Pointer to PCI_DEVICE_INFO 1352 @param UpdatePRT Pointer to BOOLEAN 1353 @param UpdatePRW Pointer to BOOLEAN 1354 1355 **/ 1356 VOID 1357 SdtCheckPciDeviceInfoChanged ( 1358 IN PCI_DEVICE_INFO *PciDeviceInfo, 1359 IN BOOLEAN *UpdatePRT, 1360 IN BOOLEAN *UpdatePRW 1361 ) 1362 { 1363 UINTN Index = 0; 1364 1365 if (mQNCPciInfo == NULL) { 1366 *UpdatePRT = FALSE; 1367 *UpdatePRW = FALSE; 1368 return; 1369 } 1370 1371 *UpdatePRT = TRUE; 1372 *UpdatePRW = TRUE; 1373 1374 for (Index = 0;Index < CURRENT_PCI_DEVICE_NUM; Index++) { 1375 if ((mQNCPciInfo[Index].BridgeAddress == PciDeviceInfo->BridgeAddress) 1376 && (mQNCPciInfo[Index].DeviceAddress == PciDeviceInfo->DeviceAddress)) { 1377 // 1378 // Find one matched entry 1379 // 1380 if (CompareMem (&(mQNCPciInfo[Index].INTA[0]), &PciDeviceInfo->INTA[0], 10) == 0) { 1381 *UpdatePRT = FALSE; 1382 *UpdatePRW = FALSE; 1383 //DEBUG ((EFI_D_ERROR, "Find one matched entry[%d] and no change\n", Index)); 1384 } else { 1385 if (CompareMem (&(mQNCPciInfo[Index].INTA[0]), &PciDeviceInfo->INTA[0], 8) == 0) 1386 *UpdatePRT = FALSE; 1387 1388 if (CompareMem (&(mQNCPciInfo[Index].GPEPin), &PciDeviceInfo->GPEPin, 2) == 0) 1389 *UpdatePRW = FALSE; 1390 1391 if (*(UINT64 *)(&PciDeviceInfo->INTA[0]) == 0xFFFFFFFFFFFFFFFFULL) 1392 *UpdatePRT = FALSE; 1393 1394 if (*(UINT16 *)(&PciDeviceInfo->GPEPin) == 0xFFFF) 1395 *UpdatePRW = FALSE; 1396 1397 //DEBUG ((EFI_D_ERROR, "Find one matched entry[%d] and but need update PRT:0x%x PRW:0x%x\n", Index, *UpdatePRT, *UpdatePRW)); 1398 } 1399 break; 1400 } 1401 } 1402 1403 //if (Index == 42) { 1404 // DEBUG ((EFI_D_ERROR, "Find No matched entry\n")); 1405 //} 1406 1407 return; 1408 } 1409