]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c
Add ReadMe.txt to specify that the EFI image FatBinPkg provides does not contain...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBus / Dxe / PciEnumerator.c
CommitLineData
ead42efc 1/*++\r
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
12Module Name:\r
13\r
14 PciEnumerator.c\r
15\r
16Abstract:\r
17\r
18 PCI Bus Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
24#include "pcibus.h"\r
25#include "PciEnumerator.h"\r
26#include "PciResourceSupport.h"\r
27#include "PciOptionRomSupport.h"\r
28\r
29EFI_STATUS\r
30PciEnumerator (\r
31 IN EFI_HANDLE Controller\r
32 )\r
33/*++\r
34\r
35Routine Description:\r
36\r
37 This routine is used to enumerate entire pci bus system\r
38 in a given platform\r
39\r
40Arguments:\r
41\r
42Returns:\r
43\r
44 None\r
45\r
46--*/\r
47// TODO: Controller - add argument and description to function comment\r
48// TODO: EFI_SUCCESS - add return value to function comment\r
49// TODO: EFI_SUCCESS - add return value to function comment\r
50{\r
51\r
52 EFI_HANDLE HostBridgeHandle;\r
53 EFI_STATUS Status;\r
54 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
55 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
56\r
57 //\r
58 // If PCI bus has already done the full enumeration, never do it again\r
59 //\r
60 if (!gFullEnumeration) {\r
61 return PciEnumeratorLight (Controller);\r
62 }\r
63\r
64 //\r
65 // If this host bridge has been already enumerated, then return successfully\r
66 //\r
67 if (RootBridgeExisted (Controller)) {\r
68 return EFI_SUCCESS;\r
69 }\r
70\r
71 //\r
72 // Get the rootbridge Io protocol to find the host bridge handle\r
73 //\r
74 Status = gBS->OpenProtocol (\r
75 Controller,\r
76 &gEfiPciRootBridgeIoProtocolGuid,\r
77 (VOID **) &PciRootBridgeIo,\r
78 gPciBusDriverBinding.DriverBindingHandle,\r
79 Controller,\r
80 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
81 );\r
82\r
83 if (EFI_ERROR (Status)) {\r
84 return Status;\r
85 }\r
86\r
87 //\r
88 // Get the host bridge handle\r
89 //\r
90 HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
91\r
92 //\r
93 // Get the pci host bridge resource allocation protocol\r
94 //\r
95 Status = gBS->OpenProtocol (\r
96 HostBridgeHandle,\r
97 &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
98 (VOID **) &PciResAlloc,\r
99 gPciBusDriverBinding.DriverBindingHandle,\r
100 Controller,\r
101 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
102 );\r
103\r
104 if (EFI_ERROR (Status)) {\r
105 return Status;\r
106 }\r
107\r
108 //\r
109 // Notify the pci bus enumeration is about to begin\r
110 //\r
111 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);\r
112\r
113 //\r
114 // Start the bus allocation phase\r
115 //\r
116 Status = PciHostBridgeEnumerator (PciResAlloc);\r
117\r
118 if (EFI_ERROR (Status)) {\r
119 return Status;\r
120 }\r
121\r
122 //\r
123 // Submit the resource request\r
124 //\r
125 Status = PciHostBridgeResourceAllocator (PciResAlloc);\r
126\r
127 if (EFI_ERROR (Status)) {\r
128 return Status;\r
129 }\r
130\r
131 //\r
132 // Process P2C\r
133 //\r
134 Status = PciHostBridgeP2CProcess (PciResAlloc);\r
135\r
136 if (EFI_ERROR (Status)) {\r
137 return Status;\r
138 }\r
139\r
140 //\r
141 // Process attributes for devices on this host bridge\r
142 //\r
143 Status = PciHostBridgeDeviceAttribute (PciResAlloc);\r
144 if (EFI_ERROR (Status)) {\r
145 return Status;\r
146 }\r
147\r
148 gFullEnumeration = FALSE;\r
149\r
150 return EFI_SUCCESS;\r
151}\r
152\r
153EFI_STATUS\r
154PciRootBridgeEnumerator (\r
155 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
156 IN PCI_IO_DEVICE *RootBridgeDev\r
157 )\r
158/*++\r
159\r
160Routine Description:\r
161\r
162Arguments:\r
163\r
164Returns:\r
165\r
166 None\r
167\r
168--*/\r
169// TODO: PciResAlloc - add argument and description to function comment\r
170// TODO: RootBridgeDev - add argument and description to function comment\r
171// TODO: EFI_SUCCESS - add return value to function comment\r
172{\r
173 EFI_STATUS Status;\r
174 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;\r
175 UINT8 SubBusNumber;\r
176 UINT8 StartBusNumber;\r
177 UINT8 PaddedBusRange;\r
178 EFI_HANDLE RootBridgeHandle;\r
179\r
180 SubBusNumber = 0;\r
181 StartBusNumber = 0;\r
182 PaddedBusRange = 0;\r
183\r
184 //\r
185 // Get the root bridge handle\r
186 //\r
187 RootBridgeHandle = RootBridgeDev->Handle;\r
188\r
189 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
190 EFI_PROGRESS_CODE,\r
191 EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,\r
192 RootBridgeDev->DevicePath\r
193 );\r
194\r
195 //\r
196 // Get the Bus information\r
197 //\r
198 Status = PciResAlloc->StartBusEnumeration (\r
199 PciResAlloc,\r
200 RootBridgeHandle,\r
201 (VOID **) &pConfiguration\r
202 );\r
203\r
204 if (EFI_ERROR (Status)) {\r
205 return Status;\r
206 }\r
207\r
208 //\r
209 // Get the bus number to start with\r
210 //\r
211 StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);\r
212\r
213 //\r
214 // Initialize the subordinate bus number\r
215 //\r
216 SubBusNumber = StartBusNumber;\r
217\r
218 //\r
219 // Assign bus number\r
220 //\r
221 Status = PciScanBus (\r
222 RootBridgeDev,\r
223 (UINT8) (pConfiguration->AddrRangeMin),\r
224 &SubBusNumber,\r
225 &PaddedBusRange\r
226 );\r
227\r
228 if (EFI_ERROR (Status)) {\r
229 return Status;\r
230 }\r
231\r
232\r
233 //\r
234 // Assign max bus number scanned\r
235 //\r
236 pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;\r
237\r
238 //\r
239 // Set bus number\r
240 //\r
241 Status = PciResAlloc->SetBusNumbers (\r
242 PciResAlloc,\r
243 RootBridgeHandle,\r
244 pConfiguration\r
245 );\r
246\r
247 if (EFI_ERROR (Status)) {\r
248 return Status;\r
249 }\r
250\r
251 return EFI_SUCCESS;\r
252}\r
253\r
254EFI_STATUS\r
255ProcessOptionRom (\r
256 IN PCI_IO_DEVICE *Bridge,\r
257 IN UINT64 RomBase,\r
258 IN UINT64 MaxLength\r
259 )\r
260/*++\r
261\r
262Routine Description:\r
263\r
264 This routine is used to process option rom on a certain root bridge\r
265\r
266Arguments:\r
267\r
268Returns:\r
269\r
270 None\r
271\r
272--*/\r
273// TODO: Bridge - add argument and description to function comment\r
274// TODO: RomBase - add argument and description to function comment\r
275// TODO: MaxLength - add argument and description to function comment\r
276// TODO: EFI_SUCCESS - add return value to function comment\r
277{\r
278 LIST_ENTRY *CurrentLink;\r
279 PCI_IO_DEVICE *Temp;\r
280 EFI_STATUS Status;\r
281\r
282 //\r
283 // Go through bridges to reach all devices\r
284 //\r
285 CurrentLink = Bridge->ChildList.ForwardLink;\r
286 while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
287 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
288 if (!IsListEmpty (&Temp->ChildList)) {\r
289\r
290 //\r
291 // Go further to process the option rom under this bridge\r
292 //\r
293 Status = ProcessOptionRom (Temp, RomBase, MaxLength);\r
294 }\r
295\r
296 if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {\r
297\r
298 //\r
299 // Load and process the option rom\r
300 //\r
301 Status = LoadOpRomImage (Temp, RomBase);\r
302 if (Status == EFI_SUCCESS) {\r
303 Status = ProcessOpRomImage (Temp);\r
304 }\r
305 }\r
306\r
307 CurrentLink = CurrentLink->ForwardLink;\r
308 }\r
309\r
310 return EFI_SUCCESS;\r
311}\r
312\r
313EFI_STATUS\r
314PciAssignBusNumber (\r
315 IN PCI_IO_DEVICE *Bridge,\r
316 IN UINT8 StartBusNumber,\r
317 OUT UINT8 *SubBusNumber\r
318 )\r
319/*++\r
320\r
321Routine Description:\r
322\r
323 This routine is used to assign bus number to the given PCI bus system\r
324\r
325Arguments:\r
326\r
327Returns:\r
328\r
329 None\r
330\r
331--*/\r
332// TODO: Bridge - add argument and description to function comment\r
333// TODO: StartBusNumber - add argument and description to function comment\r
334// TODO: SubBusNumber - add argument and description to function comment\r
335// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
336// TODO: EFI_SUCCESS - add return value to function comment\r
337{\r
338 EFI_STATUS Status;\r
339 PCI_TYPE00 Pci;\r
340 UINT8 Device;\r
341 UINT8 Func;\r
342 UINT64 Address;\r
343 UINTN SecondBus;\r
344 UINT16 Register;\r
345 UINT8 Register8;\r
346 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
347\r
348 PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
349\r
350 SecondBus = 0;\r
351 Register = 0;\r
352\r
353 *SubBusNumber = StartBusNumber;\r
354\r
355 //\r
356 // First check to see whether the parent is ppb\r
357 //\r
358 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
359 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
360\r
361 //\r
362 // Check to see whether a pci device is present\r
363 //\r
364\r
365 Status = PciDevicePresent (\r
366 PciRootBridgeIo,\r
367 &Pci,\r
368 StartBusNumber,\r
369 Device,\r
370 Func\r
371 );\r
372\r
373 if (!EFI_ERROR (Status) &&\r
374 (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
375\r
376 //\r
377 // Reserved one bus for cardbus bridge\r
378 //\r
379 SecondBus = ++(*SubBusNumber);\r
380\r
381 Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
382\r
383 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
384\r
385 Status = PciRootBridgeIoWrite (\r
386 PciRootBridgeIo,\r
387 &Pci,\r
388 EfiPciWidthUint16,\r
389 Address,\r
390 1,\r
391 &Register\r
392 );\r
393\r
394 //\r
395 // Initialize SubBusNumber to SecondBus\r
396 //\r
397 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
398 Status = PciRootBridgeIoWrite (\r
399 PciRootBridgeIo,\r
400 &Pci,\r
401 EfiPciWidthUint8,\r
402 Address,\r
403 1,\r
404 SubBusNumber\r
405 );\r
406 //\r
407 // If it is PPB, resursively search down this bridge\r
408 //\r
409 if (IS_PCI_BRIDGE (&Pci)) {\r
410\r
411 Register8 = 0xFF;\r
412 Status = PciRootBridgeIoWrite (\r
413 PciRootBridgeIo,\r
414 &Pci,\r
415 EfiPciWidthUint8,\r
416 Address,\r
417 1,\r
418 &Register8\r
419 );\r
420\r
421 Status = PciAssignBusNumber (\r
422 Bridge,\r
423 (UINT8) (SecondBus),\r
424 SubBusNumber\r
425 );\r
426\r
427 if (EFI_ERROR (Status)) {\r
428 return EFI_DEVICE_ERROR;\r
429 }\r
430 }\r
431\r
432 //\r
433 // Set the current maximum bus number under the PPB\r
434 //\r
435\r
436 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
437\r
438 Status = PciRootBridgeIoWrite (\r
439 PciRootBridgeIo,\r
440 &Pci,\r
441 EfiPciWidthUint8,\r
442 Address,\r
443 1,\r
444 SubBusNumber\r
445 );\r
446\r
447 }\r
448\r
449 if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
450\r
451 //\r
452 // Skip sub functions, this is not a multi function device\r
453 //\r
454\r
455 Func = PCI_MAX_FUNC;\r
456 }\r
457 }\r
458 }\r
459\r
460 return EFI_SUCCESS;\r
461}\r
462\r
463EFI_STATUS\r
464DetermineRootBridgeAttributes (\r
465 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
466 IN PCI_IO_DEVICE *RootBridgeDev\r
467 )\r
468/*++\r
469\r
470Routine Description:\r
471\r
472 This routine is used to determine the root bridge attribute by interfacing\r
473 the host bridge resource allocation protocol.\r
474\r
475Arguments:\r
476\r
477Returns:\r
478\r
479 None\r
480\r
481--*/\r
482// TODO: PciResAlloc - add argument and description to function comment\r
483// TODO: RootBridgeDev - add argument and description to function comment\r
484// TODO: EFI_SUCCESS - add return value to function comment\r
485{\r
486 UINT64 Attributes;\r
487 EFI_STATUS Status;\r
488 EFI_HANDLE RootBridgeHandle;\r
489\r
490 Attributes = 0;\r
491 RootBridgeHandle = RootBridgeDev->Handle;\r
492\r
493 //\r
494 // Get root bridge attribute by calling into pci host bridge resource allocation protocol\r
495 //\r
496 Status = PciResAlloc->GetAllocAttributes (\r
497 PciResAlloc,\r
498 RootBridgeHandle,\r
499 &Attributes\r
500 );\r
501\r
502 if (EFI_ERROR (Status)) {\r
503 return Status;\r
504 }\r
505\r
506 //\r
507 // Here is the point where PCI bus driver calls HOST bridge allocation protocol\r
508 // Currently we hardcoded for ea815\r
509 //\r
510\r
511 if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {\r
512 RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;\r
513 }\r
514\r
515 if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {\r
516 RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
517 }\r
518\r
519 RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
520 RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
521 RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
522\r
523 return EFI_SUCCESS;\r
524}\r
525\r
526UINT64\r
527GetMaxOptionRomSize (\r
528 IN PCI_IO_DEVICE *Bridge\r
529 )\r
530/*++\r
531\r
532Routine Description:\r
533\r
534 Get Max Option Rom size on this bridge\r
535\r
536Arguments:\r
537\r
538Returns:\r
539\r
540 None\r
541\r
542--*/\r
543// TODO: Bridge - add argument and description to function comment\r
544{\r
545 LIST_ENTRY *CurrentLink;\r
546 PCI_IO_DEVICE *Temp;\r
547 UINT64 MaxOptionRomSize;\r
548 UINT64 TempOptionRomSize;\r
549\r
550 MaxOptionRomSize = 0;\r
551\r
552 //\r
553 // Go through bridges to reach all devices\r
554 //\r
555 CurrentLink = Bridge->ChildList.ForwardLink;\r
556 while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
557 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
558 if (!IsListEmpty (&Temp->ChildList)) {\r
559\r
560 //\r
561 // Get max option rom size under this bridge\r
562 //\r
563 TempOptionRomSize = GetMaxOptionRomSize (Temp);\r
564\r
565 //\r
566 // Compare with the option rom size of the bridge\r
567 // Get the larger one\r
568 //\r
569 if (Temp->RomSize > TempOptionRomSize) {\r
570 TempOptionRomSize = Temp->RomSize;\r
571 }\r
572\r
573 } else {\r
574\r
575 //\r
576 // For devices get the rom size directly\r
577 //\r
578 TempOptionRomSize = Temp->RomSize;\r
579 }\r
580\r
581 //\r
582 // Get the largest rom size on this bridge\r
583 //\r
584 if (TempOptionRomSize > MaxOptionRomSize) {\r
585 MaxOptionRomSize = TempOptionRomSize;\r
586 }\r
587\r
588 CurrentLink = CurrentLink->ForwardLink;\r
589 }\r
590\r
591 return MaxOptionRomSize;\r
592}\r
593\r
594EFI_STATUS\r
595PciHostBridgeDeviceAttribute (\r
596 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
597 )\r
598/*++\r
599\r
600Routine Description:\r
601\r
602 Process attributes of devices on this host bridge\r
603\r
604Arguments:\r
605\r
606Returns:\r
607\r
608 None\r
609\r
610--*/\r
611// TODO: PciResAlloc - add argument and description to function comment\r
612// TODO: EFI_NOT_FOUND - add return value to function comment\r
613// TODO: EFI_SUCCESS - add return value to function comment\r
614{\r
615 EFI_HANDLE RootBridgeHandle;\r
616 PCI_IO_DEVICE *RootBridgeDev;\r
617 EFI_STATUS Status;\r
618\r
619 RootBridgeHandle = NULL;\r
620\r
621 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
622\r
623 //\r
624 // Get RootBridg Device by handle\r
625 //\r
626 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
627\r
628 if (RootBridgeDev == NULL) {\r
629 return EFI_NOT_FOUND;\r
630 }\r
631\r
632 //\r
633 // Set the attributes for devcies behind the Root Bridge\r
634 //\r
635 Status = DetermineDeviceAttribute (RootBridgeDev);\r
636 if (EFI_ERROR (Status)) {\r
637 return Status;\r
638 }\r
639\r
640 }\r
641\r
642 return EFI_SUCCESS;\r
643}\r
644\r
645EFI_STATUS\r
646GetResourceAllocationStatus (\r
647 VOID *AcpiConfig,\r
648 OUT UINT64 *IoResStatus,\r
649 OUT UINT64 *Mem32ResStatus,\r
650 OUT UINT64 *PMem32ResStatus,\r
651 OUT UINT64 *Mem64ResStatus,\r
652 OUT UINT64 *PMem64ResStatus\r
653 )\r
654/*++\r
655\r
656Routine Description:\r
657\r
658 Get resource allocation status from the ACPI pointer\r
659\r
660Arguments:\r
661\r
662Returns:\r
663\r
664 None\r
665\r
666--*/\r
667// TODO: AcpiConfig - add argument and description to function comment\r
668// TODO: IoResStatus - add argument and description to function comment\r
669// TODO: Mem32ResStatus - add argument and description to function comment\r
670// TODO: PMem32ResStatus - add argument and description to function comment\r
671// TODO: Mem64ResStatus - add argument and description to function comment\r
672// TODO: PMem64ResStatus - add argument and description to function comment\r
673// TODO: EFI_SUCCESS - add return value to function comment\r
674{\r
675\r
676 UINT8 *Temp;\r
677 UINT64 ResStatus;\r
678 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
679\r
680 Temp = (UINT8 *) AcpiConfig;\r
681\r
682 while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
683\r
684 ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
685 ResStatus = ptr->AddrTranslationOffset;\r
686\r
687 switch (ptr->ResType) {\r
688 case 0:\r
689 if (ptr->AddrSpaceGranularity == 32) {\r
690 if (ptr->SpecificFlag == 0x06) {\r
691 //\r
692 // Pmem32\r
693 //\r
694 *PMem32ResStatus = ResStatus;\r
695 } else {\r
696 //\r
697 // Mem32\r
698 //\r
699 *Mem32ResStatus = ResStatus;\r
700 }\r
701 }\r
702\r
703 if (ptr->AddrSpaceGranularity == 64) {\r
704 if (ptr->SpecificFlag == 0x06) {\r
705 //\r
706 // PMem64\r
707 //\r
708 *PMem64ResStatus = ResStatus;\r
709 } else {\r
710 //\r
711 // Mem64\r
712 //\r
713 *Mem64ResStatus = ResStatus;\r
714 }\r
715 }\r
716\r
717 break;\r
718\r
719 case 1:\r
720 //\r
721 // Io\r
722 //\r
723 *IoResStatus = ResStatus;\r
724 break;\r
725\r
726 default:\r
727 break;\r
728 }\r
729\r
730 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
731 }\r
732\r
733 return EFI_SUCCESS;\r
734}\r
735\r
736EFI_STATUS\r
737RejectPciDevice (\r
738 IN PCI_IO_DEVICE *PciDevice\r
739 )\r
740/*++\r
741\r
742Routine Description:\r
743\r
744 Remove a PCI device from device pool and mark its bar\r
745\r
746Arguments:\r
747\r
748Returns:\r
749\r
750 None\r
751\r
752--*/\r
753// TODO: PciDevice - add argument and description to function comment\r
754// TODO: EFI_SUCCESS - add return value to function comment\r
755// TODO: EFI_ABORTED - add return value to function comment\r
756// TODO: EFI_SUCCESS - add return value to function comment\r
757// TODO: EFI_ABORTED - add return value to function comment\r
758{\r
759 PCI_IO_DEVICE *Bridge;\r
760 PCI_IO_DEVICE *Temp;\r
761 LIST_ENTRY *CurrentLink;\r
762\r
763 //\r
764 // Remove the padding resource from a bridge\r
765 //\r
766 if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \\r
767 PciDevice->ResourcePaddingDescriptors ) {\r
768 gBS->FreePool (PciDevice->ResourcePaddingDescriptors);\r
769 PciDevice->ResourcePaddingDescriptors = NULL;\r
770 return EFI_SUCCESS;\r
771 }\r
772\r
773 //\r
774 // Skip RB and PPB\r
775 //\r
776 if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {\r
777 return EFI_ABORTED;\r
778 }\r
779\r
780 if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {\r
781 //\r
782 // Get the root bridge device\r
783 //\r
784 Bridge = PciDevice;\r
785 while (Bridge->Parent) {\r
786 Bridge = Bridge->Parent;\r
787 }\r
788\r
789 RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);\r
790\r
791 //\r
792 // Mark its bar\r
793 //\r
794 InitializeP2C (PciDevice);\r
795 }\r
796\r
797 //\r
798 // Remove the device\r
799 //\r
800 Bridge = PciDevice->Parent;\r
801 CurrentLink = Bridge->ChildList.ForwardLink;\r
802 while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
803 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
804 if (Temp == PciDevice) {\r
805 InitializePciDevice (Temp);\r
806 RemoveEntryList (CurrentLink);\r
807 FreePciDevice (Temp);\r
808 return EFI_SUCCESS;\r
809 }\r
810\r
811 CurrentLink = CurrentLink->ForwardLink;\r
812 }\r
813\r
814 return EFI_ABORTED;\r
815}\r
816\r
817BOOLEAN\r
818IsRejectiveDevice (\r
819 IN PCI_RESOURCE_NODE *PciResNode\r
820 )\r
821/*++\r
822\r
823Routine Description:\r
824\r
825 Determine whethter a PCI device can be rejected\r
826\r
827Arguments:\r
828\r
829Returns:\r
830\r
831 None\r
832\r
833--*/\r
834// TODO: PciResNode - add argument and description to function comment\r
835{\r
836 PCI_IO_DEVICE *Temp;\r
837\r
838 Temp = PciResNode->PciDev;\r
839\r
840 //\r
841 // Ensure the device is present\r
842 //\r
843 if (!Temp) {\r
844 return FALSE;\r
845 }\r
846\r
847 //\r
848 // PPB and RB should go ahead\r
849 //\r
850 if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {\r
851 return TRUE;\r
852 }\r
853\r
854 //\r
855 // Skip device on Bus0\r
856 //\r
857 if ((Temp->Parent) && (Temp->BusNumber == 0)) {\r
858 return FALSE;\r
859 }\r
860\r
861 //\r
862 // Skip VGA\r
863 //\r
864 if (IS_PCI_VGA (&Temp->Pci)) {\r
865 return FALSE;\r
866 }\r
867\r
868 return TRUE;\r
869}\r
870\r
871PCI_RESOURCE_NODE *\r
872GetLargerConsumerDevice (\r
873 IN PCI_RESOURCE_NODE *PciResNode1,\r
874 IN PCI_RESOURCE_NODE *PciResNode2\r
875 )\r
876/*++\r
877\r
878Routine Description:\r
879\r
880 Get the larger resource consumer\r
881\r
882Arguments:\r
883\r
884Returns:\r
885\r
886 None\r
887\r
888--*/\r
889// TODO: PciResNode1 - add argument and description to function comment\r
890// TODO: PciResNode2 - add argument and description to function comment\r
891{\r
892 if (!PciResNode2) {\r
893 return PciResNode1;\r
894 }\r
895\r
896 if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \\r
897 && (PciResNode2->ResourceUsage != PciResUsagePadding) )\r
898 {\r
899 return PciResNode1;\r
900 }\r
901\r
902 if (!PciResNode1) {\r
903 return PciResNode2;\r
904 }\r
905\r
906 if ((PciResNode1->Length) > (PciResNode2->Length)) {\r
907 return PciResNode1;\r
908 }\r
909\r
910 return PciResNode2;\r
911\r
912}\r
913\r
914PCI_RESOURCE_NODE *\r
915GetMaxResourceConsumerDevice (\r
916 IN PCI_RESOURCE_NODE *ResPool\r
917 )\r
918/*++\r
919\r
920Routine Description:\r
921\r
922 Get the max resource consumer in the host resource pool\r
923\r
924Arguments:\r
925\r
926Returns:\r
927\r
928 None\r
929\r
930--*/\r
931// TODO: ResPool - add argument and description to function comment\r
932{\r
933 PCI_RESOURCE_NODE *Temp;\r
934 LIST_ENTRY *CurrentLink;\r
935 PCI_RESOURCE_NODE *PciResNode;\r
936 PCI_RESOURCE_NODE *PPBResNode;\r
937\r
938 PciResNode = NULL;\r
939\r
940 CurrentLink = ResPool->ChildList.ForwardLink;\r
941 while (CurrentLink && CurrentLink != &ResPool->ChildList) {\r
942\r
943 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
944\r
945 if (!IsRejectiveDevice (Temp)) {\r
946 CurrentLink = CurrentLink->ForwardLink;\r
947 continue;\r
948 }\r
949\r
950 if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \\r
951 && (Temp->ResourceUsage != PciResUsagePadding))\r
952 {\r
953 PPBResNode = GetMaxResourceConsumerDevice (Temp);\r
954 PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);\r
955 } else {\r
956 PciResNode = GetLargerConsumerDevice (PciResNode, Temp);\r
957 }\r
958\r
959 CurrentLink = CurrentLink->ForwardLink;\r
960 }\r
961\r
962 return PciResNode;\r
963}\r
964\r
965EFI_STATUS\r
966PciHostBridgeAdjustAllocation (\r
967 IN PCI_RESOURCE_NODE *IoPool,\r
968 IN PCI_RESOURCE_NODE *Mem32Pool,\r
969 IN PCI_RESOURCE_NODE *PMem32Pool,\r
970 IN PCI_RESOURCE_NODE *Mem64Pool,\r
971 IN PCI_RESOURCE_NODE *PMem64Pool,\r
972 IN UINT64 IoResStatus,\r
973 IN UINT64 Mem32ResStatus,\r
974 IN UINT64 PMem32ResStatus,\r
975 IN UINT64 Mem64ResStatus,\r
976 IN UINT64 PMem64ResStatus\r
977 )\r
978/*++\r
979\r
980Routine Description:\r
981\r
982 Adjust host bridge allocation so as to reduce resource requirement\r
983\r
984Arguments:\r
985\r
986Returns:\r
987\r
988 None\r
989\r
990--*/\r
991// TODO: IoPool - add argument and description to function comment\r
992// TODO: Mem32Pool - add argument and description to function comment\r
993// TODO: PMem32Pool - add argument and description to function comment\r
994// TODO: Mem64Pool - add argument and description to function comment\r
995// TODO: PMem64Pool - add argument and description to function comment\r
996// TODO: IoResStatus - add argument and description to function comment\r
997// TODO: Mem32ResStatus - add argument and description to function comment\r
998// TODO: PMem32ResStatus - add argument and description to function comment\r
999// TODO: Mem64ResStatus - add argument and description to function comment\r
1000// TODO: PMem64ResStatus - add argument and description to function comment\r
1001// TODO: EFI_ABORTED - add return value to function comment\r
1002// TODO: EFI_SUCCESS - add return value to function comment\r
1003// TODO: EFI_ABORTED - add return value to function comment\r
1004{\r
1005 BOOLEAN AllocationAjusted;\r
1006 PCI_RESOURCE_NODE *PciResNode;\r
1007 PCI_RESOURCE_NODE *ResPool[5];\r
1008 PCI_IO_DEVICE *RemovedPciDev[5];\r
1009 UINT64 ResStatus[5];\r
1010 UINTN RemovedPciDevNum;\r
1011 UINTN DevIndex;\r
1012 UINTN ResType;\r
1013 EFI_STATUS Status;\r
1d6d9e7e 1014 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
ead42efc 1015\r
1016 PciResNode = NULL;\r
1017 ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));\r
1018 RemovedPciDevNum = 0;\r
1019\r
1020 ResPool[0] = IoPool;\r
1021 ResPool[1] = Mem32Pool;\r
1022 ResPool[2] = PMem32Pool;\r
1023 ResPool[3] = Mem64Pool;\r
1024 ResPool[4] = PMem64Pool;\r
1025\r
1026 ResStatus[0] = IoResStatus;\r
1027 ResStatus[1] = Mem32ResStatus;\r
1028 ResStatus[2] = PMem32ResStatus;\r
1029 ResStatus[3] = Mem64ResStatus;\r
1030 ResStatus[4] = PMem64ResStatus;\r
1031\r
1032 AllocationAjusted = FALSE;\r
1033\r
1034 for (ResType = 0; ResType < 5; ResType++) {\r
1035\r
1036 if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {\r
1037 continue;\r
1038 }\r
1039\r
1040 if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {\r
1041 //\r
1042 // Hostbridge hasn't this resource type\r
1043 //\r
1044 return EFI_ABORTED;\r
1045 }\r
1046\r
1047 //\r
1048 // Hostbridge hasn't enough resource\r
1049 //\r
1050 PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);\r
1051 if (!PciResNode) {\r
1052 continue;\r
1053 }\r
1054\r
1055 //\r
1056 // Check if the device has been removed before\r
1057 //\r
1058 for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {\r
1059 if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {\r
1060 continue;\r
1061 }\r
1062 }\r
1063\r
1064 //\r
1065 // Remove the device if it isn't in the array\r
1066 //\r
1067 Status = RejectPciDevice (PciResNode->PciDev);\r
1068 if (Status == EFI_SUCCESS) {\r
1069\r
1070 //\r
1071 // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
1072 //\r
1073 //\r
1074 // Have no way to get ReqRes, AllocRes & Bar here\r
1075 //\r
1076 ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
1077 AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
1078 AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;\r
1079 AllocFailExtendedData.Bar = PciResNode->Bar;\r
1080\r
1081 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
1082 EFI_PROGRESS_CODE,\r
1083 EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
1084 (VOID *) &AllocFailExtendedData,\r
1085 sizeof (AllocFailExtendedData)\r
1086 );\r
1087\r
1088 //\r
1089 // Add it to the array and indicate at least a device has been rejected\r
1090 //\r
1091 RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;\r
1092 AllocationAjusted = TRUE;\r
1093 }\r
1094 }\r
1095 //\r
1096 // End for\r
1097 //\r
1098\r
1099 if (AllocationAjusted) {\r
1100 return EFI_SUCCESS;\r
1101 } else {\r
1102 return EFI_ABORTED;\r
1103 }\r
1104}\r
1105\r
1106EFI_STATUS\r
1107ConstructAcpiResourceRequestor (\r
1108 IN PCI_IO_DEVICE *Bridge,\r
1109 IN PCI_RESOURCE_NODE *IoNode,\r
1110 IN PCI_RESOURCE_NODE *Mem32Node,\r
1111 IN PCI_RESOURCE_NODE *PMem32Node,\r
1112 IN PCI_RESOURCE_NODE *Mem64Node,\r
1113 IN PCI_RESOURCE_NODE *PMem64Node,\r
1114 OUT VOID **pConfig\r
1115 )\r
1116/*++\r
1117\r
1118Routine Description:\r
1119\r
1120Arguments:\r
1121\r
1122Returns:\r
1123\r
1124 None\r
1125\r
1126--*/\r
1127// TODO: Bridge - add argument and description to function comment\r
1128// TODO: IoNode - add argument and description to function comment\r
1129// TODO: Mem32Node - add argument and description to function comment\r
1130// TODO: PMem32Node - add argument and description to function comment\r
1131// TODO: Mem64Node - add argument and description to function comment\r
1132// TODO: PMem64Node - add argument and description to function comment\r
1133// TODO: pConfig - add argument and description to function comment\r
1134// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1135// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1136// TODO: EFI_SUCCESS - add return value to function comment\r
1137{\r
1138 UINT8 NumConfig;\r
1139 UINT8 Aperture;\r
1140 UINT8 *Configuration;\r
1141 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
1142 EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
1143\r
1144 NumConfig = 0;\r
1145 Aperture = 0;\r
1146\r
1147 *pConfig = NULL;\r
1148\r
1149 //\r
1150 // if there is io request, add to the io aperture\r
1151 //\r
1152 if (ResourceRequestExisted (IoNode)) {\r
1153 NumConfig++;\r
1154 Aperture |= 0x01;\r
1155 }\r
1156\r
1157 //\r
1158 // if there is mem32 request, add to the mem32 aperture\r
1159 //\r
1160 if (ResourceRequestExisted (Mem32Node)) {\r
1161 NumConfig++;\r
1162 Aperture |= 0x02;\r
1163 }\r
1164\r
1165 //\r
1166 // if there is pmem32 request, add to the pmem32 aperture\r
1167 //\r
1168 if (ResourceRequestExisted (PMem32Node)) {\r
1169 NumConfig++;\r
1170 Aperture |= 0x04;\r
1171 }\r
1172\r
1173 //\r
1174 // if there is mem64 request, add to the mem64 aperture\r
1175 //\r
1176 if (ResourceRequestExisted (Mem64Node)) {\r
1177 NumConfig++;\r
1178 Aperture |= 0x08;\r
1179 }\r
1180\r
1181 //\r
1182 // if there is pmem64 request, add to the pmem64 aperture\r
1183 //\r
1184 if (ResourceRequestExisted (PMem64Node)) {\r
1185 NumConfig++;\r
1186 Aperture |= 0x10;\r
1187 }\r
1188\r
1189 if (NumConfig != 0) {\r
1190\r
1191 //\r
1192 // If there is at least one type of resource request,\r
1193 // allocate a acpi resource node\r
1194 //\r
1195 Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
1196 if (Configuration == NULL) {\r
1197 return EFI_OUT_OF_RESOURCES;\r
1198 }\r
1199\r
1200 ZeroMem (\r
1201 Configuration,\r
1202 sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
1203 );\r
1204\r
1205 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
1206\r
1207 //\r
1208 // Deal with io aperture\r
1209 //\r
1210 if (Aperture & 0x01) {\r
1211 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1212 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
1213 //\r
1214 // Io\r
1215 //\r
1216 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
1217 //\r
1218 // non ISA range\r
1219 //\r
1220 Ptr->SpecificFlag = 1;\r
1221 Ptr->AddrLen = IoNode->Length;\r
1222 Ptr->AddrRangeMax = IoNode->Alignment;\r
1223\r
1224 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1225 }\r
1226 //\r
1227 // Deal with mem32 aperture\r
1228 //\r
1229 if (Aperture & 0x02) {\r
1230 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1231 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
1232 //\r
1233 // Mem\r
1234 //\r
1235 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1236 //\r
1237 // Nonprefechable\r
1238 //\r
1239 Ptr->SpecificFlag = 0;\r
1240 //\r
1241 // 32 bit\r
1242 //\r
1243 Ptr->AddrSpaceGranularity = 32;\r
1244 Ptr->AddrLen = Mem32Node->Length;\r
1245 Ptr->AddrRangeMax = Mem32Node->Alignment;\r
1246\r
1247 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1248 }\r
1249\r
1250 //\r
1251 // Deal with Pmem32 aperture\r
1252 //\r
1253 if (Aperture & 0x04) {\r
1254 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1255 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
1256 //\r
1257 // Mem\r
1258 //\r
1259 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1260 //\r
1261 // prefechable\r
1262 //\r
1263 Ptr->SpecificFlag = 0x6;\r
1264 //\r
1265 // 32 bit\r
1266 //\r
1267 Ptr->AddrSpaceGranularity = 32;\r
1268 Ptr->AddrLen = PMem32Node->Length;\r
1269 Ptr->AddrRangeMax = PMem32Node->Alignment;\r
1270\r
1271 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1272 }\r
1273 //\r
1274 // Deal with mem64 aperture\r
1275 //\r
1276 if (Aperture & 0x08) {\r
1277 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1278 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
1279 //\r
1280 // Mem\r
1281 //\r
1282 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1283 //\r
1284 // nonprefechable\r
1285 //\r
1286 Ptr->SpecificFlag = 0;\r
1287 //\r
1288 // 64 bit\r
1289 //\r
1290 Ptr->AddrSpaceGranularity = 64;\r
1291 Ptr->AddrLen = Mem64Node->Length;\r
1292 Ptr->AddrRangeMax = Mem64Node->Alignment;\r
1293\r
1294 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1295 }\r
1296 //\r
1297 // Deal with Pmem64 aperture\r
1298 //\r
1299 if (Aperture & 0x10) {\r
1300 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1301 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
1302 //\r
1303 // Mem\r
1304 //\r
1305 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1306 //\r
1307 // prefechable\r
1308 //\r
1309 Ptr->SpecificFlag = 0x06;\r
1310 //\r
1311 // 64 bit\r
1312 //\r
1313 Ptr->AddrSpaceGranularity = 64;\r
1314 Ptr->AddrLen = PMem64Node->Length;\r
1315 Ptr->AddrRangeMax = PMem64Node->Alignment;\r
1316\r
1317 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1318 }\r
1319\r
1320 //\r
1321 // put the checksum\r
1322 //\r
1323 PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
1324\r
1325 PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
1326 PtrEnd->Checksum = 0;\r
1327\r
1328 } else {\r
1329\r
1330 //\r
1331 // If there is no resource request\r
1332 //\r
1333 Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
1334 if (Configuration == NULL) {\r
1335 return EFI_OUT_OF_RESOURCES;\r
1336 }\r
1337\r
1338 ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
1339\r
1340 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);\r
1341 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1342\r
1343 PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1344 PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
1345 PtrEnd->Checksum = 0;\r
1346 }\r
1347\r
1348 *pConfig = Configuration;\r
1349\r
1350 return EFI_SUCCESS;\r
1351}\r
1352\r
1353EFI_STATUS\r
1354GetResourceBase (\r
1355 IN VOID *pConfig,\r
1356 OUT UINT64 *IoBase,\r
1357 OUT UINT64 *Mem32Base,\r
1358 OUT UINT64 *PMem32Base,\r
1359 OUT UINT64 *Mem64Base,\r
1360 OUT UINT64 *PMem64Base\r
1361 )\r
1362/*++\r
1363\r
1364Routine Description:\r
1365\r
1366Arguments:\r
1367\r
1368Returns:\r
1369\r
1370 None\r
1371\r
1372--*/\r
1373// TODO: pConfig - add argument and description to function comment\r
1374// TODO: IoBase - add argument and description to function comment\r
1375// TODO: Mem32Base - add argument and description to function comment\r
1376// TODO: PMem32Base - add argument and description to function comment\r
1377// TODO: Mem64Base - add argument and description to function comment\r
1378// TODO: PMem64Base - add argument and description to function comment\r
1379// TODO: EFI_SUCCESS - add return value to function comment\r
1380{\r
1381 UINT8 *Temp;\r
1382 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
1383 UINT64 ResStatus;\r
1384\r
1385 *IoBase = 0xFFFFFFFFFFFFFFFFULL;\r
1386 *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
1387 *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
1388 *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
1389 *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
1390\r
1391 Temp = (UINT8 *) pConfig;\r
1392\r
1393 while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
1394\r
1395 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
1396 ResStatus = Ptr->AddrTranslationOffset;\r
1397\r
1398 if (ResStatus == EFI_RESOURCE_SATISFIED) {\r
1399\r
1400 switch (Ptr->ResType) {\r
1401\r
1402 //\r
1403 // Memory type aperture\r
1404 //\r
1405 case 0:\r
1406\r
1407 //\r
1408 // Check to see the granularity\r
1409 //\r
1410 if (Ptr->AddrSpaceGranularity == 32) {\r
1411 if (Ptr->SpecificFlag & 0x06) {\r
1412 *PMem32Base = Ptr->AddrRangeMin;\r
1413 } else {\r
1414 *Mem32Base = Ptr->AddrRangeMin;\r
1415 }\r
1416 }\r
1417\r
1418 if (Ptr->AddrSpaceGranularity == 64) {\r
1419 if (Ptr->SpecificFlag & 0x06) {\r
1420 *PMem64Base = Ptr->AddrRangeMin;\r
1421 } else {\r
1422 *Mem64Base = Ptr->AddrRangeMin;\r
1423 }\r
1424 }\r
1425 break;\r
1426\r
1427 case 1:\r
1428\r
1429 //\r
1430 // Io type aperture\r
1431 //\r
1432 *IoBase = Ptr->AddrRangeMin;\r
1433 break;\r
1434\r
1435 default:\r
1436 break;\r
1437\r
1438 }\r
1439 //\r
1440 // End switch\r
1441 //\r
1442 }\r
1443 //\r
1444 // End for\r
1445 //\r
1446 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
1447 }\r
1448\r
1449 return EFI_SUCCESS;\r
1450}\r
1451\r
1452EFI_STATUS\r
1453PciBridgeEnumerator (\r
1454 IN PCI_IO_DEVICE *BridgeDev\r
1455 )\r
1456/*++\r
1457\r
1458Routine Description:\r
1459\r
1460Arguments:\r
1461\r
1462Returns:\r
1463\r
1464 None\r
1465\r
1466--*/\r
1467// TODO: BridgeDev - add argument and description to function comment\r
1468// TODO: EFI_SUCCESS - add return value to function comment\r
1469{\r
1470 UINT8 SubBusNumber;\r
1471 UINT8 StartBusNumber;\r
1472 EFI_PCI_IO_PROTOCOL *PciIo;\r
1473 EFI_STATUS Status;\r
1474\r
1475 SubBusNumber = 0;\r
1476 StartBusNumber = 0;\r
1477 PciIo = &(BridgeDev->PciIo);\r
1478 Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);\r
1479\r
1480 if (EFI_ERROR (Status)) {\r
1481 return Status;\r
1482 }\r
1483\r
1484 Status = PciAssignBusNumber (\r
1485 BridgeDev,\r
1486 StartBusNumber,\r
1487 &SubBusNumber\r
1488 );\r
1489\r
1490 if (EFI_ERROR (Status)) {\r
1491 return Status;\r
1492 }\r
1493\r
1494 Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);\r
1495\r
1496 if (EFI_ERROR (Status)) {\r
1497 return Status;\r
1498 }\r
1499\r
1500 Status = PciBridgeResourceAllocator (BridgeDev);\r
1501\r
1502 if (EFI_ERROR (Status)) {\r
1503 return Status;\r
1504 }\r
1505\r
1506 Status = DetermineDeviceAttribute (BridgeDev);\r
1507\r
1508 if (EFI_ERROR (Status)) {\r
1509 return Status;\r
1510 }\r
1511\r
1512 return EFI_SUCCESS;\r
1513\r
1514}\r
1515\r
1516EFI_STATUS\r
1517PciBridgeResourceAllocator (\r
1518 IN PCI_IO_DEVICE *Bridge\r
1519 )\r
1520/*++\r
1521\r
1522Routine Description:\r
1523\r
1524Arguments:\r
1525\r
1526Returns:\r
1527\r
1528 None\r
1529\r
1530--*/\r
1531// TODO: Bridge - add argument and description to function comment\r
1532// TODO: EFI_SUCCESS - add return value to function comment\r
1533{\r
1534 PCI_RESOURCE_NODE *IoBridge;\r
1535 PCI_RESOURCE_NODE *Mem32Bridge;\r
1536 PCI_RESOURCE_NODE *PMem32Bridge;\r
1537 PCI_RESOURCE_NODE *Mem64Bridge;\r
1538 PCI_RESOURCE_NODE *PMem64Bridge;\r
1539 UINT64 IoBase;\r
1540 UINT64 Mem32Base;\r
1541 UINT64 PMem32Base;\r
1542 UINT64 Mem64Base;\r
1543 UINT64 PMem64Base;\r
1544 EFI_STATUS Status;\r
1545\r
1546 IoBridge = CreateResourceNode (\r
1547 Bridge,\r
1548 0,\r
1549 0xFFF,\r
1550 0,\r
1551 PciBarTypeIo16,\r
1552 PciResUsageTypical\r
1553 );\r
1554\r
1555 Mem32Bridge = CreateResourceNode (\r
1556 Bridge,\r
1557 0,\r
1558 0xFFFFF,\r
1559 0,\r
1560 PciBarTypeMem32,\r
1561 PciResUsageTypical\r
1562 );\r
1563\r
1564 PMem32Bridge = CreateResourceNode (\r
1565 Bridge,\r
1566 0,\r
1567 0xFFFFF,\r
1568 0,\r
1569 PciBarTypePMem32,\r
1570 PciResUsageTypical\r
1571 );\r
1572\r
1573 Mem64Bridge = CreateResourceNode (\r
1574 Bridge,\r
1575 0,\r
1576 0xFFFFF,\r
1577 0,\r
1578 PciBarTypeMem64,\r
1579 PciResUsageTypical\r
1580 );\r
1581\r
1582 PMem64Bridge = CreateResourceNode (\r
1583 Bridge,\r
1584 0,\r
1585 0xFFFFF,\r
1586 0,\r
1587 PciBarTypePMem64,\r
1588 PciResUsageTypical\r
1589 );\r
1590\r
1591 //\r
1592 // Create resourcemap by going through all the devices subject to this root bridge\r
1593 //\r
1594 Status = CreateResourceMap (\r
1595 Bridge,\r
1596 IoBridge,\r
1597 Mem32Bridge,\r
1598 PMem32Bridge,\r
1599 Mem64Bridge,\r
1600 PMem64Bridge\r
1601 );\r
1602\r
1603 if (EFI_ERROR (Status)) {\r
1604 return Status;\r
1605 }\r
1606\r
1607 Status = GetResourceBaseFromBridge (\r
1608 Bridge,\r
1609 &IoBase,\r
1610 &Mem32Base,\r
1611 &PMem32Base,\r
1612 &Mem64Base,\r
1613 &PMem64Base\r
1614 );\r
1615\r
1616 if (EFI_ERROR (Status)) {\r
1617 return Status;\r
1618 }\r
1619\r
1620 //\r
1621 // Program IO resources\r
1622 //\r
1623 ProgramResource (\r
1624 IoBase,\r
1625 IoBridge\r
1626 );\r
1627\r
1628 //\r
1629 // Program Mem32 resources\r
1630 //\r
1631 ProgramResource (\r
1632 Mem32Base,\r
1633 Mem32Bridge\r
1634 );\r
1635\r
1636 //\r
1637 // Program PMem32 resources\r
1638 //\r
1639 ProgramResource (\r
1640 PMem32Base,\r
1641 PMem32Bridge\r
1642 );\r
1643\r
1644 //\r
1645 // Program Mem64 resources\r
1646 //\r
1647 ProgramResource (\r
1648 Mem64Base,\r
1649 Mem64Bridge\r
1650 );\r
1651\r
1652 //\r
1653 // Program PMem64 resources\r
1654 //\r
1655 ProgramResource (\r
1656 PMem64Base,\r
1657 PMem64Bridge\r
1658 );\r
1659\r
1660 DestroyResourceTree (IoBridge);\r
1661 DestroyResourceTree (Mem32Bridge);\r
1662 DestroyResourceTree (PMem32Bridge);\r
1663 DestroyResourceTree (PMem64Bridge);\r
1664 DestroyResourceTree (Mem64Bridge);\r
1665\r
1666 gBS->FreePool (IoBridge);\r
1667 gBS->FreePool (Mem32Bridge);\r
1668 gBS->FreePool (PMem32Bridge);\r
1669 gBS->FreePool (PMem64Bridge);\r
1670 gBS->FreePool (Mem64Bridge);\r
1671\r
1672 return EFI_SUCCESS;\r
1673}\r
1674\r
1675EFI_STATUS\r
1676GetResourceBaseFromBridge (\r
1677 IN PCI_IO_DEVICE *Bridge,\r
1678 OUT UINT64 *IoBase,\r
1679 OUT UINT64 *Mem32Base,\r
1680 OUT UINT64 *PMem32Base,\r
1681 OUT UINT64 *Mem64Base,\r
1682 OUT UINT64 *PMem64Base\r
1683 )\r
1684/*++\r
1685\r
1686Routine Description:\r
1687\r
1688Arguments:\r
1689\r
1690Returns:\r
1691\r
1692 None\r
1693\r
1694--*/\r
1695// TODO: Bridge - add argument and description to function comment\r
1696// TODO: IoBase - add argument and description to function comment\r
1697// TODO: Mem32Base - add argument and description to function comment\r
1698// TODO: PMem32Base - add argument and description to function comment\r
1699// TODO: Mem64Base - add argument and description to function comment\r
1700// TODO: PMem64Base - add argument and description to function comment\r
1701// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1702// TODO: EFI_SUCCESS - add return value to function comment\r
1703{\r
1704 if (!Bridge->Allocated) {\r
1705 return EFI_OUT_OF_RESOURCES;\r
1706 }\r
1707\r
1708 *IoBase = gAllOne;\r
1709 *Mem32Base = gAllOne;\r
1710 *PMem32Base = gAllOne;\r
1711 *Mem64Base = gAllOne;\r
1712 *PMem64Base = gAllOne;\r
1713\r
1714 if (IS_PCI_BRIDGE (&Bridge->Pci)) {\r
1715\r
1716 if (Bridge->PciBar[PPB_IO_RANGE].Length) {\r
1717 *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;\r
1718 }\r
1719\r
1720 if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {\r
1721 *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;\r
1722 }\r
1723\r
1724 if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {\r
1725 *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;\r
1726 }\r
1727\r
1728 if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {\r
1729 *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;\r
1730 } else {\r
1731 *PMem64Base = gAllOne;\r
1732 }\r
1733\r
1734 }\r
1735\r
1736 if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {\r
1737 if (Bridge->PciBar[P2C_IO_1].Length) {\r
1738 *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;\r
1739 } else {\r
1740 if (Bridge->PciBar[P2C_IO_2].Length) {\r
1741 *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;\r
1742 }\r
1743 }\r
1744\r
1745 if (Bridge->PciBar[P2C_MEM_1].Length) {\r
1746 if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {\r
1747 *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
1748 }\r
1749\r
1750 if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {\r
1751 *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
1752 }\r
1753 }\r
1754\r
1755 if (Bridge->PciBar[P2C_MEM_2].Length) {\r
1756 if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {\r
1757 *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
1758 }\r
1759\r
1760 if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {\r
1761 *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
1762 }\r
1763 }\r
1764 }\r
1765\r
1766 return EFI_SUCCESS;\r
1767}\r
1768\r
1769EFI_STATUS\r
1770NotifyPhase (\r
1771 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
1772 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
1773 )\r
1774/*++\r
1775\r
1776Routine Description:\r
1777\r
1778Arguments:\r
1779\r
1780Returns:\r
1781\r
1782 None\r
1783\r
1784--*/\r
1785// TODO: PciResAlloc - add argument and description to function comment\r
1786// TODO: Phase - add argument and description to function comment\r
1787// TODO: EFI_NOT_FOUND - add return value to function comment\r
1788// TODO: EFI_SUCCESS - add return value to function comment\r
1789{\r
1790 EFI_HANDLE HostBridgeHandle;\r
1791 EFI_HANDLE RootBridgeHandle;\r
1792 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
1793 EFI_STATUS Status;\r
1794\r
1795 HostBridgeHandle = NULL;\r
1796 RootBridgeHandle = NULL;\r
1797 if (gPciPlatformProtocol != NULL) {\r
1798 //\r
1799 // Get Host Bridge Handle.\r
1800 //\r
1801 PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);\r
1802\r
1803 //\r
1804 // Get the rootbridge Io protocol to find the host bridge handle\r
1805 //\r
1806 Status = gBS->HandleProtocol (\r
1807 RootBridgeHandle,\r
1808 &gEfiPciRootBridgeIoProtocolGuid,\r
1809 (VOID **) &PciRootBridgeIo\r
1810 );\r
1811\r
1812 if (EFI_ERROR (Status)) {\r
1813 return EFI_NOT_FOUND;\r
1814 }\r
1815\r
1816 HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
1817\r
1818 //\r
1819 // Call PlatformPci::PhaseNotify() if the protocol is present.\r
1820 //\r
1821 gPciPlatformProtocol->PhaseNotify (\r
1822 gPciPlatformProtocol,\r
1823 HostBridgeHandle,\r
1824 Phase,\r
1825 ChipsetEntry\r
1826 );\r
1827 }\r
1828\r
1829 Status = PciResAlloc->NotifyPhase (\r
1830 PciResAlloc,\r
1831 Phase\r
1832 );\r
1833\r
1834 if (gPciPlatformProtocol != NULL) {\r
1835 //\r
1836 // Call PlatformPci::PhaseNotify() if the protocol is present.\r
1837 //\r
1838 gPciPlatformProtocol->PhaseNotify (\r
1839 gPciPlatformProtocol,\r
1840 HostBridgeHandle,\r
1841 Phase,\r
1842 ChipsetExit\r
1843 );\r
1844\r
1845 }\r
1846\r
1847 return EFI_SUCCESS;\r
1848}\r
1849\r
1850EFI_STATUS\r
1851PreprocessController (\r
1852 IN PCI_IO_DEVICE *Bridge,\r
1853 IN UINT8 Bus,\r
1854 IN UINT8 Device,\r
1855 IN UINT8 Func,\r
1856 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
1857 )\r
1858/*++\r
1859\r
1860Routine Description:\r
1861\r
1862Arguments:\r
1863\r
1864Returns:\r
1865\r
1866 None\r
1867\r
1868--*/\r
1869// TODO: Bridge - add argument and description to function comment\r
1870// TODO: Bus - add argument and description to function comment\r
1871// TODO: Device - add argument and description to function comment\r
1872// TODO: Func - add argument and description to function comment\r
1873// TODO: Phase - add argument and description to function comment\r
1874// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1875// TODO: EFI_SUCCESS - add return value to function comment\r
1876{\r
1877 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;\r
1878 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
1879 EFI_HANDLE RootBridgeHandle;\r
1880 EFI_HANDLE HostBridgeHandle;\r
1881 EFI_STATUS Status;\r
1882\r
1883 //\r
1884 // Get the host bridge handle\r
1885 //\r
1886 HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;\r
1887\r
1888 //\r
1889 // Get the pci host bridge resource allocation protocol\r
1890 //\r
1891 Status = gBS->OpenProtocol (\r
1892 HostBridgeHandle,\r
1893 &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
1894 (VOID **) &PciResAlloc,\r
1895 NULL,\r
1896 NULL,\r
1897 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1898 );\r
1899\r
1900 if (EFI_ERROR (Status)) {\r
1901 return EFI_UNSUPPORTED;\r
1902 }\r
1903\r
1904 //\r
1905 // Get Root Brige Handle\r
1906 //\r
1907 while (Bridge->Parent) {\r
1908 Bridge = Bridge->Parent;\r
1909 }\r
1910\r
1911 RootBridgeHandle = Bridge->Handle;\r
1912\r
1913 RootBridgePciAddress.Register = 0;\r
1914 RootBridgePciAddress.Function = Func;\r
1915 RootBridgePciAddress.Device = Device;\r
1916 RootBridgePciAddress.Bus = Bus;\r
1917 RootBridgePciAddress.ExtendedRegister = 0;\r
1918\r
1919 if (gPciPlatformProtocol != NULL) {\r
1920 //\r
1921 // Call PlatformPci::PrepController() if the protocol is present.\r
1922 //\r
1923 gPciPlatformProtocol->PlatformPrepController (\r
1924 gPciPlatformProtocol,\r
1925 HostBridgeHandle,\r
1926 RootBridgeHandle,\r
1927 RootBridgePciAddress,\r
1928 Phase,\r
1929 ChipsetEntry\r
1930 );\r
1931 }\r
1932\r
1933 Status = PciResAlloc->PreprocessController (\r
1934 PciResAlloc,\r
1935 RootBridgeHandle,\r
1936 RootBridgePciAddress,\r
1937 Phase\r
1938 );\r
1939\r
1940 if (gPciPlatformProtocol != NULL) {\r
1941 //\r
1942 // Call PlatformPci::PrepController() if the protocol is present.\r
1943 //\r
1944 gPciPlatformProtocol->PlatformPrepController (\r
1945 gPciPlatformProtocol,\r
1946 HostBridgeHandle,\r
1947 RootBridgeHandle,\r
1948 RootBridgePciAddress,\r
1949 Phase,\r
1950 ChipsetExit\r
1951 );\r
1952 }\r
1953\r
1954 return EFI_SUCCESS;\r
1955}\r
1956\r
1957EFI_STATUS\r
1958EFIAPI\r
1959PciHotPlugRequestNotify (\r
1960 IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
1961 IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
1962 IN EFI_HANDLE Controller,\r
1963 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
1964 IN OUT UINT8 *NumberOfChildren,\r
1965 IN OUT EFI_HANDLE * ChildHandleBuffer\r
1966 )\r
1967/*++\r
1968\r
1969Routine Description:\r
1970\r
1971 Hot plug request notify.\r
1972\r
1973Arguments:\r
1974\r
1975 This - A pointer to the hot plug request protocol.\r
1976 Operation - The operation.\r
1977 Controller - A pointer to the controller.\r
1978 RemainningDevicePath - A pointer to the device path.\r
1979 NumberOfChildren - A the number of child handle in the ChildHandleBuffer.\r
1980 ChildHandleBuffer - A pointer to the array contain the child handle.\r
1981\r
1982Returns:\r
1983\r
1984 Status code.\r
1985\r
1986--*/\r
1987// TODO: RemainingDevicePath - add argument and description to function comment\r
1988// TODO: EFI_NOT_FOUND - add return value to function comment\r
1989// TODO: EFI_SUCCESS - add return value to function comment\r
1990// TODO: EFI_SUCCESS - add return value to function comment\r
1991// TODO: EFI_SUCCESS - add return value to function comment\r
1992{\r
1993 PCI_IO_DEVICE *Bridge;\r
1994 PCI_IO_DEVICE *Temp;\r
1995 EFI_PCI_IO_PROTOCOL *PciIo;\r
1996 UINTN Index;\r
1997 EFI_HANDLE RootBridgeHandle;\r
1998 EFI_STATUS Status;\r
1999\r
2000 Status = gBS->OpenProtocol (\r
2001 Controller,\r
2002 &gEfiPciIoProtocolGuid,\r
2003 (VOID **) &PciIo,\r
2004 gPciBusDriverBinding.DriverBindingHandle,\r
2005 Controller,\r
2006 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2007 );\r
2008\r
2009 if (EFI_ERROR (Status)) {\r
2010 return EFI_NOT_FOUND;\r
2011 }\r
2012\r
2013 Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
2014\r
2015 //\r
2016 // Get root bridge handle\r
2017 //\r
2018 Temp = Bridge;\r
2019 while (Temp->Parent) {\r
2020 Temp = Temp->Parent;\r
2021 }\r
2022\r
2023 RootBridgeHandle = Temp->Handle;\r
2024\r
2025 if (Operation == EfiPciHotPlugRequestAdd) {\r
2026\r
2027 if (NumberOfChildren != NULL) {\r
2028 *NumberOfChildren = 0;\r
2029 }\r
2030\r
2031 if (IsListEmpty (&Bridge->ChildList)) {\r
2032\r
2033 Status = PciBridgeEnumerator (Bridge);\r
2034\r
2035 if (EFI_ERROR (Status)) {\r
2036 return Status;\r
2037 }\r
2038 }\r
2039\r
2040 Status = StartPciDevicesOnBridge (\r
2041 RootBridgeHandle,\r
2042 Bridge,\r
2043 RemainingDevicePath,\r
2044 NumberOfChildren,\r
2045 ChildHandleBuffer\r
2046 );\r
2047\r
2048 return EFI_SUCCESS;\r
2049 }\r
2050\r
2051 if (Operation == EfiPciHotplugRequestRemove) {\r
2052\r
2053 if (*NumberOfChildren == 0) {\r
2054 //\r
2055 // Remove all devices on the bridge\r
2056 //\r
2057 Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);\r
2058 return Status;\r
2059\r
2060 }\r
2061\r
2062 for (Index = 0; Index < *NumberOfChildren; Index++) {\r
2063 //\r
2064 // De register all the pci device\r
2065 //\r
2066 Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);\r
2067\r
2068 if (EFI_ERROR (Status)) {\r
2069 return Status;\r
2070 }\r
2071\r
2072 }\r
2073 //\r
2074 // End for\r
2075 //\r
2076 return EFI_SUCCESS;\r
2077 }\r
2078\r
2079 return EFI_SUCCESS;\r
2080}\r
2081\r
2082BOOLEAN\r
2083SearchHostBridgeHandle (\r
2084 IN EFI_HANDLE RootBridgeHandle\r
2085 )\r
2086/*++\r
2087\r
2088Routine Description:\r
2089\r
2090Arguments:\r
2091\r
2092Returns:\r
2093\r
2094 None\r
2095\r
2096--*/\r
2097// TODO: RootBridgeHandle - add argument and description to function comment\r
2098{\r
2099 EFI_HANDLE HostBridgeHandle;\r
2100 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
2101 UINTN Index;\r
2102 EFI_STATUS Status;\r
2103\r
2104 //\r
2105 // Get the rootbridge Io protocol to find the host bridge handle\r
2106 //\r
2107 Status = gBS->OpenProtocol (\r
2108 RootBridgeHandle,\r
2109 &gEfiPciRootBridgeIoProtocolGuid,\r
2110 (VOID **) &PciRootBridgeIo,\r
2111 gPciBusDriverBinding.DriverBindingHandle,\r
2112 RootBridgeHandle,\r
2113 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2114 );\r
2115\r
2116 if (EFI_ERROR (Status)) {\r
2117 return FALSE;\r
2118 }\r
2119\r
2120 HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
2121 for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
2122 if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
2123 return TRUE;\r
2124 }\r
2125 }\r
2126\r
2127 return FALSE;\r
2128}\r
2129\r
2130EFI_STATUS\r
2131AddHostBridgeEnumerator (\r
2132 IN EFI_HANDLE HostBridgeHandle\r
2133 )\r
2134/*++\r
2135\r
2136Routine Description:\r
2137\r
2138Arguments:\r
2139\r
2140Returns:\r
2141\r
2142 None\r
2143\r
2144--*/\r
2145// TODO: HostBridgeHandle - add argument and description to function comment\r
2146// TODO: EFI_ABORTED - add return value to function comment\r
2147// TODO: EFI_ABORTED - add return value to function comment\r
2148// TODO: EFI_SUCCESS - add return value to function comment\r
2149{\r
2150 UINTN Index;\r
2151\r
2152 if (!HostBridgeHandle) {\r
2153 return EFI_ABORTED;\r
2154 }\r
2155\r
2156 for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
2157 if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
2158 return EFI_ABORTED;\r
2159 }\r
2160 }\r
2161\r
2162 if (Index < PCI_MAX_HOST_BRIDGE_NUM) {\r
2163 gPciHostBrigeHandles[Index] = HostBridgeHandle;\r
2164 gPciHostBridgeNumber++;\r
2165 }\r
2166\r
2167 return EFI_SUCCESS;\r
2168}\r