]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c
Retired PciIncompatibleDeviceSupportLib from IntelFrameworkModulePkg.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / PciLib.c
CommitLineData
97404058 1/** @file\r
8e8227d1 2 Internal library implementation for PCI Bus module.\r
ead42efc 3\r
8e8227d1 4Copyright (c) 2006 - 2009, Intel Corporation\r
4beb4afe 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
ead42efc 12\r
3db51098 13**/\r
ead42efc 14\r
03417d8d 15#include "PciBus.h"\r
ead42efc 16\r
ead42efc 17\r
57076f45 18/**\r
8e8227d1 19 Retrieve the PCI Card device BAR information via PciIo interface.\r
20\r
21 @param PciIoDevice PCI Card device instance.\r
22\r
57076f45 23**/\r
ead42efc 24VOID\r
25GetBackPcCardBar (\r
26 IN PCI_IO_DEVICE *PciIoDevice\r
27 )\r
ead42efc 28{\r
29 UINT32 Address;\r
30\r
31 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
32 return;\r
33 }\r
34\r
35 //\r
36 // Read PciBar information from the bar register\r
37 //\r
38 if (!gFullEnumeration) {\r
ead42efc 39 Address = 0;\r
9eb130ff 40 PciIoDevice->PciIo.Pci.Read (\r
41 &(PciIoDevice->PciIo),\r
42 EfiPciIoWidthUint32,\r
43 PCI_CARD_MEMORY_BASE_0,\r
44 1,\r
45 &Address\r
46 );\r
ead42efc 47\r
48 (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address);\r
49 (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000;\r
50 (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32;\r
51\r
52 Address = 0;\r
9eb130ff 53 PciIoDevice->PciIo.Pci.Read (\r
54 &(PciIoDevice->PciIo),\r
55 EfiPciIoWidthUint32,\r
56 PCI_CARD_MEMORY_BASE_1,\r
57 1,\r
58 &Address\r
59 );\r
ead42efc 60 (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address);\r
61 (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000;\r
62 (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32;\r
63\r
64 Address = 0;\r
9eb130ff 65 PciIoDevice->PciIo.Pci.Read (\r
66 &(PciIoDevice->PciIo),\r
67 EfiPciIoWidthUint32,\r
68 PCI_CARD_IO_BASE_0_LOWER,\r
69 1,\r
70 &Address\r
71 );\r
ead42efc 72 (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address);\r
73 (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100;\r
74 (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16;\r
75\r
76 Address = 0;\r
9eb130ff 77 PciIoDevice->PciIo.Pci.Read (\r
78 &(PciIoDevice->PciIo),\r
79 EfiPciIoWidthUint32,\r
80 PCI_CARD_IO_BASE_1_LOWER,\r
81 1,\r
82 &Address\r
83 );\r
ead42efc 84 (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address);\r
85 (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100;\r
86 (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16;\r
87\r
88 }\r
89\r
8e8227d1 90 if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
ead42efc 91 GetResourcePaddingForHpb (PciIoDevice);\r
92 }\r
93}\r
94\r
57076f45 95/**\r
96 Remove rejected pci device from specific root bridge\r
97 handle.\r
8e8227d1 98\r
99 @param RootBridgeHandle Specific parent root bridge handle.\r
eeefcb9d 100 @param Bridge Bridge device instance.\r
8e8227d1 101\r
57076f45 102**/\r
8e8227d1 103VOID\r
ead42efc 104RemoveRejectedPciDevices (\r
8e8227d1 105 IN EFI_HANDLE RootBridgeHandle,\r
106 IN PCI_IO_DEVICE *Bridge\r
ead42efc 107 )\r
ead42efc 108{\r
109 PCI_IO_DEVICE *Temp;\r
110 LIST_ENTRY *CurrentLink;\r
111 LIST_ENTRY *LastLink;\r
112\r
113 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
8e8227d1 114 return;\r
ead42efc 115 }\r
116\r
117 CurrentLink = Bridge->ChildList.ForwardLink;\r
118\r
97404058 119 while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {\r
ead42efc 120\r
121 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
122\r
123 if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
124 //\r
125 // Remove rejected devices recusively\r
126 //\r
127 RemoveRejectedPciDevices (RootBridgeHandle, Temp);\r
128 } else {\r
129 //\r
130 // Skip rejection for all PPBs, while detect rejection for others\r
131 //\r
132 if (IsPciDeviceRejected (Temp)) {\r
133\r
134 //\r
135 // For P2C, remove all devices on it\r
136 //\r
ead42efc 137 if (!IsListEmpty (&Temp->ChildList)) {\r
138 RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
139 }\r
140\r
141 //\r
142 // Finally remove itself\r
143 //\r
ead42efc 144 LastLink = CurrentLink->BackLink;\r
145 RemoveEntryList (CurrentLink);\r
146 FreePciDevice (Temp);\r
147\r
148 CurrentLink = LastLink;\r
149 }\r
150 }\r
151\r
152 CurrentLink = CurrentLink->ForwardLink;\r
153 }\r
ead42efc 154}\r
155\r
57076f45 156/**\r
8e8227d1 157 Submits the I/O and memory resource requirements for the specified PCI Host Bridge.\r
57076f45 158\r
eeefcb9d 159 @param PciResAlloc Point to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.\r
ead42efc 160\r
8e8227d1 161 @retval EFI_SUCCESS Successfully finished resource allocation.\r
162 @retval EFI_NOT_FOUND Cannot get root bridge instance.\r
163 @retval EFI_OUT_OF_RESOURCES Platform failed to program the resources if no hot plug supported.\r
164 @retval other Some error occurred when allocating resources for the PCI Host Bridge.\r
ead42efc 165\r
8e8227d1 166 @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug.\r
ead42efc 167\r
57076f45 168**/\r
ead42efc 169EFI_STATUS\r
8e8227d1 170PciHostBridgeResourceAllocator (\r
ead42efc 171 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
172 )\r
ead42efc 173{\r
8e8227d1 174 PCI_IO_DEVICE *RootBridgeDev;\r
175 EFI_HANDLE RootBridgeHandle;\r
176 VOID *AcpiConfig;\r
177 EFI_STATUS Status;\r
178 UINT64 IoBase;\r
179 UINT64 Mem32Base;\r
180 UINT64 PMem32Base;\r
181 UINT64 Mem64Base;\r
182 UINT64 PMem64Base;\r
183 UINT64 IoResStatus;\r
184 UINT64 Mem32ResStatus;\r
185 UINT64 PMem32ResStatus;\r
186 UINT64 Mem64ResStatus;\r
187 UINT64 PMem64ResStatus;\r
188 UINT64 MaxOptionRomSize;\r
189 PCI_RESOURCE_NODE *IoBridge;\r
190 PCI_RESOURCE_NODE *Mem32Bridge;\r
191 PCI_RESOURCE_NODE *PMem32Bridge;\r
192 PCI_RESOURCE_NODE *Mem64Bridge;\r
193 PCI_RESOURCE_NODE *PMem64Bridge;\r
194 PCI_RESOURCE_NODE IoPool;\r
195 PCI_RESOURCE_NODE Mem32Pool;\r
196 PCI_RESOURCE_NODE PMem32Pool;\r
197 PCI_RESOURCE_NODE Mem64Pool;\r
198 PCI_RESOURCE_NODE PMem64Pool;\r
199 BOOLEAN ReAllocate;\r
938f2b4f 200 EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData;\r
201 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
ead42efc 202\r
203 //\r
204 // Reallocate flag\r
205 //\r
206 ReAllocate = FALSE;\r
207\r
208 //\r
8e8227d1 209 // It may try several times if the resource allocation fails\r
ead42efc 210 //\r
211 while (TRUE) {\r
ead42efc 212 //\r
213 // Initialize resource pool\r
214 //\r
215 InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
216 InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
217 InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
218 InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
219 InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
220\r
221 RootBridgeDev = NULL;\r
222 RootBridgeHandle = 0;\r
223\r
224 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
ead42efc 225 //\r
8e8227d1 226 // Get Root Bridge Device by handle\r
ead42efc 227 //\r
228 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
229\r
230 if (RootBridgeDev == NULL) {\r
231 return EFI_NOT_FOUND;\r
232 }\r
233\r
234 //\r
235 // Create the entire system resource map from the information collected by\r
236 // enumerator. Several resource tree was created\r
237 //\r
238\r
239 IoBridge = CreateResourceNode (\r
48a9ea7b 240 RootBridgeDev,\r
241 0,\r
242 0xFFF,\r
243 0,\r
244 PciBarTypeIo16,\r
245 PciResUsageTypical\r
246 );\r
ead42efc 247\r
248 Mem32Bridge = CreateResourceNode (\r
249 RootBridgeDev,\r
250 0,\r
251 0xFFFFF,\r
252 0,\r
253 PciBarTypeMem32,\r
254 PciResUsageTypical\r
255 );\r
256\r
257 PMem32Bridge = CreateResourceNode (\r
48a9ea7b 258 RootBridgeDev,\r
259 0,\r
260 0xFFFFF,\r
261 0,\r
262 PciBarTypePMem32,\r
263 PciResUsageTypical\r
264 );\r
ead42efc 265\r
266 Mem64Bridge = CreateResourceNode (\r
267 RootBridgeDev,\r
268 0,\r
269 0xFFFFF,\r
270 0,\r
271 PciBarTypeMem64,\r
272 PciResUsageTypical\r
273 );\r
274\r
275 PMem64Bridge = CreateResourceNode (\r
48a9ea7b 276 RootBridgeDev,\r
277 0,\r
278 0xFFFFF,\r
279 0,\r
280 PciBarTypePMem64,\r
281 PciResUsageTypical\r
282 );\r
ead42efc 283\r
8e8227d1 284 //\r
285 // Create resourcemap by going through all the devices subject to this root bridge\r
286 //\r
287 CreateResourceMap (\r
288 RootBridgeDev,\r
289 IoBridge,\r
290 Mem32Bridge,\r
291 PMem32Bridge,\r
292 Mem64Bridge,\r
293 PMem64Bridge\r
294 );\r
ead42efc 295\r
296 //\r
297 // Get the max ROM size that the root bridge can process\r
298 //\r
299 RootBridgeDev->RomSize = Mem32Bridge->Length;\r
300\r
301 //\r
302 // Skip to enlarge the resource request during realloction\r
303 //\r
304 if (!ReAllocate) {\r
305 //\r
306 // Get Max Option Rom size for current root bridge\r
307 //\r
308 MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
309\r
310 //\r
311 // Enlarger the mem32 resource to accomdate the option rom\r
312 // if the mem32 resource is not enough to hold the rom\r
313 //\r
314 if (MaxOptionRomSize > Mem32Bridge->Length) {\r
315\r
316 Mem32Bridge->Length = MaxOptionRomSize;\r
317 RootBridgeDev->RomSize = MaxOptionRomSize;\r
318\r
319 //\r
320 // Alignment should be adjusted as well\r
321 //\r
322 if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
323 Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
324 }\r
325 }\r
326 }\r
327\r
328 //\r
329 // Based on the all the resource tree, contruct ACPI resource node to\r
330 // submit the resource aperture to pci host bridge protocol\r
331 //\r
332 Status = ConstructAcpiResourceRequestor (\r
48a9ea7b 333 RootBridgeDev,\r
334 IoBridge,\r
335 Mem32Bridge,\r
336 PMem32Bridge,\r
337 Mem64Bridge,\r
338 PMem64Bridge,\r
339 &AcpiConfig\r
340 );\r
ead42efc 341\r
342 //\r
343 // Insert these resource nodes into the database\r
344 //\r
345 InsertResourceNode (&IoPool, IoBridge);\r
346 InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
347 InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
348 InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
349 InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
350\r
351 if (Status == EFI_SUCCESS) {\r
352 //\r
353 // Submit the resource requirement\r
354 //\r
355 Status = PciResAlloc->SubmitResources (\r
356 PciResAlloc,\r
357 RootBridgeDev->Handle,\r
358 AcpiConfig\r
359 );\r
360 }\r
361\r
362 //\r
363 // Free acpi resource node\r
364 //\r
365 if (AcpiConfig != NULL) {\r
366 FreePool (AcpiConfig);\r
367 }\r
368\r
369 if (EFI_ERROR (Status)) {\r
370 //\r
371 // Destroy all the resource tree\r
372 //\r
373 DestroyResourceTree (&IoPool);\r
374 DestroyResourceTree (&Mem32Pool);\r
375 DestroyResourceTree (&PMem32Pool);\r
376 DestroyResourceTree (&Mem64Pool);\r
377 DestroyResourceTree (&PMem64Pool);\r
378 return Status;\r
379 }\r
380 }\r
ead42efc 381 //\r
9c10bff3 382 // End while, at least one Root Bridge should be found.\r
ead42efc 383 //\r
9c10bff3 384 ASSERT (RootBridgeDev != NULL);\r
ead42efc 385\r
8e8227d1 386 //\r
387 // Notify platform to start to program the resource\r
388 //\r
ead42efc 389 Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
8e8227d1 390 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
ead42efc 391 //\r
8e8227d1 392 // If Hot Plug is not supported\r
ead42efc 393 //\r
8e8227d1 394 if (EFI_ERROR (Status)) {\r
395 //\r
396 // Allocation failed, then return\r
397 //\r
398 return EFI_OUT_OF_RESOURCES;\r
399 }\r
400 //\r
401 // Allocation succeed.\r
402 // Get host bridge handle for status report, and then skip the main while\r
403 //\r
404 HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
ead42efc 405\r
8e8227d1 406 break;\r
ead42efc 407\r
8e8227d1 408 } else {\r
ead42efc 409 //\r
8e8227d1 410 // If Hot Plug is supported\r
ead42efc 411 //\r
8e8227d1 412 if (!EFI_ERROR (Status)) {\r
413 //\r
414 // Allocation succeed, then continue the following\r
415 //\r
416 break;\r
ead42efc 417 }\r
418\r
419 //\r
8e8227d1 420 // If the resource allocation is unsuccessful, free resources on bridge\r
ead42efc 421 //\r
ead42efc 422\r
8e8227d1 423 RootBridgeDev = NULL;\r
424 RootBridgeHandle = 0;\r
ead42efc 425\r
8e8227d1 426 IoResStatus = EFI_RESOURCE_SATISFIED;\r
427 Mem32ResStatus = EFI_RESOURCE_SATISFIED;\r
428 PMem32ResStatus = EFI_RESOURCE_SATISFIED;\r
429 Mem64ResStatus = EFI_RESOURCE_SATISFIED;\r
430 PMem64ResStatus = EFI_RESOURCE_SATISFIED;\r
ead42efc 431\r
8e8227d1 432 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
433 //\r
434 // Get RootBridg Device by handle\r
435 //\r
436 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
437 if (RootBridgeDev == NULL) {\r
438 return EFI_NOT_FOUND;\r
439 }\r
ead42efc 440\r
ead42efc 441 //\r
8e8227d1 442 // Get host bridge handle for status report\r
ead42efc 443 //\r
8e8227d1 444 HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
ead42efc 445\r
8e8227d1 446 //\r
447 // Get acpi resource node for all the resource types\r
448 //\r
449 AcpiConfig = NULL;\r
ead42efc 450\r
8e8227d1 451 Status = PciResAlloc->GetProposedResources (\r
452 PciResAlloc,\r
453 RootBridgeDev->Handle,\r
454 &AcpiConfig\r
455 );\r
ead42efc 456\r
8e8227d1 457 if (EFI_ERROR (Status)) {\r
458 return Status;\r
459 }\r
ead42efc 460\r
8e8227d1 461 if (AcpiConfig != NULL) {\r
462 //\r
463 // Adjust resource allocation policy for each RB\r
464 //\r
465 GetResourceAllocationStatus (\r
466 AcpiConfig,\r
467 &IoResStatus,\r
468 &Mem32ResStatus,\r
469 &PMem32ResStatus,\r
470 &Mem64ResStatus,\r
471 &PMem64ResStatus\r
472 );\r
473 FreePool (AcpiConfig);\r
474 }\r
475 }\r
476 //\r
477 // End while\r
478 //\r
479\r
480 //\r
481 // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
482 //\r
483 //\r
484 // It is very difficult to follow the spec here\r
485 // Device path , Bar index can not be get here\r
486 //\r
487 ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
ead42efc 488\r
8e8227d1 489 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
490 EFI_PROGRESS_CODE,\r
491 EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
492 (VOID *) &AllocFailExtendedData,\r
493 sizeof (AllocFailExtendedData)\r
494 );\r
ead42efc 495\r
8e8227d1 496 Status = PciHostBridgeAdjustAllocation (\r
497 &IoPool,\r
498 &Mem32Pool,\r
499 &PMem32Pool,\r
500 &Mem64Pool,\r
501 &PMem64Pool,\r
502 IoResStatus,\r
503 Mem32ResStatus,\r
504 PMem32ResStatus,\r
505 Mem64ResStatus,\r
506 PMem64ResStatus\r
507 );\r
508\r
509 //\r
510 // Destroy all the resource tree\r
511 //\r
512 DestroyResourceTree (&IoPool);\r
513 DestroyResourceTree (&Mem32Pool);\r
514 DestroyResourceTree (&PMem32Pool);\r
515 DestroyResourceTree (&Mem64Pool);\r
516 DestroyResourceTree (&PMem64Pool);\r
ead42efc 517\r
8e8227d1 518 NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources);\r
519\r
520 if (EFI_ERROR (Status)) {\r
521 return Status;\r
522 }\r
ead42efc 523\r
8e8227d1 524 ReAllocate = TRUE;\r
525 }\r
ead42efc 526 }\r
527 //\r
528 // End main while\r
529 //\r
530\r
531 //\r
532 // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
533 //\r
534 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
535 EFI_PROGRESS_CODE,\r
536 EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
537 (VOID *) &HandleExtendedData,\r
538 sizeof (HandleExtendedData)\r
539 );\r
540\r
541 //\r
542 // Notify pci bus driver starts to program the resource\r
543 //\r
544 NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
545\r
546 RootBridgeDev = NULL;\r
547\r
548 RootBridgeHandle = 0;\r
549\r
550 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
ead42efc 551 //\r
552 // Get RootBridg Device by handle\r
553 //\r
554 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
555\r
556 if (RootBridgeDev == NULL) {\r
557 return EFI_NOT_FOUND;\r
558 }\r
559\r
560 //\r
561 // Get acpi resource node for all the resource types\r
562 //\r
563 AcpiConfig = NULL;\r
564 Status = PciResAlloc->GetProposedResources (\r
565 PciResAlloc,\r
566 RootBridgeDev->Handle,\r
567 &AcpiConfig\r
568 );\r
569\r
570 if (EFI_ERROR (Status)) {\r
571 return Status;\r
572 }\r
573\r
574 //\r
575 // Get the resource base by interpreting acpi resource node\r
576 //\r
577 //\r
578 GetResourceBase (\r
579 AcpiConfig,\r
580 &IoBase,\r
581 &Mem32Base,\r
582 &PMem32Base,\r
583 &Mem64Base,\r
584 &PMem64Base\r
585 );\r
586\r
587 //\r
588 // Process option rom for this root bridge\r
589 //\r
8e8227d1 590 ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
ead42efc 591\r
592 //\r
593 // Create the entire system resource map from the information collected by\r
594 // enumerator. Several resource tree was created\r
595 //\r
8e8227d1 596 GetResourceMap (\r
597 RootBridgeDev,\r
598 &IoBridge,\r
599 &Mem32Bridge,\r
600 &PMem32Bridge,\r
601 &Mem64Bridge,\r
602 &PMem64Bridge,\r
603 &IoPool,\r
604 &Mem32Pool,\r
605 &PMem32Pool,\r
606 &Mem64Pool,\r
607 &PMem64Pool\r
608 );\r
ead42efc 609\r
610 //\r
611 // Program IO resources\r
612 //\r
613 ProgramResource (\r
614 IoBase,\r
615 IoBridge\r
616 );\r
617\r
618 //\r
619 // Program Mem32 resources\r
620 //\r
621 ProgramResource (\r
622 Mem32Base,\r
623 Mem32Bridge\r
624 );\r
625\r
626 //\r
8e8227d1 627 // Program PMem32 resources\r
628 //\r
629 ProgramResource (\r
630 PMem32Base,\r
631 PMem32Bridge\r
632 );\r
ead42efc 633\r
8e8227d1 634 //\r
635 // Program Mem64 resources\r
636 //\r
637 ProgramResource (\r
638 Mem64Base,\r
639 Mem64Bridge\r
640 );\r
ead42efc 641\r
8e8227d1 642 //\r
643 // Program PMem64 resources\r
644 //\r
645 ProgramResource (\r
646 PMem64Base,\r
647 PMem64Bridge\r
648 );\r
649\r
650 FreePool (AcpiConfig);\r
ead42efc 651 }\r
652\r
8e8227d1 653 //\r
654 // Destroy all the resource tree\r
655 //\r
656 DestroyResourceTree (&IoPool);\r
657 DestroyResourceTree (&Mem32Pool);\r
658 DestroyResourceTree (&PMem32Pool);\r
659 DestroyResourceTree (&Mem64Pool);\r
660 DestroyResourceTree (&PMem64Pool);\r
661\r
662 //\r
663 // Notify the resource allocation phase is to end\r
664 //\r
665 NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
666\r
ead42efc 667 return EFI_SUCCESS;\r
668}\r
669\r
57076f45 670/**\r
8e8227d1 671 Scan pci bus and assign bus number to the given PCI bus system.\r
672\r
673 @param Bridge Bridge device instance.\r
674 @param StartBusNumber start point.\r
675 @param SubBusNumber Point to sub bus number.\r
676 @param PaddedBusRange Customized bus number.\r
677\r
678 @retval EFI_SUCCESS Successfully scanned and assigned bus number.\r
679 @retval other Some error occurred when scanning pci bus.\r
680\r
681 @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug.\r
682\r
57076f45 683**/\r
ead42efc 684EFI_STATUS\r
8e8227d1 685PciScanBus (\r
ead42efc 686 IN PCI_IO_DEVICE *Bridge,\r
687 IN UINT8 StartBusNumber,\r
688 OUT UINT8 *SubBusNumber,\r
689 OUT UINT8 *PaddedBusRange\r
690 )\r
ead42efc 691{\r
692 EFI_STATUS Status;\r
693 PCI_TYPE00 Pci;\r
694 UINT8 Device;\r
695 UINT8 Func;\r
696 UINT64 Address;\r
697 UINTN SecondBus;\r
698 UINT16 Register;\r
699 UINTN HpIndex;\r
700 PCI_IO_DEVICE *PciDevice;\r
701 EFI_EVENT Event;\r
702 EFI_HPC_STATE State;\r
703 UINT64 PciAddress;\r
704 EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
705 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
706 UINT16 BusRange;\r
707 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
708 BOOLEAN BusPadding;\r
709\r
710 PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
711 SecondBus = 0;\r
712 Register = 0;\r
713 State = 0;\r
714 Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0;\r
715 BusRange = 0;\r
8e8227d1 716 BusPadding = FALSE;\r
717 PciDevice = NULL;\r
718 PciAddress = 0;\r
ead42efc 719\r
ead42efc 720 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
721 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
722\r
723 //\r
724 // Check to see whether a pci device is present\r
725 //\r
726 Status = PciDevicePresent (\r
727 PciRootBridgeIo,\r
728 &Pci,\r
729 StartBusNumber,\r
730 Device,\r
731 Func\r
732 );\r
733\r
734 if (EFI_ERROR (Status)) {\r
735 if (Func == 0) {\r
736 //\r
737 // Skip sub functions, this is not a multi function device\r
738 //\r
739 Func = PCI_MAX_FUNC;\r
740 }\r
741\r
742 continue;\r
743 }\r
744\r
ff62de37 745 DEBUG((EFI_D_ERROR, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));\r
4beb4afe 746\r
8e8227d1 747 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
748 //\r
749 // Get the PCI device information\r
750 //\r
751 Status = PciSearchDevice (\r
752 Bridge,\r
753 &Pci,\r
754 StartBusNumber,\r
755 Device,\r
756 Func,\r
757 &PciDevice\r
758 );\r
ead42efc 759\r
8e8227d1 760 ASSERT (!EFI_ERROR (Status));\r
ead42efc 761\r
8e8227d1 762 PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
ead42efc 763\r
8e8227d1 764 if (!IS_PCI_BRIDGE (&Pci)) {\r
765 //\r
766 // PCI bridges will be called later\r
767 // Here just need for PCI device or PCI to cardbus controller\r
768 // EfiPciBeforeChildBusEnumeration for PCI Device Node\r
769 //\r
770 PreprocessController (\r
771 PciDevice,\r
772 PciDevice->BusNumber,\r
773 PciDevice->DeviceNumber,\r
774 PciDevice->FunctionNumber,\r
775 EfiPciBeforeChildBusEnumeration\r
776 );\r
777 }\r
ead42efc 778\r
ead42efc 779 //\r
8e8227d1 780 // For Pci Hotplug controller devcie only\r
ead42efc 781 //\r
8e8227d1 782 if (gPciHotPlugInit != NULL) {\r
783 //\r
784 // Check if it is a Hotplug PCI controller\r
785 //\r
786 if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) {\r
ead42efc 787\r
8e8227d1 788 if (!gPciRootHpcData[HpIndex].Initialized) {\r
ead42efc 789\r
8e8227d1 790 Status = CreateEventForHpc (HpIndex, &Event);\r
ead42efc 791\r
8e8227d1 792 ASSERT (!EFI_ERROR (Status));\r
ead42efc 793\r
8e8227d1 794 Status = gPciHotPlugInit->InitializeRootHpc (\r
795 gPciHotPlugInit,\r
796 gPciRootHpcPool[HpIndex].HpcDevicePath,\r
797 PciAddress,\r
798 Event,\r
799 &State\r
800 );\r
ead42efc 801\r
8e8227d1 802 PreprocessController (\r
803 PciDevice,\r
804 PciDevice->BusNumber,\r
805 PciDevice->DeviceNumber,\r
806 PciDevice->FunctionNumber,\r
807 EfiPciBeforeChildBusEnumeration\r
808 );\r
809 }\r
ead42efc 810 }\r
811 }\r
812 }\r
813\r
814 if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) {\r
815 //\r
816 // For PPB\r
ead42efc 817 //\r
8e8227d1 818 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
819 //\r
820 // If Hot Plug is not supported,\r
821 // get the bridge information\r
822 //\r
823 Status = PciSearchDevice (\r
824 Bridge,\r
825 &Pci,\r
826 StartBusNumber,\r
827 Device,\r
828 Func,\r
829 &PciDevice\r
830 );\r
ead42efc 831\r
8e8227d1 832 if (EFI_ERROR (Status)) {\r
833 return Status;\r
834 }\r
835 } else {\r
836 //\r
837 // If Hot Plug is supported,\r
838 // Get the bridge information\r
839 //\r
840 BusPadding = FALSE;\r
841 if (gPciHotPlugInit != NULL) {\r
842\r
843 if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
844\r
845 //\r
846 // If it is initialized, get the padded bus range\r
847 //\r
848 Status = gPciHotPlugInit->GetResourcePadding (\r
849 gPciHotPlugInit,\r
850 gPciRootHpcPool[HpIndex].HpbDevicePath,\r
851 PciAddress,\r
852 &State,\r
853 (VOID **) &Descriptors,\r
854 &Attributes\r
855 );\r
ead42efc 856\r
8e8227d1 857 if (EFI_ERROR (Status)) {\r
858 return Status;\r
859 }\r
ead42efc 860\r
8e8227d1 861 BusRange = 0;\r
862 Status = PciGetBusRange (\r
863 &Descriptors,\r
864 NULL,\r
865 NULL,\r
866 &BusRange\r
867 );\r
ead42efc 868\r
8e8227d1 869 FreePool (Descriptors);\r
ead42efc 870\r
8e8227d1 871 if (EFI_ERROR (Status)) {\r
872 return Status;\r
873 }\r
ead42efc 874\r
8e8227d1 875 BusPadding = TRUE;\r
876 }\r
ead42efc 877 }\r
878 }\r
879\r
ff62de37 880 //\r
881 // Add feature to support customized secondary bus number\r
882 //\r
a3b8e257 883 if (*SubBusNumber == 0) {\r
ff62de37 884 *SubBusNumber = *PaddedBusRange;\r
885 *PaddedBusRange = 0;\r
886 }\r
887\r
ead42efc 888 (*SubBusNumber)++;\r
889 SecondBus = *SubBusNumber;\r
890\r
891 Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
8e8227d1 892 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET);\r
ead42efc 893\r
9eb130ff 894 Status = PciRootBridgeIo->Pci.Write (\r
ead42efc 895 PciRootBridgeIo,\r
ead42efc 896 EfiPciWidthUint16,\r
897 Address,\r
898 1,\r
899 &Register\r
900 );\r
901\r
902\r
903 //\r
904 // If it is PPB, resursively search down this bridge\r
905 //\r
906 if (IS_PCI_BRIDGE (&Pci)) {\r
907\r
908 //\r
8e8227d1 909 // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
910 // PCI configuration transaction to go through any PPB\r
ead42efc 911 //\r
912 Register = 0xFF;\r
8e8227d1 913 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);\r
9eb130ff 914 Status = PciRootBridgeIo->Pci.Write (\r
ead42efc 915 PciRootBridgeIo,\r
ead42efc 916 EfiPciWidthUint8,\r
917 Address,\r
918 1,\r
919 &Register\r
920 );\r
921\r
922 //\r
923 // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige\r
924 //\r
925 PreprocessController (\r
926 PciDevice,\r
927 PciDevice->BusNumber,\r
928 PciDevice->DeviceNumber,\r
929 PciDevice->FunctionNumber,\r
930 EfiPciBeforeChildBusEnumeration\r
931 );\r
932\r
8e8227d1 933 DEBUG((EFI_D_ERROR, "Scan PPB(%02d,%02d,%02d)\n", PciDevice->BusNumber, PciDevice->DeviceNumber,PciDevice->FunctionNumber));\r
ead42efc 934 Status = PciScanBus (\r
935 PciDevice,\r
936 (UINT8) (SecondBus),\r
937 SubBusNumber,\r
938 PaddedBusRange\r
939 );\r
ead42efc 940 if (EFI_ERROR (Status)) {\r
8e8227d1 941 return Status;\r
ead42efc 942 }\r
943 }\r
944\r
8e8227d1 945 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport) && BusPadding) {\r
ead42efc 946 //\r
947 // Ensure the device is enabled and initialized\r
948 //\r
949 if ((Attributes == EfiPaddingPciRootBridge) &&\r
97404058 950 (State & EFI_HPC_STATE_ENABLED) != 0 &&\r
951 (State & EFI_HPC_STATE_INITIALIZED) != 0) {\r
ead42efc 952 *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);\r
953 } else {\r
954 *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);\r
955 }\r
956 }\r
957\r
958 //\r
959 // Set the current maximum bus number under the PPB\r
960 //\r
8e8227d1 961 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);\r
ead42efc 962\r
9eb130ff 963 Status = PciRootBridgeIo->Pci.Write (\r
ead42efc 964 PciRootBridgeIo,\r
ead42efc 965 EfiPciWidthUint8,\r
966 Address,\r
967 1,\r
968 SubBusNumber\r
969 );\r
970 }\r
971\r
972 if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
973\r
974 //\r
975 // Skip sub functions, this is not a multi function device\r
976 //\r
8e8227d1 977\r
ead42efc 978 Func = PCI_MAX_FUNC;\r
979 }\r
ead42efc 980 }\r
981 }\r
982\r
983 return EFI_SUCCESS;\r
984}\r
985\r
57076f45 986/**\r
8e8227d1 987 Process Option Rom on the specified root bridge.\r
988\r
989 @param Bridge Pci root bridge device instance.\r
990\r
991 @retval EFI_SUCCESS Success process.\r
992 @retval other Some error occurred when processing Option Rom on the root bridge.\r
993\r
57076f45 994**/\r
ead42efc 995EFI_STATUS\r
996PciRootBridgeP2CProcess (\r
997 IN PCI_IO_DEVICE *Bridge\r
998 )\r
ead42efc 999{\r
1000 LIST_ENTRY *CurrentLink;\r
1001 PCI_IO_DEVICE *Temp;\r
1002 EFI_HPC_STATE State;\r
1003 UINT64 PciAddress;\r
1004 EFI_STATUS Status;\r
1005\r
1006 CurrentLink = Bridge->ChildList.ForwardLink;\r
1007\r
97404058 1008 while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {\r
ead42efc 1009\r
1010 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
1011\r
1012 if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
1013\r
8e8227d1 1014 if (gPciHotPlugInit != NULL && Temp->Allocated && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
ead42efc 1015\r
1016 //\r
1017 // Raise the EFI_IOB_PCI_HPC_INIT status code\r
1018 //\r
1019 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1020 EFI_PROGRESS_CODE,\r
1021 EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT,\r
1022 Temp->DevicePath\r
1023 );\r
1024\r
1025 PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
1026 Status = gPciHotPlugInit->InitializeRootHpc (\r
1027 gPciHotPlugInit,\r
1028 Temp->DevicePath,\r
1029 PciAddress,\r
1030 NULL,\r
1031 &State\r
1032 );\r
1033\r
1034 if (!EFI_ERROR (Status)) {\r
1035 Status = PciBridgeEnumerator (Temp);\r
1036\r
1037 if (EFI_ERROR (Status)) {\r
1038 return Status;\r
1039 }\r
1040 }\r
1041\r
1042 CurrentLink = CurrentLink->ForwardLink;\r
1043 continue;\r
1044\r
1045 }\r
1046 }\r
1047\r
1048 if (!IsListEmpty (&Temp->ChildList)) {\r
1049 Status = PciRootBridgeP2CProcess (Temp);\r
1050 }\r
1051\r
1052 CurrentLink = CurrentLink->ForwardLink;\r
1053 }\r
1054\r
1055 return EFI_SUCCESS;\r
1056}\r
1057\r
a3b8e257 1058/**\r
8e8227d1 1059 Process Option Rom on the specified host bridge.\r
1060\r
1061 @param PciResAlloc Pointer to instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.\r
1062\r
eeefcb9d 1063 @retval EFI_SUCCESS Success process.\r
8e8227d1 1064 @retval EFI_NOT_FOUND Can not find the root bridge instance.\r
1065 @retval other Some error occurred when processing Option Rom on the host bridge.\r
1066\r
a3b8e257 1067**/\r
ead42efc 1068EFI_STATUS\r
1069PciHostBridgeP2CProcess (\r
1070 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
1071 )\r
ead42efc 1072{\r
1073 EFI_HANDLE RootBridgeHandle;\r
1074 PCI_IO_DEVICE *RootBridgeDev;\r
1075 EFI_STATUS Status;\r
1076\r
1077 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
1078 return EFI_SUCCESS;\r
1079 }\r
1080\r
1081 RootBridgeHandle = NULL;\r
1082\r
1083 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
1084\r
1085 //\r
1086 // Get RootBridg Device by handle\r
1087 //\r
1088 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
1089\r
1090 if (RootBridgeDev == NULL) {\r
1091 return EFI_NOT_FOUND;\r
1092 }\r
1093\r
1094 Status = PciRootBridgeP2CProcess (RootBridgeDev);\r
ead42efc 1095 if (EFI_ERROR (Status)) {\r
1096 return Status;\r
1097 }\r
1098\r
1099 }\r
1100\r
1101 return EFI_SUCCESS;\r
1102}\r
1103\r
bcd70414 1104/**\r
ead42efc 1105 This function is used to enumerate the entire host bridge\r
eeefcb9d 1106 in a given platform.\r
ead42efc 1107\r
8e8227d1 1108 @param PciResAlloc A pointer to the PCI Host Resource Allocation protocol.\r
ead42efc 1109\r
8e8227d1 1110 @retval EFI_SUCCESS Successfully enumerated the host bridge.\r
1111 @retval EFI_OUT_OF_RESOURCES No enough memory available.\r
1112 @retval other Some error occurred when enumerating the host bridge.\r
ead42efc 1113\r
bcd70414 1114**/\r
57076f45 1115EFI_STATUS\r
1116PciHostBridgeEnumerator (\r
9eb130ff 1117 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
57076f45 1118 )\r
ead42efc 1119{\r
1120 EFI_HANDLE RootBridgeHandle;\r
1121 PCI_IO_DEVICE *RootBridgeDev;\r
1122 EFI_STATUS Status;\r
1123 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
1124 UINT16 MinBus;\r
1125 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
5326528b 1126 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;\r
4beb4afe 1127 UINT8 StartBusNumber;\r
1128 LIST_ENTRY RootBridgeList;\r
1129 LIST_ENTRY *Link;\r
ead42efc 1130\r
8e8227d1 1131 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
1132 InitializeHotPlugSupport ();\r
1133 }\r
ead42efc 1134\r
4beb4afe 1135 InitializeListHead (&RootBridgeList);\r
1136\r
ead42efc 1137 //\r
1138 // Notify the bus allocation phase is about to start\r
1139 //\r
1140 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
1141\r
ff62de37 1142 DEBUG((EFI_D_ERROR, "PCI Bus First Scanning\n"));\r
ead42efc 1143 RootBridgeHandle = NULL;\r
1144 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
1145\r
1146 //\r
1147 // if a root bridge instance is found, create root bridge device for it\r
1148 //\r
1149\r
1150 RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
1151\r
1152 if (RootBridgeDev == NULL) {\r
1153 return EFI_OUT_OF_RESOURCES;\r
1154 }\r
1155\r
1156 //\r
1157 // Enumerate all the buses under this root bridge\r
1158 //\r
ead42efc 1159 Status = PciRootBridgeEnumerator (\r
1160 PciResAlloc,\r
1161 RootBridgeDev\r
1162 );\r
1163\r
8e8227d1 1164 if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
4beb4afe 1165 InsertTailList (&RootBridgeList, &(RootBridgeDev->Link));\r
1166 } else {\r
1167 DestroyRootBridge (RootBridgeDev);\r
1168 }\r
ead42efc 1169 if (EFI_ERROR (Status)) {\r
1170 return Status;\r
1171 }\r
1172 }\r
1173\r
1174 //\r
1175 // Notify the bus allocation phase is finished for the first time\r
1176 //\r
1177 NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
1178\r
8e8227d1 1179 if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
1180 //\r
1181 // Reset all assigned PCI bus number in all PPB\r
1182 //\r
1183 RootBridgeHandle = NULL;\r
1184 Link = GetFirstNode (&RootBridgeList);\r
1185 while ((PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) &&\r
1186 (!IsNull (&RootBridgeList, Link))) {\r
1187 RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (Link);\r
ead42efc 1188 //\r
8e8227d1 1189 // Get the Bus information\r
4beb4afe 1190 //\r
8e8227d1 1191 Status = PciResAlloc->StartBusEnumeration (\r
1192 PciResAlloc,\r
1193 RootBridgeHandle,\r
1194 (VOID **) &Configuration\r
1195 );\r
ead42efc 1196 if (EFI_ERROR (Status)) {\r
1197 return Status;\r
1198 }\r
1199\r
1200 //\r
8e8227d1 1201 // Get the bus number to start with\r
ead42efc 1202 //\r
8e8227d1 1203 StartBusNumber = (UINT8) (Configuration->AddrRangeMin);\r
ead42efc 1204\r
8e8227d1 1205 ResetAllPpbBusNumber (\r
1206 RootBridgeDev,\r
1207 StartBusNumber\r
1208 );\r
ead42efc 1209\r
8e8227d1 1210 FreePool (Configuration);\r
1211 Link = GetNextNode (&RootBridgeList, Link);\r
1212 DestroyRootBridge (RootBridgeDev);\r
1213 }\r
ead42efc 1214\r
8e8227d1 1215 //\r
1216 // Wait for all HPC initialized\r
1217 //\r
1218 Status = AllRootHPCInitialized (STALL_1_SECOND * 15);\r
ead42efc 1219\r
8e8227d1 1220 if (EFI_ERROR (Status)) {\r
1221 return Status;\r
1222 }\r
ead42efc 1223\r
8e8227d1 1224 //\r
1225 // Notify the bus allocation phase is about to start for the 2nd time\r
1226 //\r
1227 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
ead42efc 1228\r
8e8227d1 1229 DEBUG((EFI_D_ERROR, "PCI Bus Second Scanning\n"));\r
1230 RootBridgeHandle = NULL;\r
1231 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
ead42efc 1232\r
8e8227d1 1233 //\r
1234 // if a root bridge instance is found, create root bridge device for it\r
1235 //\r
1236 RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
1237\r
1238 if (RootBridgeDev == NULL) {\r
1239 return EFI_OUT_OF_RESOURCES;\r
ead42efc 1240 }\r
1241\r
1242 //\r
8e8227d1 1243 // Enumerate all the buses under this root bridge\r
ead42efc 1244 //\r
8e8227d1 1245 Status = PciRootBridgeEnumerator (\r
1246 PciResAlloc,\r
1247 RootBridgeDev\r
1248 );\r
1249\r
1250 DestroyRootBridge (RootBridgeDev);\r
1251 if (EFI_ERROR (Status)) {\r
1252 return Status;\r
1253 }\r
ead42efc 1254 }\r
8e8227d1 1255\r
1256 //\r
1257 // Notify the bus allocation phase is to end for the 2nd time\r
1258 //\r
1259 NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
ead42efc 1260 }\r
1261\r
1262 //\r
1263 // Notify the resource allocation phase is to start\r
1264 //\r
1265 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);\r
1266\r
1267 RootBridgeHandle = NULL;\r
1268 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
1269\r
1270 //\r
1271 // if a root bridge instance is found, create root bridge device for it\r
1272 //\r
ead42efc 1273 RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
1274\r
1275 if (RootBridgeDev == NULL) {\r
1276 return EFI_OUT_OF_RESOURCES;\r
1277 }\r
1278\r
1279 Status = StartManagingRootBridge (RootBridgeDev);\r
1280\r
1281 if (EFI_ERROR (Status)) {\r
1282 return Status;\r
1283 }\r
1284\r
1285 PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;\r
1286 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
1287\r
1288 if (EFI_ERROR (Status)) {\r
1289 return Status;\r
1290 }\r
1291\r
1292 Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);\r
1293\r
1294 if (EFI_ERROR (Status)) {\r
1295 return Status;\r
1296 }\r
1297\r
1298 //\r
1299 // Determine root bridge attribute by calling interface of Pcihostbridge\r
1300 // protocol\r
1301 //\r
1302 DetermineRootBridgeAttributes (\r
1303 PciResAlloc,\r
1304 RootBridgeDev\r
1305 );\r
1306\r
1307 //\r
1308 // Collect all the resource information under this root bridge\r
1309 // A database that records all the information about pci device subject to this\r
1310 // root bridge will then be created\r
1311 //\r
1312 Status = PciPciDeviceInfoCollector (\r
1313 RootBridgeDev,\r
1314 (UINT8) MinBus\r
1315 );\r
1316\r
1317 if (EFI_ERROR (Status)) {\r
1318 return Status;\r
1319 }\r
1320\r
1321 InsertRootBridge (RootBridgeDev);\r
1322\r
1323 //\r
1324 // Record the hostbridge handle\r
1325 //\r
1326 AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);\r
1327 }\r
1328\r
1329 return EFI_SUCCESS;\r
1330}\r