feat: [common] Enable PCIe resizable BAR support
This commit adds support for PCIe resizable BARsupport. The feature can be enabled by setting PcdResizableBarSupport for the board build script and its disabled by default. Signed-off-by: pastorcx <mariano-paulx.pastorcici@intel.com>
This commit is contained in:
parent
32704b0653
commit
c50658ae6b
|
@ -248,6 +248,7 @@
|
|||
gPlatformModuleTokenSpaceGuid.PcdEnableSetup | FALSE | BOOLEAN | 0x20000213
|
||||
gPlatformModuleTokenSpaceGuid.PcdLegacyEfSegmentEnabled | TRUE | BOOLEAN | 0x20000214
|
||||
gPlatformModuleTokenSpaceGuid.PcdEnableDts | FALSE | BOOLEAN | 0x20000215
|
||||
gPlatformModuleTokenSpaceGuid.PcdResizableBarSupport | FALSE | BOOLEAN | 0x20000216
|
||||
gPlatformModuleTokenSpaceGuid.PcdEnablePciePm | FALSE | BOOLEAN | 0x20000222
|
||||
gPlatformModuleTokenSpaceGuid.PcdEnableFwuNotify | FALSE | BOOLEAN | 0x20000225
|
||||
|
||||
|
|
|
@ -347,6 +347,7 @@
|
|||
gPlatformCommonLibTokenSpaceGuid.PcdCpuX2ApicEnabled | $(SUPPORT_X2APIC)
|
||||
gPlatformModuleTokenSpaceGuid.PcdAriSupport | $(SUPPORT_ARI)
|
||||
gPlatformModuleTokenSpaceGuid.PcdSrIovSupport | $(SUPPORT_SR_IOV)
|
||||
gPlatformModuleTokenSpaceGuid.PcdResizableBarSupport | $(SUPPORT_RESIZABLE_BAR)
|
||||
gPlatformModuleTokenSpaceGuid.PcdEnableSetup | $(ENABLE_SBL_SETUP)
|
||||
gPayloadTokenSpaceGuid.PcdPayloadModuleEnabled | $(ENABLE_PAYLOD_MODULE)
|
||||
gPlatformModuleTokenSpaceGuid.PcdEnableDts | $(ENABLE_DTS)
|
||||
|
|
|
@ -61,6 +61,11 @@ typedef enum {
|
|||
BusScanTypeInvalid = 0xFF
|
||||
} BUS_SCAN_TYPE;
|
||||
|
||||
typedef enum {
|
||||
PciResizableBarMin = 0x00,
|
||||
PciResizableBarMax = 0xFF
|
||||
} PCI_RESIZABLE_BAR_OPERATION;
|
||||
|
||||
typedef struct {
|
||||
UINT16 Io32 : 1;
|
||||
UINT16 Mem64 : 1;
|
||||
|
@ -152,6 +157,7 @@ struct _PCI_IO_DEVICE {
|
|||
BOOLEAN IsPciExp;
|
||||
UINT8 PciExpressCapabilityOffset;
|
||||
UINT32 AriCapabilityOffset;
|
||||
|
||||
//
|
||||
// SR-IOV
|
||||
//
|
||||
|
@ -161,6 +167,15 @@ struct _PCI_IO_DEVICE {
|
|||
UINT16 InitialVFs;
|
||||
UINT16 ReservedBusNum;
|
||||
|
||||
//
|
||||
// Per PCI to PCI Bridge spec, I/O window is 4K aligned,
|
||||
// but some chipsets support non-standard I/O window alignments less than 4K.
|
||||
// This field is used to support this case.
|
||||
//
|
||||
UINT16 BridgeIoAlignment;
|
||||
UINT32 ResizableBarOffset;
|
||||
UINT32 ResizableBarNumber;
|
||||
|
||||
//
|
||||
// The bridge device this pci device is subject to
|
||||
//
|
||||
|
@ -194,4 +209,15 @@ BarExisted (
|
|||
OUT UINT32 *OriginalBarValue
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize Resizable BAR
|
||||
|
||||
@param[in,out] PciIoDevice Pointer to instance of PCI_IO_DEVICE.
|
||||
|
||||
**/
|
||||
VOID
|
||||
InitializeResizeBar (
|
||||
IN OUT PCI_IO_DEVICE *PciIoDevice
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <Library/BootloaderCommonLib.h>
|
||||
#include "PciAri.h"
|
||||
#include "PciIov.h"
|
||||
#include "InternalPciEnumerationLib.h"
|
||||
|
||||
#define DEBUG_PCI_ENUM 0
|
||||
|
||||
|
@ -432,7 +433,7 @@ CreatePciIoDevice (
|
|||
PciIoDevice->Decodes = 0;
|
||||
PciIoDevice->IsPciExp = FALSE;
|
||||
PciIoDevice->PciExpressCapabilityOffset = 0;
|
||||
if (FeaturePcdGet (PcdAriSupport) || FeaturePcdGet (PcdSrIovSupport)) {
|
||||
if (FeaturePcdGet (PcdAriSupport) || FeaturePcdGet (PcdSrIovSupport) || FeaturePcdGet (PcdResizableBarSupport)) {
|
||||
InitializePciExpCapability (PciIoDevice);
|
||||
}
|
||||
if (FeaturePcdGet (PcdAriSupport)) {
|
||||
|
@ -441,7 +442,9 @@ CreatePciIoDevice (
|
|||
if (FeaturePcdGet (PcdSrIovSupport)) {
|
||||
InitializeSrIov (PciIoDevice, Bus, Device, Func);
|
||||
}
|
||||
|
||||
if (FeaturePcdGet (PcdResizableBarSupport)) {
|
||||
InitializeResizeBar (PciIoDevice);
|
||||
}
|
||||
return PciIoDevice;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
PciCommand.c
|
||||
PciAri.c
|
||||
PciIov.c
|
||||
PciResizableBar.c
|
||||
PciEnumerationLib.c
|
||||
|
||||
[Packages]
|
||||
|
@ -55,5 +56,6 @@
|
|||
gPlatformModuleTokenSpaceGuid.PcdPciResourceMem64Base
|
||||
gPlatformModuleTokenSpaceGuid.PcdAriSupport
|
||||
gPlatformModuleTokenSpaceGuid.PcdSrIovSupport
|
||||
gPlatformModuleTokenSpaceGuid.PcdResizableBarSupport
|
||||
gPlatformModuleTokenSpaceGuid.PcdPciResAllocTableBase
|
||||
gPlatformModuleTokenSpaceGuid.PcdPciEnumHookProc
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2020 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PciExpressLib.h>
|
||||
#include "InternalPciEnumerationLib.h"
|
||||
#include "PciCommand.h"
|
||||
|
||||
/**
|
||||
This function is used to program the Resizable BAR Register.
|
||||
|
||||
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
|
||||
@param ResizableBarOp PciResizableBarMax: Set BAR to max size
|
||||
PciResizableBarMin: set BAR to min size.
|
||||
|
||||
@retval EFI_SUCCESS Successfully enumerated the host bridge.
|
||||
@retval other Some error occurred when enumerating the host bridge.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PciProgramResizableBar (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN PCI_RESIZABLE_BAR_OPERATION ResizableBarOp
|
||||
)
|
||||
{
|
||||
UINT64 Capabilities;
|
||||
UINT32 Index;
|
||||
UINT32 Offset;
|
||||
INTN Bit;
|
||||
UINTN ResizableBarNumber;
|
||||
PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY Entries[PCI_MAX_BAR];
|
||||
|
||||
ASSERT (PciIoDevice->ResizableBarOffset != 0);
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "Programs Resizable BAR register, address %x offset: 0x%08x, number: %d\n",
|
||||
PciIoDevice->Address,
|
||||
PciIoDevice->ResizableBarOffset,
|
||||
PciIoDevice->ResizableBarNumber));
|
||||
ResizableBarNumber = MIN (PciIoDevice->ResizableBarNumber, PCI_MAX_BAR);
|
||||
for (Index = 0; Index < ResizableBarNumber; Index++) {
|
||||
Offset = PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER) +
|
||||
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY) * Index;
|
||||
Entries[Index].ResizableBarCapability.Uint32 = PciExpressRead32 (PciIoDevice->Address + Offset);
|
||||
Offset += sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY);
|
||||
Entries[Index].ResizableBarControl.Uint32 = PciExpressRead32 (PciIoDevice->Address + Offset);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < ResizableBarNumber; Index++) {
|
||||
//
|
||||
// When the bit of Capabilities Set, indicates that the Function supports
|
||||
// operating with the BAR sized to (2^Bit) MB.
|
||||
// Example:
|
||||
// Bit 0 is set: supports operating with the BAR sized to 1 MB
|
||||
// Bit 1 is set: supports operating with the BAR sized to 2 MB
|
||||
// Bit n is set: supports operating with the BAR sized to (2^n) MB
|
||||
//
|
||||
Capabilities = LShiftU64 (Entries[Index].ResizableBarControl.Bits.BarSizeCapability, 28)
|
||||
| Entries[Index].ResizableBarCapability.Bits.BarSizeCapability;
|
||||
|
||||
if (ResizableBarOp == PciResizableBarMax) {
|
||||
Bit = HighBitSet64 (Capabilities);
|
||||
} else {
|
||||
ASSERT (ResizableBarOp == PciResizableBarMin);
|
||||
Bit = LowBitSet64 (Capabilities);
|
||||
}
|
||||
|
||||
ASSERT (Bit >= 0);
|
||||
|
||||
Offset = PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)
|
||||
+ Index * sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY)
|
||||
+ OFFSET_OF (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY, ResizableBarControl);
|
||||
|
||||
Entries[Index].ResizableBarControl.Bits.BarSize = (UINT32)Bit;
|
||||
DEBUG ((DEBUG_VERBOSE, "Resizable Bar: Offset = 0x%x, Bar Size Capability = 0x%016lx, New Bar Size = 0x%lx\n",
|
||||
OFFSET_OF (PCI_TYPE00, Device.Bar[Entries[Index].ResizableBarControl.Bits.BarIndex]),
|
||||
Capabilities,
|
||||
LShiftU64 (SIZE_1MB, Bit)));
|
||||
PciExpressWrite32 (PciIoDevice->Address + Offset, Entries[Index].ResizableBarControl.Uint32);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize Resizable BAR
|
||||
|
||||
@param[in,out] PciIoDevice Pointer to instance of PCI_IO_DEVICE.
|
||||
|
||||
**/
|
||||
VOID
|
||||
InitializeResizeBar (
|
||||
IN OUT PCI_IO_DEVICE *PciIoDevice
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
PciIoDevice->ResizableBarOffset = 0;
|
||||
Status = LocatePciExpressCapabilityRegBlock (
|
||||
PciIoDevice,
|
||||
PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID,
|
||||
&PciIoDevice->ResizableBarOffset
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL ResizableBarControl;
|
||||
UINT32 Offset;
|
||||
|
||||
Offset = PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER) +
|
||||
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY);
|
||||
ResizableBarControl.Uint32 = PciExpressRead32(PciIoDevice->Address + Offset);
|
||||
PciIoDevice->ResizableBarNumber = ResizableBarControl.Bits.ResizableBarNumber;
|
||||
DEBUG ((DEBUG_VERBOSE, "PciResizableBarNumber %d ResizableBarControl %x \n", PciIoDevice->ResizableBarNumber, ResizableBarControl.Uint32));
|
||||
PciProgramResizableBar (PciIoDevice, PciResizableBarMax);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue