+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciEnumerator.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciEnumerator.h"\r
-#include "PciResourceSupport.h"\r
-#include "PciOptionRomSupport.h"\r
-\r
-EFI_STATUS\r
-PciEnumerator (\r
- IN EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to enumerate entire pci bus system\r
- in a given platform\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_STATUS Status;\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- //\r
- // If PCI bus has already done the full enumeration, never do it again\r
- //\r
- if (!gFullEnumeration) {\r
- return PciEnumeratorLight (Controller);\r
- }\r
-\r
- //\r
- // If this host bridge has been already enumerated, then return successfully\r
- //\r
- if (RootBridgeExisted (Controller)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Get the rootbridge Io protocol to find the host bridge handle\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the host bridge handle\r
- //\r
- HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Get the pci host bridge resource allocation protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- HostBridgeHandle,\r
- &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
- (VOID **) &PciResAlloc,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Notify the pci bus enumeration is about to begin\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);\r
-\r
- //\r
- // Start the bus allocation phase\r
- //\r
- Status = PciHostBridgeEnumerator (PciResAlloc);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Submit the resource request\r
- //\r
- Status = PciHostBridgeResourceAllocator (PciResAlloc);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Process P2C\r
- //\r
- Status = PciHostBridgeP2CProcess (PciResAlloc);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Process attributes for devices on this host bridge\r
- //\r
- Status = PciHostBridgeDeviceAttribute (PciResAlloc);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gFullEnumeration = FALSE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciRootBridgeEnumerator (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: RootBridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;\r
- UINT8 SubBusNumber;\r
- UINT8 StartBusNumber;\r
- UINT8 PaddedBusRange;\r
- EFI_HANDLE RootBridgeHandle;\r
-\r
- SubBusNumber = 0;\r
- StartBusNumber = 0;\r
- PaddedBusRange = 0;\r
-\r
- //\r
- // Get the root bridge handle\r
- //\r
- RootBridgeHandle = RootBridgeDev->Handle;\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,\r
- RootBridgeDev->DevicePath\r
- );\r
-\r
- //\r
- // Get the Bus information\r
- //\r
- Status = PciResAlloc->StartBusEnumeration (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- (VOID **) &pConfiguration\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the bus number to start with\r
- //\r
- StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);\r
-\r
- //\r
- // Initialize the subordinate bus number\r
- //\r
- SubBusNumber = StartBusNumber;\r
-\r
- //\r
- // Assign bus number\r
- //\r
- Status = PciScanBus (\r
- RootBridgeDev,\r
- (UINT8) (pConfiguration->AddrRangeMin),\r
- &SubBusNumber,\r
- &PaddedBusRange\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
-\r
- //\r
- // Assign max bus number scanned\r
- //\r
- pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;\r
-\r
- //\r
- // Set bus number\r
- //\r
- Status = PciResAlloc->SetBusNumbers (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- pConfiguration\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProcessOptionRom (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT64 RomBase,\r
- IN UINT64 MaxLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to process option rom on a certain root bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: RomBase - add argument and description to function comment\r
-// TODO: MaxLength - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Go through bridges to reach all devices\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
-\r
- //\r
- // Go further to process the option rom under this bridge\r
- //\r
- Status = ProcessOptionRom (Temp, RomBase, MaxLength);\r
- }\r
-\r
- if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {\r
-\r
- //\r
- // Load and process the option rom\r
- //\r
- Status = LoadOpRomImage (Temp, RomBase);\r
- if (Status == EFI_SUCCESS) {\r
- Status = ProcessOpRomImage (Temp);\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciAssignBusNumber (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to assign bus number to the given PCI bus system\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: StartBusNumber - add argument and description to function comment\r
-// TODO: SubBusNumber - add argument and description to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT8 Func;\r
- UINT64 Address;\r
- UINTN SecondBus;\r
- UINT16 Register;\r
- UINT8 Register8;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
-\r
- SecondBus = 0;\r
- Register = 0;\r
-\r
- *SubBusNumber = StartBusNumber;\r
-\r
- //\r
- // First check to see whether the parent is ppb\r
- //\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether a pci device is present\r
- //\r
-\r
- Status = PciDevicePresent (\r
- PciRootBridgeIo,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!EFI_ERROR (Status) &&\r
- (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
-\r
- //\r
- // Reserved one bus for cardbus bridge\r
- //\r
- SecondBus = ++(*SubBusNumber);\r
-\r
- Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
-\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint16,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
-\r
- //\r
- // Initialize SubBusNumber to SecondBus\r
- //\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
- //\r
- // If it is PPB, resursively search down this bridge\r
- //\r
- if (IS_PCI_BRIDGE (&Pci)) {\r
-\r
- Register8 = 0xFF;\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- &Register8\r
- );\r
-\r
- Status = PciAssignBusNumber (\r
- Bridge,\r
- (UINT8) (SecondBus),\r
- SubBusNumber\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- //\r
- // Set the current maximum bus number under the PPB\r
- //\r
-\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
-\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
-\r
- Func = PCI_MAX_FUNC;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DetermineRootBridgeAttributes (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to determine the root bridge attribute by interfacing\r
- the host bridge resource allocation protocol.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: RootBridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 Attributes;\r
- EFI_STATUS Status;\r
- EFI_HANDLE RootBridgeHandle;\r
-\r
- Attributes = 0;\r
- RootBridgeHandle = RootBridgeDev->Handle;\r
-\r
- //\r
- // Get root bridge attribute by calling into pci host bridge resource allocation protocol\r
- //\r
- Status = PciResAlloc->GetAllocAttributes (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- &Attributes\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Here is the point where PCI bus driver calls HOST bridge allocation protocol\r
- // Currently we hardcoded for ea815\r
- //\r
-\r
- if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;\r
- }\r
-\r
- if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
- }\r
-\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINT64\r
-GetMaxOptionRomSize (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get Max Option Rom size on this bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
- UINT64 MaxOptionRomSize;\r
- UINT64 TempOptionRomSize;\r
-\r
- MaxOptionRomSize = 0;\r
-\r
- //\r
- // Go through bridges to reach all devices\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
-\r
- //\r
- // Get max option rom size under this bridge\r
- //\r
- TempOptionRomSize = GetMaxOptionRomSize (Temp);\r
-\r
- //\r
- // Compare with the option rom size of the bridge\r
- // Get the larger one\r
- //\r
- if (Temp->RomSize > TempOptionRomSize) {\r
- TempOptionRomSize = Temp->RomSize;\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // For devices get the rom size directly\r
- //\r
- TempOptionRomSize = Temp->RomSize;\r
- }\r
-\r
- //\r
- // Get the largest rom size on this bridge\r
- //\r
- if (TempOptionRomSize > MaxOptionRomSize) {\r
- MaxOptionRomSize = TempOptionRomSize;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return MaxOptionRomSize;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeDeviceAttribute (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process attributes of devices on this host bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE RootBridgeHandle;\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- EFI_STATUS Status;\r
-\r
- RootBridgeHandle = NULL;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Set the attributes for devcies behind the Root Bridge\r
- //\r
- Status = DetermineDeviceAttribute (RootBridgeDev);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceAllocationStatus (\r
- VOID *AcpiConfig,\r
- OUT UINT64 *IoResStatus,\r
- OUT UINT64 *Mem32ResStatus,\r
- OUT UINT64 *PMem32ResStatus,\r
- OUT UINT64 *Mem64ResStatus,\r
- OUT UINT64 *PMem64ResStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get resource allocation status from the ACPI pointer\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: AcpiConfig - add argument and description to function comment\r
-// TODO: IoResStatus - add argument and description to function comment\r
-// TODO: Mem32ResStatus - add argument and description to function comment\r
-// TODO: PMem32ResStatus - add argument and description to function comment\r
-// TODO: Mem64ResStatus - add argument and description to function comment\r
-// TODO: PMem64ResStatus - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT8 *Temp;\r
- UINT64 ResStatus;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
-\r
- Temp = (UINT8 *) AcpiConfig;\r
-\r
- while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
-\r
- ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
- ResStatus = ptr->AddrTranslationOffset;\r
-\r
- switch (ptr->ResType) {\r
- case 0:\r
- if (ptr->AddrSpaceGranularity == 32) {\r
- if (ptr->SpecificFlag == 0x06) {\r
- //\r
- // Pmem32\r
- //\r
- *PMem32ResStatus = ResStatus;\r
- } else {\r
- //\r
- // Mem32\r
- //\r
- *Mem32ResStatus = ResStatus;\r
- }\r
- }\r
-\r
- if (ptr->AddrSpaceGranularity == 64) {\r
- if (ptr->SpecificFlag == 0x06) {\r
- //\r
- // PMem64\r
- //\r
- *PMem64ResStatus = ResStatus;\r
- } else {\r
- //\r
- // Mem64\r
- //\r
- *Mem64ResStatus = ResStatus;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case 1:\r
- //\r
- // Io\r
- //\r
- *IoResStatus = ResStatus;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RejectPciDevice (\r
- IN PCI_IO_DEVICE *PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Remove a PCI device from device pool and mark its bar\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Bridge;\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- //\r
- // Remove the padding resource from a bridge\r
- //\r
- if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \\r
- PciDevice->ResourcePaddingDescriptors ) {\r
- gBS->FreePool (PciDevice->ResourcePaddingDescriptors);\r
- PciDevice->ResourcePaddingDescriptors = NULL;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Skip RB and PPB\r
- //\r
- if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {\r
- //\r
- // Get the root bridge device\r
- //\r
- Bridge = PciDevice;\r
- while (Bridge->Parent) {\r
- Bridge = Bridge->Parent;\r
- }\r
-\r
- RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);\r
-\r
- //\r
- // Mark its bar\r
- //\r
- InitializeP2C (PciDevice);\r
- }\r
-\r
- //\r
- // Remove the device\r
- //\r
- Bridge = PciDevice->Parent;\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (Temp == PciDevice) {\r
- InitializePciDevice (Temp);\r
- RemoveEntryList (CurrentLink);\r
- FreePciDevice (Temp);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_ABORTED;\r
-}\r
-\r
-BOOLEAN\r
-IsRejectiveDevice (\r
- IN PCI_RESOURCE_NODE *PciResNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Determine whethter a PCI device can be rejected\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResNode - add argument and description to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
-\r
- Temp = PciResNode->PciDev;\r
-\r
- //\r
- // Ensure the device is present\r
- //\r
- if (!Temp) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // PPB and RB should go ahead\r
- //\r
- if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {\r
- return TRUE;\r
- }\r
-\r
- //\r
- // Skip device on Bus0\r
- //\r
- if ((Temp->Parent) && (Temp->BusNumber == 0)) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Skip VGA\r
- //\r
- if (IS_PCI_VGA (&Temp->Pci)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-PCI_RESOURCE_NODE *\r
-GetLargerConsumerDevice (\r
- IN PCI_RESOURCE_NODE *PciResNode1,\r
- IN PCI_RESOURCE_NODE *PciResNode2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the larger resource consumer\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResNode1 - add argument and description to function comment\r
-// TODO: PciResNode2 - add argument and description to function comment\r
-{\r
- if (!PciResNode2) {\r
- return PciResNode1;\r
- }\r
-\r
- if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \\r
- && (PciResNode2->ResourceUsage != PciResUsagePadding) )\r
- {\r
- return PciResNode1;\r
- }\r
-\r
- if (!PciResNode1) {\r
- return PciResNode2;\r
- }\r
-\r
- if ((PciResNode1->Length) > (PciResNode2->Length)) {\r
- return PciResNode1;\r
- }\r
-\r
- return PciResNode2;\r
-\r
-}\r
-\r
-PCI_RESOURCE_NODE *\r
-GetMaxResourceConsumerDevice (\r
- IN PCI_RESOURCE_NODE *ResPool\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the max resource consumer in the host resource pool\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: ResPool - add argument and description to function comment\r
-{\r
- PCI_RESOURCE_NODE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *PciResNode;\r
- PCI_RESOURCE_NODE *PPBResNode;\r
-\r
- PciResNode = NULL;\r
-\r
- CurrentLink = ResPool->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &ResPool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (!IsRejectiveDevice (Temp)) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \\r
- && (Temp->ResourceUsage != PciResUsagePadding))\r
- {\r
- PPBResNode = GetMaxResourceConsumerDevice (Temp);\r
- PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);\r
- } else {\r
- PciResNode = GetLargerConsumerDevice (PciResNode, Temp);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return PciResNode;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeAdjustAllocation (\r
- IN PCI_RESOURCE_NODE *IoPool,\r
- IN PCI_RESOURCE_NODE *Mem32Pool,\r
- IN PCI_RESOURCE_NODE *PMem32Pool,\r
- IN PCI_RESOURCE_NODE *Mem64Pool,\r
- IN PCI_RESOURCE_NODE *PMem64Pool,\r
- IN UINT64 IoResStatus,\r
- IN UINT64 Mem32ResStatus,\r
- IN UINT64 PMem32ResStatus,\r
- IN UINT64 Mem64ResStatus,\r
- IN UINT64 PMem64ResStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Adjust host bridge allocation so as to reduce resource requirement\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: IoPool - add argument and description to function comment\r
-// TODO: Mem32Pool - add argument and description to function comment\r
-// TODO: PMem32Pool - add argument and description to function comment\r
-// TODO: Mem64Pool - add argument and description to function comment\r
-// TODO: PMem64Pool - add argument and description to function comment\r
-// TODO: IoResStatus - add argument and description to function comment\r
-// TODO: Mem32ResStatus - add argument and description to function comment\r
-// TODO: PMem32ResStatus - add argument and description to function comment\r
-// TODO: Mem64ResStatus - add argument and description to function comment\r
-// TODO: PMem64ResStatus - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- BOOLEAN AllocationAjusted;\r
- PCI_RESOURCE_NODE *PciResNode;\r
- PCI_RESOURCE_NODE *ResPool[5];\r
- PCI_IO_DEVICE *RemovedPciDev[5];\r
- UINT64 ResStatus[5];\r
- UINTN RemovedPciDevNum;\r
- UINTN DevIndex;\r
- UINTN ResType;\r
- EFI_STATUS Status;\r
- EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
-\r
- PciResNode = NULL;\r
- ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));\r
- RemovedPciDevNum = 0;\r
-\r
- ResPool[0] = IoPool;\r
- ResPool[1] = Mem32Pool;\r
- ResPool[2] = PMem32Pool;\r
- ResPool[3] = Mem64Pool;\r
- ResPool[4] = PMem64Pool;\r
-\r
- ResStatus[0] = IoResStatus;\r
- ResStatus[1] = Mem32ResStatus;\r
- ResStatus[2] = PMem32ResStatus;\r
- ResStatus[3] = Mem64ResStatus;\r
- ResStatus[4] = PMem64ResStatus;\r
-\r
- AllocationAjusted = FALSE;\r
-\r
- for (ResType = 0; ResType < 5; ResType++) {\r
-\r
- if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {\r
- continue;\r
- }\r
-\r
- if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {\r
- //\r
- // Hostbridge hasn't this resource type\r
- //\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Hostbridge hasn't enough resource\r
- //\r
- PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);\r
- if (!PciResNode) {\r
- continue;\r
- }\r
-\r
- //\r
- // Check if the device has been removed before\r
- //\r
- for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {\r
- if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {\r
- continue;\r
- }\r
- }\r
-\r
- //\r
- // Remove the device if it isn't in the array\r
- //\r
- Status = RejectPciDevice (PciResNode->PciDev);\r
- if (Status == EFI_SUCCESS) {\r
-\r
- //\r
- // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
- //\r
- //\r
- // Have no way to get ReqRes, AllocRes & Bar here\r
- //\r
- ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
- AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
- AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;\r
- AllocFailExtendedData.Bar = PciResNode->Bar;\r
-\r
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
- (VOID *) &AllocFailExtendedData,\r
- sizeof (AllocFailExtendedData)\r
- );\r
-\r
- //\r
- // Add it to the array and indicate at least a device has been rejected\r
- //\r
- RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;\r
- AllocationAjusted = TRUE;\r
- }\r
- }\r
- //\r
- // End for\r
- //\r
-\r
- if (AllocationAjusted) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_ABORTED;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-ConstructAcpiResourceRequestor (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *IoNode,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node,\r
- OUT VOID **pConfig\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: pConfig - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 NumConfig;\r
- UINT8 Aperture;\r
- UINT8 *Configuration;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
-\r
- NumConfig = 0;\r
- Aperture = 0;\r
-\r
- *pConfig = NULL;\r
-\r
- //\r
- // if there is io request, add to the io aperture\r
- //\r
- if (ResourceRequestExisted (IoNode)) {\r
- NumConfig++;\r
- Aperture |= 0x01;\r
- }\r
-\r
- //\r
- // if there is mem32 request, add to the mem32 aperture\r
- //\r
- if (ResourceRequestExisted (Mem32Node)) {\r
- NumConfig++;\r
- Aperture |= 0x02;\r
- }\r
-\r
- //\r
- // if there is pmem32 request, add to the pmem32 aperture\r
- //\r
- if (ResourceRequestExisted (PMem32Node)) {\r
- NumConfig++;\r
- Aperture |= 0x04;\r
- }\r
-\r
- //\r
- // if there is mem64 request, add to the mem64 aperture\r
- //\r
- if (ResourceRequestExisted (Mem64Node)) {\r
- NumConfig++;\r
- Aperture |= 0x08;\r
- }\r
-\r
- //\r
- // if there is pmem64 request, add to the pmem64 aperture\r
- //\r
- if (ResourceRequestExisted (PMem64Node)) {\r
- NumConfig++;\r
- Aperture |= 0x10;\r
- }\r
-\r
- if (NumConfig != 0) {\r
-\r
- //\r
- // If there is at least one type of resource request,\r
- // allocate a acpi resource node\r
- //\r
- Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Configuration == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem (\r
- Configuration,\r
- sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
- );\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
-\r
- //\r
- // Deal with io aperture\r
- //\r
- if (Aperture & 0x01) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Io\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
- //\r
- // non ISA range\r
- //\r
- Ptr->SpecificFlag = 1;\r
- Ptr->AddrLen = IoNode->Length;\r
- Ptr->AddrRangeMax = IoNode->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- //\r
- // Deal with mem32 aperture\r
- //\r
- if (Aperture & 0x02) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // Nonprefechable\r
- //\r
- Ptr->SpecificFlag = 0;\r
- //\r
- // 32 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 32;\r
- Ptr->AddrLen = Mem32Node->Length;\r
- Ptr->AddrRangeMax = Mem32Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
-\r
- //\r
- // Deal with Pmem32 aperture\r
- //\r
- if (Aperture & 0x04) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // prefechable\r
- //\r
- Ptr->SpecificFlag = 0x6;\r
- //\r
- // 32 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 32;\r
- Ptr->AddrLen = PMem32Node->Length;\r
- Ptr->AddrRangeMax = PMem32Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- //\r
- // Deal with mem64 aperture\r
- //\r
- if (Aperture & 0x08) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // nonprefechable\r
- //\r
- Ptr->SpecificFlag = 0;\r
- //\r
- // 64 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 64;\r
- Ptr->AddrLen = Mem64Node->Length;\r
- Ptr->AddrRangeMax = Mem64Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- //\r
- // Deal with Pmem64 aperture\r
- //\r
- if (Aperture & 0x10) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // prefechable\r
- //\r
- Ptr->SpecificFlag = 0x06;\r
- //\r
- // 64 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 64;\r
- Ptr->AddrLen = PMem64Node->Length;\r
- Ptr->AddrRangeMax = PMem64Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
-\r
- //\r
- // put the checksum\r
- //\r
- PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
-\r
- PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- PtrEnd->Checksum = 0;\r
-\r
- } else {\r
-\r
- //\r
- // If there is no resource request\r
- //\r
- Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Configuration == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
-\r
- PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- PtrEnd->Checksum = 0;\r
- }\r
-\r
- *pConfig = Configuration;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceBase (\r
- IN VOID *pConfig,\r
- OUT UINT64 *IoBase,\r
- OUT UINT64 *Mem32Base,\r
- OUT UINT64 *PMem32Base,\r
- OUT UINT64 *Mem64Base,\r
- OUT UINT64 *PMem64Base\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: pConfig - add argument and description to function comment\r
-// TODO: IoBase - add argument and description to function comment\r
-// TODO: Mem32Base - add argument and description to function comment\r
-// TODO: PMem32Base - add argument and description to function comment\r
-// TODO: Mem64Base - add argument and description to function comment\r
-// TODO: PMem64Base - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 *Temp;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- UINT64 ResStatus;\r
-\r
- *IoBase = 0xFFFFFFFFFFFFFFFFULL;\r
- *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
- *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
- *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
- *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
-\r
- Temp = (UINT8 *) pConfig;\r
-\r
- while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
- ResStatus = Ptr->AddrTranslationOffset;\r
-\r
- if (ResStatus == EFI_RESOURCE_SATISFIED) {\r
-\r
- switch (Ptr->ResType) {\r
-\r
- //\r
- // Memory type aperture\r
- //\r
- case 0:\r
-\r
- //\r
- // Check to see the granularity\r
- //\r
- if (Ptr->AddrSpaceGranularity == 32) {\r
- if (Ptr->SpecificFlag & 0x06) {\r
- *PMem32Base = Ptr->AddrRangeMin;\r
- } else {\r
- *Mem32Base = Ptr->AddrRangeMin;\r
- }\r
- }\r
-\r
- if (Ptr->AddrSpaceGranularity == 64) {\r
- if (Ptr->SpecificFlag & 0x06) {\r
- *PMem64Base = Ptr->AddrRangeMin;\r
- } else {\r
- *Mem64Base = Ptr->AddrRangeMin;\r
- }\r
- }\r
- break;\r
-\r
- case 1:\r
-\r
- //\r
- // Io type aperture\r
- //\r
- *IoBase = Ptr->AddrRangeMin;\r
- break;\r
-\r
- default:\r
- break;\r
-\r
- }\r
- //\r
- // End switch\r
- //\r
- }\r
- //\r
- // End for\r
- //\r
- Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciBridgeEnumerator (\r
- IN PCI_IO_DEVICE *BridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: BridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 SubBusNumber;\r
- UINT8 StartBusNumber;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_STATUS Status;\r
-\r
- SubBusNumber = 0;\r
- StartBusNumber = 0;\r
- PciIo = &(BridgeDev->PciIo);\r
- Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciAssignBusNumber (\r
- BridgeDev,\r
- StartBusNumber,\r
- &SubBusNumber\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciBridgeResourceAllocator (BridgeDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = DetermineDeviceAttribute (BridgeDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-PciBridgeResourceAllocator (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESOURCE_NODE *IoBridge;\r
- PCI_RESOURCE_NODE *Mem32Bridge;\r
- PCI_RESOURCE_NODE *PMem32Bridge;\r
- PCI_RESOURCE_NODE *Mem64Bridge;\r
- PCI_RESOURCE_NODE *PMem64Bridge;\r
- UINT64 IoBase;\r
- UINT64 Mem32Base;\r
- UINT64 PMem32Base;\r
- UINT64 Mem64Base;\r
- UINT64 PMem64Base;\r
- EFI_STATUS Status;\r
-\r
- IoBridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFF,\r
- 0,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem32Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem32Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem64Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem64Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- //\r
- // Create resourcemap by going through all the devices subject to this root bridge\r
- //\r
- Status = CreateResourceMap (\r
- Bridge,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = GetResourceBaseFromBridge (\r
- Bridge,\r
- &IoBase,\r
- &Mem32Base,\r
- &PMem32Base,\r
- &Mem64Base,\r
- &PMem64Base\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Program IO resources\r
- //\r
- ProgramResource (\r
- IoBase,\r
- IoBridge\r
- );\r
-\r
- //\r
- // Program Mem32 resources\r
- //\r
- ProgramResource (\r
- Mem32Base,\r
- Mem32Bridge\r
- );\r
-\r
- //\r
- // Program PMem32 resources\r
- //\r
- ProgramResource (\r
- PMem32Base,\r
- PMem32Bridge\r
- );\r
-\r
- //\r
- // Program Mem64 resources\r
- //\r
- ProgramResource (\r
- Mem64Base,\r
- Mem64Bridge\r
- );\r
-\r
- //\r
- // Program PMem64 resources\r
- //\r
- ProgramResource (\r
- PMem64Base,\r
- PMem64Bridge\r
- );\r
-\r
- DestroyResourceTree (IoBridge);\r
- DestroyResourceTree (Mem32Bridge);\r
- DestroyResourceTree (PMem32Bridge);\r
- DestroyResourceTree (PMem64Bridge);\r
- DestroyResourceTree (Mem64Bridge);\r
-\r
- gBS->FreePool (IoBridge);\r
- gBS->FreePool (Mem32Bridge);\r
- gBS->FreePool (PMem32Bridge);\r
- gBS->FreePool (PMem64Bridge);\r
- gBS->FreePool (Mem64Bridge);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceBaseFromBridge (\r
- IN PCI_IO_DEVICE *Bridge,\r
- OUT UINT64 *IoBase,\r
- OUT UINT64 *Mem32Base,\r
- OUT UINT64 *PMem32Base,\r
- OUT UINT64 *Mem64Base,\r
- OUT UINT64 *PMem64Base\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: IoBase - add argument and description to function comment\r
-// TODO: Mem32Base - add argument and description to function comment\r
-// TODO: PMem32Base - add argument and description to function comment\r
-// TODO: Mem64Base - add argument and description to function comment\r
-// TODO: PMem64Base - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- if (!Bridge->Allocated) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- *IoBase = gAllOne;\r
- *Mem32Base = gAllOne;\r
- *PMem32Base = gAllOne;\r
- *Mem64Base = gAllOne;\r
- *PMem64Base = gAllOne;\r
-\r
- if (IS_PCI_BRIDGE (&Bridge->Pci)) {\r
-\r
- if (Bridge->PciBar[PPB_IO_RANGE].Length) {\r
- *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {\r
- *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {\r
- *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {\r
- *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;\r
- } else {\r
- *PMem64Base = gAllOne;\r
- }\r
-\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {\r
- if (Bridge->PciBar[P2C_IO_1].Length) {\r
- *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;\r
- } else {\r
- if (Bridge->PciBar[P2C_IO_2].Length) {\r
- *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;\r
- }\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_1].Length) {\r
- if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {\r
- *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {\r
- *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
- }\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_2].Length) {\r
- if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {\r
- *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {\r
- *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-NotifyPhase (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: Phase - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- EFI_STATUS Status;\r
-\r
- HostBridgeHandle = NULL;\r
- RootBridgeHandle = NULL;\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Get Host Bridge Handle.\r
- //\r
- PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);\r
-\r
- //\r
- // Get the rootbridge Io protocol to find the host bridge handle\r
- //\r
- Status = gBS->HandleProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Call PlatformPci::PhaseNotify() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PhaseNotify (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- Phase,\r
- ChipsetEntry\r
- );\r
- }\r
-\r
- Status = PciResAlloc->NotifyPhase (\r
- PciResAlloc,\r
- Phase\r
- );\r
-\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Call PlatformPci::PhaseNotify() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PhaseNotify (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- Phase,\r
- ChipsetExit\r
- );\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PreprocessController (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func,\r
- IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-// TODO: Phase - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the host bridge handle\r
- //\r
- HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Get the pci host bridge resource allocation protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- HostBridgeHandle,\r
- &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
- (VOID **) &PciResAlloc,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Get Root Brige Handle\r
- //\r
- while (Bridge->Parent) {\r
- Bridge = Bridge->Parent;\r
- }\r
-\r
- RootBridgeHandle = Bridge->Handle;\r
-\r
- RootBridgePciAddress.Register = 0;\r
- RootBridgePciAddress.Function = Func;\r
- RootBridgePciAddress.Device = Device;\r
- RootBridgePciAddress.Bus = Bus;\r
- RootBridgePciAddress.ExtendedRegister = 0;\r
-\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Call PlatformPci::PrepController() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PlatformPrepController (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- RootBridgeHandle,\r
- RootBridgePciAddress,\r
- Phase,\r
- ChipsetEntry\r
- );\r
- }\r
-\r
- Status = PciResAlloc->PreprocessController (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- RootBridgePciAddress,\r
- Phase\r
- );\r
-\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Call PlatformPci::PrepController() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PlatformPrepController (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- RootBridgeHandle,\r
- RootBridgePciAddress,\r
- Phase,\r
- ChipsetExit\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciHotPlugRequestNotify (\r
- IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
- IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
- IN OUT UINT8 *NumberOfChildren,\r
- IN OUT EFI_HANDLE * ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Hot plug request notify.\r
-\r
-Arguments:\r
-\r
- This - A pointer to the hot plug request protocol.\r
- Operation - The operation.\r
- Controller - A pointer to the controller.\r
- RemainningDevicePath - A pointer to the device path.\r
- NumberOfChildren - A the number of child handle in the ChildHandleBuffer.\r
- ChildHandleBuffer - A pointer to the array contain the child handle.\r
-\r
-Returns:\r
-\r
- Status code.\r
-\r
---*/\r
-// TODO: RemainingDevicePath - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Bridge;\r
- PCI_IO_DEVICE *Temp;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINTN Index;\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_STATUS Status;\r
-\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
-\r
- //\r
- // Get root bridge handle\r
- //\r
- Temp = Bridge;\r
- while (Temp->Parent) {\r
- Temp = Temp->Parent;\r
- }\r
-\r
- RootBridgeHandle = Temp->Handle;\r
-\r
- if (Operation == EfiPciHotPlugRequestAdd) {\r
-\r
- if (NumberOfChildren != NULL) {\r
- *NumberOfChildren = 0;\r
- }\r
-\r
- if (IsListEmpty (&Bridge->ChildList)) {\r
-\r
- Status = PciBridgeEnumerator (Bridge);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- Status = StartPciDevicesOnBridge (\r
- RootBridgeHandle,\r
- Bridge,\r
- RemainingDevicePath,\r
- NumberOfChildren,\r
- ChildHandleBuffer\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Operation == EfiPciHotplugRequestRemove) {\r
-\r
- if (*NumberOfChildren == 0) {\r
- //\r
- // Remove all devices on the bridge\r
- //\r
- Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);\r
- return Status;\r
-\r
- }\r
-\r
- for (Index = 0; Index < *NumberOfChildren; Index++) {\r
- //\r
- // De register all the pci device\r
- //\r
- Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- }\r
- //\r
- // End for\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-SearchHostBridgeHandle (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: RootBridgeHandle - add argument and description to function comment\r
-{\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the rootbridge Io protocol to find the host bridge handle\r
- //\r
- Status = gBS->OpenProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- RootBridgeHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
- for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
- if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-AddHostBridgeEnumerator (\r
- IN EFI_HANDLE HostBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: HostBridgeHandle - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINTN Index;\r
-\r
- if (!HostBridgeHandle) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
- if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- if (Index < PCI_MAX_HOST_BRIDGE_NUM) {\r
- gPciHostBrigeHandles[Index] = HostBridgeHandle;\r
- gPciHostBridgeNumber++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r