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