]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
QuarkPlatformPkg: Add new package for Galileo boards
[mirror_edk2.git] / QuarkPlatformPkg / Acpi / Dxe / AcpiPlatform / AcpiPciUpdate.c
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 }