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