From 6874dbd0e24535c3c4a89dddfdac98ad25b0617b Mon Sep 17 00:00:00 2001 From: qwang12 Date: Wed, 13 Dec 2006 03:11:47 +0000 Subject: [PATCH 1/1] 1) Use FeatureFlag PcdPciBusHotplugDeviceSupport to merge LightPciLib.c with PcdLib.c. 2) Correct some minor bugs: when invoking gRT->GetVariable the Attributes field can be optianal. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2090 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Bus/Pci/IdeBus/Dxe/DriverConfiguration.c | 6 +- EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c | 3 +- EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa | 26 +- EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c | 697 +++++++++++++++++- EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h | 36 +- EdkModulePkg/EdkModulePkg.fpd | 32 + EdkModulePkg/EdkModulePkg.spd | 29 +- EdkModulePkg/Universal/PCD/Dxe/Service.c | 2 +- .../Dxe/PlatformBds/Generic/MemoryTest.c | 3 +- 9 files changed, 762 insertions(+), 72 deletions(-) diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c index dfe134a2ee..75794f8125 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c @@ -161,7 +161,6 @@ IDEBusDriverConfigurationSetOptions ( UINT8 NewValue; UINTN DataSize; UINTN Index; - UINT32 Attributes; if (ChildHandle != NULL) { return EFI_UNSUPPORTED; @@ -173,7 +172,7 @@ IDEBusDriverConfigurationSetOptions ( Status = gRT->GetVariable ( L"Configuration", &gEfiCallerIdGuid, - &Attributes, + NULL, &DataSize, &Value ); @@ -255,7 +254,6 @@ IDEBusDriverConfigurationOptionsValid ( EFI_STATUS Status; UINT8 Value; UINTN DataSize; - UINT32 Attributes; if (ChildHandle != NULL) { return EFI_UNSUPPORTED; @@ -265,7 +263,7 @@ IDEBusDriverConfigurationOptionsValid ( Status = gRT->GetVariable ( L"Configuration", &gEfiCallerIdGuid, - &Attributes, + NULL, &DataSize, &Value ); diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c index 83dd5510e4..d17ce5f07d 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c @@ -181,7 +181,6 @@ IDEBusDriverBindingStart ( UINT16 CommandBlockBaseAddr; UINT16 ControlBlockBaseAddr; UINTN DataSize; - UINT32 Attributes; IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; // @@ -316,7 +315,7 @@ IDEBusDriverBindingStart ( Status = gRT->GetVariable ( (CHAR16 *) L"Configuration", &gEfiCallerIdGuid, - &Attributes, + NULL, &DataSize, &ConfigurationOptions ); diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa index 855fdd7591..b8e15f9fb3 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa @@ -6,18 +6,15 @@ 93B80004-9FB3-11d4-9A3A-0090273FC14D 1.0 Component description file for PciBus module. - PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO - space for these devices. - LightPcdLib.c tagged with "ToolCode="DUMMY"" is light weight verison for PCI library - function. This version provide simple implementation and do not support hot plug. Only one - between PcdLib.c and LightPcdLib.c can be choosed. - + PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO + space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable + support hot plug. Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 @@ -93,7 +90,6 @@ pcibus.c PciIo.c PciLib.c - LightPciLib.c @@ -178,5 +174,11 @@ gEfiGenericPlatformTokenSpaceGuid Whether VGA decoding is enabled on this platform so we should avoid those aliased resources + + PcdPciBusHotplugDeviceSupport + gEfiGenericPlatformTokenSpaceGuid + TRUE + If TRUE, the PCI bus driver will support hot plug device. If not hot plug device is supported, this feature flag can be set to FALSE to save size. + \ No newline at end of file diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c index 11a0c29210..a4d3577d35 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c @@ -25,7 +25,7 @@ Revision History #include "pcibus.h" -EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = { +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = { PciHotPlugRequestNotify }; @@ -49,6 +49,10 @@ Returns: { EFI_HANDLE Handle; + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + Handle = NULL; *Status = gBS->InstallProtocolInterface ( &Handle, @@ -78,6 +82,10 @@ Returns: { EFI_STATUS Status; + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) { Status = gBS->InstallProtocolInterface ( @@ -109,6 +117,10 @@ Returns: { EFI_STATUS Status; + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + Status = gBS->OpenProtocol ( PciIoDevice->Handle, &gEfiPciHotplugDeviceGuid, @@ -152,6 +164,10 @@ Returns: { UINT32 Address; + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + // // Read PciBar information from the bar register // @@ -239,6 +255,10 @@ Returns: LIST_ENTRY *CurrentLink; LIST_ENTRY *LastLink; + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return EFI_SUCCESS; + } + CurrentLink = Bridge->ChildList.ForwardLink; while (CurrentLink && CurrentLink != &Bridge->ChildList) { @@ -286,6 +306,396 @@ EFI_STATUS PciHostBridgeResourceAllocator ( IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc ) +{ + if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( + PciResAlloc + ); + } else { + return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( + PciResAlloc + ); + } +} + + +EFI_STATUS +PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *RootBridgeDev; + EFI_HANDLE RootBridgeHandle; + VOID *AcpiConfig; + EFI_STATUS Status; + UINT64 IoBase; + UINT64 Mem32Base; + UINT64 PMem32Base; + UINT64 Mem64Base; + UINT64 PMem64Base; + UINT64 MaxOptionRomSize; + PCI_RESOURCE_NODE *IoBridge; + PCI_RESOURCE_NODE *Mem32Bridge; + PCI_RESOURCE_NODE *PMem32Bridge; + PCI_RESOURCE_NODE *Mem64Bridge; + PCI_RESOURCE_NODE *PMem64Bridge; + PCI_RESOURCE_NODE IoPool; + PCI_RESOURCE_NODE Mem32Pool; + PCI_RESOURCE_NODE PMem32Pool; + PCI_RESOURCE_NODE Mem64Pool; + PCI_RESOURCE_NODE PMem64Pool; + REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA ExtendedData; + + // + // Initialize resource pool + // + + InitializeResourcePool (&IoPool, PciBarTypeIo16); + InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); + InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); + InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); + InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); + + RootBridgeDev = NULL; + RootBridgeHandle = 0; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get host bridge handle for status report + // + ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; + + // + // Create the entire system resource map from the information collected by + // enumerator. Several resource tree was created + // + + IoBridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFF, + 0, + PciBarTypeIo16, + PciResUsageTypical + ); + + Mem32Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypeMem32, + PciResUsageTypical + ); + + PMem32Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypePMem32, + PciResUsageTypical + ); + + Mem64Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypeMem64, + PciResUsageTypical + ); + + PMem64Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypePMem64, + PciResUsageTypical + ); + + // + // Create resourcemap by going through all the devices subject to this root bridge + // + Status = CreateResourceMap ( + RootBridgeDev, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge + ); + + // + // Get the max ROM size that the root bridge can process + // + RootBridgeDev->RomSize = Mem32Bridge->Length; + + // + // Get Max Option Rom size for current root bridge + // + MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); + + // + // Enlarger the mem32 resource to accomdate the option rom + // if the mem32 resource is not enough to hold the rom + // + if (MaxOptionRomSize > Mem32Bridge->Length) { + + Mem32Bridge->Length = MaxOptionRomSize; + RootBridgeDev->RomSize = MaxOptionRomSize; + + // + // Alignment should be adjusted as well + // + if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { + Mem32Bridge->Alignment = MaxOptionRomSize - 1; + } + } + + // + // Based on the all the resource tree, contruct ACPI resource node to + // submit the resource aperture to pci host bridge protocol + // + Status = ConstructAcpiResourceRequestor ( + RootBridgeDev, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge, + &AcpiConfig + ); + + // + // Insert these resource nodes into the database + // + InsertResourceNode (&IoPool, IoBridge); + InsertResourceNode (&Mem32Pool, Mem32Bridge); + InsertResourceNode (&PMem32Pool, PMem32Bridge); + InsertResourceNode (&Mem64Pool, Mem64Bridge); + InsertResourceNode (&PMem64Pool, PMem64Bridge); + + if (Status == EFI_SUCCESS) { + // + // Submit the resource requirement + // + Status = PciResAlloc->SubmitResources ( + PciResAlloc, + RootBridgeDev->Handle, + AcpiConfig + ); + } + // + // Free acpi resource node + // + if (AcpiConfig) { + gBS->FreePool (AcpiConfig); + } + + if (EFI_ERROR (Status)) { + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + return Status; + } + } + // + // End while + // + + // + // Notify pci bus driver starts to program the resource + // + Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); + + if (EFI_ERROR (Status)) { + // + // Allocation failed, then return + // + return EFI_OUT_OF_RESOURCES; + } + // + // Raise the EFI_IOB_PCI_RES_ALLOC status code + // + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC, + (VOID *) &ExtendedData, + sizeof (ExtendedData) + ); + + // + // Notify pci bus driver starts to program the resource + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); + + RootBridgeDev = NULL; + + RootBridgeHandle = 0; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get acpi resource node for all the resource types + // + AcpiConfig = NULL; + Status = PciResAlloc->GetProposedResources ( + PciResAlloc, + RootBridgeDev->Handle, + &AcpiConfig + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the resource base by interpreting acpi resource node + // + // + GetResourceBase ( + AcpiConfig, + &IoBase, + &Mem32Base, + &PMem32Base, + &Mem64Base, + &PMem64Base + ); + + // + // Process option rom for this root bridge + // + Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); + + // + // Create the entire system resource map from the information collected by + // enumerator. Several resource tree was created + // + Status = GetResourceMap ( + RootBridgeDev, + &IoBridge, + &Mem32Bridge, + &PMem32Bridge, + &Mem64Bridge, + &PMem64Bridge, + &IoPool, + &Mem32Pool, + &PMem32Pool, + &Mem64Pool, + &PMem64Pool + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Program IO resources + // + ProgramResource ( + IoBase, + IoBridge + ); + + // + // Program Mem32 resources + // + ProgramResource ( + Mem32Base, + Mem32Bridge + ); + + // + // Program PMem32 resources + // + ProgramResource ( + PMem32Base, + PMem32Bridge + ); + + // + // Program Mem64 resources + // + ProgramResource ( + Mem64Base, + Mem64Bridge + ); + + // + // Program PMem64 resources + // + ProgramResource ( + PMem64Base, + PMem64Bridge + ); + + if (AcpiConfig != NULL) { + gBS->FreePool (AcpiConfig); + } + } + + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + + // + // Notify the resource allocation phase is to end + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation); + + return EFI_SUCCESS; +} + + +EFI_STATUS +PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) /*++ Routine Description: @@ -787,6 +1197,7 @@ Returns: return EFI_SUCCESS; } + EFI_STATUS PciScanBus ( IN PCI_IO_DEVICE *Bridge, @@ -794,6 +1205,204 @@ PciScanBus ( OUT UINT8 *SubBusNumber, OUT UINT8 *PaddedBusRange ) +{ + if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return PciScanBus_WithHotPlugDeviceSupport ( + Bridge, + StartBusNumber, + SubBusNumber, + PaddedBusRange + ); + } else { + return PciScanBus_WithoutHotPlugDeviceSupport ( + Bridge, + StartBusNumber, + SubBusNumber, + PaddedBusRange + ); + } +} + + +EFI_STATUS +PciScanBus_WithoutHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +/*++ + +Routine Description: + + This routine is used to assign bus number to the given PCI bus system + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: StartBusNumber - add argument and description to function comment +// TODO: SubBusNumber - add argument and description to function comment +// TODO: PaddedBusRange - add argument and description to function comment +// TODO: EFI_DEVICE_ERROR - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_TYPE00 Pci; + UINT8 Device; + UINT8 Func; + UINT64 Address; + UINTN SecondBus; + UINT16 Register; + PCI_IO_DEVICE *PciDevice; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + SecondBus = 0; + Register = 0; + + ResetAllPpbBusReg (Bridge, StartBusNumber); + + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + + // + // Check to see whether a pci device is present + // + Status = PciDevicePresent ( + PciRootBridgeIo, + &Pci, + StartBusNumber, + Device, + Func + ); + + if (!EFI_ERROR (Status) && + (IS_PCI_BRIDGE (&Pci) || + IS_CARDBUS_BRIDGE (&Pci))) { + + // + // Get the bridge information + // + Status = PciSearchDevice ( + Bridge, + &Pci, + StartBusNumber, + Device, + Func, + &PciDevice + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + (*SubBusNumber)++; + + SecondBus = (*SubBusNumber); + + Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); + + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); + + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + EfiPciWidthUint16, + Address, + 1, + &Register + ); + + // + // Initialize SubBusNumber to SecondBus + // + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + // + // If it is PPB, resursively search down this bridge + // + if (IS_PCI_BRIDGE (&Pci)) { + // + // Temporarily initialize SubBusNumber to maximum bus number to ensure the + // PCI configuration transaction to go through any PPB + // + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + Register = 0xFF; + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + EfiPciWidthUint8, + Address, + 1, + &Register + ); + + PreprocessController ( + PciDevice, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + EfiPciBeforeChildBusEnumeration + ); + + Status = PciScanBus ( + PciDevice, + (UINT8) (SecondBus), + SubBusNumber, + PaddedBusRange + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + + // + // Set the current maximum bus number under the PPB + // + + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + + } + + if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { + + // + // Skip sub functions, this is not a multi function device + // + + Func = PCI_MAX_FUNC; + } + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciScanBus_WithHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) /*++ Routine Description: @@ -1175,6 +1784,10 @@ Returns: PCI_IO_DEVICE *RootBridgeDev; EFI_STATUS Status; + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return EFI_SUCCESS; + } + RootBridgeHandle = NULL; while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { @@ -1271,55 +1884,63 @@ Returns: // } - // - // Notify the bus allocation phase is finished for the first time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); - - - if (gPciHotPlugInit != NULL) { - // - // Wait for all HPC initialized - // - Status = AllRootHPCInitialized (STALL_1_SECOND * 15); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Notify the bus allocation phase is about to start for the 2nd time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); - - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + // + // Notify the bus allocation phase is finished for the first time + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); + + + if (gPciHotPlugInit != NULL) { // - // if a root bridge instance is found, create root bridge device for it + // Wait for all HPC initialized // + Status = AllRootHPCInitialized (STALL_1_SECOND * 15); - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; + if (EFI_ERROR (Status)) { + return Status; } // - // Enumerate all the buses under this root bridge + // Notify the bus allocation phase is about to start for the 2nd time // + NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); + + RootBridgeHandle = NULL; + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - Status = PciRootBridgeEnumerator ( - PciResAlloc, - RootBridgeDev - ); + // + // if a root bridge instance is found, create root bridge device for it + // - DestroyRootBridge (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; + RootBridgeDev = CreateRootBridge (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Enumerate all the buses under this root bridge + // + + Status = PciRootBridgeEnumerator ( + PciResAlloc, + RootBridgeDev + ); + + DestroyRootBridge (RootBridgeDev); + if (EFI_ERROR (Status)) { + return Status; + } } + + // + // Notify the bus allocation phase is to end + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); } - + } else { // // Notify the bus allocation phase is to end // diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h index 1e89445df6..f8e88375d7 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h @@ -15,9 +15,9 @@ Module Name: Abstract: - PCI Bus Driver Lib header file - It abstracts some functions that can be different - between light PCI bus driver and full PCI bus driver + PCI Bus Driver Lib header file. + Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable + support hot plug. Revision History @@ -154,6 +154,18 @@ Returns: --*/ ; +EFI_STATUS +PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +; + +EFI_STATUS +PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +; + EFI_STATUS PciScanBus ( IN PCI_IO_DEVICE *Bridge, @@ -181,6 +193,24 @@ Returns: --*/ ; +EFI_STATUS +PciScanBus_WithHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +; + +EFI_STATUS +PciScanBus_WithoutHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +; + EFI_STATUS PciRootBridgeP2CProcess ( IN PCI_IO_DEVICE *Bridge diff --git a/EdkModulePkg/EdkModulePkg.fpd b/EdkModulePkg/EdkModulePkg.fpd index 78c46fd054..7ed449c1af 100644 --- a/EdkModulePkg/EdkModulePkg.fpd +++ b/EdkModulePkg/EdkModulePkg.fpd @@ -3698,6 +3698,14 @@ 1 FALSE + + PcdPciBusHotplugDeviceSupport + 0x0001003d + gEfiGenericPlatformTokenSpaceGuid + BOOLEAN + 1 + TRUE + NULL @@ -8991,6 +8999,14 @@ 1 FALSE + + PcdPciBusHotplugDeviceSupport + 0x0001003d + gEfiGenericPlatformTokenSpaceGuid + BOOLEAN + 1 + TRUE + NULL @@ -13262,6 +13278,14 @@ 1 FALSE + + PcdPciBusHotplugDeviceSupport + 0x0001003d + gEfiGenericPlatformTokenSpaceGuid + BOOLEAN + 1 + TRUE + NULL @@ -17180,6 +17204,14 @@ 1 FALSE + + PcdPciBusHotplugDeviceSupport + 0x0001003d + gEfiGenericPlatformTokenSpaceGuid + BOOLEAN + 1 + TRUE + NULL diff --git a/EdkModulePkg/EdkModulePkg.spd b/EdkModulePkg/EdkModulePkg.spd index e63427f955..db8be51a64 100644 --- a/EdkModulePkg/EdkModulePkg.spd +++ b/EdkModulePkg/EdkModulePkg.spd @@ -7,11 +7,11 @@ Edk Module Package Reference Implementations This Module provides standard reference information for EFI/Tiano implementations. Copyright (c) 2006, Intel Corporation. - All rights reserved. - This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this distribution. - The full text of the license may be found at http://opensource.org/licenses/bsd-license.php - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES + All rights reserved. + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this distribution. + The full text of the license may be found at http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 @@ -452,7 +452,7 @@ gEfiGenericPlatformTokenSpaceGuid 18D15EA6-9E14-40a1-B39C-59C44DA9D891 - This is the token space GUID for platform generic PCD definitions. + This is the token space GUID for platform generic PCD definitions. Now FlashLayout and Platform CPU belong to this space. @@ -903,7 +903,7 @@ UINT32 FIXED_AT_BUILD 0x08 - The maximum number of callback function, which will be triggered when + The maximum number of callback function, which will be triggered when a PCD entry is been set, can be registered for a single PCD entry in PEI phase. @@ -913,7 +913,7 @@ UINT32 FIXED_AT_BUILD 0x0 - The base address of the VPD (Vital Product Data) region. It is + The base address of the VPD (Vital Product Data) region. It is normally a region reserved on flash. @@ -950,7 +950,7 @@ BOOLEAN FEATURE_FLAG TRUE - This feature flag can be used to enable or disable the Pcd PEIM database + This feature flag can be used to enable or disable the Pcd PEIM database traverse capability. Disable it can reduce the size of final image generated. @@ -960,7 +960,7 @@ BOOLEAN FEATURE_FLAG TRUE - This feature flag can be used to enable or disable the Pcd DXE database + This feature flag can be used to enable or disable the Pcd DXE database traverse capability. Disable it can reduce the size of final image generated. @@ -1260,5 +1260,14 @@ FALSE If this feature is enabled, DXE IPL will build a series of HOBs to share code with DXE Core. + + PcdPciBusHotplugDeviceSupport + 0x0001003d + gEfiGenericPlatformTokenSpaceGuid + BOOLEAN + FEATURE_FLAG + TRUE + If TRUE, the PCI bus driver will support hot plug device. If not hot plug device is supported, this feature flag can be set to FALSE to save size. + \ No newline at end of file diff --git a/EdkModulePkg/Universal/PCD/Dxe/Service.c b/EdkModulePkg/Universal/PCD/Dxe/Service.c index ff93ef5421..a4b19878a5 100644 --- a/EdkModulePkg/Universal/PCD/Dxe/Service.c +++ b/EdkModulePkg/Universal/PCD/Dxe/Service.c @@ -767,7 +767,7 @@ SetHiiVariable ( Status = gRT->GetVariable ( (UINT16 *)VariableName, VariableGuid, - &Attribute, + NULL, &Size, NULL ); diff --git a/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c b/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c index af6c1ab217..d4e5bc50ef 100644 --- a/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c +++ b/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c @@ -240,7 +240,6 @@ Returns: EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; UINT8 Value; UINTN DataSize; - UINT32 Attributes; ReturnStatus = EFI_SUCCESS; ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); @@ -412,7 +411,7 @@ Done: Status = gRT->GetVariable ( L"BootState", &gEfiBootStateGuid, - &Attributes, + NULL, &DataSize, &Value ); -- 2.39.2