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