]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c
Change UINAME to CName of GUID/PPI/Protocol in all Msa file and change tool to suppo...
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciResourceSupport.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 PciResourceSupport.c\r
15 \r
16Abstract:\r
17\r
18 PCI Bus Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
f0ec738d 24#include "pcibus.h"\r
878ddf1f 25#include "PciResourceSupport.h"\r
26#include "PciCommand.h"\r
27\r
28EFI_STATUS\r
29SkipVGAAperture (\r
30 OUT UINT64 *Start,\r
31 IN UINT64 Length\r
32 )\r
33/*++\r
34\r
35Routine Description:\r
36\r
37 The function is used to skip VGA range\r
38\r
39Arguments:\r
40\r
41Returns:\r
42\r
43 None\r
44\r
45--*/\r
46// TODO: Start - add argument and description to function comment\r
47// TODO: Length - add argument and description to function comment\r
48// TODO: EFI_SUCCESS - add return value to function comment\r
49{\r
50 UINT64 Original;\r
51 UINT64 Mask;\r
52 UINT64 StartOffset;\r
53 UINT64 LimitOffset;\r
54\r
55 //\r
56 // For legacy VGA, bit 10 to bit 15 is not decoded\r
57 //\r
58 Mask = 0x3FF;\r
59\r
60 Original = *Start;\r
61 StartOffset = Original & Mask;\r
62 LimitOffset = ((*Start) + Length - 1) & Mask;\r
63 if (LimitOffset >= VGABASE1) {\r
64 *Start = *Start - StartOffset + VGALIMIT2 + 1;\r
65 }\r
66\r
67 return EFI_SUCCESS;\r
68}\r
69\r
70EFI_STATUS\r
71SkipIsaAliasAperture (\r
72 OUT UINT64 *Start,\r
73 IN UINT64 Length\r
74 )\r
75/*++\r
76\r
77Routine Description:\r
78\r
79 This function is used to skip ISA aliasing aperture\r
80\r
81Arguments:\r
82\r
83Returns:\r
84\r
85 None\r
86\r
87--*/\r
88// TODO: Start - add argument and description to function comment\r
89// TODO: Length - add argument and description to function comment\r
90// TODO: EFI_SUCCESS - add return value to function comment\r
91{\r
92\r
93 UINT64 Original;\r
94 UINT64 Mask;\r
95 UINT64 StartOffset;\r
96 UINT64 LimitOffset;\r
97\r
98 //\r
99 // For legacy ISA, bit 10 to bit 15 is not decoded\r
100 //\r
101 Mask = 0x3FF;\r
102\r
103 Original = *Start;\r
104 StartOffset = Original & Mask;\r
105 LimitOffset = ((*Start) + Length - 1) & Mask;\r
106\r
107 if (LimitOffset >= ISABASE) {\r
108 *Start = *Start - StartOffset + ISALIMIT + 1;\r
109 }\r
110\r
111 return EFI_SUCCESS;\r
112}\r
113\r
114EFI_STATUS\r
115InsertResourceNode (\r
116 PCI_RESOURCE_NODE *Bridge,\r
117 PCI_RESOURCE_NODE *ResNode\r
118 )\r
119/*++\r
120\r
121Routine Description:\r
122\r
123 This function inserts a resource node into the resource list.\r
124 The resource list is sorted in descend order.\r
125\r
126Arguments:\r
127\r
128Returns:\r
129\r
130 None\r
131\r
132--*/\r
133// TODO: Bridge - add argument and description to function comment\r
134// TODO: ResNode - add argument and description to function comment\r
135// TODO: EFI_SUCCESS - add return value to function comment\r
136{\r
137 LIST_ENTRY *CurrentLink;\r
138 PCI_RESOURCE_NODE *Temp;\r
139 UINT64 ResNodeAlignRest;\r
140 UINT64 TempAlignRest;\r
141\r
142 InsertHeadList (&Bridge->ChildList, &ResNode->Link);\r
143\r
144 CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;\r
145 while (CurrentLink != &Bridge->ChildList) {\r
146 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
147\r
148 if (ResNode->Alignment > Temp->Alignment) {\r
149 break;\r
150 } else if (ResNode->Alignment == Temp->Alignment) {\r
151 ResNodeAlignRest = ResNode->Length & ResNode->Alignment;\r
152 TempAlignRest = Temp->Length & Temp->Alignment;\r
153 if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {\r
154 break;\r
155 }\r
156 }\r
157\r
158 SwapListEntries (&ResNode->Link, CurrentLink);\r
159\r
160 CurrentLink = ResNode->Link.ForwardLink;\r
161 }\r
162\r
163 return EFI_SUCCESS;\r
164}\r
165\r
166EFI_STATUS\r
167MergeResourceTree (\r
168 PCI_RESOURCE_NODE *Dst,\r
169 PCI_RESOURCE_NODE *Res,\r
170 BOOLEAN TypeMerge\r
171 )\r
172/*++\r
173\r
174Routine Description:\r
175\r
176 This routine is used to merge two different resource tree in need of\r
177 resoure degradation. For example, if a upstream PPB doesn't support,\r
178 prefetchable memory decoding, the PCI bus driver will choose to call this function\r
179 to merge prefectchable memory resource list into normal memory list.\r
180\r
181 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource\r
182 type.\r
183\r
184Arguments:\r
185\r
186Returns:\r
187\r
188 None\r
189\r
190--*/\r
191// TODO: Dst - add argument and description to function comment\r
192// TODO: Res - add argument and description to function comment\r
193// TODO: TypeMerge - add argument and description to function comment\r
194// TODO: EFI_SUCCESS - add return value to function comment\r
195{\r
196\r
197 LIST_ENTRY *CurrentLink;\r
198 PCI_RESOURCE_NODE *Temp;\r
199\r
200 while (!IsListEmpty (&Res->ChildList)) {\r
201 CurrentLink = Res->ChildList.ForwardLink;\r
202\r
203 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
204\r
205 if (TypeMerge) {\r
206 Temp->ResType = Dst->ResType;\r
207 }\r
208\r
209 RemoveEntryList (CurrentLink);\r
210 InsertResourceNode (Dst, Temp);\r
211\r
212 }\r
213\r
214 return EFI_SUCCESS;\r
215}\r
216\r
217EFI_STATUS\r
218CalculateApertureIo16 (\r
219 IN PCI_RESOURCE_NODE *Bridge\r
220 )\r
221/*++\r
222\r
223Routine Description:\r
224\r
225 This function is used to calculate the IO16 aperture\r
226 for a bridge.\r
227\r
228Arguments:\r
229\r
230Returns:\r
231\r
232 None\r
233\r
234--*/\r
235// TODO: Bridge - add argument and description to function comment\r
236// TODO: EFI_SUCCESS - add return value to function comment\r
237// TODO: EFI_SUCCESS - add return value to function comment\r
238{\r
239\r
240 UINT64 Aperture;\r
241 LIST_ENTRY *CurrentLink;\r
242 PCI_RESOURCE_NODE *Node;\r
243 UINT64 offset;\r
244\r
245 //\r
246 // Always assume there is ISA device and VGA device on the platform\r
247 // will be customized later\r
248 //\r
249 Aperture = 0;\r
250\r
251 if (!Bridge) {\r
252 return EFI_SUCCESS;\r
253 }\r
254\r
255 CurrentLink = Bridge->ChildList.ForwardLink;\r
256\r
257 //\r
258 // Assume the bridge is aligned\r
259 //\r
260 while (CurrentLink != &Bridge->ChildList) {\r
261\r
262 Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
263\r
264 //\r
265 // Consider the aperture alignment\r
266 //\r
267 offset = Aperture & (Node->Alignment);\r
268\r
269 if (offset) {\r
270\r
271 Aperture = Aperture + (Node->Alignment + 1) - offset;\r
272\r
273 }\r
274\r
275 //\r
276 // IsaEnable and VGAEnable can not be implemented now.\r
277 // If both of them are enabled, then the IO resource would\r
278 // become too limited to meet the requirement of most of devices.\r
279 //\r
280\r
281 Node->Offset = Aperture;\r
282\r
283 //\r
284 // Increment aperture by the length of node\r
285 //\r
286 Aperture += Node->Length;\r
287\r
288 CurrentLink = CurrentLink->ForwardLink;\r
289 }\r
290\r
291 //\r
292 // At last, adjust the aperture with the bridge's\r
293 // alignment\r
294 //\r
295 offset = Aperture & (Bridge->Alignment);\r
296\r
297 if (offset) {\r
298 Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
299 }\r
300\r
301 Bridge->Length = Aperture;\r
302 //\r
303 // At last, adjust the bridge's alignment to the first child's alignment\r
304 // if the bridge has at least one child\r
305 //\r
306 CurrentLink = Bridge->ChildList.ForwardLink;\r
307 if (CurrentLink != &Bridge->ChildList) {\r
308 Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
309 if (Node->Alignment > Bridge->Alignment) {\r
310 Bridge->Alignment = Node->Alignment;\r
311 }\r
312 }\r
313\r
314 return EFI_SUCCESS;\r
315}\r
316\r
317EFI_STATUS\r
318CalculateResourceAperture (\r
319 IN PCI_RESOURCE_NODE *Bridge\r
320 )\r
321/*++\r
322\r
323Routine Description:\r
324\r
325 This function is used to calculate the resource aperture\r
326 for a given bridge device\r
327\r
328Arguments:\r
329\r
330Returns:\r
331\r
332 None\r
333\r
334--*/\r
335// TODO: Bridge - add argument and description to function comment\r
336// TODO: EFI_SUCCESS - add return value to function comment\r
337// TODO: EFI_SUCCESS - add return value to function comment\r
338{\r
339 UINT64 Aperture;\r
340 LIST_ENTRY *CurrentLink;\r
341 PCI_RESOURCE_NODE *Node;\r
342\r
343 UINT64 offset;\r
344\r
345 Aperture = 0;\r
346\r
347 if (!Bridge) {\r
348 return EFI_SUCCESS;\r
349 }\r
350\r
351 if (Bridge->ResType == PciBarTypeIo16) {\r
352 return CalculateApertureIo16 (Bridge);\r
353 }\r
354\r
355 CurrentLink = Bridge->ChildList.ForwardLink;\r
356\r
357 //\r
358 // Assume the bridge is aligned\r
359 //\r
360 while (CurrentLink != &Bridge->ChildList) {\r
361\r
362 Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
363\r
364 //\r
365 // Apply padding resource if available\r
366 //\r
367 \r
368 offset = Aperture & (Node->Alignment);\r
369\r
370 if (offset) {\r
371\r
372 Aperture = Aperture + (Node->Alignment + 1) - offset;\r
373\r
374 }\r
375\r
376 //\r
377 // Recode current aperture as a offset\r
378 // this offset will be used in future real allocation\r
379 //\r
380 Node->Offset = Aperture;\r
381\r
382 //\r
383 // Increment aperture by the length of node\r
384 //\r
385 Aperture += Node->Length;\r
386\r
387 //\r
388 // Consider the aperture alignment\r
389 //\r
390 \r
391 CurrentLink = CurrentLink->ForwardLink;\r
392 }\r
393\r
394 //\r
395 // At last, adjust the aperture with the bridge's\r
396 // alignment\r
397 //\r
398 offset = Aperture & (Bridge->Alignment);\r
399 if (offset) {\r
400 Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
401 }\r
402\r
403 //\r
404 // If the bridge has already padded the resource and the\r
405 // amount of padded resource is larger, then keep the\r
406 // padded resource\r
407 //\r
408 if (Bridge->Length < Aperture) {\r
409 Bridge->Length = Aperture;\r
410 }\r
411 \r
412 //\r
413 // At last, adjust the bridge's alignment to the first child's alignment\r
414 // if the bridge has at least one child\r
415 //\r
416 CurrentLink = Bridge->ChildList.ForwardLink;\r
417 if (CurrentLink != &Bridge->ChildList) {\r
418 Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
419 if (Node->Alignment > Bridge->Alignment) {\r
420 Bridge->Alignment = Node->Alignment;\r
421 }\r
422 }\r
423\r
424 return EFI_SUCCESS;\r
425}\r
426\r
427EFI_STATUS\r
428GetResourceFromDevice (\r
429 PCI_IO_DEVICE *PciDev,\r
430 PCI_RESOURCE_NODE *IoNode,\r
431 PCI_RESOURCE_NODE *Mem32Node,\r
432 PCI_RESOURCE_NODE *PMem32Node,\r
433 PCI_RESOURCE_NODE *Mem64Node,\r
434 PCI_RESOURCE_NODE *PMem64Node\r
435 )\r
436/*++\r
437\r
438Routine Description:\r
439\r
440Arguments:\r
441\r
442Returns:\r
443\r
444 None\r
445\r
446--*/\r
447// TODO: PciDev - add argument and description to function comment\r
448// TODO: IoNode - add argument and description to function comment\r
449// TODO: Mem32Node - add argument and description to function comment\r
450// TODO: PMem32Node - add argument and description to function comment\r
451// TODO: Mem64Node - add argument and description to function comment\r
452// TODO: PMem64Node - add argument and description to function comment\r
453// TODO: EFI_SUCCESS - add return value to function comment\r
454{\r
455\r
456 UINT8 Index;\r
457 PCI_RESOURCE_NODE *Node;\r
458 BOOLEAN ResourceRequested;\r
459\r
460 Node = NULL;\r
461 ResourceRequested = FALSE;\r
462\r
463 for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
464\r
465 switch ((PciDev->PciBar)[Index].BarType) {\r
466\r
467 case PciBarTypeMem32:\r
468\r
469 Node = CreateResourceNode (\r
470 PciDev,\r
471 (PciDev->PciBar)[Index].Length,\r
472 (PciDev->PciBar)[Index].Alignment,\r
473 Index,\r
474 PciBarTypeMem32,\r
475 PciResUsageTypical\r
476 );\r
477\r
478 InsertResourceNode (\r
479 Mem32Node,\r
480 Node\r
481 );\r
482\r
483 ResourceRequested = TRUE;\r
484 break;\r
485\r
486 case PciBarTypeMem64:\r
487\r
488 Node = CreateResourceNode (\r
489 PciDev,\r
490 (PciDev->PciBar)[Index].Length,\r
491 (PciDev->PciBar)[Index].Alignment,\r
492 Index,\r
493 PciBarTypeMem64,\r
494 PciResUsageTypical\r
495 );\r
496\r
497 InsertResourceNode (\r
498 Mem64Node,\r
499 Node\r
500 );\r
501\r
502 ResourceRequested = TRUE;\r
503 break;\r
504\r
505 case PciBarTypePMem64:\r
506\r
507 Node = CreateResourceNode (\r
508 PciDev,\r
509 (PciDev->PciBar)[Index].Length,\r
510 (PciDev->PciBar)[Index].Alignment,\r
511 Index,\r
512 PciBarTypePMem64,\r
513 PciResUsageTypical\r
514 );\r
515\r
516 InsertResourceNode (\r
517 PMem64Node,\r
518 Node\r
519 );\r
520\r
521 ResourceRequested = TRUE;\r
522 break;\r
523\r
524 case PciBarTypePMem32:\r
525\r
526 Node = CreateResourceNode (\r
527 PciDev,\r
528 (PciDev->PciBar)[Index].Length,\r
529 (PciDev->PciBar)[Index].Alignment,\r
530 Index,\r
531 PciBarTypePMem32,\r
532 PciResUsageTypical\r
533 );\r
534\r
535 InsertResourceNode (\r
536 PMem32Node,\r
537 Node\r
538 );\r
539 ResourceRequested = TRUE;\r
540 break;\r
541\r
542 case PciBarTypeIo16:\r
543 case PciBarTypeIo32:\r
544\r
545 Node = CreateResourceNode (\r
546 PciDev,\r
547 (PciDev->PciBar)[Index].Length,\r
548 (PciDev->PciBar)[Index].Alignment,\r
549 Index,\r
550 PciBarTypeIo16,\r
551 PciResUsageTypical\r
552 );\r
553\r
554 InsertResourceNode (\r
555 IoNode,\r
556 Node\r
557 );\r
558 ResourceRequested = TRUE;\r
559 break;\r
560\r
561 case PciBarTypeUnknown:\r
562 break;\r
563\r
564 default:\r
565 break;\r
566 }\r
567 }\r
568\r
569 //\r
570 // If there is no resource requested from this device,\r
571 // then we indicate this device has been allocated naturally.\r
572 //\r
573 if (!ResourceRequested) {\r
574 PciDev->Allocated = TRUE;\r
575 }\r
576\r
577 return EFI_SUCCESS;\r
578}\r
579\r
580PCI_RESOURCE_NODE *\r
581CreateResourceNode (\r
582 IN PCI_IO_DEVICE *PciDev,\r
583 IN UINT64 Length,\r
584 IN UINT64 Alignment,\r
585 IN UINT8 Bar,\r
586 IN PCI_BAR_TYPE ResType,\r
587 IN PCI_RESOURCE_USAGE ResUsage\r
588 )\r
589/*++\r
590\r
591Routine Description:\r
592\r
593 This function is used to create a resource node\r
594\r
595Arguments:\r
596\r
597Returns:\r
598\r
599 None\r
600\r
601--*/\r
602// TODO: PciDev - add argument and description to function comment\r
603// TODO: Length - add argument and description to function comment\r
604// TODO: Alignment - add argument and description to function comment\r
605// TODO: Bar - add argument and description to function comment\r
606// TODO: ResType - add argument and description to function comment\r
607// TODO: ResUsage - add argument and description to function comment\r
608{\r
609 EFI_STATUS Status;\r
610 PCI_RESOURCE_NODE *Node;\r
611\r
612 Status = 0;\r
613 Node = NULL;\r
614\r
615 Node = AllocatePool (sizeof (PCI_RESOURCE_NODE));\r
616 if (Node == NULL) {\r
617 return NULL;\r
618 }\r
619\r
620 ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));\r
621\r
622 Node->Signature = PCI_RESOURCE_SIGNATURE;\r
623 Node->PciDev = PciDev;\r
624 Node->Length = Length;\r
625 Node->Alignment = Alignment;\r
626 Node->Bar = Bar;\r
627 Node->ResType = ResType;\r
628 Node->Reserved = FALSE;\r
629 Node->ResourceUsage = ResUsage;\r
630 InitializeListHead (&Node->ChildList);\r
631 return Node;\r
632}\r
633\r
634EFI_STATUS\r
635CreateResourceMap (\r
636 IN PCI_IO_DEVICE *Bridge,\r
637 IN PCI_RESOURCE_NODE *IoNode,\r
638 IN PCI_RESOURCE_NODE *Mem32Node,\r
639 IN PCI_RESOURCE_NODE *PMem32Node,\r
640 IN PCI_RESOURCE_NODE *Mem64Node,\r
641 IN PCI_RESOURCE_NODE *PMem64Node\r
642 )\r
643/*++\r
644\r
645Routine Description:\r
646\r
647 This routine is used to extract resource request from\r
648 device node list.\r
649\r
650Arguments:\r
651\r
652Returns:\r
653\r
654 None\r
655\r
656--*/\r
657// TODO: Bridge - add argument and description to function comment\r
658// TODO: IoNode - add argument and description to function comment\r
659// TODO: Mem32Node - add argument and description to function comment\r
660// TODO: PMem32Node - add argument and description to function comment\r
661// TODO: Mem64Node - add argument and description to function comment\r
662// TODO: PMem64Node - add argument and description to function comment\r
663// TODO: EFI_SUCCESS - add return value to function comment\r
664{\r
665 PCI_IO_DEVICE *Temp;\r
666 EFI_STATUS Status;\r
667 PCI_RESOURCE_NODE *IoBridge;\r
668 PCI_RESOURCE_NODE *Mem32Bridge;\r
669 PCI_RESOURCE_NODE *PMem32Bridge;\r
670 PCI_RESOURCE_NODE *Mem64Bridge;\r
671 PCI_RESOURCE_NODE *PMem64Bridge;\r
672 LIST_ENTRY *CurrentLink;\r
673\r
674 CurrentLink = Bridge->ChildList.ForwardLink;\r
675\r
676 while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
677\r
678 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
679\r
680 //\r
681 // Create resource nodes for this device by scanning the\r
682 // Bar array in the device private data\r
683 // If the upstream bridge doesn't support this device,\r
684 // no any resource node will be created for this device\r
685 //\r
686 GetResourceFromDevice (\r
687 Temp,\r
688 IoNode,\r
689 Mem32Node,\r
690 PMem32Node,\r
691 Mem64Node,\r
692 PMem64Node\r
693 );\r
694\r
695 if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
696\r
697 //\r
698 // If the device has children, create a bridge resource node for this PPB\r
699 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
700 // is aligned with 4KB\r
701 // This device is typically a bridge device like PPB and P2C\r
702 //\r
703 IoBridge = CreateResourceNode (\r
704 Temp,\r
705 0,\r
706 0xFFF,\r
707 PPB_IO_RANGE,\r
708 PciBarTypeIo16,\r
709 PciResUsageTypical\r
710 ); //0x1000 aligned\r
711 \r
712 Mem32Bridge = CreateResourceNode (\r
713 Temp,\r
714 0,\r
715 0xFFFFF,\r
716 PPB_MEM32_RANGE,\r
717 PciBarTypeMem32,\r
718 PciResUsageTypical\r
719 );\r
720\r
721 PMem32Bridge = CreateResourceNode (\r
722 Temp,\r
723 0,\r
724 0xFFFFF,\r
725 PPB_PMEM32_RANGE,\r
726 PciBarTypePMem32,\r
727 PciResUsageTypical\r
728 );\r
729\r
730 Mem64Bridge = CreateResourceNode (\r
731 Temp,\r
732 0,\r
733 0xFFFFF,\r
734 PPB_MEM64_RANGE,\r
735 PciBarTypeMem64,\r
736 PciResUsageTypical\r
737 );\r
738\r
739 PMem64Bridge = CreateResourceNode (\r
740 Temp,\r
741 0,\r
742 0xFFFFF,\r
743 PPB_PMEM64_RANGE,\r
744 PciBarTypePMem64,\r
745 PciResUsageTypical\r
746 );\r
747\r
748 //\r
749 // Recursively create resouce map on this bridge\r
750 //\r
751 Status = CreateResourceMap (\r
752 Temp,\r
753 IoBridge,\r
754 Mem32Bridge,\r
755 PMem32Bridge,\r
756 Mem64Bridge,\r
757 PMem64Bridge\r
758 );\r
759\r
760 if (ResourceRequestExisted (IoBridge)) {\r
761 InsertResourceNode (\r
762 IoNode,\r
763 IoBridge\r
764 );\r
765 } else {\r
766 gBS->FreePool (IoBridge);\r
767 IoBridge = NULL;\r
768 }\r
769\r
770 //\r
771 // If there is node under this resource bridge,\r
772 // then calculate bridge's aperture of this type\r
773 // and insert it into the respective resource tree.\r
774 // If no, delete this resource bridge\r
775 //\r
776 if (ResourceRequestExisted (Mem32Bridge)) {\r
777 InsertResourceNode (\r
778 Mem32Node,\r
779 Mem32Bridge\r
780 );\r
781 } else {\r
782 gBS->FreePool (Mem32Bridge);\r
783 Mem32Bridge = NULL;\r
784 }\r
785\r
786 //\r
787 // If there is node under this resource bridge,\r
788 // then calculate bridge's aperture of this type\r
789 // and insert it into the respective resource tree.\r
790 // If no, delete this resource bridge\r
791 //\r
792 if (ResourceRequestExisted (PMem32Bridge)) {\r
793 InsertResourceNode (\r
794 PMem32Node,\r
795 PMem32Bridge\r
796 );\r
797 } else {\r
798 gBS->FreePool (PMem32Bridge);\r
799 PMem32Bridge = NULL;\r
800 }\r
801\r
802 //\r
803 // If there is node under this resource bridge,\r
804 // then calculate bridge's aperture of this type\r
805 // and insert it into the respective resource tree.\r
806 // If no, delete this resource bridge\r
807 //\r
808 if (ResourceRequestExisted (Mem64Bridge)) {\r
809 InsertResourceNode (\r
810 Mem64Node,\r
811 Mem64Bridge\r
812 );\r
813 } else {\r
814 gBS->FreePool (Mem64Bridge);\r
815 Mem64Bridge = NULL;\r
816 }\r
817\r
818 //\r
819 // If there is node under this resource bridge,\r
820 // then calculate bridge's aperture of this type\r
821 // and insert it into the respective resource tree.\r
822 // If no, delete this resource bridge\r
823 //\r
824 if (ResourceRequestExisted (PMem64Bridge)) {\r
825 InsertResourceNode (\r
826 PMem64Node,\r
827 PMem64Bridge\r
828 );\r
829 } else {\r
830 gBS->FreePool (PMem64Bridge);\r
831 PMem64Bridge = NULL;\r
832 }\r
833\r
834 }\r
835\r
836 //\r
837 // If it is P2C, apply hard coded resource padding\r
838 //\r
839 //\r
840 if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
841 ResourcePaddingForCardBusBridge (\r
842 Temp,\r
843 IoNode,\r
844 Mem32Node,\r
845 PMem32Node,\r
846 Mem64Node,\r
847 PMem64Node\r
848 );\r
849 }\r
850\r
851 CurrentLink = CurrentLink->ForwardLink;\r
852 }\r
853 //\r
854 //\r
855 // To do some platform specific resource padding ...\r
856 //\r
857 Status = ResourcePaddingPolicy (\r
858 Bridge,\r
859 IoNode,\r
860 Mem32Node,\r
861 PMem32Node,\r
862 Mem64Node,\r
863 PMem64Node\r
864 );\r
865\r
866 //\r
867 // Degrade resource if necessary\r
868 //\r
869 DegradeResource (\r
870 Bridge,\r
871 Mem32Node,\r
872 PMem32Node,\r
873 Mem64Node,\r
874 PMem64Node\r
875 );\r
876\r
877 //\r
878 // Calculate resource aperture for this bridge device\r
879 //\r
880 CalculateResourceAperture (Mem32Node);\r
881 CalculateResourceAperture (PMem32Node);\r
882 CalculateResourceAperture (Mem64Node);\r
883 CalculateResourceAperture (PMem64Node);\r
884 CalculateResourceAperture (IoNode);\r
885\r
886 return EFI_SUCCESS;\r
887\r
888}\r
889\r
890EFI_STATUS\r
891ResourcePaddingPolicy (\r
892 PCI_IO_DEVICE *PciDev,\r
893 PCI_RESOURCE_NODE *IoNode,\r
894 PCI_RESOURCE_NODE *Mem32Node,\r
895 PCI_RESOURCE_NODE *PMem32Node,\r
896 PCI_RESOURCE_NODE *Mem64Node,\r
897 PCI_RESOURCE_NODE *PMem64Node\r
898 )\r
899/*++\r
900\r
901Routine Description:\r
902\r
903 This function is used to do the resource padding for a specific platform\r
904\r
905Arguments:\r
906\r
907 PciDev - A pointer to the PCI_IO_DEVICE structrue. \r
908 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.\r
909 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
910 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
911 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
912 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
913\r
914Returns:\r
915 Status code\r
916\r
917 None\r
918\r
919--*/\r
920// TODO: EFI_SUCCESS - add return value to function comment\r
921{\r
922 //\r
923 // Create padding resource node\r
924 //\r
925 if (PciDev->ResourcePaddingDescriptors != NULL) {\r
926 ApplyResourcePadding (\r
927 PciDev,\r
928 IoNode,\r
929 Mem32Node,\r
930 PMem32Node,\r
931 Mem64Node,\r
932 PMem64Node\r
933 );\r
934 }\r
935\r
936 return EFI_SUCCESS;\r
937\r
938}\r
939\r
940EFI_STATUS\r
941DegradeResource (\r
942 IN PCI_IO_DEVICE *Bridge,\r
943 IN PCI_RESOURCE_NODE *Mem32Node,\r
944 IN PCI_RESOURCE_NODE *PMem32Node,\r
945 IN PCI_RESOURCE_NODE *Mem64Node,\r
946 IN PCI_RESOURCE_NODE *PMem64Node\r
947 )\r
948/*++\r
949\r
950Routine Description:\r
951\r
952 This function is used to degrade resource if the upstream bridge \r
953 doesn't support certain resource. Degradation path is \r
954 PMEM64 -> MEM64 -> MEM32\r
955 PMEM64 -> PMEM32 -> MEM32\r
956 IO32 -> IO16\r
957\r
958Arguments:\r
959\r
960Returns:\r
961\r
962 None\r
963\r
964--*/\r
965// TODO: Bridge - add argument and description to function comment\r
966// TODO: Mem32Node - add argument and description to function comment\r
967// TODO: PMem32Node - add argument and description to function comment\r
968// TODO: Mem64Node - add argument and description to function comment\r
969// TODO: PMem64Node - add argument and description to function comment\r
970// TODO: EFI_SUCCESS - add return value to function comment\r
971{\r
972\r
973 //\r
974 // If bridge doesn't support Prefetchable\r
975 // memory64, degrade it to Mem64\r
976 //\r
977 if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
978 MergeResourceTree (\r
979 PMem32Node,\r
980 PMem64Node,\r
981 TRUE\r
982 );\r
983 } else {\r
984 //\r
985 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32\r
986 //\r
987 if (PMem32Node != NULL) {\r
988 MergeResourceTree (\r
989 PMem32Node,\r
990 PMem64Node,\r
991 TRUE\r
992 );\r
993 }\r
994 }\r
995\r
996\r
997 //\r
998 // If bridge doesn't support Mem64\r
999 // degrade it to mem32\r
1000 //\r
1001 if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
1002 MergeResourceTree (\r
1003 Mem32Node,\r
1004 Mem64Node,\r
1005 TRUE\r
1006 );\r
1007 }\r
1008\r
1009 //\r
1010 // If bridge doesn't support Pmem32\r
1011 // degrade it to mem32\r
1012 //\r
1013 if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {\r
1014 MergeResourceTree (\r
1015 Mem32Node,\r
1016 PMem32Node,\r
1017 TRUE\r
1018 );\r
1019 }\r
1020\r
1021 //\r
1022 // if bridge supports combined Pmem Mem decoding\r
1023 // merge these two type of resource\r
1024 //\r
1025 if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
1026 MergeResourceTree (\r
1027 Mem32Node,\r
1028 PMem32Node,\r
1029 FALSE\r
1030 );\r
1031\r
1032 MergeResourceTree (\r
1033 Mem64Node,\r
1034 PMem64Node,\r
1035 FALSE\r
1036 );\r
1037 }\r
1038\r
1039 return EFI_SUCCESS;\r
1040}\r
1041\r
1042BOOLEAN\r
1043BridgeSupportResourceDecode (\r
1044 IN PCI_IO_DEVICE *Bridge,\r
1045 IN UINT32 Decode\r
1046 )\r
1047/*++\r
1048\r
1049Routine Description:\r
1050\r
1051 TODO: Add function description\r
1052\r
1053Arguments:\r
1054\r
1055 Bridge - TODO: add argument description\r
1056 Decode - TODO: add argument description\r
1057\r
1058Returns:\r
1059\r
1060 TODO: add return values\r
1061\r
1062--*/\r
1063{\r
1064 /*++\r
1065\r
1066Routine Description:\r
1067\r
1068Arguments:\r
1069\r
1070Returns:\r
1071 \r
1072 None\r
1073\r
1074--*/\r
1075 if ((Bridge->Decodes) & Decode) {\r
1076 return TRUE;\r
1077 }\r
1078\r
1079 return FALSE;\r
1080}\r
1081\r
1082EFI_STATUS\r
1083ProgramResource (\r
1084 IN UINT64 Base,\r
1085 IN PCI_RESOURCE_NODE *Bridge\r
1086 )\r
1087/*++\r
1088\r
1089Routine Description:\r
1090\r
1091 This function is used to program the resource allocated \r
1092 for each resource node\r
1093\r
1094Arguments:\r
1095\r
1096Returns:\r
1097\r
1098 None\r
1099\r
1100--*/\r
1101// TODO: Base - add argument and description to function comment\r
1102// TODO: Bridge - add argument and description to function comment\r
1103// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1104// TODO: EFI_SUCCESS - add return value to function comment\r
1105{\r
1106 LIST_ENTRY *CurrentLink;\r
1107 PCI_RESOURCE_NODE *Node;\r
1108 EFI_STATUS Status;\r
1109\r
1110 if (Base == gAllOne) {\r
1111 return EFI_OUT_OF_RESOURCES;\r
1112 }\r
1113\r
1114 CurrentLink = Bridge->ChildList.ForwardLink;\r
1115\r
1116 while (CurrentLink != &Bridge->ChildList) {\r
1117\r
1118 Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1119\r
1120 if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {\r
1121\r
1122 if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
1123 ProgramP2C (Base, Node);\r
1124 } else {\r
1125 ProgramBar (Base, Node);\r
1126 }\r
1127 } else {\r
1128 Status = ProgramResource (Base + Node->Offset, Node);\r
1129\r
1130 if (EFI_ERROR (Status)) {\r
1131 return Status;\r
1132 }\r
1133\r
1134 ProgramPpbApperture (Base, Node);\r
1135 }\r
1136\r
1137 CurrentLink = CurrentLink->ForwardLink;\r
1138 }\r
1139\r
1140 return EFI_SUCCESS;\r
1141}\r
1142\r
1143EFI_STATUS\r
1144ProgramBar (\r
1145 IN UINT64 Base,\r
1146 IN PCI_RESOURCE_NODE *Node\r
1147 )\r
1148/*++\r
1149\r
1150Routine Description:\r
1151\r
1152Arguments:\r
1153\r
1154Returns:\r
1155 \r
1156 None\r
1157\r
1158--*/\r
1159// TODO: Base - add argument and description to function comment\r
1160// TODO: Node - add argument and description to function comment\r
1161// TODO: EFI_SUCCESS - add return value to function comment\r
1162{\r
1163 EFI_PCI_IO_PROTOCOL *PciIo;\r
1164 UINT64 Address;\r
1165 UINT32 Address32;\r
1166\r
1167 Address = 0;\r
1168 PciIo = &(Node->PciDev->PciIo);\r
1169\r
1170 Address = Base + Node->Offset;\r
1171\r
1172 //\r
1173 // Indicate pci bus driver has allocated\r
1174 // resource for this device\r
1175 // It might be a temporary solution here since\r
1176 // pci device could have multiple bar\r
1177 //\r
1178 Node->PciDev->Allocated = TRUE;\r
1179\r
1180 switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {\r
1181\r
1182 case PciBarTypeIo16:\r
1183 case PciBarTypeIo32:\r
1184 case PciBarTypeMem32:\r
1185 case PciBarTypePMem32:\r
1186\r
1187 PciIo->Pci.Write (\r
1188 PciIo,\r
1189 EfiPciIoWidthUint32,\r
1190 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1191 1,\r
1192 &Address\r
1193 );\r
1194\r
1195 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1196\r
1197 break;\r
1198\r
1199 case PciBarTypeMem64:\r
1200 case PciBarTypePMem64:\r
1201\r
1202 Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
1203\r
1204 PciIo->Pci.Write (\r
1205 PciIo,\r
1206 EfiPciIoWidthUint32,\r
1207 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1208 1,\r
1209 &Address32\r
1210 );\r
1211\r
1212 Address32 = (UINT32) RShiftU64 (Address, 32);\r
1213\r
1214 PciIo->Pci.Write (\r
1215 PciIo,\r
1216 EfiPciIoWidthUint32,\r
1217 (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),\r
1218 1,\r
1219 &Address32\r
1220 );\r
1221\r
1222 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1223\r
1224 break;\r
1225\r
1226 default:\r
1227 break;\r
1228 }\r
1229\r
1230 return EFI_SUCCESS;\r
1231}\r
1232\r
1233EFI_STATUS\r
1234ProgramPpbApperture (\r
1235 IN UINT64 Base,\r
1236 IN PCI_RESOURCE_NODE *Node\r
1237 )\r
1238/*++\r
1239\r
1240Routine Description:\r
1241\r
1242Arguments:\r
1243\r
1244Returns:\r
1245 \r
1246 None\r
1247\r
1248--*/\r
1249// TODO: Base - add argument and description to function comment\r
1250// TODO: Node - add argument and description to function comment\r
1251// TODO: EFI_SUCCESS - add return value to function comment\r
1252// TODO: EFI_SUCCESS - add return value to function comment\r
1253{\r
1254 EFI_PCI_IO_PROTOCOL *PciIo;\r
1255 UINT64 Address;\r
1256 UINT32 Address32;\r
1257\r
1258 Address = 0;\r
1259 //\r
1260 // if no device south of this PPB, return anyway\r
1261 // Apperture is set default in the initialization code\r
1262 //\r
1263 if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {\r
1264 //\r
1265 // For padding resource node, just ignore when programming\r
1266 //\r
1267 return EFI_SUCCESS;\r
1268 }\r
1269\r
1270 PciIo = &(Node->PciDev->PciIo);\r
1271 Address = Base + Node->Offset;\r
1272\r
1273 //\r
1274 // Indicate the PPB resource has been allocated\r
1275 //\r
1276 Node->PciDev->Allocated = TRUE;\r
1277\r
1278 switch (Node->Bar) {\r
1279\r
1280 case PPB_BAR_0:\r
1281 case PPB_BAR_1:\r
1282 PciIo->Pci.Write (\r
1283 PciIo,\r
1284 EfiPciIoWidthUint32,\r
1285 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1286 1,\r
1287 &Address\r
1288 );\r
1289\r
1290 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1291 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1292\r
1293 break;\r
1294\r
1295 case PPB_IO_RANGE:\r
1296\r
1297 Address32 = ((UINT32) (Address)) >> 8;\r
1298 PciIo->Pci.Write (\r
1299 PciIo,\r
1300 EfiPciIoWidthUint8,\r
1301 0x1C,\r
1302 1,\r
1303 &Address32\r
1304 );\r
1305\r
1306 Address32 >>= 8;\r
1307 PciIo->Pci.Write (\r
1308 PciIo,\r
1309 EfiPciIoWidthUint16,\r
1310 0x30,\r
1311 1,\r
1312 &Address32\r
1313 );\r
1314\r
1315 Address32 = (UINT32) (Address + Node->Length - 1);\r
1316 Address32 = ((UINT32) (Address32)) >> 8;\r
1317 PciIo->Pci.Write (\r
1318 PciIo,\r
1319 EfiPciIoWidthUint8,\r
1320 0x1D,\r
1321 1,\r
1322 &Address32\r
1323 );\r
1324\r
1325 Address32 >>= 8;\r
1326 PciIo->Pci.Write (\r
1327 PciIo,\r
1328 EfiPciIoWidthUint16,\r
1329 0x32,\r
1330 1,\r
1331 &Address32\r
1332 );\r
1333\r
1334 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1335 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1336 break;\r
1337\r
1338 case PPB_MEM32_RANGE:\r
1339\r
1340 Address32 = ((UINT32) (Address)) >> 16;\r
1341 PciIo->Pci.Write (\r
1342 PciIo,\r
1343 EfiPciIoWidthUint16,\r
1344 0x20,\r
1345 1,\r
1346 &Address32\r
1347 );\r
1348\r
1349 Address32 = (UINT32) (Address + Node->Length - 1);\r
1350 Address32 = ((UINT32) (Address32)) >> 16;\r
1351 PciIo->Pci.Write (\r
1352 PciIo,\r
1353 EfiPciIoWidthUint16,\r
1354 0x22,\r
1355 1,\r
1356 &Address32\r
1357 );\r
1358\r
1359 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1360 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1361 break;\r
1362\r
1363 case PPB_PMEM32_RANGE:\r
1364 case PPB_PMEM64_RANGE:\r
1365\r
1366 Address32 = ((UINT32) (Address)) >> 16;\r
1367 PciIo->Pci.Write (\r
1368 PciIo,\r
1369 EfiPciIoWidthUint16,\r
1370 0x24,\r
1371 1,\r
1372 &Address32\r
1373 );\r
1374\r
1375 Address32 = (UINT32) (Address + Node->Length - 1);\r
1376 Address32 = ((UINT32) (Address32)) >> 16;\r
1377 PciIo->Pci.Write (\r
1378 PciIo,\r
1379 EfiPciIoWidthUint16,\r
1380 0x26,\r
1381 1,\r
1382 &Address32\r
1383 );\r
1384\r
1385 Address32 = (UINT32) RShiftU64 (Address, 32);\r
1386 PciIo->Pci.Write (\r
1387 PciIo,\r
1388 EfiPciIoWidthUint32,\r
1389 0x28,\r
1390 1,\r
1391 &Address32\r
1392 );\r
1393\r
1394 Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);\r
1395 PciIo->Pci.Write (\r
1396 PciIo,\r
1397 EfiPciIoWidthUint32,\r
1398 0x2C,\r
1399 1,\r
1400 &Address32\r
1401 );\r
1402\r
1403 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1404 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1405 break;\r
1406\r
1407 default:\r
1408 break;\r
1409 }\r
1410\r
1411 return EFI_SUCCESS;\r
1412}\r
1413\r
1414EFI_STATUS\r
1415ProgrameUpstreamBridgeForRom (\r
1416 IN PCI_IO_DEVICE *PciDevice,\r
1417 IN UINT32 OptionRomBase,\r
1418 IN BOOLEAN Enable\r
1419 )\r
1420/*++\r
1421\r
1422Routine Description:\r
1423\r
1424Arguments:\r
1425\r
1426Returns:\r
1427\r
1428--*/\r
1429// TODO: PciDevice - add argument and description to function comment\r
1430// TODO: OptionRomBase - add argument and description to function comment\r
1431// TODO: Enable - add argument and description to function comment\r
1432// TODO: EFI_SUCCESS - add return value to function comment\r
1433{\r
1434 PCI_IO_DEVICE *Parent;\r
1435 PCI_RESOURCE_NODE Node;\r
1436 //\r
1437 // For root bridge, just return.\r
1438 //\r
1439 Parent = PciDevice->Parent;\r
1440 ZeroMem (&Node, sizeof (Node));\r
1441 while (Parent) {\r
1442 if (!IS_PCI_BRIDGE (&Parent->Pci)) {\r
1443 break;\r
1444 }\r
1445\r
1446 Node.PciDev = Parent;\r
1447 Node.Length = PciDevice->RomSize;\r
1448 Node.Alignment = 0;\r
1449 Node.Bar = PPB_MEM32_RANGE;\r
1450 Node.ResType = PciBarTypeMem32;\r
1451 Node.Offset = 0;\r
1452\r
1453 //\r
1454 // Program PPB to only open a single <= 16<MB apperture\r
1455 //\r
1456 if (Enable) {\r
1457 ProgramPpbApperture (OptionRomBase, &Node);\r
1458 PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
1459 } else {\r
1460 InitializePpb (Parent);\r
1461 PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
1462 }\r
1463\r
1464 Parent = Parent->Parent;\r
1465 }\r
1466\r
1467 return EFI_SUCCESS;\r
1468}\r
1469\r
1470BOOLEAN\r
1471ResourceRequestExisted (\r
1472 IN PCI_RESOURCE_NODE *Bridge\r
1473 )\r
1474/*++\r
1475\r
1476Routine Description:\r
1477\r
1478Arguments:\r
1479\r
1480 Bridge - A pointer to the PCI_RESOURCE_NODE.\r
1481\r
1482Returns:\r
1483\r
1484 None\r
1485\r
1486--*/\r
1487{\r
1488 if (Bridge != NULL) {\r
1489 if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {\r
1490 return TRUE;\r
1491 }\r
1492 }\r
1493\r
1494 return FALSE;\r
1495}\r
1496\r
1497EFI_STATUS\r
1498InitializeResourcePool (\r
1499 PCI_RESOURCE_NODE *ResourcePool,\r
1500 PCI_BAR_TYPE ResourceType\r
1501 )\r
1502/*++\r
1503\r
1504Routine Description:\r
1505\r
1506Arguments:\r
1507\r
1508Returns:\r
1509\r
1510 None\r
1511\r
1512--*/\r
1513// TODO: ResourcePool - add argument and description to function comment\r
1514// TODO: ResourceType - add argument and description to function comment\r
1515// TODO: EFI_SUCCESS - add return value to function comment\r
1516{\r
1517\r
1518 ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));\r
1519 ResourcePool->ResType = ResourceType;\r
1520 ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;\r
1521 InitializeListHead (&ResourcePool->ChildList);\r
1522\r
1523 return EFI_SUCCESS;\r
1524}\r
1525\r
1526EFI_STATUS\r
1527GetResourceMap (\r
1528 PCI_IO_DEVICE *PciDev,\r
1529 PCI_RESOURCE_NODE **IoBridge,\r
1530 PCI_RESOURCE_NODE **Mem32Bridge,\r
1531 PCI_RESOURCE_NODE **PMem32Bridge,\r
1532 PCI_RESOURCE_NODE **Mem64Bridge,\r
1533 PCI_RESOURCE_NODE **PMem64Bridge,\r
1534 PCI_RESOURCE_NODE *IoPool,\r
1535 PCI_RESOURCE_NODE *Mem32Pool,\r
1536 PCI_RESOURCE_NODE *PMem32Pool,\r
1537 PCI_RESOURCE_NODE *Mem64Pool,\r
1538 PCI_RESOURCE_NODE *PMem64Pool\r
1539 )\r
1540/*++\r
1541\r
1542Routine Description:\r
1543\r
1544Arguments:\r
1545\r
1546Returns:\r
1547\r
1548 None\r
1549\r
1550--*/\r
1551// TODO: PciDev - add argument and description to function comment\r
1552// TODO: IoBridge - add argument and description to function comment\r
1553// TODO: Mem32Bridge - add argument and description to function comment\r
1554// TODO: PMem32Bridge - add argument and description to function comment\r
1555// TODO: Mem64Bridge - add argument and description to function comment\r
1556// TODO: PMem64Bridge - add argument and description to function comment\r
1557// TODO: IoPool - add argument and description to function comment\r
1558// TODO: Mem32Pool - add argument and description to function comment\r
1559// TODO: PMem32Pool - add argument and description to function comment\r
1560// TODO: Mem64Pool - add argument and description to function comment\r
1561// TODO: PMem64Pool - add argument and description to function comment\r
1562// TODO: EFI_SUCCESS - add return value to function comment\r
1563{\r
1564\r
1565 PCI_RESOURCE_NODE *Temp;\r
1566 LIST_ENTRY *CurrentLink;\r
1567\r
1568 CurrentLink = IoPool->ChildList.ForwardLink;\r
1569\r
1570 //\r
1571 // Get Io resource map\r
1572 //\r
1573 while (CurrentLink != &IoPool->ChildList) {\r
1574\r
1575 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1576\r
1577 if (Temp->PciDev == PciDev) {\r
1578 *IoBridge = Temp;\r
1579 }\r
1580\r
1581 CurrentLink = CurrentLink->ForwardLink;\r
1582 }\r
1583\r
1584 //\r
1585 // Get Mem32 resource map\r
1586 //\r
1587 CurrentLink = Mem32Pool->ChildList.ForwardLink;\r
1588\r
1589 while (CurrentLink != &Mem32Pool->ChildList) {\r
1590\r
1591 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1592\r
1593 if (Temp->PciDev == PciDev) {\r
1594 *Mem32Bridge = Temp;\r
1595 }\r
1596\r
1597 CurrentLink = CurrentLink->ForwardLink;\r
1598 }\r
1599\r
1600 //\r
1601 // Get Pmem32 resource map\r
1602 //\r
1603 CurrentLink = PMem32Pool->ChildList.ForwardLink;\r
1604\r
1605 while (CurrentLink != &PMem32Pool->ChildList) {\r
1606\r
1607 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1608\r
1609 if (Temp->PciDev == PciDev) {\r
1610 *PMem32Bridge = Temp;\r
1611 }\r
1612\r
1613 CurrentLink = CurrentLink->ForwardLink;\r
1614 }\r
1615\r
1616 //\r
1617 // Get Mem64 resource map\r
1618 //\r
1619 CurrentLink = Mem64Pool->ChildList.ForwardLink;\r
1620\r
1621 while (CurrentLink != &Mem64Pool->ChildList) {\r
1622\r
1623 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1624\r
1625 if (Temp->PciDev == PciDev) {\r
1626 *Mem64Bridge = Temp;\r
1627 }\r
1628\r
1629 CurrentLink = CurrentLink->ForwardLink;\r
1630 }\r
1631\r
1632 //\r
1633 // Get Pmem64 resource map\r
1634 //\r
1635 CurrentLink = PMem64Pool->ChildList.ForwardLink;\r
1636\r
1637 while (CurrentLink != &PMem64Pool->ChildList) {\r
1638\r
1639 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1640\r
1641 if (Temp->PciDev == PciDev) {\r
1642 *PMem64Bridge = Temp;\r
1643 }\r
1644\r
1645 CurrentLink = CurrentLink->ForwardLink;\r
1646 }\r
1647\r
1648 return EFI_SUCCESS;\r
1649}\r
1650\r
1651EFI_STATUS\r
1652DestroyResourceTree (\r
1653 IN PCI_RESOURCE_NODE *Bridge\r
1654 )\r
1655/*++\r
1656\r
1657Routine Description:\r
1658\r
1659Arguments:\r
1660\r
1661Returns:\r
1662\r
1663 None\r
1664\r
1665--*/\r
1666// TODO: Bridge - add argument and description to function comment\r
1667// TODO: EFI_SUCCESS - add return value to function comment\r
1668{\r
1669 PCI_RESOURCE_NODE *Temp;\r
1670 LIST_ENTRY *CurrentLink;\r
1671\r
1672 while (!IsListEmpty (&Bridge->ChildList)) {\r
1673\r
1674 CurrentLink = Bridge->ChildList.ForwardLink;\r
1675\r
1676 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1677\r
1678 RemoveEntryList (CurrentLink);\r
1679\r
1680 if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {\r
1681 DestroyResourceTree (Temp);\r
1682 }\r
1683\r
1684 gBS->FreePool (Temp);\r
1685 }\r
1686\r
1687 return EFI_SUCCESS;\r
1688}\r
1689\r
1690EFI_STATUS\r
1691RecordReservedResource (\r
1692 IN UINT64 Base,\r
1693 IN UINT64 Length,\r
1694 IN PCI_BAR_TYPE ResType,\r
1695 IN PCI_IO_DEVICE *Bridge\r
1696 )\r
1697/*++\r
1698\r
1699Routine Description:\r
1700 \r
1701Arguments:\r
1702\r
1703Returns:\r
1704\r
1705 None\r
1706\r
1707--*/\r
1708// TODO: Base - add argument and description to function comment\r
1709// TODO: Length - add argument and description to function comment\r
1710// TODO: ResType - add argument and description to function comment\r
1711// TODO: Bridge - add argument and description to function comment\r
1712// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1713// TODO: EFI_SUCCESS - add return value to function comment\r
1714{\r
1715 PCI_RESERVED_RESOURCE_LIST *ReservedNode;\r
1716\r
1717 ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));\r
1718 if (ReservedNode == NULL) {\r
1719 return EFI_OUT_OF_RESOURCES;\r
1720 }\r
1721\r
1722 ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE;\r
1723 ReservedNode->Node.Base = Base;\r
1724 ReservedNode->Node.Length = Length;\r
1725 ReservedNode->Node.ResType = ResType;\r
1726\r
1727 InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));\r
1728\r
1729 return EFI_SUCCESS;\r
1730}\r
1731\r
1732EFI_STATUS\r
1733ResourcePaddingForCardBusBridge (\r
1734 PCI_IO_DEVICE *PciDev,\r
1735 PCI_RESOURCE_NODE *IoNode,\r
1736 PCI_RESOURCE_NODE *Mem32Node,\r
1737 PCI_RESOURCE_NODE *PMem32Node,\r
1738 PCI_RESOURCE_NODE *Mem64Node,\r
1739 PCI_RESOURCE_NODE *PMem64Node\r
1740 )\r
1741/*++\r
1742\r
1743Routine Description:\r
1744\r
1745Arguments:\r
1746\r
1747Returns:\r
1748\r
1749 None\r
1750\r
1751--*/\r
1752// TODO: PciDev - add argument and description to function comment\r
1753// TODO: IoNode - add argument and description to function comment\r
1754// TODO: Mem32Node - add argument and description to function comment\r
1755// TODO: PMem32Node - add argument and description to function comment\r
1756// TODO: Mem64Node - add argument and description to function comment\r
1757// TODO: PMem64Node - add argument and description to function comment\r
1758// TODO: EFI_SUCCESS - add return value to function comment\r
1759{\r
1760 PCI_RESOURCE_NODE *Node;\r
1761\r
1762 Node = NULL;\r
1763\r
1764 //\r
1765 // Memory Base/Limit Register 0\r
1766 // Bar 1 denodes memory range 0\r
1767 //\r
1768 Node = CreateResourceNode (\r
1769 PciDev,\r
1770 0x2000000,\r
1771 0x1ffffff,\r
1772 1,\r
1773 PciBarTypeMem32,\r
1774 PciResUsagePadding\r
1775 );\r
1776\r
1777 InsertResourceNode (\r
1778 Mem32Node,\r
1779 Node\r
1780 );\r
1781\r
1782 //\r
1783 // Memory Base/Limit Register 1\r
1784 // Bar 2 denodes memory range1\r
1785 //\r
1786 Node = CreateResourceNode (\r
1787 PciDev,\r
1788 0x2000000,\r
1789 0x1ffffff,\r
1790 2,\r
1791 PciBarTypePMem32,\r
1792 PciResUsagePadding\r
1793 );\r
1794\r
1795 InsertResourceNode (\r
1796 PMem32Node,\r
1797 Node\r
1798 );\r
1799\r
1800 //\r
1801 // Io Base/Limit\r
1802 // Bar 3 denodes io range 0\r
1803 //\r
1804 Node = CreateResourceNode (\r
1805 PciDev,\r
1806 0x100,\r
1807 0xff,\r
1808 3,\r
1809 PciBarTypeIo16,\r
1810 PciResUsagePadding\r
1811 );\r
1812\r
1813 InsertResourceNode (\r
1814 IoNode,\r
1815 Node\r
1816 );\r
1817\r
1818 //\r
1819 // Io Base/Limit\r
1820 // Bar 4 denodes io range 0\r
1821 //\r
1822 Node = CreateResourceNode (\r
1823 PciDev,\r
1824 0x100,\r
1825 0xff,\r
1826 4,\r
1827 PciBarTypeIo16,\r
1828 PciResUsagePadding\r
1829 );\r
1830\r
1831 InsertResourceNode (\r
1832 IoNode,\r
1833 Node\r
1834 );\r
1835\r
1836 return EFI_SUCCESS;\r
1837}\r
1838\r
1839EFI_STATUS\r
1840ProgramP2C (\r
1841 IN UINT64 Base,\r
1842 IN PCI_RESOURCE_NODE *Node\r
1843 )\r
1844/*++\r
1845\r
1846Routine Description:\r
1847\r
1848Arguments:\r
1849\r
1850Returns:\r
1851 \r
1852 None\r
1853\r
1854--*/\r
1855// TODO: Base - add argument and description to function comment\r
1856// TODO: Node - add argument and description to function comment\r
1857// TODO: EFI_SUCCESS - add return value to function comment\r
1858{\r
1859 EFI_PCI_IO_PROTOCOL *PciIo;\r
1860 UINT64 Address;\r
1861 UINT64 TempAddress;\r
1862 UINT16 BridgeControl;\r
1863\r
1864 Address = 0;\r
1865 PciIo = &(Node->PciDev->PciIo);\r
1866\r
1867 Address = Base + Node->Offset;\r
1868\r
1869 //\r
1870 // Indicate pci bus driver has allocated\r
1871 // resource for this device\r
1872 // It might be a temporary solution here since\r
1873 // pci device could have multiple bar\r
1874 //\r
1875 Node->PciDev->Allocated = TRUE;\r
1876\r
1877 switch (Node->Bar) {\r
1878\r
1879 case P2C_BAR_0:\r
1880 PciIo->Pci.Write (\r
1881 PciIo,\r
1882 EfiPciIoWidthUint32,\r
1883 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1884 1,\r
1885 &Address\r
1886 );\r
1887\r
1888 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1889 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1890 break;\r
1891\r
1892 case P2C_MEM_1:\r
1893 PciIo->Pci.Write (\r
1894 PciIo,\r
1895 EfiPciIoWidthUint32,\r
1896 0x1c,\r
1897 1,\r
1898 &Address\r
1899 );\r
1900\r
1901 TempAddress = Address + Node->Length - 1;\r
1902 PciIo->Pci.Write (\r
1903 PciIo,\r
1904 EfiPciIoWidthUint32,\r
1905 0x20,\r
1906 1,\r
1907 &TempAddress\r
1908 );\r
1909\r
1910 if (Node->ResType == PciBarTypeMem32) {\r
1911\r
1912 //\r
1913 // Set non-prefetchable bit\r
1914 //\r
1915 PciIo->Pci.Read (\r
1916 PciIo,\r
1917 EfiPciIoWidthUint16,\r
1918 0x3e,\r
1919 1,\r
1920 &BridgeControl\r
1921 );\r
1922\r
1923 BridgeControl &= 0xfeff;\r
1924 PciIo->Pci.Write (\r
1925 PciIo,\r
1926 EfiPciIoWidthUint16,\r
1927 0x3e,\r
1928 1,\r
1929 &BridgeControl\r
1930 );\r
1931\r
1932 } else {\r
1933\r
1934 //\r
1935 // Set pre-fetchable bit\r
1936 //\r
1937 PciIo->Pci.Read (\r
1938 PciIo,\r
1939 EfiPciIoWidthUint16,\r
1940 0x3e,\r
1941 1,\r
1942 &BridgeControl\r
1943 );\r
1944\r
1945 BridgeControl |= 0x0100;\r
1946 PciIo->Pci.Write (\r
1947 PciIo,\r
1948 EfiPciIoWidthUint16,\r
1949 0x3e,\r
1950 1,\r
1951 &BridgeControl\r
1952 );\r
1953 }\r
1954\r
1955 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1956 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1957 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
1958\r
1959 break;\r
1960\r
1961 case P2C_MEM_2:\r
1962 PciIo->Pci.Write (\r
1963 PciIo,\r
1964 EfiPciIoWidthUint32,\r
1965 0x24,\r
1966 1,\r
1967 &Address\r
1968 );\r
1969\r
1970 TempAddress = Address + Node->Length - 1;\r
1971\r
1972 PciIo->Pci.Write (\r
1973 PciIo,\r
1974 EfiPciIoWidthUint32,\r
1975 0x28,\r
1976 1,\r
1977 &TempAddress\r
1978 );\r
1979\r
1980 if (Node->ResType == PciBarTypeMem32) {\r
1981\r
1982 //\r
1983 // Set non-prefetchable bit\r
1984 //\r
1985 PciIo->Pci.Read (\r
1986 PciIo,\r
1987 EfiPciIoWidthUint16,\r
1988 0x3e,\r
1989 1,\r
1990 &BridgeControl\r
1991 );\r
1992\r
1993 BridgeControl &= 0xfdff;\r
1994 PciIo->Pci.Write (\r
1995 PciIo,\r
1996 EfiPciIoWidthUint16,\r
1997 0x3e,\r
1998 1,\r
1999 &BridgeControl\r
2000 );\r
2001 } else {\r
2002\r
2003 //\r
2004 // Set pre-fetchable bit\r
2005 //\r
2006 PciIo->Pci.Read (\r
2007 PciIo,\r
2008 EfiPciIoWidthUint16,\r
2009 0x3e,\r
2010 1,\r
2011 &BridgeControl\r
2012 );\r
2013\r
2014 BridgeControl |= 0x0200;\r
2015 PciIo->Pci.Write (\r
2016 PciIo,\r
2017 EfiPciIoWidthUint16,\r
2018 0x3e,\r
2019 1,\r
2020 &BridgeControl\r
2021 );\r
2022 }\r
2023\r
2024 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
2025 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
2026 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
2027 break;\r
2028\r
2029 case P2C_IO_1:\r
2030 PciIo->Pci.Write (\r
2031 PciIo,\r
2032 EfiPciIoWidthUint32,\r
2033 0x2c,\r
2034 1,\r
2035 &Address\r
2036 );\r
2037 TempAddress = Address + Node->Length - 1;\r
2038 PciIo->Pci.Write (\r
2039 PciIo,\r
2040 EfiPciIoWidthUint32,\r
2041 0x30,\r
2042 1,\r
2043 &TempAddress\r
2044 );\r
2045\r
2046 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
2047 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
2048 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
2049\r
2050 break;\r
2051\r
2052 case P2C_IO_2:\r
2053 PciIo->Pci.Write (\r
2054 PciIo,\r
2055 EfiPciIoWidthUint32,\r
2056 0x34,\r
2057 1,\r
2058 &Address\r
2059 );\r
2060\r
2061 TempAddress = Address + Node->Length - 1;\r
2062 PciIo->Pci.Write (\r
2063 PciIo,\r
2064 EfiPciIoWidthUint32,\r
2065 0x38,\r
2066 1,\r
2067 &TempAddress\r
2068 );\r
2069\r
2070 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
2071 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
2072 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
2073 break;\r
2074\r
2075 default:\r
2076 break;\r
2077 }\r
2078\r
2079 return EFI_SUCCESS;\r
2080}\r
2081\r
2082EFI_STATUS\r
2083ApplyResourcePadding (\r
2084 PCI_IO_DEVICE *PciDev,\r
2085 PCI_RESOURCE_NODE *IoNode,\r
2086 PCI_RESOURCE_NODE *Mem32Node,\r
2087 PCI_RESOURCE_NODE *PMem32Node,\r
2088 PCI_RESOURCE_NODE *Mem64Node,\r
2089 PCI_RESOURCE_NODE *PMem64Node\r
2090 )\r
2091/*++\r
2092\r
2093Routine Description:\r
2094\r
2095Arguments:\r
2096\r
2097Returns:\r
2098 \r
2099 None\r
2100\r
2101--*/\r
2102// TODO: PciDev - add argument and description to function comment\r
2103// TODO: IoNode - add argument and description to function comment\r
2104// TODO: Mem32Node - add argument and description to function comment\r
2105// TODO: PMem32Node - add argument and description to function comment\r
2106// TODO: Mem64Node - add argument and description to function comment\r
2107// TODO: PMem64Node - add argument and description to function comment\r
2108// TODO: EFI_SUCCESS - add return value to function comment\r
2109{\r
2110 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
2111 PCI_RESOURCE_NODE *Node;\r
2112 UINT8 DummyBarIndex;\r
2113\r
2114 DummyBarIndex = 0;\r
2115 Ptr = PciDev->ResourcePaddingDescriptors;\r
2116\r
2117 while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
2118\r
2119 if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {\r
2120 if (Ptr->AddrLen != 0) {\r
2121\r
2122 Node = CreateResourceNode (\r
2123 PciDev,\r
2124 Ptr->AddrLen,\r
2125 Ptr->AddrRangeMax,\r
2126 DummyBarIndex,\r
2127 PciBarTypeIo16,\r
2128 PciResUsagePadding\r
2129 );\r
2130 InsertResourceNode (\r
2131 IoNode,\r
2132 Node\r
2133 );\r
2134 }\r
2135\r
2136 Ptr++;\r
2137 continue;\r
2138 }\r
2139\r
2140 if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
2141\r
2142 if (Ptr->AddrSpaceGranularity == 32) {\r
2143\r
2144 //\r
2145 // prefechable\r
2146 //\r
2147 if (Ptr->SpecificFlag == 0x6) {\r
2148 if (Ptr->AddrLen) {\r
2149 Node = CreateResourceNode (\r
2150 PciDev,\r
2151 Ptr->AddrLen,\r
2152 Ptr->AddrRangeMax,\r
2153 DummyBarIndex,\r
2154 PciBarTypePMem32,\r
2155 PciResUsagePadding\r
2156 );\r
2157 InsertResourceNode (\r
2158 PMem32Node,\r
2159 Node\r
2160 );\r
2161 }\r
2162\r
2163 Ptr++;\r
2164 continue;\r
2165 }\r
2166\r
2167 //\r
2168 // Non-prefechable\r
2169 //\r
2170 if (Ptr->SpecificFlag == 0) {\r
2171 if (Ptr->AddrLen) {\r
2172 Node = CreateResourceNode (\r
2173 PciDev,\r
2174 Ptr->AddrLen,\r
2175 Ptr->AddrRangeMax,\r
2176 DummyBarIndex,\r
2177 PciBarTypeMem32,\r
2178 PciResUsagePadding\r
2179 );\r
2180 InsertResourceNode (\r
2181 Mem32Node,\r
2182 Node\r
2183 );\r
2184 }\r
2185\r
2186 Ptr++;\r
2187 continue;\r
2188 }\r
2189 }\r
2190\r
2191 if (Ptr->AddrSpaceGranularity == 64) {\r
2192\r
2193 //\r
2194 // prefechable\r
2195 //\r
2196 if (Ptr->SpecificFlag == 0x6) {\r
2197 if (Ptr->AddrLen) {\r
2198 Node = CreateResourceNode (\r
2199 PciDev,\r
2200 Ptr->AddrLen,\r
2201 Ptr->AddrRangeMax,\r
2202 DummyBarIndex,\r
2203 PciBarTypePMem64,\r
2204 PciResUsagePadding\r
2205 );\r
2206 InsertResourceNode (\r
2207 PMem64Node,\r
2208 Node\r
2209 );\r
2210 }\r
2211\r
2212 Ptr++;\r
2213 continue;\r
2214 }\r
2215\r
2216 //\r
2217 // Non-prefechable\r
2218 //\r
2219 if (Ptr->SpecificFlag == 0) {\r
2220 if (Ptr->AddrLen) {\r
2221 Node = CreateResourceNode (\r
2222 PciDev,\r
2223 Ptr->AddrLen,\r
2224 Ptr->AddrRangeMax,\r
2225 DummyBarIndex,\r
2226 PciBarTypeMem64,\r
2227 PciResUsagePadding\r
2228 );\r
2229 InsertResourceNode (\r
2230 Mem64Node,\r
2231 Node\r
2232 );\r
2233 }\r
2234\r
2235 Ptr++;\r
2236 continue;\r
2237 }\r
2238 }\r
2239 }\r
2240\r
2241 Ptr++;\r
2242 }\r
2243\r
2244 return EFI_SUCCESS;\r
2245}\r
2246\r
2247//\r
2248// Light PCI bus driver woundn't support hotplug root device\r
2249// So no need to pad resource for them\r
2250//\r
2251VOID\r
2252GetResourcePaddingPpb (\r
2253 IN PCI_IO_DEVICE *PciIoDevice\r
2254 )\r
2255/*++\r
2256\r
2257Routine Description:\r
2258\r
2259 Get resource.\r
2260\r
2261Arguments:\r
2262\r
2263 PciIoDevice A pointer to a pci device.\r
2264\r
2265Returns:\r
2266\r
2267 None\r
2268\r
2269--*/\r
2270{\r
2271 if (gPciHotPlugInit) {\r
2272 if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
2273 GetResourcePaddingForHpb (PciIoDevice);\r
2274 }\r
2275 }\r
2276}\r