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