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