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