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