]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c
Add security check to pass klockwork.
[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
7fc72ecb 709 UINT32 TempReservedBusNum;\r
ead42efc 710\r
711 PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
712 SecondBus = 0;\r
713 Register = 0;\r
714 State = 0;\r
715 Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0;\r
716 BusRange = 0;\r
8e8227d1 717 BusPadding = FALSE;\r
718 PciDevice = NULL;\r
719 PciAddress = 0;\r
ead42efc 720\r
ead42efc 721 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
7fc72ecb 722 TempReservedBusNum = 0;\r
ead42efc 723 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
724\r
725 //\r
726 // Check to see whether a pci device is present\r
727 //\r
728 Status = PciDevicePresent (\r
729 PciRootBridgeIo,\r
730 &Pci,\r
731 StartBusNumber,\r
732 Device,\r
733 Func\r
734 );\r
735\r
736 if (EFI_ERROR (Status)) {\r
737 if (Func == 0) {\r
738 //\r
739 // Skip sub functions, this is not a multi function device\r
740 //\r
741 Func = PCI_MAX_FUNC;\r
742 }\r
743\r
744 continue;\r
745 }\r
746\r
7fc72ecb 747 DEBUG((EFI_D_INFO, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));\r
4beb4afe 748\r
8e8227d1 749 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
750 //\r
751 // Get the PCI device information\r
752 //\r
753 Status = PciSearchDevice (\r
754 Bridge,\r
755 &Pci,\r
756 StartBusNumber,\r
757 Device,\r
758 Func,\r
759 &PciDevice\r
760 );\r
ead42efc 761\r
8e8227d1 762 ASSERT (!EFI_ERROR (Status));\r
ead42efc 763\r
8e8227d1 764 PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
ead42efc 765\r
8e8227d1 766 if (!IS_PCI_BRIDGE (&Pci)) {\r
767 //\r
768 // PCI bridges will be called later\r
769 // Here just need for PCI device or PCI to cardbus controller\r
770 // EfiPciBeforeChildBusEnumeration for PCI Device Node\r
771 //\r
772 PreprocessController (\r
773 PciDevice,\r
774 PciDevice->BusNumber,\r
775 PciDevice->DeviceNumber,\r
776 PciDevice->FunctionNumber,\r
777 EfiPciBeforeChildBusEnumeration\r
778 );\r
779 }\r
ead42efc 780\r
ead42efc 781 //\r
8e8227d1 782 // For Pci Hotplug controller devcie only\r
ead42efc 783 //\r
8e8227d1 784 if (gPciHotPlugInit != NULL) {\r
785 //\r
786 // Check if it is a Hotplug PCI controller\r
787 //\r
788 if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) {\r
ead42efc 789\r
8e8227d1 790 if (!gPciRootHpcData[HpIndex].Initialized) {\r
ead42efc 791\r
8e8227d1 792 Status = CreateEventForHpc (HpIndex, &Event);\r
ead42efc 793\r
8e8227d1 794 ASSERT (!EFI_ERROR (Status));\r
ead42efc 795\r
8e8227d1 796 Status = gPciHotPlugInit->InitializeRootHpc (\r
797 gPciHotPlugInit,\r
798 gPciRootHpcPool[HpIndex].HpcDevicePath,\r
799 PciAddress,\r
800 Event,\r
801 &State\r
802 );\r
ead42efc 803\r
8e8227d1 804 PreprocessController (\r
805 PciDevice,\r
806 PciDevice->BusNumber,\r
807 PciDevice->DeviceNumber,\r
808 PciDevice->FunctionNumber,\r
809 EfiPciBeforeChildBusEnumeration\r
810 );\r
811 }\r
ead42efc 812 }\r
813 }\r
814 }\r
815\r
816 if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) {\r
817 //\r
818 // For PPB\r
ead42efc 819 //\r
8e8227d1 820 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
821 //\r
822 // If Hot Plug is not supported,\r
823 // get the bridge information\r
824 //\r
825 Status = PciSearchDevice (\r
826 Bridge,\r
827 &Pci,\r
828 StartBusNumber,\r
829 Device,\r
830 Func,\r
831 &PciDevice\r
832 );\r
ead42efc 833\r
8e8227d1 834 if (EFI_ERROR (Status)) {\r
835 return Status;\r
836 }\r
837 } else {\r
838 //\r
839 // If Hot Plug is supported,\r
840 // Get the bridge information\r
841 //\r
842 BusPadding = FALSE;\r
843 if (gPciHotPlugInit != NULL) {\r
844\r
845 if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
846\r
847 //\r
848 // If it is initialized, get the padded bus range\r
849 //\r
850 Status = gPciHotPlugInit->GetResourcePadding (\r
851 gPciHotPlugInit,\r
852 gPciRootHpcPool[HpIndex].HpbDevicePath,\r
853 PciAddress,\r
854 &State,\r
855 (VOID **) &Descriptors,\r
856 &Attributes\r
857 );\r
ead42efc 858\r
8e8227d1 859 if (EFI_ERROR (Status)) {\r
860 return Status;\r
861 }\r
ead42efc 862\r
8e8227d1 863 BusRange = 0;\r
864 Status = PciGetBusRange (\r
865 &Descriptors,\r
866 NULL,\r
867 NULL,\r
868 &BusRange\r
869 );\r
ead42efc 870\r
8e8227d1 871 FreePool (Descriptors);\r
ead42efc 872\r
8e8227d1 873 if (EFI_ERROR (Status)) {\r
874 return Status;\r
875 }\r
ead42efc 876\r
8e8227d1 877 BusPadding = TRUE;\r
878 }\r
ead42efc 879 }\r
880 }\r
881\r
ff62de37 882 //\r
883 // Add feature to support customized secondary bus number\r
884 //\r
a3b8e257 885 if (*SubBusNumber == 0) {\r
ff62de37 886 *SubBusNumber = *PaddedBusRange;\r
887 *PaddedBusRange = 0;\r
888 }\r
889\r
ead42efc 890 (*SubBusNumber)++;\r
891 SecondBus = *SubBusNumber;\r
892\r
893 Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
8e8227d1 894 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET);\r
ead42efc 895\r
9eb130ff 896 Status = PciRootBridgeIo->Pci.Write (\r
ead42efc 897 PciRootBridgeIo,\r
ead42efc 898 EfiPciWidthUint16,\r
899 Address,\r
900 1,\r
901 &Register\r
902 );\r
903\r
904\r
905 //\r
906 // If it is PPB, resursively search down this bridge\r
907 //\r
908 if (IS_PCI_BRIDGE (&Pci)) {\r
909\r
910 //\r
8e8227d1 911 // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
912 // PCI configuration transaction to go through any PPB\r
ead42efc 913 //\r
914 Register = 0xFF;\r
8e8227d1 915 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);\r
9eb130ff 916 Status = PciRootBridgeIo->Pci.Write (\r
ead42efc 917 PciRootBridgeIo,\r
ead42efc 918 EfiPciWidthUint8,\r
919 Address,\r
920 1,\r
921 &Register\r
922 );\r
923\r
924 //\r
925 // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige\r
926 //\r
927 PreprocessController (\r
928 PciDevice,\r
929 PciDevice->BusNumber,\r
930 PciDevice->DeviceNumber,\r
931 PciDevice->FunctionNumber,\r
932 EfiPciBeforeChildBusEnumeration\r
933 );\r
934\r
7fc72ecb 935 DEBUG((EFI_D_INFO, "Scan PPB(%02d,%02d,%02d)\n", PciDevice->BusNumber, PciDevice->DeviceNumber,PciDevice->FunctionNumber));\r
ead42efc 936 Status = PciScanBus (\r
937 PciDevice,\r
938 (UINT8) (SecondBus),\r
939 SubBusNumber,\r
940 PaddedBusRange\r
941 );\r
ead42efc 942 if (EFI_ERROR (Status)) {\r
8e8227d1 943 return Status;\r
ead42efc 944 }\r
945 }\r
946\r
8e8227d1 947 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport) && BusPadding) {\r
ead42efc 948 //\r
949 // Ensure the device is enabled and initialized\r
950 //\r
951 if ((Attributes == EfiPaddingPciRootBridge) &&\r
97404058 952 (State & EFI_HPC_STATE_ENABLED) != 0 &&\r
953 (State & EFI_HPC_STATE_INITIALIZED) != 0) {\r
ead42efc 954 *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);\r
955 } else {\r
956 *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);\r
957 }\r
958 }\r
959\r
960 //\r
961 // Set the current maximum bus number under the PPB\r
962 //\r
8e8227d1 963 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);\r
ead42efc 964\r
9eb130ff 965 Status = PciRootBridgeIo->Pci.Write (\r
ead42efc 966 PciRootBridgeIo,\r
ead42efc 967 EfiPciWidthUint8,\r
968 Address,\r
969 1,\r
970 SubBusNumber\r
971 );\r
7fc72ecb 972 } else {\r
973 //\r
974 // It is device. Check PCI IOV for Bus reservation\r
975 //\r
9dd44c0b 976 if (PciDevice == NULL) {\r
977 //\r
978 // No PciDevice found, conitue Scan\r
979 //\r
980 continue;\r
981 }\r
7fc72ecb 982 //\r
983 // Go through each function, just reserve the MAX ReservedBusNum for one device\r
984 //\r
985 if ((PciDevice->AriCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
986\r
987 if (TempReservedBusNum < PciDevice->ReservedBusNum) {\r
988\r
989 (*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum);\r
990 TempReservedBusNum = PciDevice->ReservedBusNum;\r
991\r
992 if (Func == 0) {\r
993 DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x\n", *SubBusNumber));\r
994 } else {\r
995 DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x (Update)\n", *SubBusNumber));\r
996 }\r
997 }\r
998 }\r
ead42efc 999 }\r
1000\r
1001 if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
1002\r
1003 //\r
1004 // Skip sub functions, this is not a multi function device\r
1005 //\r
8e8227d1 1006\r
ead42efc 1007 Func = PCI_MAX_FUNC;\r
1008 }\r
ead42efc 1009 }\r
1010 }\r
1011\r
1012 return EFI_SUCCESS;\r
1013}\r
1014\r
57076f45 1015/**\r
8e8227d1 1016 Process Option Rom on the specified root bridge.\r
1017\r
1018 @param Bridge Pci root bridge device instance.\r
1019\r
1020 @retval EFI_SUCCESS Success process.\r
1021 @retval other Some error occurred when processing Option Rom on the root bridge.\r
1022\r
57076f45 1023**/\r
ead42efc 1024EFI_STATUS\r
1025PciRootBridgeP2CProcess (\r
1026 IN PCI_IO_DEVICE *Bridge\r
1027 )\r
ead42efc 1028{\r
1029 LIST_ENTRY *CurrentLink;\r
1030 PCI_IO_DEVICE *Temp;\r
1031 EFI_HPC_STATE State;\r
1032 UINT64 PciAddress;\r
1033 EFI_STATUS Status;\r
1034\r
1035 CurrentLink = Bridge->ChildList.ForwardLink;\r
1036\r
97404058 1037 while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {\r
ead42efc 1038\r
1039 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
1040\r
1041 if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
1042\r
8e8227d1 1043 if (gPciHotPlugInit != NULL && Temp->Allocated && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
ead42efc 1044\r
1045 //\r
1046 // Raise the EFI_IOB_PCI_HPC_INIT status code\r
1047 //\r
1048 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1049 EFI_PROGRESS_CODE,\r
1050 EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT,\r
1051 Temp->DevicePath\r
1052 );\r
1053\r
1054 PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
1055 Status = gPciHotPlugInit->InitializeRootHpc (\r
1056 gPciHotPlugInit,\r
1057 Temp->DevicePath,\r
1058 PciAddress,\r
1059 NULL,\r
1060 &State\r
1061 );\r
1062\r
1063 if (!EFI_ERROR (Status)) {\r
1064 Status = PciBridgeEnumerator (Temp);\r
1065\r
1066 if (EFI_ERROR (Status)) {\r
1067 return Status;\r
1068 }\r
1069 }\r
1070\r
1071 CurrentLink = CurrentLink->ForwardLink;\r
1072 continue;\r
1073\r
1074 }\r
1075 }\r
1076\r
1077 if (!IsListEmpty (&Temp->ChildList)) {\r
1078 Status = PciRootBridgeP2CProcess (Temp);\r
1079 }\r
1080\r
1081 CurrentLink = CurrentLink->ForwardLink;\r
1082 }\r
1083\r
1084 return EFI_SUCCESS;\r
1085}\r
1086\r
a3b8e257 1087/**\r
8e8227d1 1088 Process Option Rom on the specified host bridge.\r
1089\r
1090 @param PciResAlloc Pointer to instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.\r
1091\r
eeefcb9d 1092 @retval EFI_SUCCESS Success process.\r
8e8227d1 1093 @retval EFI_NOT_FOUND Can not find the root bridge instance.\r
1094 @retval other Some error occurred when processing Option Rom on the host bridge.\r
1095\r
a3b8e257 1096**/\r
ead42efc 1097EFI_STATUS\r
1098PciHostBridgeP2CProcess (\r
1099 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
1100 )\r
ead42efc 1101{\r
1102 EFI_HANDLE RootBridgeHandle;\r
1103 PCI_IO_DEVICE *RootBridgeDev;\r
1104 EFI_STATUS Status;\r
1105\r
1106 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
1107 return EFI_SUCCESS;\r
1108 }\r
1109\r
1110 RootBridgeHandle = NULL;\r
1111\r
1112 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
1113\r
1114 //\r
1115 // Get RootBridg Device by handle\r
1116 //\r
1117 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
1118\r
1119 if (RootBridgeDev == NULL) {\r
1120 return EFI_NOT_FOUND;\r
1121 }\r
1122\r
1123 Status = PciRootBridgeP2CProcess (RootBridgeDev);\r
ead42efc 1124 if (EFI_ERROR (Status)) {\r
1125 return Status;\r
1126 }\r
1127\r
1128 }\r
1129\r
1130 return EFI_SUCCESS;\r
1131}\r
1132\r
bcd70414 1133/**\r
ead42efc 1134 This function is used to enumerate the entire host bridge\r
eeefcb9d 1135 in a given platform.\r
ead42efc 1136\r
8e8227d1 1137 @param PciResAlloc A pointer to the PCI Host Resource Allocation protocol.\r
ead42efc 1138\r
8e8227d1 1139 @retval EFI_SUCCESS Successfully enumerated the host bridge.\r
1140 @retval EFI_OUT_OF_RESOURCES No enough memory available.\r
1141 @retval other Some error occurred when enumerating the host bridge.\r
ead42efc 1142\r
bcd70414 1143**/\r
57076f45 1144EFI_STATUS\r
1145PciHostBridgeEnumerator (\r
9eb130ff 1146 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
57076f45 1147 )\r
ead42efc 1148{\r
1149 EFI_HANDLE RootBridgeHandle;\r
1150 PCI_IO_DEVICE *RootBridgeDev;\r
1151 EFI_STATUS Status;\r
1152 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
1153 UINT16 MinBus;\r
1154 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
5326528b 1155 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;\r
4beb4afe 1156 UINT8 StartBusNumber;\r
1157 LIST_ENTRY RootBridgeList;\r
1158 LIST_ENTRY *Link;\r
ead42efc 1159\r
8e8227d1 1160 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
1161 InitializeHotPlugSupport ();\r
1162 }\r
ead42efc 1163\r
4beb4afe 1164 InitializeListHead (&RootBridgeList);\r
1165\r
ead42efc 1166 //\r
1167 // Notify the bus allocation phase is about to start\r
1168 //\r
1169 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
1170\r
7fc72ecb 1171 DEBUG((EFI_D_INFO, "PCI Bus First Scanning\n"));\r
ead42efc 1172 RootBridgeHandle = NULL;\r
1173 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
1174\r
1175 //\r
1176 // if a root bridge instance is found, create root bridge device for it\r
1177 //\r
1178\r
1179 RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
1180\r
1181 if (RootBridgeDev == NULL) {\r
1182 return EFI_OUT_OF_RESOURCES;\r
1183 }\r
1184\r
1185 //\r
1186 // Enumerate all the buses under this root bridge\r
1187 //\r
ead42efc 1188 Status = PciRootBridgeEnumerator (\r
1189 PciResAlloc,\r
1190 RootBridgeDev\r
1191 );\r
1192\r
8e8227d1 1193 if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
4beb4afe 1194 InsertTailList (&RootBridgeList, &(RootBridgeDev->Link));\r
1195 } else {\r
1196 DestroyRootBridge (RootBridgeDev);\r
1197 }\r
ead42efc 1198 if (EFI_ERROR (Status)) {\r
1199 return Status;\r
1200 }\r
1201 }\r
1202\r
1203 //\r
1204 // Notify the bus allocation phase is finished for the first time\r
1205 //\r
1206 NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
1207\r
8e8227d1 1208 if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
1209 //\r
1210 // Reset all assigned PCI bus number in all PPB\r
1211 //\r
1212 RootBridgeHandle = NULL;\r
1213 Link = GetFirstNode (&RootBridgeList);\r
1214 while ((PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) &&\r
1215 (!IsNull (&RootBridgeList, Link))) {\r
1216 RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (Link);\r
ead42efc 1217 //\r
8e8227d1 1218 // Get the Bus information\r
4beb4afe 1219 //\r
8e8227d1 1220 Status = PciResAlloc->StartBusEnumeration (\r
1221 PciResAlloc,\r
1222 RootBridgeHandle,\r
1223 (VOID **) &Configuration\r
1224 );\r
ead42efc 1225 if (EFI_ERROR (Status)) {\r
1226 return Status;\r
1227 }\r
1228\r
1229 //\r
8e8227d1 1230 // Get the bus number to start with\r
ead42efc 1231 //\r
8e8227d1 1232 StartBusNumber = (UINT8) (Configuration->AddrRangeMin);\r
ead42efc 1233\r
8e8227d1 1234 ResetAllPpbBusNumber (\r
1235 RootBridgeDev,\r
1236 StartBusNumber\r
1237 );\r
ead42efc 1238\r
8e8227d1 1239 FreePool (Configuration);\r
1240 Link = GetNextNode (&RootBridgeList, Link);\r
1241 DestroyRootBridge (RootBridgeDev);\r
1242 }\r
ead42efc 1243\r
8e8227d1 1244 //\r
1245 // Wait for all HPC initialized\r
1246 //\r
1247 Status = AllRootHPCInitialized (STALL_1_SECOND * 15);\r
ead42efc 1248\r
8e8227d1 1249 if (EFI_ERROR (Status)) {\r
1250 return Status;\r
1251 }\r
ead42efc 1252\r
8e8227d1 1253 //\r
1254 // Notify the bus allocation phase is about to start for the 2nd time\r
1255 //\r
1256 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
ead42efc 1257\r
7fc72ecb 1258 DEBUG((EFI_D_INFO, "PCI Bus Second Scanning\n"));\r
8e8227d1 1259 RootBridgeHandle = NULL;\r
1260 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
ead42efc 1261\r
8e8227d1 1262 //\r
1263 // if a root bridge instance is found, create root bridge device for it\r
1264 //\r
1265 RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
1266\r
1267 if (RootBridgeDev == NULL) {\r
1268 return EFI_OUT_OF_RESOURCES;\r
ead42efc 1269 }\r
1270\r
1271 //\r
8e8227d1 1272 // Enumerate all the buses under this root bridge\r
ead42efc 1273 //\r
8e8227d1 1274 Status = PciRootBridgeEnumerator (\r
1275 PciResAlloc,\r
1276 RootBridgeDev\r
1277 );\r
1278\r
1279 DestroyRootBridge (RootBridgeDev);\r
1280 if (EFI_ERROR (Status)) {\r
1281 return Status;\r
1282 }\r
ead42efc 1283 }\r
8e8227d1 1284\r
1285 //\r
1286 // Notify the bus allocation phase is to end for the 2nd time\r
1287 //\r
1288 NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
ead42efc 1289 }\r
1290\r
1291 //\r
1292 // Notify the resource allocation phase is to start\r
1293 //\r
1294 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);\r
1295\r
1296 RootBridgeHandle = NULL;\r
1297 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
1298\r
1299 //\r
1300 // if a root bridge instance is found, create root bridge device for it\r
1301 //\r
ead42efc 1302 RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
1303\r
1304 if (RootBridgeDev == NULL) {\r
1305 return EFI_OUT_OF_RESOURCES;\r
1306 }\r
1307\r
1308 Status = StartManagingRootBridge (RootBridgeDev);\r
1309\r
1310 if (EFI_ERROR (Status)) {\r
1311 return Status;\r
1312 }\r
1313\r
1314 PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;\r
1315 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
1316\r
1317 if (EFI_ERROR (Status)) {\r
1318 return Status;\r
1319 }\r
1320\r
1321 Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);\r
1322\r
1323 if (EFI_ERROR (Status)) {\r
1324 return Status;\r
1325 }\r
1326\r
1327 //\r
1328 // Determine root bridge attribute by calling interface of Pcihostbridge\r
1329 // protocol\r
1330 //\r
1331 DetermineRootBridgeAttributes (\r
1332 PciResAlloc,\r
1333 RootBridgeDev\r
1334 );\r
1335\r
1336 //\r
1337 // Collect all the resource information under this root bridge\r
1338 // A database that records all the information about pci device subject to this\r
1339 // root bridge will then be created\r
1340 //\r
1341 Status = PciPciDeviceInfoCollector (\r
1342 RootBridgeDev,\r
1343 (UINT8) MinBus\r
1344 );\r
1345\r
1346 if (EFI_ERROR (Status)) {\r
1347 return Status;\r
1348 }\r
1349\r
1350 InsertRootBridge (RootBridgeDev);\r
1351\r
1352 //\r
1353 // Record the hostbridge handle\r
1354 //\r
1355 AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);\r
1356 }\r
1357\r
1358 return EFI_SUCCESS;\r
1359}\r