3 Copyright (c) 2006, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
16 #include "PciEnumerator.h"
\r
17 #include "PciResourceSupport.h"
\r
18 #include "PciOptionRomSupport.h"
\r
22 IN EFI_HANDLE Controller
\r
26 Routine Description:
\r
28 This routine is used to enumerate entire pci bus system
\r
38 // TODO: Controller - add argument and description to function comment
\r
39 // TODO: EFI_SUCCESS - add return value to function comment
\r
40 // TODO: EFI_SUCCESS - add return value to function comment
\r
43 EFI_HANDLE HostBridgeHandle;
\r
45 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;
\r
46 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
\r
49 // If PCI bus has already done the full enumeration, never do it again
\r
51 if (!gFullEnumeration) {
\r
52 return PciEnumeratorLight (Controller);
\r
56 // Get the rootbridge Io protocol to find the host bridge handle
\r
58 Status = gBS->OpenProtocol (
\r
60 &gEfiPciRootBridgeIoProtocolGuid,
\r
61 (VOID **) &PciRootBridgeIo,
\r
62 gPciBusDriverBinding.DriverBindingHandle,
\r
64 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
67 if (EFI_ERROR (Status)) {
\r
72 // Get the host bridge handle
\r
74 HostBridgeHandle = PciRootBridgeIo->ParentHandle;
\r
77 // Get the pci host bridge resource allocation protocol
\r
79 Status = gBS->OpenProtocol (
\r
81 &gEfiPciHostBridgeResourceAllocationProtocolGuid,
\r
82 (VOID **) &PciResAlloc,
\r
83 gPciBusDriverBinding.DriverBindingHandle,
\r
85 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
88 if (EFI_ERROR (Status)) {
\r
93 // Notify the pci bus enumeration is about to begin
\r
95 NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);
\r
98 // Start the bus allocation phase
\r
100 Status = PciHostBridgeEnumerator (PciResAlloc);
\r
102 if (EFI_ERROR (Status)) {
\r
107 // Submit the resource request
\r
109 Status = PciHostBridgeResourceAllocator (PciResAlloc);
\r
111 if (EFI_ERROR (Status)) {
\r
118 Status = PciHostBridgeP2CProcess (PciResAlloc);
\r
120 if (EFI_ERROR (Status)) {
\r
125 // Process attributes for devices on this host bridge
\r
127 Status = PciHostBridgeDeviceAttribute (PciResAlloc);
\r
128 if (EFI_ERROR (Status)) {
\r
132 gFullEnumeration = FALSE;
\r
134 return EFI_SUCCESS;
\r
138 PciRootBridgeEnumerator (
\r
139 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
\r
140 IN PCI_IO_DEVICE *RootBridgeDev
\r
144 Routine Description:
\r
153 // TODO: PciResAlloc - add argument and description to function comment
\r
154 // TODO: RootBridgeDev - add argument and description to function comment
\r
155 // TODO: EFI_SUCCESS - add return value to function comment
\r
158 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;
\r
159 UINT8 SubBusNumber;
\r
160 UINT8 StartBusNumber;
\r
161 UINT8 PaddedBusRange;
\r
162 EFI_HANDLE RootBridgeHandle;
\r
165 StartBusNumber = 0;
\r
166 PaddedBusRange = 0;
\r
169 // Get the root bridge handle
\r
171 RootBridgeHandle = RootBridgeDev->Handle;
\r
173 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
\r
175 EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,
\r
176 RootBridgeDev->DevicePath
\r
180 // Get the Bus information
\r
182 Status = PciResAlloc->StartBusEnumeration (
\r
185 (VOID **) &pConfiguration
\r
188 if (EFI_ERROR (Status)) {
\r
193 // Get the bus number to start with
\r
195 StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);
\r
196 PaddedBusRange = (UINT8) (pConfiguration->AddrRangeMax);
\r
199 // Initialize the subordinate bus number
\r
201 SubBusNumber = StartBusNumber;
\r
204 // Reset all assigned PCI bus number
\r
206 ResetAllPpbBusNumber (
\r
212 // Assign bus number
\r
214 Status = PciScanBus (
\r
216 (UINT8) (pConfiguration->AddrRangeMin),
\r
221 if (EFI_ERROR (Status)) {
\r
227 // Assign max bus number scanned
\r
229 pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;
\r
234 Status = PciResAlloc->SetBusNumbers (
\r
240 if (EFI_ERROR (Status)) {
\r
244 return EFI_SUCCESS;
\r
249 IN PCI_IO_DEVICE *Bridge,
\r
251 IN UINT64 MaxLength
\r
255 Routine Description:
\r
257 This routine is used to process option rom on a certain root bridge
\r
266 // TODO: Bridge - add argument and description to function comment
\r
267 // TODO: RomBase - add argument and description to function comment
\r
268 // TODO: MaxLength - add argument and description to function comment
\r
269 // TODO: EFI_SUCCESS - add return value to function comment
\r
271 LIST_ENTRY *CurrentLink;
\r
272 PCI_IO_DEVICE *Temp;
\r
275 // Go through bridges to reach all devices
\r
277 CurrentLink = Bridge->ChildList.ForwardLink;
\r
278 while (CurrentLink && CurrentLink != &Bridge->ChildList) {
\r
279 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
\r
280 if (!IsListEmpty (&Temp->ChildList)) {
\r
283 // Go further to process the option rom under this bridge
\r
285 ProcessOptionRom (Temp, RomBase, MaxLength);
\r
288 if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {
\r
291 // Load and process the option rom
\r
293 LoadOpRomImage (Temp, RomBase);
\r
296 CurrentLink = CurrentLink->ForwardLink;
\r
299 return EFI_SUCCESS;
\r
303 PciAssignBusNumber (
\r
304 IN PCI_IO_DEVICE *Bridge,
\r
305 IN UINT8 StartBusNumber,
\r
306 OUT UINT8 *SubBusNumber
\r
310 Routine Description:
\r
312 This routine is used to assign bus number to the given PCI bus system
\r
321 // TODO: Bridge - add argument and description to function comment
\r
322 // TODO: StartBusNumber - add argument and description to function comment
\r
323 // TODO: SubBusNumber - add argument and description to function comment
\r
324 // TODO: EFI_DEVICE_ERROR - add return value to function comment
\r
325 // TODO: EFI_SUCCESS - add return value to function comment
\r
335 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
\r
337 PciRootBridgeIo = Bridge->PciRootBridgeIo;
\r
342 *SubBusNumber = StartBusNumber;
\r
345 // First check to see whether the parent is ppb
\r
347 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
\r
348 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
\r
351 // Check to see whether a pci device is present
\r
354 Status = PciDevicePresent (
\r
362 if (!EFI_ERROR (Status) &&
\r
363 (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {
\r
366 // Reserved one bus for cardbus bridge
\r
368 SecondBus = ++(*SubBusNumber);
\r
370 Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
\r
372 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);
\r
374 Status = PciRootBridgeIoWrite (
\r
384 // Initialize SubBusNumber to SecondBus
\r
386 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
\r
387 Status = PciRootBridgeIoWrite (
\r
396 // If it is PPB, resursively search down this bridge
\r
398 if (IS_PCI_BRIDGE (&Pci)) {
\r
401 Status = PciRootBridgeIoWrite (
\r
410 Status = PciAssignBusNumber (
\r
412 (UINT8) (SecondBus),
\r
416 if (EFI_ERROR (Status)) {
\r
417 return EFI_DEVICE_ERROR;
\r
422 // Set the current maximum bus number under the PPB
\r
425 Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
\r
427 Status = PciRootBridgeIoWrite (
\r
438 if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
\r
441 // Skip sub functions, this is not a multi function device
\r
444 Func = PCI_MAX_FUNC;
\r
449 return EFI_SUCCESS;
\r
453 DetermineRootBridgeAttributes (
\r
454 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
\r
455 IN PCI_IO_DEVICE *RootBridgeDev
\r
459 Routine Description:
\r
461 This routine is used to determine the root bridge attribute by interfacing
\r
462 the host bridge resource allocation protocol.
\r
471 // TODO: PciResAlloc - add argument and description to function comment
\r
472 // TODO: RootBridgeDev - add argument and description to function comment
\r
473 // TODO: EFI_SUCCESS - add return value to function comment
\r
477 EFI_HANDLE RootBridgeHandle;
\r
480 RootBridgeHandle = RootBridgeDev->Handle;
\r
483 // Get root bridge attribute by calling into pci host bridge resource allocation protocol
\r
485 Status = PciResAlloc->GetAllocAttributes (
\r
491 if (EFI_ERROR (Status)) {
\r
496 // Here is the point where PCI bus driver calls HOST bridge allocation protocol
\r
497 // Currently we hardcoded for ea815
\r
500 if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {
\r
501 RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;
\r
504 if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {
\r
505 RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
\r
508 RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;
\r
509 RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
\r
510 RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;
\r
512 return EFI_SUCCESS;
\r
516 GetMaxOptionRomSize (
\r
517 IN PCI_IO_DEVICE *Bridge
\r
521 Routine Description:
\r
523 Get Max Option Rom size on this bridge
\r
532 // TODO: Bridge - add argument and description to function comment
\r
534 LIST_ENTRY *CurrentLink;
\r
535 PCI_IO_DEVICE *Temp;
\r
536 UINT64 MaxOptionRomSize;
\r
537 UINT64 TempOptionRomSize;
\r
539 MaxOptionRomSize = 0;
\r
542 // Go through bridges to reach all devices
\r
544 CurrentLink = Bridge->ChildList.ForwardLink;
\r
545 while (CurrentLink && CurrentLink != &Bridge->ChildList) {
\r
546 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
\r
547 if (!IsListEmpty (&Temp->ChildList)) {
\r
550 // Get max option rom size under this bridge
\r
552 TempOptionRomSize = GetMaxOptionRomSize (Temp);
\r
555 // Compare with the option rom size of the bridge
\r
556 // Get the larger one
\r
558 if (Temp->RomSize > TempOptionRomSize) {
\r
559 TempOptionRomSize = Temp->RomSize;
\r
565 // For devices get the rom size directly
\r
567 TempOptionRomSize = Temp->RomSize;
\r
571 // Get the largest rom size on this bridge
\r
573 if (TempOptionRomSize > MaxOptionRomSize) {
\r
574 MaxOptionRomSize = TempOptionRomSize;
\r
577 CurrentLink = CurrentLink->ForwardLink;
\r
580 return MaxOptionRomSize;
\r
584 PciHostBridgeDeviceAttribute (
\r
585 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
\r
589 Routine Description:
\r
591 Process attributes of devices on this host bridge
\r
600 // TODO: PciResAlloc - add argument and description to function comment
\r
601 // TODO: EFI_NOT_FOUND - add return value to function comment
\r
602 // TODO: EFI_SUCCESS - add return value to function comment
\r
604 EFI_HANDLE RootBridgeHandle;
\r
605 PCI_IO_DEVICE *RootBridgeDev;
\r
608 RootBridgeHandle = NULL;
\r
610 while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
\r
613 // Get RootBridg Device by handle
\r
615 RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
\r
617 if (RootBridgeDev == NULL) {
\r
618 return EFI_NOT_FOUND;
\r
622 // Set the attributes for devcies behind the Root Bridge
\r
624 Status = DetermineDeviceAttribute (RootBridgeDev);
\r
625 if (EFI_ERROR (Status)) {
\r
631 return EFI_SUCCESS;
\r
635 GetResourceAllocationStatus (
\r
637 OUT UINT64 *IoResStatus,
\r
638 OUT UINT64 *Mem32ResStatus,
\r
639 OUT UINT64 *PMem32ResStatus,
\r
640 OUT UINT64 *Mem64ResStatus,
\r
641 OUT UINT64 *PMem64ResStatus
\r
645 Routine Description:
\r
647 Get resource allocation status from the ACPI pointer
\r
656 // TODO: AcpiConfig - add argument and description to function comment
\r
657 // TODO: IoResStatus - add argument and description to function comment
\r
658 // TODO: Mem32ResStatus - add argument and description to function comment
\r
659 // TODO: PMem32ResStatus - add argument and description to function comment
\r
660 // TODO: Mem64ResStatus - add argument and description to function comment
\r
661 // TODO: PMem64ResStatus - add argument and description to function comment
\r
662 // TODO: EFI_SUCCESS - add return value to function comment
\r
667 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
\r
669 Temp = (UINT8 *) AcpiConfig;
\r
671 while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
\r
673 ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
\r
674 ResStatus = ptr->AddrTranslationOffset;
\r
676 switch (ptr->ResType) {
\r
678 if (ptr->AddrSpaceGranularity == 32) {
\r
679 if (ptr->SpecificFlag == 0x06) {
\r
683 *PMem32ResStatus = ResStatus;
\r
688 *Mem32ResStatus = ResStatus;
\r
692 if (ptr->AddrSpaceGranularity == 64) {
\r
693 if (ptr->SpecificFlag == 0x06) {
\r
697 *PMem64ResStatus = ResStatus;
\r
702 *Mem64ResStatus = ResStatus;
\r
712 *IoResStatus = ResStatus;
\r
719 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
\r
722 return EFI_SUCCESS;
\r
727 IN PCI_IO_DEVICE *PciDevice
\r
731 Routine Description:
\r
733 Remove a PCI device from device pool and mark its bar
\r
742 // TODO: PciDevice - add argument and description to function comment
\r
743 // TODO: EFI_SUCCESS - add return value to function comment
\r
744 // TODO: EFI_ABORTED - add return value to function comment
\r
745 // TODO: EFI_SUCCESS - add return value to function comment
\r
746 // TODO: EFI_ABORTED - add return value to function comment
\r
748 PCI_IO_DEVICE *Bridge;
\r
749 PCI_IO_DEVICE *Temp;
\r
750 LIST_ENTRY *CurrentLink;
\r
753 // Remove the padding resource from a bridge
\r
755 if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \
\r
756 PciDevice->ResourcePaddingDescriptors ) {
\r
757 gBS->FreePool (PciDevice->ResourcePaddingDescriptors);
\r
758 PciDevice->ResourcePaddingDescriptors = NULL;
\r
759 return EFI_SUCCESS;
\r
765 if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {
\r
766 return EFI_ABORTED;
\r
769 if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {
\r
771 // Get the root bridge device
\r
773 Bridge = PciDevice;
\r
774 while (Bridge->Parent) {
\r
775 Bridge = Bridge->Parent;
\r
778 RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);
\r
783 InitializeP2C (PciDevice);
\r
787 // Remove the device
\r
789 Bridge = PciDevice->Parent;
\r
790 CurrentLink = Bridge->ChildList.ForwardLink;
\r
791 while (CurrentLink && CurrentLink != &Bridge->ChildList) {
\r
792 Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
\r
793 if (Temp == PciDevice) {
\r
794 InitializePciDevice (Temp);
\r
795 RemoveEntryList (CurrentLink);
\r
796 FreePciDevice (Temp);
\r
797 return EFI_SUCCESS;
\r
800 CurrentLink = CurrentLink->ForwardLink;
\r
803 return EFI_ABORTED;
\r
807 IsRejectiveDevice (
\r
808 IN PCI_RESOURCE_NODE *PciResNode
\r
812 Routine Description:
\r
814 Determine whethter a PCI device can be rejected
\r
823 // TODO: PciResNode - add argument and description to function comment
\r
825 PCI_IO_DEVICE *Temp;
\r
827 Temp = PciResNode->PciDev;
\r
830 // Ensure the device is present
\r
837 // PPB and RB should go ahead
\r
839 if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {
\r
844 // Skip device on Bus0
\r
846 if ((Temp->Parent) && (Temp->BusNumber == 0)) {
\r
853 if (IS_PCI_VGA (&Temp->Pci)) {
\r
860 PCI_RESOURCE_NODE *
\r
861 GetLargerConsumerDevice (
\r
862 IN PCI_RESOURCE_NODE *PciResNode1,
\r
863 IN PCI_RESOURCE_NODE *PciResNode2
\r
867 Routine Description:
\r
869 Get the larger resource consumer
\r
878 // TODO: PciResNode1 - add argument and description to function comment
\r
879 // TODO: PciResNode2 - add argument and description to function comment
\r
881 if (!PciResNode2) {
\r
882 return PciResNode1;
\r
885 if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \
\r
886 && (PciResNode2->ResourceUsage != PciResUsagePadding) )
\r
888 return PciResNode1;
\r
891 if (!PciResNode1) {
\r
892 return PciResNode2;
\r
895 if ((PciResNode1->Length) > (PciResNode2->Length)) {
\r
896 return PciResNode1;
\r
899 return PciResNode2;
\r
903 PCI_RESOURCE_NODE *
\r
904 GetMaxResourceConsumerDevice (
\r
905 IN PCI_RESOURCE_NODE *ResPool
\r
909 Routine Description:
\r
911 Get the max resource consumer in the host resource pool
\r
920 // TODO: ResPool - add argument and description to function comment
\r
922 PCI_RESOURCE_NODE *Temp;
\r
923 LIST_ENTRY *CurrentLink;
\r
924 PCI_RESOURCE_NODE *PciResNode;
\r
925 PCI_RESOURCE_NODE *PPBResNode;
\r
929 CurrentLink = ResPool->ChildList.ForwardLink;
\r
930 while (CurrentLink && CurrentLink != &ResPool->ChildList) {
\r
932 Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
\r
934 if (!IsRejectiveDevice (Temp)) {
\r
935 CurrentLink = CurrentLink->ForwardLink;
\r
939 if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \
\r
940 && (Temp->ResourceUsage != PciResUsagePadding))
\r
942 PPBResNode = GetMaxResourceConsumerDevice (Temp);
\r
943 PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);
\r
945 PciResNode = GetLargerConsumerDevice (PciResNode, Temp);
\r
948 CurrentLink = CurrentLink->ForwardLink;
\r
955 PciHostBridgeAdjustAllocation (
\r
956 IN PCI_RESOURCE_NODE *IoPool,
\r
957 IN PCI_RESOURCE_NODE *Mem32Pool,
\r
958 IN PCI_RESOURCE_NODE *PMem32Pool,
\r
959 IN PCI_RESOURCE_NODE *Mem64Pool,
\r
960 IN PCI_RESOURCE_NODE *PMem64Pool,
\r
961 IN UINT64 IoResStatus,
\r
962 IN UINT64 Mem32ResStatus,
\r
963 IN UINT64 PMem32ResStatus,
\r
964 IN UINT64 Mem64ResStatus,
\r
965 IN UINT64 PMem64ResStatus
\r
969 Routine Description:
\r
971 Adjust host bridge allocation so as to reduce resource requirement
\r
980 // TODO: IoPool - add argument and description to function comment
\r
981 // TODO: Mem32Pool - add argument and description to function comment
\r
982 // TODO: PMem32Pool - add argument and description to function comment
\r
983 // TODO: Mem64Pool - add argument and description to function comment
\r
984 // TODO: PMem64Pool - add argument and description to function comment
\r
985 // TODO: IoResStatus - add argument and description to function comment
\r
986 // TODO: Mem32ResStatus - add argument and description to function comment
\r
987 // TODO: PMem32ResStatus - add argument and description to function comment
\r
988 // TODO: Mem64ResStatus - add argument and description to function comment
\r
989 // TODO: PMem64ResStatus - add argument and description to function comment
\r
990 // TODO: EFI_ABORTED - add return value to function comment
\r
991 // TODO: EFI_SUCCESS - add return value to function comment
\r
992 // TODO: EFI_ABORTED - add return value to function comment
\r
994 BOOLEAN AllocationAjusted;
\r
995 PCI_RESOURCE_NODE *PciResNode;
\r
996 PCI_RESOURCE_NODE *ResPool[5];
\r
997 PCI_IO_DEVICE *RemovedPciDev[5];
\r
998 UINT64 ResStatus[5];
\r
999 UINTN RemovedPciDevNum;
\r
1002 EFI_STATUS Status;
\r
1003 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;
\r
1005 PciResNode = NULL;
\r
1006 ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));
\r
1007 RemovedPciDevNum = 0;
\r
1009 ResPool[0] = IoPool;
\r
1010 ResPool[1] = Mem32Pool;
\r
1011 ResPool[2] = PMem32Pool;
\r
1012 ResPool[3] = Mem64Pool;
\r
1013 ResPool[4] = PMem64Pool;
\r
1015 ResStatus[0] = IoResStatus;
\r
1016 ResStatus[1] = Mem32ResStatus;
\r
1017 ResStatus[2] = PMem32ResStatus;
\r
1018 ResStatus[3] = Mem64ResStatus;
\r
1019 ResStatus[4] = PMem64ResStatus;
\r
1021 AllocationAjusted = FALSE;
\r
1023 for (ResType = 0; ResType < 5; ResType++) {
\r
1025 if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {
\r
1029 if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {
\r
1031 // Hostbridge hasn't this resource type
\r
1033 return EFI_ABORTED;
\r
1037 // Hostbridge hasn't enough resource
\r
1039 PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);
\r
1040 if (!PciResNode) {
\r
1045 // Check if the device has been removed before
\r
1047 for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {
\r
1048 if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {
\r
1053 if (DevIndex != RemovedPciDevNum) {
\r
1058 // Remove the device if it isn't in the array
\r
1060 Status = RejectPciDevice (PciResNode->PciDev);
\r
1061 if (Status == EFI_SUCCESS) {
\r
1064 // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code
\r
1067 // Have no way to get ReqRes, AllocRes & Bar here
\r
1069 ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));
\r
1070 AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);
\r
1071 AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;
\r
1072 AllocFailExtendedData.Bar = PciResNode->Bar;
\r
1074 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
\r
1075 EFI_PROGRESS_CODE,
\r
1076 EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,
\r
1077 (VOID *) &AllocFailExtendedData,
\r
1078 sizeof (AllocFailExtendedData)
\r
1082 // Add it to the array and indicate at least a device has been rejected
\r
1084 RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;
\r
1085 AllocationAjusted = TRUE;
\r
1092 if (AllocationAjusted) {
\r
1093 return EFI_SUCCESS;
\r
1095 return EFI_ABORTED;
\r
1100 ConstructAcpiResourceRequestor (
\r
1101 IN PCI_IO_DEVICE *Bridge,
\r
1102 IN PCI_RESOURCE_NODE *IoNode,
\r
1103 IN PCI_RESOURCE_NODE *Mem32Node,
\r
1104 IN PCI_RESOURCE_NODE *PMem32Node,
\r
1105 IN PCI_RESOURCE_NODE *Mem64Node,
\r
1106 IN PCI_RESOURCE_NODE *PMem64Node,
\r
1107 OUT VOID **pConfig
\r
1111 Routine Description:
\r
1120 // TODO: Bridge - add argument and description to function comment
\r
1121 // TODO: IoNode - add argument and description to function comment
\r
1122 // TODO: Mem32Node - add argument and description to function comment
\r
1123 // TODO: PMem32Node - add argument and description to function comment
\r
1124 // TODO: Mem64Node - add argument and description to function comment
\r
1125 // TODO: PMem64Node - add argument and description to function comment
\r
1126 // TODO: pConfig - add argument and description to function comment
\r
1127 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
\r
1128 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
\r
1129 // TODO: EFI_SUCCESS - add return value to function comment
\r
1133 UINT8 *Configuration;
\r
1134 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
\r
1135 EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;
\r
1143 // if there is io request, add to the io aperture
\r
1145 if (ResourceRequestExisted (IoNode)) {
\r
1151 // if there is mem32 request, add to the mem32 aperture
\r
1153 if (ResourceRequestExisted (Mem32Node)) {
\r
1159 // if there is pmem32 request, add to the pmem32 aperture
\r
1161 if (ResourceRequestExisted (PMem32Node)) {
\r
1167 // if there is mem64 request, add to the mem64 aperture
\r
1169 if (ResourceRequestExisted (Mem64Node)) {
\r
1175 // if there is pmem64 request, add to the pmem64 aperture
\r
1177 if (ResourceRequestExisted (PMem64Node)) {
\r
1182 if (NumConfig != 0) {
\r
1185 // If there is at least one type of resource request,
\r
1186 // allocate a acpi resource node
\r
1188 Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
\r
1189 if (Configuration == NULL) {
\r
1190 return EFI_OUT_OF_RESOURCES;
\r
1195 sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
\r
1198 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
\r
1201 // Deal with io aperture
\r
1203 if (Aperture & 0x01) {
\r
1204 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
\r
1205 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
\r
1209 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
\r
1213 Ptr->SpecificFlag = 1;
\r
1214 Ptr->AddrLen = IoNode->Length;
\r
1215 Ptr->AddrRangeMax = IoNode->Alignment;
\r
1217 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
\r
1220 // Deal with mem32 aperture
\r
1222 if (Aperture & 0x02) {
\r
1223 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
\r
1224 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
\r
1228 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
\r
1232 Ptr->SpecificFlag = 0;
\r
1236 Ptr->AddrSpaceGranularity = 32;
\r
1237 Ptr->AddrLen = Mem32Node->Length;
\r
1238 Ptr->AddrRangeMax = Mem32Node->Alignment;
\r
1240 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
\r
1244 // Deal with Pmem32 aperture
\r
1246 if (Aperture & 0x04) {
\r
1247 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
\r
1248 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
\r
1252 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
\r
1256 Ptr->SpecificFlag = 0x6;
\r
1260 Ptr->AddrSpaceGranularity = 32;
\r
1261 Ptr->AddrLen = PMem32Node->Length;
\r
1262 Ptr->AddrRangeMax = PMem32Node->Alignment;
\r
1264 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
\r
1267 // Deal with mem64 aperture
\r
1269 if (Aperture & 0x08) {
\r
1270 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
\r
1271 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
\r
1275 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
\r
1279 Ptr->SpecificFlag = 0;
\r
1283 Ptr->AddrSpaceGranularity = 64;
\r
1284 Ptr->AddrLen = Mem64Node->Length;
\r
1285 Ptr->AddrRangeMax = Mem64Node->Alignment;
\r
1287 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
\r
1290 // Deal with Pmem64 aperture
\r
1292 if (Aperture & 0x10) {
\r
1293 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
\r
1294 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
\r
1298 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
\r
1302 Ptr->SpecificFlag = 0x06;
\r
1306 Ptr->AddrSpaceGranularity = 64;
\r
1307 Ptr->AddrLen = PMem64Node->Length;
\r
1308 Ptr->AddrRangeMax = PMem64Node->Alignment;
\r
1310 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
\r
1314 // put the checksum
\r
1316 PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);
\r
1318 PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
\r
1319 PtrEnd->Checksum = 0;
\r
1324 // If there is no resource request
\r
1326 Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
\r
1327 if (Configuration == NULL) {
\r
1328 return EFI_OUT_OF_RESOURCES;
\r
1331 ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
\r
1333 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);
\r
1334 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
\r
1336 PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
\r
1337 PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
\r
1338 PtrEnd->Checksum = 0;
\r
1341 *pConfig = Configuration;
\r
1343 return EFI_SUCCESS;
\r
1349 OUT UINT64 *IoBase,
\r
1350 OUT UINT64 *Mem32Base,
\r
1351 OUT UINT64 *PMem32Base,
\r
1352 OUT UINT64 *Mem64Base,
\r
1353 OUT UINT64 *PMem64Base
\r
1357 Routine Description:
\r
1366 // TODO: pConfig - add argument and description to function comment
\r
1367 // TODO: IoBase - add argument and description to function comment
\r
1368 // TODO: Mem32Base - add argument and description to function comment
\r
1369 // TODO: PMem32Base - add argument and description to function comment
\r
1370 // TODO: Mem64Base - add argument and description to function comment
\r
1371 // TODO: PMem64Base - add argument and description to function comment
\r
1372 // TODO: EFI_SUCCESS - add return value to function comment
\r
1375 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
\r
1378 *IoBase = 0xFFFFFFFFFFFFFFFFULL;
\r
1379 *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;
\r
1380 *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;
\r
1381 *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;
\r
1382 *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;
\r
1384 Temp = (UINT8 *) pConfig;
\r
1386 while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
\r
1388 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
\r
1389 ResStatus = Ptr->AddrTranslationOffset;
\r
1391 if (ResStatus == EFI_RESOURCE_SATISFIED) {
\r
1393 switch (Ptr->ResType) {
\r
1396 // Memory type aperture
\r
1401 // Check to see the granularity
\r
1403 if (Ptr->AddrSpaceGranularity == 32) {
\r
1404 if (Ptr->SpecificFlag & 0x06) {
\r
1405 *PMem32Base = Ptr->AddrRangeMin;
\r
1407 *Mem32Base = Ptr->AddrRangeMin;
\r
1411 if (Ptr->AddrSpaceGranularity == 64) {
\r
1412 if (Ptr->SpecificFlag & 0x06) {
\r
1413 *PMem64Base = Ptr->AddrRangeMin;
\r
1415 *Mem64Base = Ptr->AddrRangeMin;
\r
1423 // Io type aperture
\r
1425 *IoBase = Ptr->AddrRangeMin;
\r
1439 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
\r
1442 return EFI_SUCCESS;
\r
1446 PciBridgeEnumerator (
\r
1447 IN PCI_IO_DEVICE *BridgeDev
\r
1451 Routine Description:
\r
1460 // TODO: BridgeDev - add argument and description to function comment
\r
1461 // TODO: EFI_SUCCESS - add return value to function comment
\r
1463 UINT8 SubBusNumber;
\r
1464 UINT8 StartBusNumber;
\r
1465 EFI_PCI_IO_PROTOCOL *PciIo;
\r
1466 EFI_STATUS Status;
\r
1469 StartBusNumber = 0;
\r
1470 PciIo = &(BridgeDev->PciIo);
\r
1471 Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);
\r
1473 if (EFI_ERROR (Status)) {
\r
1477 Status = PciAssignBusNumber (
\r
1483 if (EFI_ERROR (Status)) {
\r
1487 Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);
\r
1489 if (EFI_ERROR (Status)) {
\r
1493 Status = PciBridgeResourceAllocator (BridgeDev);
\r
1495 if (EFI_ERROR (Status)) {
\r
1499 Status = DetermineDeviceAttribute (BridgeDev);
\r
1501 if (EFI_ERROR (Status)) {
\r
1505 return EFI_SUCCESS;
\r
1510 PciBridgeResourceAllocator (
\r
1511 IN PCI_IO_DEVICE *Bridge
\r
1515 Routine Description:
\r
1524 // TODO: Bridge - add argument and description to function comment
\r
1525 // TODO: EFI_SUCCESS - add return value to function comment
\r
1527 PCI_RESOURCE_NODE *IoBridge;
\r
1528 PCI_RESOURCE_NODE *Mem32Bridge;
\r
1529 PCI_RESOURCE_NODE *PMem32Bridge;
\r
1530 PCI_RESOURCE_NODE *Mem64Bridge;
\r
1531 PCI_RESOURCE_NODE *PMem64Bridge;
\r
1534 UINT64 PMem32Base;
\r
1536 UINT64 PMem64Base;
\r
1537 EFI_STATUS Status;
\r
1539 IoBridge = CreateResourceNode (
\r
1545 PciResUsageTypical
\r
1548 Mem32Bridge = CreateResourceNode (
\r
1554 PciResUsageTypical
\r
1557 PMem32Bridge = CreateResourceNode (
\r
1563 PciResUsageTypical
\r
1566 Mem64Bridge = CreateResourceNode (
\r
1572 PciResUsageTypical
\r
1575 PMem64Bridge = CreateResourceNode (
\r
1581 PciResUsageTypical
\r
1585 // Create resourcemap by going through all the devices subject to this root bridge
\r
1587 Status = CreateResourceMap (
\r
1596 if (EFI_ERROR (Status)) {
\r
1600 Status = GetResourceBaseFromBridge (
\r
1609 if (EFI_ERROR (Status)) {
\r
1614 // Program IO resources
\r
1622 // Program Mem32 resources
\r
1630 // Program PMem32 resources
\r
1638 // Program Mem64 resources
\r
1646 // Program PMem64 resources
\r
1653 DestroyResourceTree (IoBridge);
\r
1654 DestroyResourceTree (Mem32Bridge);
\r
1655 DestroyResourceTree (PMem32Bridge);
\r
1656 DestroyResourceTree (PMem64Bridge);
\r
1657 DestroyResourceTree (Mem64Bridge);
\r
1659 gBS->FreePool (IoBridge);
\r
1660 gBS->FreePool (Mem32Bridge);
\r
1661 gBS->FreePool (PMem32Bridge);
\r
1662 gBS->FreePool (PMem64Bridge);
\r
1663 gBS->FreePool (Mem64Bridge);
\r
1665 return EFI_SUCCESS;
\r
1669 GetResourceBaseFromBridge (
\r
1670 IN PCI_IO_DEVICE *Bridge,
\r
1671 OUT UINT64 *IoBase,
\r
1672 OUT UINT64 *Mem32Base,
\r
1673 OUT UINT64 *PMem32Base,
\r
1674 OUT UINT64 *Mem64Base,
\r
1675 OUT UINT64 *PMem64Base
\r
1679 Routine Description:
\r
1688 // TODO: Bridge - add argument and description to function comment
\r
1689 // TODO: IoBase - add argument and description to function comment
\r
1690 // TODO: Mem32Base - add argument and description to function comment
\r
1691 // TODO: PMem32Base - add argument and description to function comment
\r
1692 // TODO: Mem64Base - add argument and description to function comment
\r
1693 // TODO: PMem64Base - add argument and description to function comment
\r
1694 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
\r
1695 // TODO: EFI_SUCCESS - add return value to function comment
\r
1697 if (!Bridge->Allocated) {
\r
1698 return EFI_OUT_OF_RESOURCES;
\r
1701 *IoBase = gAllOne;
\r
1702 *Mem32Base = gAllOne;
\r
1703 *PMem32Base = gAllOne;
\r
1704 *Mem64Base = gAllOne;
\r
1705 *PMem64Base = gAllOne;
\r
1707 if (IS_PCI_BRIDGE (&Bridge->Pci)) {
\r
1709 if (Bridge->PciBar[PPB_IO_RANGE].Length) {
\r
1710 *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;
\r
1713 if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {
\r
1714 *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;
\r
1717 if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {
\r
1718 *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;
\r
1721 if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {
\r
1722 *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;
\r
1724 *PMem64Base = gAllOne;
\r
1729 if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {
\r
1730 if (Bridge->PciBar[P2C_IO_1].Length) {
\r
1731 *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;
\r
1733 if (Bridge->PciBar[P2C_IO_2].Length) {
\r
1734 *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;
\r
1738 if (Bridge->PciBar[P2C_MEM_1].Length) {
\r
1739 if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {
\r
1740 *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
\r
1743 if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {
\r
1744 *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
\r
1748 if (Bridge->PciBar[P2C_MEM_2].Length) {
\r
1749 if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {
\r
1750 *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
\r
1753 if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {
\r
1754 *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
\r
1759 return EFI_SUCCESS;
\r
1764 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
\r
1765 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
\r
1769 Routine Description:
\r
1778 // TODO: PciResAlloc - add argument and description to function comment
\r
1779 // TODO: Phase - add argument and description to function comment
\r
1780 // TODO: EFI_NOT_FOUND - add return value to function comment
\r
1781 // TODO: EFI_SUCCESS - add return value to function comment
\r
1783 EFI_HANDLE HostBridgeHandle;
\r
1784 EFI_HANDLE RootBridgeHandle;
\r
1785 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
\r
1786 EFI_STATUS Status;
\r
1788 HostBridgeHandle = NULL;
\r
1789 RootBridgeHandle = NULL;
\r
1790 if (gPciPlatformProtocol != NULL) {
\r
1792 // Get Host Bridge Handle.
\r
1794 PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);
\r
1797 // Get the rootbridge Io protocol to find the host bridge handle
\r
1799 Status = gBS->HandleProtocol (
\r
1801 &gEfiPciRootBridgeIoProtocolGuid,
\r
1802 (VOID **) &PciRootBridgeIo
\r
1805 if (EFI_ERROR (Status)) {
\r
1806 return EFI_NOT_FOUND;
\r
1809 HostBridgeHandle = PciRootBridgeIo->ParentHandle;
\r
1812 // Call PlatformPci::PhaseNotify() if the protocol is present.
\r
1814 gPciPlatformProtocol->PhaseNotify (
\r
1815 gPciPlatformProtocol,
\r
1822 Status = PciResAlloc->NotifyPhase (
\r
1827 if (gPciPlatformProtocol != NULL) {
\r
1829 // Call PlatformPci::PhaseNotify() if the protocol is present.
\r
1831 gPciPlatformProtocol->PhaseNotify (
\r
1832 gPciPlatformProtocol,
\r
1840 return EFI_SUCCESS;
\r
1844 PreprocessController (
\r
1845 IN PCI_IO_DEVICE *Bridge,
\r
1849 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
\r
1853 Routine Description:
\r
1862 // TODO: Bridge - add argument and description to function comment
\r
1863 // TODO: Bus - add argument and description to function comment
\r
1864 // TODO: Device - add argument and description to function comment
\r
1865 // TODO: Func - add argument and description to function comment
\r
1866 // TODO: Phase - add argument and description to function comment
\r
1867 // TODO: EFI_UNSUPPORTED - add return value to function comment
\r
1868 // TODO: EFI_SUCCESS - add return value to function comment
\r
1870 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;
\r
1871 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;
\r
1872 EFI_HANDLE RootBridgeHandle;
\r
1873 EFI_HANDLE HostBridgeHandle;
\r
1874 EFI_STATUS Status;
\r
1877 // Get the host bridge handle
\r
1879 HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;
\r
1882 // Get the pci host bridge resource allocation protocol
\r
1884 Status = gBS->OpenProtocol (
\r
1886 &gEfiPciHostBridgeResourceAllocationProtocolGuid,
\r
1887 (VOID **) &PciResAlloc,
\r
1890 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
1893 if (EFI_ERROR (Status)) {
\r
1894 return EFI_UNSUPPORTED;
\r
1898 // Get Root Brige Handle
\r
1900 while (Bridge->Parent) {
\r
1901 Bridge = Bridge->Parent;
\r
1904 RootBridgeHandle = Bridge->Handle;
\r
1906 RootBridgePciAddress.Register = 0;
\r
1907 RootBridgePciAddress.Function = Func;
\r
1908 RootBridgePciAddress.Device = Device;
\r
1909 RootBridgePciAddress.Bus = Bus;
\r
1910 RootBridgePciAddress.ExtendedRegister = 0;
\r
1912 if (gPciPlatformProtocol != NULL) {
\r
1914 // Call PlatformPci::PrepController() if the protocol is present.
\r
1916 gPciPlatformProtocol->PlatformPrepController (
\r
1917 gPciPlatformProtocol,
\r
1920 RootBridgePciAddress,
\r
1926 Status = PciResAlloc->PreprocessController (
\r
1929 RootBridgePciAddress,
\r
1933 if (gPciPlatformProtocol != NULL) {
\r
1935 // Call PlatformPci::PrepController() if the protocol is present.
\r
1937 gPciPlatformProtocol->PlatformPrepController (
\r
1938 gPciPlatformProtocol,
\r
1941 RootBridgePciAddress,
\r
1947 return EFI_SUCCESS;
\r
1952 PciHotPlugRequestNotify (
\r
1953 IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,
\r
1954 IN EFI_PCI_HOTPLUG_OPERATION Operation,
\r
1955 IN EFI_HANDLE Controller,
\r
1956 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,
\r
1957 IN OUT UINT8 *NumberOfChildren,
\r
1958 IN OUT EFI_HANDLE * ChildHandleBuffer
\r
1962 Routine Description:
\r
1964 Hot plug request notify.
\r
1968 This - A pointer to the hot plug request protocol.
\r
1969 Operation - The operation.
\r
1970 Controller - A pointer to the controller.
\r
1971 RemainningDevicePath - A pointer to the device path.
\r
1972 NumberOfChildren - A the number of child handle in the ChildHandleBuffer.
\r
1973 ChildHandleBuffer - A pointer to the array contain the child handle.
\r
1980 // TODO: RemainingDevicePath - add argument and description to function comment
\r
1981 // TODO: EFI_NOT_FOUND - add return value to function comment
\r
1982 // TODO: EFI_SUCCESS - add return value to function comment
\r
1983 // TODO: EFI_SUCCESS - add return value to function comment
\r
1984 // TODO: EFI_SUCCESS - add return value to function comment
\r
1986 PCI_IO_DEVICE *Bridge;
\r
1987 PCI_IO_DEVICE *Temp;
\r
1988 EFI_PCI_IO_PROTOCOL *PciIo;
\r
1990 EFI_HANDLE RootBridgeHandle;
\r
1991 EFI_STATUS Status;
\r
1993 Status = gBS->OpenProtocol (
\r
1995 &gEfiPciIoProtocolGuid,
\r
1997 gPciBusDriverBinding.DriverBindingHandle,
\r
1999 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
2002 if (EFI_ERROR (Status)) {
\r
2003 return EFI_NOT_FOUND;
\r
2006 Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
\r
2009 // Get root bridge handle
\r
2012 while (Temp->Parent) {
\r
2013 Temp = Temp->Parent;
\r
2016 RootBridgeHandle = Temp->Handle;
\r
2018 if (Operation == EfiPciHotPlugRequestAdd) {
\r
2020 if (NumberOfChildren != NULL) {
\r
2021 *NumberOfChildren = 0;
\r
2024 if (IsListEmpty (&Bridge->ChildList)) {
\r
2026 Status = PciBridgeEnumerator (Bridge);
\r
2028 if (EFI_ERROR (Status)) {
\r
2033 Status = StartPciDevicesOnBridge (
\r
2036 RemainingDevicePath,
\r
2041 return EFI_SUCCESS;
\r
2044 if (Operation == EfiPciHotplugRequestRemove) {
\r
2046 if (*NumberOfChildren == 0) {
\r
2048 // Remove all devices on the bridge
\r
2050 Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);
\r
2055 for (Index = 0; Index < *NumberOfChildren; Index++) {
\r
2057 // De register all the pci device
\r
2059 Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);
\r
2061 if (EFI_ERROR (Status)) {
\r
2069 return EFI_SUCCESS;
\r
2072 return EFI_SUCCESS;
\r
2076 SearchHostBridgeHandle (
\r
2077 IN EFI_HANDLE RootBridgeHandle
\r
2081 Routine Description:
\r
2090 // TODO: RootBridgeHandle - add argument and description to function comment
\r
2092 EFI_HANDLE HostBridgeHandle;
\r
2093 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
\r
2095 EFI_STATUS Status;
\r
2098 // Get the rootbridge Io protocol to find the host bridge handle
\r
2100 Status = gBS->OpenProtocol (
\r
2102 &gEfiPciRootBridgeIoProtocolGuid,
\r
2103 (VOID **) &PciRootBridgeIo,
\r
2104 gPciBusDriverBinding.DriverBindingHandle,
\r
2106 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
2109 if (EFI_ERROR (Status)) {
\r
2113 HostBridgeHandle = PciRootBridgeIo->ParentHandle;
\r
2114 for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
\r
2115 if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
\r
2124 AddHostBridgeEnumerator (
\r
2125 IN EFI_HANDLE HostBridgeHandle
\r
2129 Routine Description:
\r
2138 // TODO: HostBridgeHandle - add argument and description to function comment
\r
2139 // TODO: EFI_ABORTED - add return value to function comment
\r
2140 // TODO: EFI_ABORTED - add return value to function comment
\r
2141 // TODO: EFI_SUCCESS - add return value to function comment
\r
2145 if (!HostBridgeHandle) {
\r
2146 return EFI_ABORTED;
\r
2149 for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
\r
2150 if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
\r
2151 return EFI_ABORTED;
\r
2155 if (Index < PCI_MAX_HOST_BRIDGE_NUM) {
\r
2156 gPciHostBrigeHandles[Index] = HostBridgeHandle;
\r
2157 gPciHostBridgeNumber++;
\r
2160 return EFI_SUCCESS;
\r