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