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