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