]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
Merge tracker. Add check whether CreateResourceNode successful or not.
[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
7f0f1b8f 645 ASSERT (Node != NULL);\r
ead42efc 646 if (Node == NULL) {\r
647 return NULL;\r
648 }\r
649\r
650 ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));\r
651\r
652 Node->Signature = PCI_RESOURCE_SIGNATURE;\r
653 Node->PciDev = PciDev;\r
654 Node->Length = Length;\r
655 Node->Alignment = Alignment;\r
656 Node->Bar = Bar;\r
657 Node->ResType = ResType;\r
658 Node->Reserved = FALSE;\r
659 Node->ResourceUsage = ResUsage;\r
660 InitializeListHead (&Node->ChildList);\r
661 return Node;\r
662}\r
663\r
664EFI_STATUS\r
665CreateResourceMap (\r
666 IN PCI_IO_DEVICE *Bridge,\r
667 IN PCI_RESOURCE_NODE *IoNode,\r
668 IN PCI_RESOURCE_NODE *Mem32Node,\r
669 IN PCI_RESOURCE_NODE *PMem32Node,\r
670 IN PCI_RESOURCE_NODE *Mem64Node,\r
671 IN PCI_RESOURCE_NODE *PMem64Node\r
672 )\r
673/*++\r
674\r
675Routine Description:\r
676\r
677 This routine is used to extract resource request from\r
678 device node list.\r
679\r
680Arguments:\r
681\r
682Returns:\r
683\r
684 None\r
685\r
686--*/\r
687// TODO: Bridge - add argument and description to function comment\r
688// TODO: IoNode - add argument and description to function comment\r
689// TODO: Mem32Node - add argument and description to function comment\r
690// TODO: PMem32Node - add argument and description to function comment\r
691// TODO: Mem64Node - add argument and description to function comment\r
692// TODO: PMem64Node - add argument and description to function comment\r
693// TODO: EFI_SUCCESS - add return value to function comment\r
694{\r
695 PCI_IO_DEVICE *Temp;\r
696 PCI_RESOURCE_NODE *IoBridge;\r
697 PCI_RESOURCE_NODE *Mem32Bridge;\r
698 PCI_RESOURCE_NODE *PMem32Bridge;\r
699 PCI_RESOURCE_NODE *Mem64Bridge;\r
700 PCI_RESOURCE_NODE *PMem64Bridge;\r
701 LIST_ENTRY *CurrentLink;\r
702\r
703 CurrentLink = Bridge->ChildList.ForwardLink;\r
704\r
705 while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
706\r
707 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
708\r
709 //\r
710 // Create resource nodes for this device by scanning the\r
711 // Bar array in the device private data\r
712 // If the upstream bridge doesn't support this device,\r
713 // no any resource node will be created for this device\r
714 //\r
715 GetResourceFromDevice (\r
716 Temp,\r
717 IoNode,\r
718 Mem32Node,\r
719 PMem32Node,\r
720 Mem64Node,\r
721 PMem64Node\r
722 );\r
723\r
724 if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
725\r
726 //\r
727 // If the device has children, create a bridge resource node for this PPB\r
728 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
729 // is aligned with 4KB\r
730 // This device is typically a bridge device like PPB and P2C\r
731 //\r
732 IoBridge = CreateResourceNode (\r
733 Temp,\r
734 0,\r
735 0xFFF,\r
736 PPB_IO_RANGE,\r
737 PciBarTypeIo16,\r
738 PciResUsageTypical\r
739 ); //0x1000 aligned\r
740 \r
741 Mem32Bridge = CreateResourceNode (\r
742 Temp,\r
743 0,\r
744 0xFFFFF,\r
745 PPB_MEM32_RANGE,\r
746 PciBarTypeMem32,\r
747 PciResUsageTypical\r
748 );\r
749\r
750 PMem32Bridge = CreateResourceNode (\r
751 Temp,\r
752 0,\r
753 0xFFFFF,\r
754 PPB_PMEM32_RANGE,\r
755 PciBarTypePMem32,\r
756 PciResUsageTypical\r
757 );\r
758\r
759 Mem64Bridge = CreateResourceNode (\r
760 Temp,\r
761 0,\r
762 0xFFFFF,\r
763 PPB_MEM64_RANGE,\r
764 PciBarTypeMem64,\r
765 PciResUsageTypical\r
766 );\r
767\r
768 PMem64Bridge = CreateResourceNode (\r
769 Temp,\r
770 0,\r
771 0xFFFFF,\r
772 PPB_PMEM64_RANGE,\r
773 PciBarTypePMem64,\r
774 PciResUsageTypical\r
775 );\r
776\r
777 //\r
778 // Recursively create resouce map on this bridge\r
779 //\r
780 CreateResourceMap (\r
781 Temp,\r
782 IoBridge,\r
783 Mem32Bridge,\r
784 PMem32Bridge,\r
785 Mem64Bridge,\r
786 PMem64Bridge\r
787 );\r
788\r
789 if (ResourceRequestExisted (IoBridge)) {\r
790 InsertResourceNode (\r
791 IoNode,\r
792 IoBridge\r
793 );\r
794 } else {\r
795 gBS->FreePool (IoBridge);\r
796 IoBridge = NULL;\r
797 }\r
798\r
799 //\r
800 // If there is node under this resource bridge,\r
801 // then calculate bridge's aperture of this type\r
802 // and insert it into the respective resource tree.\r
803 // If no, delete this resource bridge\r
804 //\r
805 if (ResourceRequestExisted (Mem32Bridge)) {\r
806 InsertResourceNode (\r
807 Mem32Node,\r
808 Mem32Bridge\r
809 );\r
810 } else {\r
811 gBS->FreePool (Mem32Bridge);\r
812 Mem32Bridge = NULL;\r
813 }\r
814\r
815 //\r
816 // If there is node under this resource bridge,\r
817 // then calculate bridge's aperture of this type\r
818 // and insert it into the respective resource tree.\r
819 // If no, delete this resource bridge\r
820 //\r
821 if (ResourceRequestExisted (PMem32Bridge)) {\r
822 InsertResourceNode (\r
823 PMem32Node,\r
824 PMem32Bridge\r
825 );\r
826 } else {\r
827 gBS->FreePool (PMem32Bridge);\r
828 PMem32Bridge = NULL;\r
829 }\r
830\r
831 //\r
832 // If there is node under this resource bridge,\r
833 // then calculate bridge's aperture of this type\r
834 // and insert it into the respective resource tree.\r
835 // If no, delete this resource bridge\r
836 //\r
837 if (ResourceRequestExisted (Mem64Bridge)) {\r
838 InsertResourceNode (\r
839 Mem64Node,\r
840 Mem64Bridge\r
841 );\r
842 } else {\r
843 gBS->FreePool (Mem64Bridge);\r
844 Mem64Bridge = NULL;\r
845 }\r
846\r
847 //\r
848 // If there is node under this resource bridge,\r
849 // then calculate bridge's aperture of this type\r
850 // and insert it into the respective resource tree.\r
851 // If no, delete this resource bridge\r
852 //\r
853 if (ResourceRequestExisted (PMem64Bridge)) {\r
854 InsertResourceNode (\r
855 PMem64Node,\r
856 PMem64Bridge\r
857 );\r
858 } else {\r
859 gBS->FreePool (PMem64Bridge);\r
860 PMem64Bridge = NULL;\r
861 }\r
862\r
863 }\r
864\r
865 //\r
866 // If it is P2C, apply hard coded resource padding\r
867 //\r
868 //\r
869 if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
870 ResourcePaddingForCardBusBridge (\r
871 Temp,\r
872 IoNode,\r
873 Mem32Node,\r
874 PMem32Node,\r
875 Mem64Node,\r
876 PMem64Node\r
877 );\r
878 }\r
879\r
880 CurrentLink = CurrentLink->ForwardLink;\r
881 }\r
882 //\r
883 //\r
884 // To do some platform specific resource padding ...\r
885 //\r
886 ResourcePaddingPolicy (\r
887 Bridge,\r
888 IoNode,\r
889 Mem32Node,\r
890 PMem32Node,\r
891 Mem64Node,\r
892 PMem64Node\r
893 );\r
894\r
895 //\r
896 // Degrade resource if necessary\r
897 //\r
898 DegradeResource (\r
899 Bridge,\r
900 Mem32Node,\r
901 PMem32Node,\r
902 Mem64Node,\r
903 PMem64Node\r
904 );\r
905\r
906 //\r
907 // Calculate resource aperture for this bridge device\r
908 //\r
909 CalculateResourceAperture (Mem32Node);\r
910 CalculateResourceAperture (PMem32Node);\r
911 CalculateResourceAperture (Mem64Node);\r
912 CalculateResourceAperture (PMem64Node);\r
913 CalculateResourceAperture (IoNode);\r
914\r
915 return EFI_SUCCESS;\r
916\r
917}\r
918\r
919EFI_STATUS\r
920ResourcePaddingPolicy (\r
921 PCI_IO_DEVICE *PciDev,\r
922 PCI_RESOURCE_NODE *IoNode,\r
923 PCI_RESOURCE_NODE *Mem32Node,\r
924 PCI_RESOURCE_NODE *PMem32Node,\r
925 PCI_RESOURCE_NODE *Mem64Node,\r
926 PCI_RESOURCE_NODE *PMem64Node\r
927 )\r
928/*++\r
929\r
930Routine Description:\r
931\r
932 This function is used to do the resource padding for a specific platform\r
933\r
934Arguments:\r
935\r
936 PciDev - A pointer to the PCI_IO_DEVICE structrue. \r
937 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.\r
938 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
939 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
940 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
941 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
942\r
943Returns:\r
944 Status code\r
945\r
946 None\r
947\r
948--*/\r
949// TODO: EFI_SUCCESS - add return value to function comment\r
950{\r
951 //\r
952 // Create padding resource node\r
953 //\r
954 if (PciDev->ResourcePaddingDescriptors != NULL) {\r
955 ApplyResourcePadding (\r
956 PciDev,\r
957 IoNode,\r
958 Mem32Node,\r
959 PMem32Node,\r
960 Mem64Node,\r
961 PMem64Node\r
962 );\r
963 }\r
964\r
965 return EFI_SUCCESS;\r
966\r
967}\r
968\r
969EFI_STATUS\r
970DegradeResource (\r
971 IN PCI_IO_DEVICE *Bridge,\r
972 IN PCI_RESOURCE_NODE *Mem32Node,\r
973 IN PCI_RESOURCE_NODE *PMem32Node,\r
974 IN PCI_RESOURCE_NODE *Mem64Node,\r
975 IN PCI_RESOURCE_NODE *PMem64Node\r
976 )\r
977/*++\r
978\r
979Routine Description:\r
980\r
981 This function is used to degrade resource if the upstream bridge \r
982 doesn't support certain resource. Degradation path is \r
983 PMEM64 -> MEM64 -> MEM32\r
984 PMEM64 -> PMEM32 -> MEM32\r
985 IO32 -> IO16\r
986\r
987Arguments:\r
988\r
989Returns:\r
990\r
991 None\r
992\r
993--*/\r
994// TODO: Bridge - add argument and description to function comment\r
995// TODO: Mem32Node - add argument and description to function comment\r
996// TODO: PMem32Node - add argument and description to function comment\r
997// TODO: Mem64Node - add argument and description to function comment\r
998// TODO: PMem64Node - add argument and description to function comment\r
999// TODO: EFI_SUCCESS - add return value to function comment\r
1000{\r
1001\r
1002 //\r
1003 // If bridge doesn't support Prefetchable\r
1004 // memory64, degrade it to Prefetchable memory32\r
1005 //\r
1006 if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
1007 MergeResourceTree (\r
1008 PMem32Node,\r
1009 PMem64Node,\r
1010 TRUE\r
1011 );\r
1012 } else {\r
1013 //\r
1014 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32\r
1015 //\r
1016 if (PMem32Node != NULL) {\r
1017 MergeResourceTree (\r
1018 PMem32Node,\r
1019 PMem64Node,\r
1020 TRUE\r
1021 );\r
1022 }\r
1023 }\r
1024\r
1025\r
1026 //\r
1027 // If bridge doesn't support Mem64\r
1028 // degrade it to mem32\r
1029 //\r
1030 if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
1031 MergeResourceTree (\r
1032 Mem32Node,\r
1033 Mem64Node,\r
1034 TRUE\r
1035 );\r
1036 }\r
1037\r
1038 //\r
1039 // If bridge doesn't support Pmem32\r
1040 // degrade it to mem32\r
1041 //\r
1042 if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {\r
1043 MergeResourceTree (\r
1044 Mem32Node,\r
1045 PMem32Node,\r
1046 TRUE\r
1047 );\r
1048 }\r
1049\r
1050 //\r
1051 // if bridge supports combined Pmem Mem decoding\r
1052 // merge these two type of resource\r
1053 //\r
1054 if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
1055 MergeResourceTree (\r
1056 Mem32Node,\r
1057 PMem32Node,\r
1058 FALSE\r
1059 );\r
1060\r
1061 MergeResourceTree (\r
1062 Mem64Node,\r
1063 PMem64Node,\r
1064 FALSE\r
1065 );\r
1066 }\r
1067\r
1068 return EFI_SUCCESS;\r
1069}\r
1070\r
1071BOOLEAN\r
1072BridgeSupportResourceDecode (\r
1073 IN PCI_IO_DEVICE *Bridge,\r
1074 IN UINT32 Decode\r
1075 )\r
1076/*++\r
1077\r
1078Routine Description:\r
1079\r
1080 TODO: Add function description\r
1081\r
1082Arguments:\r
1083\r
1084 Bridge - TODO: add argument description\r
1085 Decode - TODO: add argument description\r
1086\r
1087Returns:\r
1088\r
1089 TODO: add return values\r
1090\r
1091--*/\r
1092{\r
1093 /*++\r
1094\r
1095Routine Description:\r
1096\r
1097Arguments:\r
1098\r
1099Returns:\r
1100 \r
1101 None\r
1102\r
1103--*/\r
1104 if ((Bridge->Decodes) & Decode) {\r
1105 return TRUE;\r
1106 }\r
1107\r
1108 return FALSE;\r
1109}\r
1110\r
1111EFI_STATUS\r
1112ProgramResource (\r
1113 IN UINT64 Base,\r
1114 IN PCI_RESOURCE_NODE *Bridge\r
1115 )\r
1116/*++\r
1117\r
1118Routine Description:\r
1119\r
1120 This function is used to program the resource allocated \r
1121 for each resource node\r
1122\r
1123Arguments:\r
1124\r
1125Returns:\r
1126\r
1127 None\r
1128\r
1129--*/\r
1130// TODO: Base - add argument and description to function comment\r
1131// TODO: Bridge - add argument and description to function comment\r
1132// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1133// TODO: EFI_SUCCESS - add return value to function comment\r
1134{\r
1135 LIST_ENTRY *CurrentLink;\r
1136 PCI_RESOURCE_NODE *Node;\r
1137 EFI_STATUS Status;\r
1138\r
1139 if (Base == gAllOne) {\r
1140 return EFI_OUT_OF_RESOURCES;\r
1141 }\r
1142\r
1143 CurrentLink = Bridge->ChildList.ForwardLink;\r
1144\r
1145 while (CurrentLink != &Bridge->ChildList) {\r
1146\r
1147 Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1148\r
1149 if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {\r
1150\r
1151 if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
1152 ProgramP2C (Base, Node);\r
1153 } else {\r
1154 ProgramBar (Base, Node);\r
1155 }\r
1156 } else {\r
1157 Status = ProgramResource (Base + Node->Offset, Node);\r
1158\r
1159 if (EFI_ERROR (Status)) {\r
1160 return Status;\r
1161 }\r
1162\r
1163 ProgramPpbApperture (Base, Node);\r
1164 }\r
1165\r
1166 CurrentLink = CurrentLink->ForwardLink;\r
1167 }\r
1168\r
1169 return EFI_SUCCESS;\r
1170}\r
1171\r
1172EFI_STATUS\r
1173ProgramBar (\r
1174 IN UINT64 Base,\r
1175 IN PCI_RESOURCE_NODE *Node\r
1176 )\r
1177/*++\r
1178\r
1179Routine Description:\r
1180\r
1181Arguments:\r
1182\r
1183Returns:\r
1184 \r
1185 None\r
1186\r
1187--*/\r
1188// TODO: Base - add argument and description to function comment\r
1189// TODO: Node - add argument and description to function comment\r
1190// TODO: EFI_SUCCESS - add return value to function comment\r
1191{\r
1192 EFI_PCI_IO_PROTOCOL *PciIo;\r
1193 UINT64 Address;\r
1194 UINT32 Address32;\r
1195\r
1196 Address = 0;\r
1197 PciIo = &(Node->PciDev->PciIo);\r
1198\r
1199 Address = Base + Node->Offset;\r
1200\r
1201 //\r
1202 // Indicate pci bus driver has allocated\r
1203 // resource for this device\r
1204 // It might be a temporary solution here since\r
1205 // pci device could have multiple bar\r
1206 //\r
1207 Node->PciDev->Allocated = TRUE;\r
1208\r
1209 switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {\r
1210\r
1211 case PciBarTypeIo16:\r
1212 case PciBarTypeIo32:\r
1213 case PciBarTypeMem32:\r
1214 case PciBarTypePMem32:\r
1215\r
1216 PciIoWrite (\r
1217 PciIo,\r
1218 EfiPciIoWidthUint32,\r
1219 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1220 1,\r
1221 &Address\r
1222 );\r
1223\r
1224 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1225\r
1226 break;\r
1227\r
1228 case PciBarTypeMem64:\r
1229 case PciBarTypePMem64:\r
1230\r
1231 Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
1232\r
1233 PciIoWrite (\r
1234 PciIo,\r
1235 EfiPciIoWidthUint32,\r
1236 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1237 1,\r
1238 &Address32\r
1239 );\r
1240\r
1241 Address32 = (UINT32) RShiftU64 (Address, 32);\r
1242\r
1243 PciIoWrite (\r
1244 PciIo,\r
1245 EfiPciIoWidthUint32,\r
1246 (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),\r
1247 1,\r
1248 &Address32\r
1249 );\r
1250\r
1251 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1252\r
1253 break;\r
1254\r
1255 default:\r
1256 break;\r
1257 }\r
1258\r
1259 return EFI_SUCCESS;\r
1260}\r
1261\r
1262EFI_STATUS\r
1263ProgramPpbApperture (\r
1264 IN UINT64 Base,\r
1265 IN PCI_RESOURCE_NODE *Node\r
1266 )\r
1267/*++\r
1268\r
1269Routine Description:\r
1270\r
1271Arguments:\r
1272\r
1273Returns:\r
1274 \r
1275 None\r
1276\r
1277--*/\r
1278// TODO: Base - add argument and description to function comment\r
1279// TODO: Node - add argument and description to function comment\r
1280// TODO: EFI_SUCCESS - add return value to function comment\r
1281// TODO: EFI_SUCCESS - add return value to function comment\r
1282{\r
1283 EFI_PCI_IO_PROTOCOL *PciIo;\r
1284 UINT64 Address;\r
1285 UINT32 Address32;\r
1286\r
1287 Address = 0;\r
1288 //\r
1289 // if no device south of this PPB, return anyway\r
1290 // Apperture is set default in the initialization code\r
1291 //\r
1292 if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {\r
1293 //\r
1294 // For padding resource node, just ignore when programming\r
1295 //\r
1296 return EFI_SUCCESS;\r
1297 }\r
1298\r
1299 PciIo = &(Node->PciDev->PciIo);\r
1300 Address = Base + Node->Offset;\r
1301\r
1302 //\r
1303 // Indicate the PPB resource has been allocated\r
1304 //\r
1305 Node->PciDev->Allocated = TRUE;\r
1306\r
1307 switch (Node->Bar) {\r
1308\r
1309 case PPB_BAR_0:\r
1310 case PPB_BAR_1:\r
1311 PciIoWrite (\r
1312 PciIo,\r
1313 EfiPciIoWidthUint32,\r
1314 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1315 1,\r
1316 &Address\r
1317 );\r
1318\r
1319 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1320 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1321\r
1322 break;\r
1323\r
1324 case PPB_IO_RANGE:\r
1325\r
1326 Address32 = ((UINT32) (Address)) >> 8;\r
1327 PciIoWrite (\r
1328 PciIo,\r
1329 EfiPciIoWidthUint8,\r
1330 0x1C,\r
1331 1,\r
1332 &Address32\r
1333 );\r
1334\r
1335 Address32 >>= 8;\r
1336 PciIoWrite (\r
1337 PciIo,\r
1338 EfiPciIoWidthUint16,\r
1339 0x30,\r
1340 1,\r
1341 &Address32\r
1342 );\r
1343\r
1344 Address32 = (UINT32) (Address + Node->Length - 1);\r
1345 Address32 = ((UINT32) (Address32)) >> 8;\r
1346 PciIoWrite (\r
1347 PciIo,\r
1348 EfiPciIoWidthUint8,\r
1349 0x1D,\r
1350 1,\r
1351 &Address32\r
1352 );\r
1353\r
1354 Address32 >>= 8;\r
1355 PciIoWrite (\r
1356 PciIo,\r
1357 EfiPciIoWidthUint16,\r
1358 0x32,\r
1359 1,\r
1360 &Address32\r
1361 );\r
1362\r
1363 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1364 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1365 break;\r
1366\r
1367 case PPB_MEM32_RANGE:\r
1368\r
1369 Address32 = ((UINT32) (Address)) >> 16;\r
1370 PciIoWrite (\r
1371 PciIo,\r
1372 EfiPciIoWidthUint16,\r
1373 0x20,\r
1374 1,\r
1375 &Address32\r
1376 );\r
1377\r
1378 Address32 = (UINT32) (Address + Node->Length - 1);\r
1379 Address32 = ((UINT32) (Address32)) >> 16;\r
1380 PciIoWrite (\r
1381 PciIo,\r
1382 EfiPciIoWidthUint16,\r
1383 0x22,\r
1384 1,\r
1385 &Address32\r
1386 );\r
1387\r
1388 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1389 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1390 break;\r
1391\r
1392 case PPB_PMEM32_RANGE:\r
1393 case PPB_PMEM64_RANGE:\r
1394\r
1395 Address32 = ((UINT32) (Address)) >> 16;\r
1396 PciIoWrite (\r
1397 PciIo,\r
1398 EfiPciIoWidthUint16,\r
1399 0x24,\r
1400 1,\r
1401 &Address32\r
1402 );\r
1403\r
1404 Address32 = (UINT32) (Address + Node->Length - 1);\r
1405 Address32 = ((UINT32) (Address32)) >> 16;\r
1406 PciIoWrite (\r
1407 PciIo,\r
1408 EfiPciIoWidthUint16,\r
1409 0x26,\r
1410 1,\r
1411 &Address32\r
1412 );\r
1413\r
1414 Address32 = (UINT32) RShiftU64 (Address, 32);\r
1415 PciIoWrite (\r
1416 PciIo,\r
1417 EfiPciIoWidthUint32,\r
1418 0x28,\r
1419 1,\r
1420 &Address32\r
1421 );\r
1422\r
1423 Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);\r
1424 PciIoWrite (\r
1425 PciIo,\r
1426 EfiPciIoWidthUint32,\r
1427 0x2C,\r
1428 1,\r
1429 &Address32\r
1430 );\r
1431\r
1432 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1433 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1434 break;\r
1435\r
1436 default:\r
1437 break;\r
1438 }\r
1439\r
1440 return EFI_SUCCESS;\r
1441}\r
1442\r
1443EFI_STATUS\r
1444ProgrameUpstreamBridgeForRom (\r
1445 IN PCI_IO_DEVICE *PciDevice,\r
1446 IN UINT32 OptionRomBase,\r
1447 IN BOOLEAN Enable\r
1448 )\r
1449/*++\r
1450\r
1451Routine Description:\r
1452\r
1453Arguments:\r
1454\r
1455Returns:\r
1456\r
1457--*/\r
1458// TODO: PciDevice - add argument and description to function comment\r
1459// TODO: OptionRomBase - add argument and description to function comment\r
1460// TODO: Enable - add argument and description to function comment\r
1461// TODO: EFI_SUCCESS - add return value to function comment\r
1462{\r
1463 PCI_IO_DEVICE *Parent;\r
1464 PCI_RESOURCE_NODE Node;\r
1465 //\r
1466 // For root bridge, just return.\r
1467 //\r
1468 Parent = PciDevice->Parent;\r
1469 ZeroMem (&Node, sizeof (Node));\r
1470 while (Parent) {\r
1471 if (!IS_PCI_BRIDGE (&Parent->Pci)) {\r
1472 break;\r
1473 }\r
1474\r
1475 Node.PciDev = Parent;\r
1476 Node.Length = PciDevice->RomSize;\r
1477 Node.Alignment = 0;\r
1478 Node.Bar = PPB_MEM32_RANGE;\r
1479 Node.ResType = PciBarTypeMem32;\r
1480 Node.Offset = 0;\r
1481\r
1482 //\r
1483 // Program PPB to only open a single <= 16<MB apperture\r
1484 //\r
1485 if (Enable) {\r
1486 ProgramPpbApperture (OptionRomBase, &Node);\r
1487 PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
1488 } else {\r
1489 InitializePpb (Parent);\r
1490 PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
1491 }\r
1492\r
1493 Parent = Parent->Parent;\r
1494 }\r
1495\r
1496 return EFI_SUCCESS;\r
1497}\r
1498\r
1499BOOLEAN\r
1500ResourceRequestExisted (\r
1501 IN PCI_RESOURCE_NODE *Bridge\r
1502 )\r
1503/*++\r
1504\r
1505Routine Description:\r
1506\r
1507Arguments:\r
1508\r
1509 Bridge - A pointer to the PCI_RESOURCE_NODE.\r
1510\r
1511Returns:\r
1512\r
1513 None\r
1514\r
1515--*/\r
1516{\r
1517 if (Bridge != NULL) {\r
1518 if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {\r
1519 return TRUE;\r
1520 }\r
1521 }\r
1522\r
1523 return FALSE;\r
1524}\r
1525\r
1526EFI_STATUS\r
1527InitializeResourcePool (\r
1528 PCI_RESOURCE_NODE *ResourcePool,\r
1529 PCI_BAR_TYPE ResourceType\r
1530 )\r
1531/*++\r
1532\r
1533Routine Description:\r
1534\r
1535Arguments:\r
1536\r
1537Returns:\r
1538\r
1539 None\r
1540\r
1541--*/\r
1542// TODO: ResourcePool - add argument and description to function comment\r
1543// TODO: ResourceType - add argument and description to function comment\r
1544// TODO: EFI_SUCCESS - add return value to function comment\r
1545{\r
1546\r
1547 ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));\r
1548 ResourcePool->ResType = ResourceType;\r
1549 ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;\r
1550 InitializeListHead (&ResourcePool->ChildList);\r
1551\r
1552 return EFI_SUCCESS;\r
1553}\r
1554\r
1555EFI_STATUS\r
1556GetResourceMap (\r
1557 PCI_IO_DEVICE *PciDev,\r
1558 PCI_RESOURCE_NODE **IoBridge,\r
1559 PCI_RESOURCE_NODE **Mem32Bridge,\r
1560 PCI_RESOURCE_NODE **PMem32Bridge,\r
1561 PCI_RESOURCE_NODE **Mem64Bridge,\r
1562 PCI_RESOURCE_NODE **PMem64Bridge,\r
1563 PCI_RESOURCE_NODE *IoPool,\r
1564 PCI_RESOURCE_NODE *Mem32Pool,\r
1565 PCI_RESOURCE_NODE *PMem32Pool,\r
1566 PCI_RESOURCE_NODE *Mem64Pool,\r
1567 PCI_RESOURCE_NODE *PMem64Pool\r
1568 )\r
1569/*++\r
1570\r
1571Routine Description:\r
1572\r
1573Arguments:\r
1574\r
1575Returns:\r
1576\r
1577 None\r
1578\r
1579--*/\r
1580// TODO: PciDev - add argument and description to function comment\r
1581// TODO: IoBridge - add argument and description to function comment\r
1582// TODO: Mem32Bridge - add argument and description to function comment\r
1583// TODO: PMem32Bridge - add argument and description to function comment\r
1584// TODO: Mem64Bridge - add argument and description to function comment\r
1585// TODO: PMem64Bridge - add argument and description to function comment\r
1586// TODO: IoPool - add argument and description to function comment\r
1587// TODO: Mem32Pool - add argument and description to function comment\r
1588// TODO: PMem32Pool - add argument and description to function comment\r
1589// TODO: Mem64Pool - add argument and description to function comment\r
1590// TODO: PMem64Pool - add argument and description to function comment\r
1591// TODO: EFI_SUCCESS - add return value to function comment\r
1592{\r
1593\r
1594 PCI_RESOURCE_NODE *Temp;\r
1595 LIST_ENTRY *CurrentLink;\r
1596\r
1597 CurrentLink = IoPool->ChildList.ForwardLink;\r
1598\r
1599 //\r
1600 // Get Io resource map\r
1601 //\r
1602 while (CurrentLink != &IoPool->ChildList) {\r
1603\r
1604 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1605\r
1606 if (Temp->PciDev == PciDev) {\r
1607 *IoBridge = Temp;\r
1608 }\r
1609\r
1610 CurrentLink = CurrentLink->ForwardLink;\r
1611 }\r
1612\r
1613 //\r
1614 // Get Mem32 resource map\r
1615 //\r
1616 CurrentLink = Mem32Pool->ChildList.ForwardLink;\r
1617\r
1618 while (CurrentLink != &Mem32Pool->ChildList) {\r
1619\r
1620 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1621\r
1622 if (Temp->PciDev == PciDev) {\r
1623 *Mem32Bridge = Temp;\r
1624 }\r
1625\r
1626 CurrentLink = CurrentLink->ForwardLink;\r
1627 }\r
1628\r
1629 //\r
1630 // Get Pmem32 resource map\r
1631 //\r
1632 CurrentLink = PMem32Pool->ChildList.ForwardLink;\r
1633\r
1634 while (CurrentLink != &PMem32Pool->ChildList) {\r
1635\r
1636 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1637\r
1638 if (Temp->PciDev == PciDev) {\r
1639 *PMem32Bridge = Temp;\r
1640 }\r
1641\r
1642 CurrentLink = CurrentLink->ForwardLink;\r
1643 }\r
1644\r
1645 //\r
1646 // Get Mem64 resource map\r
1647 //\r
1648 CurrentLink = Mem64Pool->ChildList.ForwardLink;\r
1649\r
1650 while (CurrentLink != &Mem64Pool->ChildList) {\r
1651\r
1652 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1653\r
1654 if (Temp->PciDev == PciDev) {\r
1655 *Mem64Bridge = Temp;\r
1656 }\r
1657\r
1658 CurrentLink = CurrentLink->ForwardLink;\r
1659 }\r
1660\r
1661 //\r
1662 // Get Pmem64 resource map\r
1663 //\r
1664 CurrentLink = PMem64Pool->ChildList.ForwardLink;\r
1665\r
1666 while (CurrentLink != &PMem64Pool->ChildList) {\r
1667\r
1668 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1669\r
1670 if (Temp->PciDev == PciDev) {\r
1671 *PMem64Bridge = Temp;\r
1672 }\r
1673\r
1674 CurrentLink = CurrentLink->ForwardLink;\r
1675 }\r
1676\r
1677 return EFI_SUCCESS;\r
1678}\r
1679\r
1680EFI_STATUS\r
1681DestroyResourceTree (\r
1682 IN PCI_RESOURCE_NODE *Bridge\r
1683 )\r
1684/*++\r
1685\r
1686Routine Description:\r
1687\r
1688Arguments:\r
1689\r
1690Returns:\r
1691\r
1692 None\r
1693\r
1694--*/\r
1695// TODO: Bridge - add argument and description to function comment\r
1696// TODO: EFI_SUCCESS - add return value to function comment\r
1697{\r
1698 PCI_RESOURCE_NODE *Temp;\r
1699 LIST_ENTRY *CurrentLink;\r
1700\r
1701 while (!IsListEmpty (&Bridge->ChildList)) {\r
1702\r
1703 CurrentLink = Bridge->ChildList.ForwardLink;\r
1704\r
1705 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
1706\r
1707 RemoveEntryList (CurrentLink);\r
1708\r
1709 if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {\r
1710 DestroyResourceTree (Temp);\r
1711 }\r
1712\r
1713 gBS->FreePool (Temp);\r
1714 }\r
1715\r
1716 return EFI_SUCCESS;\r
1717}\r
1718\r
1719EFI_STATUS\r
1720RecordReservedResource (\r
1721 IN UINT64 Base,\r
1722 IN UINT64 Length,\r
1723 IN PCI_BAR_TYPE ResType,\r
1724 IN PCI_IO_DEVICE *Bridge\r
1725 )\r
1726/*++\r
1727\r
1728Routine Description:\r
1729 \r
1730Arguments:\r
1731\r
1732Returns:\r
1733\r
1734 None\r
1735\r
1736--*/\r
1737// TODO: Base - add argument and description to function comment\r
1738// TODO: Length - add argument and description to function comment\r
1739// TODO: ResType - add argument and description to function comment\r
1740// TODO: Bridge - add argument and description to function comment\r
1741// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1742// TODO: EFI_SUCCESS - add return value to function comment\r
1743{\r
1744 PCI_RESERVED_RESOURCE_LIST *ReservedNode;\r
1745\r
1746 ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));\r
1747 if (ReservedNode == NULL) {\r
1748 return EFI_OUT_OF_RESOURCES;\r
1749 }\r
1750\r
1751 ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE;\r
1752 ReservedNode->Node.Base = Base;\r
1753 ReservedNode->Node.Length = Length;\r
1754 ReservedNode->Node.ResType = ResType;\r
1755\r
1756 InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));\r
1757\r
1758 return EFI_SUCCESS;\r
1759}\r
1760\r
1761EFI_STATUS\r
1762ResourcePaddingForCardBusBridge (\r
1763 PCI_IO_DEVICE *PciDev,\r
1764 PCI_RESOURCE_NODE *IoNode,\r
1765 PCI_RESOURCE_NODE *Mem32Node,\r
1766 PCI_RESOURCE_NODE *PMem32Node,\r
1767 PCI_RESOURCE_NODE *Mem64Node,\r
1768 PCI_RESOURCE_NODE *PMem64Node\r
1769 )\r
1770/*++\r
1771\r
1772Routine Description:\r
1773\r
1774Arguments:\r
1775\r
1776Returns:\r
1777\r
1778 None\r
1779\r
1780--*/\r
1781// TODO: PciDev - add argument and description to function comment\r
1782// TODO: IoNode - add argument and description to function comment\r
1783// TODO: Mem32Node - add argument and description to function comment\r
1784// TODO: PMem32Node - add argument and description to function comment\r
1785// TODO: Mem64Node - add argument and description to function comment\r
1786// TODO: PMem64Node - add argument and description to function comment\r
1787// TODO: EFI_SUCCESS - add return value to function comment\r
1788{\r
1789 PCI_RESOURCE_NODE *Node;\r
1790\r
1791 Node = NULL;\r
1792\r
1793 //\r
1794 // Memory Base/Limit Register 0\r
1795 // Bar 1 denodes memory range 0\r
1796 //\r
1797 Node = CreateResourceNode (\r
1798 PciDev,\r
1799 0x2000000,\r
1800 0x1ffffff,\r
1801 1,\r
1802 PciBarTypeMem32,\r
1803 PciResUsagePadding\r
1804 );\r
1805\r
1806 InsertResourceNode (\r
1807 Mem32Node,\r
1808 Node\r
1809 );\r
1810\r
1811 //\r
1812 // Memory Base/Limit Register 1\r
1813 // Bar 2 denodes memory range1\r
1814 //\r
1815 Node = CreateResourceNode (\r
1816 PciDev,\r
1817 0x2000000,\r
1818 0x1ffffff,\r
1819 2,\r
1820 PciBarTypePMem32,\r
1821 PciResUsagePadding\r
1822 );\r
1823\r
1824 InsertResourceNode (\r
1825 PMem32Node,\r
1826 Node\r
1827 );\r
1828\r
1829 //\r
1830 // Io Base/Limit\r
1831 // Bar 3 denodes io range 0\r
1832 //\r
1833 Node = CreateResourceNode (\r
1834 PciDev,\r
1835 0x100,\r
1836 0xff,\r
1837 3,\r
1838 PciBarTypeIo16,\r
1839 PciResUsagePadding\r
1840 );\r
1841\r
1842 InsertResourceNode (\r
1843 IoNode,\r
1844 Node\r
1845 );\r
1846\r
1847 //\r
1848 // Io Base/Limit\r
1849 // Bar 4 denodes io range 0\r
1850 //\r
1851 Node = CreateResourceNode (\r
1852 PciDev,\r
1853 0x100,\r
1854 0xff,\r
1855 4,\r
1856 PciBarTypeIo16,\r
1857 PciResUsagePadding\r
1858 );\r
1859\r
1860 InsertResourceNode (\r
1861 IoNode,\r
1862 Node\r
1863 );\r
1864\r
1865 return EFI_SUCCESS;\r
1866}\r
1867\r
1868EFI_STATUS\r
1869ProgramP2C (\r
1870 IN UINT64 Base,\r
1871 IN PCI_RESOURCE_NODE *Node\r
1872 )\r
1873/*++\r
1874\r
1875Routine Description:\r
1876\r
1877Arguments:\r
1878\r
1879Returns:\r
1880 \r
1881 None\r
1882\r
1883--*/\r
1884// TODO: Base - add argument and description to function comment\r
1885// TODO: Node - add argument and description to function comment\r
1886// TODO: EFI_SUCCESS - add return value to function comment\r
1887{\r
1888 EFI_PCI_IO_PROTOCOL *PciIo;\r
1889 UINT64 Address;\r
1890 UINT64 TempAddress;\r
1891 UINT16 BridgeControl;\r
1892\r
1893 Address = 0;\r
1894 PciIo = &(Node->PciDev->PciIo);\r
1895\r
1896 Address = Base + Node->Offset;\r
1897\r
1898 //\r
1899 // Indicate pci bus driver has allocated\r
1900 // resource for this device\r
1901 // It might be a temporary solution here since\r
1902 // pci device could have multiple bar\r
1903 //\r
1904 Node->PciDev->Allocated = TRUE;\r
1905\r
1906 switch (Node->Bar) {\r
1907\r
1908 case P2C_BAR_0:\r
1909 PciIoWrite (\r
1910 PciIo,\r
1911 EfiPciIoWidthUint32,\r
1912 (Node->PciDev->PciBar[Node->Bar]).Offset,\r
1913 1,\r
1914 &Address\r
1915 );\r
1916\r
1917 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1918 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1919 break;\r
1920\r
1921 case P2C_MEM_1:\r
1922 PciIoWrite (\r
1923 PciIo,\r
1924 EfiPciIoWidthUint32,\r
1925 0x1c,\r
1926 1,\r
1927 &Address\r
1928 );\r
1929\r
1930 TempAddress = Address + Node->Length - 1;\r
1931 PciIoWrite (\r
1932 PciIo,\r
1933 EfiPciIoWidthUint32,\r
1934 0x20,\r
1935 1,\r
1936 &TempAddress\r
1937 );\r
1938\r
1939 if (Node->ResType == PciBarTypeMem32) {\r
1940\r
1941 //\r
1942 // Set non-prefetchable bit\r
1943 //\r
1944 PciIoRead (\r
1945 PciIo,\r
1946 EfiPciIoWidthUint16,\r
1947 0x3e,\r
1948 1,\r
1949 &BridgeControl\r
1950 );\r
1951\r
1952 BridgeControl &= 0xfeff;\r
1953 PciIoWrite (\r
1954 PciIo,\r
1955 EfiPciIoWidthUint16,\r
1956 0x3e,\r
1957 1,\r
1958 &BridgeControl\r
1959 );\r
1960\r
1961 } else {\r
1962\r
1963 //\r
1964 // Set pre-fetchable bit\r
1965 //\r
1966 PciIoRead (\r
1967 PciIo,\r
1968 EfiPciIoWidthUint16,\r
1969 0x3e,\r
1970 1,\r
1971 &BridgeControl\r
1972 );\r
1973\r
1974 BridgeControl |= 0x0100;\r
1975 PciIoWrite (\r
1976 PciIo,\r
1977 EfiPciIoWidthUint16,\r
1978 0x3e,\r
1979 1,\r
1980 &BridgeControl\r
1981 );\r
1982 }\r
1983\r
1984 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
1985 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
1986 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
1987\r
1988 break;\r
1989\r
1990 case P2C_MEM_2:\r
1991 PciIoWrite (\r
1992 PciIo,\r
1993 EfiPciIoWidthUint32,\r
1994 0x24,\r
1995 1,\r
1996 &Address\r
1997 );\r
1998\r
1999 TempAddress = Address + Node->Length - 1;\r
2000\r
2001 PciIoWrite (\r
2002 PciIo,\r
2003 EfiPciIoWidthUint32,\r
2004 0x28,\r
2005 1,\r
2006 &TempAddress\r
2007 );\r
2008\r
2009 if (Node->ResType == PciBarTypeMem32) {\r
2010\r
2011 //\r
2012 // Set non-prefetchable bit\r
2013 //\r
2014 PciIoRead (\r
2015 PciIo,\r
2016 EfiPciIoWidthUint16,\r
2017 0x3e,\r
2018 1,\r
2019 &BridgeControl\r
2020 );\r
2021\r
2022 BridgeControl &= 0xfdff;\r
2023 PciIoWrite (\r
2024 PciIo,\r
2025 EfiPciIoWidthUint16,\r
2026 0x3e,\r
2027 1,\r
2028 &BridgeControl\r
2029 );\r
2030 } else {\r
2031\r
2032 //\r
2033 // Set pre-fetchable bit\r
2034 //\r
2035 PciIoRead (\r
2036 PciIo,\r
2037 EfiPciIoWidthUint16,\r
2038 0x3e,\r
2039 1,\r
2040 &BridgeControl\r
2041 );\r
2042\r
2043 BridgeControl |= 0x0200;\r
2044 PciIoWrite (\r
2045 PciIo,\r
2046 EfiPciIoWidthUint16,\r
2047 0x3e,\r
2048 1,\r
2049 &BridgeControl\r
2050 );\r
2051 }\r
2052\r
2053 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
2054 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
2055 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
2056 break;\r
2057\r
2058 case P2C_IO_1:\r
2059 PciIoWrite (\r
2060 PciIo,\r
2061 EfiPciIoWidthUint32,\r
2062 0x2c,\r
2063 1,\r
2064 &Address\r
2065 );\r
2066 TempAddress = Address + Node->Length - 1;\r
2067 PciIoWrite (\r
2068 PciIo,\r
2069 EfiPciIoWidthUint32,\r
2070 0x30,\r
2071 1,\r
2072 &TempAddress\r
2073 );\r
2074\r
2075 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
2076 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
2077 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
2078\r
2079 break;\r
2080\r
2081 case P2C_IO_2:\r
2082 PciIoWrite (\r
2083 PciIo,\r
2084 EfiPciIoWidthUint32,\r
2085 0x34,\r
2086 1,\r
2087 &Address\r
2088 );\r
2089\r
2090 TempAddress = Address + Node->Length - 1;\r
2091 PciIoWrite (\r
2092 PciIo,\r
2093 EfiPciIoWidthUint32,\r
2094 0x38,\r
2095 1,\r
2096 &TempAddress\r
2097 );\r
2098\r
2099 Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
2100 Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
2101 Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
2102 break;\r
2103\r
2104 default:\r
2105 break;\r
2106 }\r
2107\r
2108 return EFI_SUCCESS;\r
2109}\r
2110\r
2111EFI_STATUS\r
2112ApplyResourcePadding (\r
2113 PCI_IO_DEVICE *PciDev,\r
2114 PCI_RESOURCE_NODE *IoNode,\r
2115 PCI_RESOURCE_NODE *Mem32Node,\r
2116 PCI_RESOURCE_NODE *PMem32Node,\r
2117 PCI_RESOURCE_NODE *Mem64Node,\r
2118 PCI_RESOURCE_NODE *PMem64Node\r
2119 )\r
2120/*++\r
2121\r
2122Routine Description:\r
2123\r
2124Arguments:\r
2125\r
2126Returns:\r
2127 \r
2128 None\r
2129\r
2130--*/\r
2131// TODO: PciDev - add argument and description to function comment\r
2132// TODO: IoNode - add argument and description to function comment\r
2133// TODO: Mem32Node - add argument and description to function comment\r
2134// TODO: PMem32Node - add argument and description to function comment\r
2135// TODO: Mem64Node - add argument and description to function comment\r
2136// TODO: PMem64Node - add argument and description to function comment\r
2137// TODO: EFI_SUCCESS - add return value to function comment\r
2138{\r
2139 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
2140 PCI_RESOURCE_NODE *Node;\r
2141 UINT8 DummyBarIndex;\r
2142\r
2143 DummyBarIndex = 0;\r
2144 Ptr = PciDev->ResourcePaddingDescriptors;\r
2145\r
2146 while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
2147\r
2148 if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {\r
2149 if (Ptr->AddrLen != 0) {\r
2150\r
2151 Node = CreateResourceNode (\r
2152 PciDev,\r
2153 Ptr->AddrLen,\r
2154 Ptr->AddrRangeMax,\r
2155 DummyBarIndex,\r
2156 PciBarTypeIo16,\r
2157 PciResUsagePadding\r
2158 );\r
2159 InsertResourceNode (\r
2160 IoNode,\r
2161 Node\r
2162 );\r
2163 }\r
2164\r
2165 Ptr++;\r
2166 continue;\r
2167 }\r
2168\r
2169 if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
2170\r
2171 if (Ptr->AddrSpaceGranularity == 32) {\r
2172\r
2173 //\r
2174 // prefechable\r
2175 //\r
2176 if (Ptr->SpecificFlag == 0x6) {\r
2177 if (Ptr->AddrLen) {\r
2178 Node = CreateResourceNode (\r
2179 PciDev,\r
2180 Ptr->AddrLen,\r
2181 Ptr->AddrRangeMax,\r
2182 DummyBarIndex,\r
2183 PciBarTypePMem32,\r
2184 PciResUsagePadding\r
2185 );\r
2186 InsertResourceNode (\r
2187 PMem32Node,\r
2188 Node\r
2189 );\r
2190 }\r
2191\r
2192 Ptr++;\r
2193 continue;\r
2194 }\r
2195\r
2196 //\r
2197 // Non-prefechable\r
2198 //\r
2199 if (Ptr->SpecificFlag == 0) {\r
2200 if (Ptr->AddrLen) {\r
2201 Node = CreateResourceNode (\r
2202 PciDev,\r
2203 Ptr->AddrLen,\r
2204 Ptr->AddrRangeMax,\r
2205 DummyBarIndex,\r
2206 PciBarTypeMem32,\r
2207 PciResUsagePadding\r
2208 );\r
2209 InsertResourceNode (\r
2210 Mem32Node,\r
2211 Node\r
2212 );\r
2213 }\r
2214\r
2215 Ptr++;\r
2216 continue;\r
2217 }\r
2218 }\r
2219\r
2220 if (Ptr->AddrSpaceGranularity == 64) {\r
2221\r
2222 //\r
2223 // prefechable\r
2224 //\r
2225 if (Ptr->SpecificFlag == 0x6) {\r
2226 if (Ptr->AddrLen) {\r
2227 Node = CreateResourceNode (\r
2228 PciDev,\r
2229 Ptr->AddrLen,\r
2230 Ptr->AddrRangeMax,\r
2231 DummyBarIndex,\r
2232 PciBarTypePMem64,\r
2233 PciResUsagePadding\r
2234 );\r
2235 InsertResourceNode (\r
2236 PMem64Node,\r
2237 Node\r
2238 );\r
2239 }\r
2240\r
2241 Ptr++;\r
2242 continue;\r
2243 }\r
2244\r
2245 //\r
2246 // Non-prefechable\r
2247 //\r
2248 if (Ptr->SpecificFlag == 0) {\r
2249 if (Ptr->AddrLen) {\r
2250 Node = CreateResourceNode (\r
2251 PciDev,\r
2252 Ptr->AddrLen,\r
2253 Ptr->AddrRangeMax,\r
2254 DummyBarIndex,\r
2255 PciBarTypeMem64,\r
2256 PciResUsagePadding\r
2257 );\r
2258 InsertResourceNode (\r
2259 Mem64Node,\r
2260 Node\r
2261 );\r
2262 }\r
2263\r
2264 Ptr++;\r
2265 continue;\r
2266 }\r
2267 }\r
2268 }\r
2269\r
2270 Ptr++;\r
2271 }\r
2272\r
2273 return EFI_SUCCESS;\r
2274}\r
2275\r
2276//\r
2277// Light PCI bus driver woundn't support hotplug root device\r
2278// So no need to pad resource for them\r
2279//\r
2280VOID\r
2281GetResourcePaddingPpb (\r
2282 IN PCI_IO_DEVICE *PciIoDevice\r
2283 )\r
2284/*++\r
2285\r
2286Routine Description:\r
2287\r
2288 Get resource.\r
2289\r
2290Arguments:\r
2291\r
2292 PciIoDevice A pointer to a pci device.\r
2293\r
2294Returns:\r
2295\r
2296 None\r
2297\r
2298--*/\r
2299{\r
2300 if (gPciHotPlugInit) {\r
2301 if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
2302 GetResourcePaddingForHpb (PciIoDevice);\r
2303 }\r
2304 }\r
2305}\r