On Wed, Sep 15, 2021 at 22:55:27 +0700, Nhi Pham wrote: > From: Vu Nguyen <vungu...@os.amperecomputing.com> > > This screen provide menu options to configure Max Payload and Max Read > Request size for each PCIe device under Root Port. PCIe devices which > attach to external switch are not supported yet. > > Cc: Thang Nguyen <th...@os.amperecomputing.com> > Cc: Chuong Tran <chu...@os.amperecomputing.com> > Cc: Phong Vo <ph...@os.amperecomputing.com> > Cc: Leif Lindholm <l...@nuviainc.com> > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> > Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> > > Signed-off-by: Vu Nguyen <vungu...@os.amperecomputing.com>
Reviewed-by: Leif Lindholm <l...@nuviainc.com> > --- > Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > | 3 + > Platform/Ampere/JadePkg/Jade.dsc > | 1 + > Platform/Ampere/JadePkg/Jade.fdf > | 1 + > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.inf > | 59 ++ > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.h > | 78 ++ > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.h > | 56 ++ > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.h > | 58 ++ > Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformPcieDeviceConfigHii.h > | 19 + > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.vfr > | 50 + > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.c > | 1045 ++++++++++++++++++++ > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.c > | 191 ++++ > > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.uni > | 24 + > 12 files changed, 1585 insertions(+) > > diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > index b0e1f3ec6f2a..6ce545fda8dd 100644 > --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > @@ -59,6 +59,9 @@ [Guids] > # GUID for the Watchdog HII configuration form > gWatchdogConfigFormSetGuid = { 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, > 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } } > > + # GUID for the Pcie Device HII configuration form > + gPlatformPcieDeviceConfigFormSetGuid = { 0xEC7B1D21, 0x9167, 0x4B9D, { > 0xF7, 0x94, 0xCD, 0x1A, 0xEB, 0xBC, 0xB7, 0x59 } } > + > ## NVParam MM GUID > gNVParamMmGuid = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, > 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } } > > diff --git a/Platform/Ampere/JadePkg/Jade.dsc > b/Platform/Ampere/JadePkg/Jade.dsc > index b752ea3e5264..9db1cf316249 100644 > --- a/Platform/Ampere/JadePkg/Jade.dsc > +++ b/Platform/Ampere/JadePkg/Jade.dsc > @@ -202,3 +202,4 @@ [Components.common] > Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf > Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf > > Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf > + > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.inf > diff --git a/Platform/Ampere/JadePkg/Jade.fdf > b/Platform/Ampere/JadePkg/Jade.fdf > index 8f3df6ccf01b..ae444d702bbe 100644 > --- a/Platform/Ampere/JadePkg/Jade.fdf > +++ b/Platform/Ampere/JadePkg/Jade.fdf > @@ -360,5 +360,6 @@ [FV.FvMain] > INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf > INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf > INF > Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf > + INF > Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.inf > > !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.inf > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.inf > new file mode 100644 > index 000000000000..79d7bd185b7d > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.inf > @@ -0,0 +1,59 @@ > +## @file > +# > +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = PlatformPcieDeviceConfigDxe > + FILE_GUID = 17E9369D-0A1B-45F4-A286-B1DED6D85D33 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = PlatformPcieDeviceConfigEntryPoint > + > +[Sources.common] > + PlatformPcieDeviceConfigDxe.c > + PlatformPcieDeviceConfigDxe.h > + PlatformPcieDeviceConfigDxe.uni > + PlatformPcieDeviceConfigVfr.h > + PlatformPcieDeviceConfigVfr.vfr > + PlatformPcieHelper.c > + PlatformPcieHelper.h > + > +[Packages] > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + DevicePathLib > + HiiLib > + MemoryAllocationLib > + PrintLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + UefiLib > + UefiRuntimeServicesTableLib > + > +[Protocols] > + gEfiPciIoProtocolGuid > + gEfiDevicePathProtocolGuid ## CONSUMES > + gEfiHiiConfigRoutingProtocolGuid ## CONSUMES > + gEfiHiiConfigAccessProtocolGuid ## PRODUCES > + gEfiDevicePathToTextProtocolGuid > + > +[Guids] > + gEfiIfrTianoGuid > + gPlatformPcieDeviceConfigFormSetGuid > + gPlatformManagerFormsetGuid > + gPlatformManagerEntryEventGuid > + > +[Depex] > + TRUE > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.h > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.h > new file mode 100644 > index 000000000000..a39257da06ba > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.h > @@ -0,0 +1,78 @@ > +/** @file > + > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PLATFORM_PCIE_DEVICE_CONFIG_H_ > +#define PLATFORM_PCIE_DEVICE_CONFIG_H_ > + > +#include <Uefi.h> > + > +#include <Library/HiiLib.h> > +#include <Protocol/HiiConfigAccess.h> > +#include <Protocol/HiiConfigKeyword.h> > +#include <Protocol/HiiConfigRouting.h> > +#include <Protocol/HiiDatabase.h> > +#include <Protocol/HiiString.h> > + > +#include "PlatformPcieDeviceConfigVfr.h" > + > +#define MAX_STRING_SIZE 100 > + > +#define PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'E', 'D', 'C') > +#define PRIVATE_DATA_FROM_THIS(a) \ > + CR (a, PRIVATE_DATA, ConfigAccess, PRIVATE_DATA_SIGNATURE) > + > +#pragma pack(1) > + > +/// > +/// HII specific Vendor Device Path definition. > +/// > +typedef struct { > + VENDOR_DEVICE_PATH VendorDevicePath; > + EFI_DEVICE_PATH_PROTOCOL End; > +} HII_VENDOR_DEVICE_PATH; > + > +#pragma pack() > + > +// > +// This is the generated IFR binary data for each formset defined in VFR. > +// This data array is ready to be used as input of HiiAddPackages() to > +// create a packagelist (which contains Form packages, String packages, etc). > +// > +extern UINT8 PlatformPcieDeviceConfigVfrBin[]; > + > +// > +// This is the generated String package data for all .UNI files. > +// This data array is ready to be used as input of HiiAddPackages() to > +// create a packagelist (which contains Form packages, String packages, etc). > +// > +extern UINT8 PlatformPcieDeviceConfigDxeStrings[]; > + > +typedef struct { > + UINTN Signature; > + > + EFI_HANDLE DriverHandle; > + EFI_HII_HANDLE HiiHandle; > + VARSTORE_DATA LastVarStoreConfig; > + VARSTORE_DATA VarStoreConfig; > + > + // > + // Consumed protocol > + // > + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; > + EFI_HII_STRING_PROTOCOL *HiiString; > + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; > + EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; > + EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; > + > + // > + // Produced protocol > + // > + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; > +} PRIVATE_DATA; > + > +#endif // PLATFORM_PCIE_DEVICE_CONFIG_H_ > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.h > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.h > new file mode 100644 > index 000000000000..ee4469ea5a2a > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.h > @@ -0,0 +1,56 @@ > +/** @file > + > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PLATFORM_PCIE_DEVICE_CONFIG_VFR_H_ > +#define PLATFORM_PCIE_DEVICE_CONFIG_VFR_H_ > + > +#include <Guid/PlatformPcieDeviceConfigHii.h> > + > +#define VARSTORE_NAME L"PlatformPcieDeviceConfigNVData" > + > +#define MAIN_FORM_ID 0x01 > +#define DEVICE_FORM_ID 0x02 > +#define VARSTORE_ID 0x03 > + > +#define MAIN_LABEL_UPDATE 0x21 > +#define MAIN_LABEL_END 0x22 > +#define DEVICE_LABEL_UPDATE 0x31 > +#define DEVICE_LABEL_END 0x32 > + > +#define DEVICE_KEY 0x6000 > +#define MPS_ONE_OF_KEY 0x7000 > +#define MRR_ONE_OF_KEY 0x8000 > + > +#define MAX_DEVICE 40 > + > +#define DEFAULT_MPS 0x00 // Section 7.5.3.4 > +#define DEFAULT_MRR 0x02 // Section 7.5.3.4 > + > +#define PCIE_ADD(Vid, Did, Seg, Bus, Dev) \ > + (UINT64)(Vid) << 40 | (UINT64)(Did) << 24 | Seg << 16 | Bus << 8 | > Dev; > + > +#pragma pack(1) > + > +typedef struct { > + UINT8 DEV; > + UINT8 BUS; > + UINT8 SEG; > + UINT16 DID; > + UINT16 VID; > + UINT8 SlotId; > +} SLOT_INFO; > + > +typedef struct { > + UINT8 MPS[MAX_DEVICE]; > + UINT8 MRR[MAX_DEVICE]; > + UINT64 SlotInfo[MAX_DEVICE]; > +} VARSTORE_DATA; > + > +#pragma pack() > + > +#endif /* PLATFORM_PCIE_DEVICE_CONFIG_VFR_H_ */ > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.h > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.h > new file mode 100644 > index 000000000000..56aed0379539 > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.h > @@ -0,0 +1,58 @@ > +/** @file > + > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PLATFORM_PCIE_HELPER_H_ > +#define PLATFORM_PCIE_HELPER_H_ > + > +#define PCIE_MAX_PAYLOAD_MASK 0x07 > +#define PCIE_CONTROL_MAX_PAYLOAD_OFF 5 > +#define PCIE_MAX_READ_REQUEST_MASK 0x07 > +#define PCIE_CONTROL_READ_REQUEST_OFF 12 > + > +#define PCI_EXPRESS_CAPABILITY_DEVICE_CAPABILITIES_REG 0x04 > +#define PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG 0x08 > + > +#define FOR_EACH(Node, Tail, Type) \ > + for (Node = Tail->Type; Node != NULL; Node = Node->Type) > + > +struct _PCIE_NODE { > + EFI_PCI_IO_PROTOCOL *PciIo; > + UINT8 MaxMps; > + UINT8 PcieCapOffset; > + UINT16 Vid; > + UINT16 Did; > + UINT8 Seg; > + UINT8 Bus; > + UINT8 Dev; > + UINT8 Fun; > + struct _PCIE_NODE *Parent; > + struct _PCIE_NODE *Brother; > +}; > + > +typedef struct _PCIE_NODE PCIE_NODE; > + > +EFI_STATUS > +WriteMps ( > + PCIE_NODE *Node, > + UINT8 Value > + ); > + > +EFI_STATUS > +WriteMrr ( > + PCIE_NODE *Node, > + UINT8 Value > + ); > + > +EFI_STATUS > +FindCapabilityPtr ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 CapabilityId, > + OUT UINT8 *CapabilityPtr > + ); > + > +#endif // PLATFORM_PCIE_HELPER_H_ > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformPcieDeviceConfigHii.h > b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformPcieDeviceConfigHii.h > new file mode 100644 > index 000000000000..ed592a0027ed > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformPcieDeviceConfigHii.h > @@ -0,0 +1,19 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PLATFORM_PCIE_DEVICE_CONFIG_HII_H_ > +#define PLATFORM_PCIE_DEVICE_CONFIG_HII_H_ > + > +#define PLATFORM_PCIE_DEVICE_CONFIG_FORMSET_GUID \ > + { \ > + 0xEC7B1D21, 0x9167, 0x4B9D, { 0xF7, 0x94, 0xCD, 0x1A, 0xEB, 0xBC, 0xB7, > 0x59 } \ > + } > + > +extern EFI_GUID gPlatformPcieDeviceConfigFormSetGuid; > + > +#endif /* PLATFORM_PCIE_DEVICE_CONFIG_HII_H_ */ > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.vfr > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.vfr > new file mode 100644 > index 000000000000..27ca33164e23 > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigVfr.vfr > @@ -0,0 +1,50 @@ > +/** @file > + > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Guid/PlatformManagerHii.h> > +#include "PlatformPcieDeviceConfigVfr.h" > + > +formset > + guid = PLATFORM_PCIE_DEVICE_CONFIG_FORMSET_GUID, > + title = STRING_TOKEN(STR_DEVICE_CONFIG_FORM), > + help = STRING_TOKEN(STR_DEVICE_CONFIG_HELP), > + classguid = gPlatformManagerFormsetGuid, > + > + // > + // Define a variable Storage > + // > + varstore VARSTORE_DATA, > + varid = VARSTORE_ID, > + name = PlatformPcieDeviceConfigNVData, > + guid = PLATFORM_PCIE_DEVICE_CONFIG_FORMSET_GUID; > + > + form > + formid = MAIN_FORM_ID, > + title = STRING_TOKEN(STR_DEVICE_CONFIG_FORM); > + > + subtitle text = STRING_TOKEN(STR_DEVICE_CONFIG_FORM); > + > + label MAIN_LABEL_UPDATE; > + // dynamic content here > + label MAIN_LABEL_END; > + > + endform; > + > + form > + formid = DEVICE_FORM_ID, > + title = STRING_TOKEN(STR_DEVICE_FORM); > + > + subtitle text = STRING_TOKEN(STR_DEVICE_FORM); > + > + label DEVICE_LABEL_UPDATE; > + // dynamic content here > + label DEVICE_LABEL_END; > + > + endform; > + > +endformset; > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.c > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.c > new file mode 100644 > index 000000000000..b06014529c7b > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.c > @@ -0,0 +1,1045 @@ > +/** @file > + > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <Guid/MdeModuleHii.h> > +#include <Guid/PlatformPcieDeviceConfigHii.h> > +#include <IndustryStandard/Pci.h> > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/DevicePathLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/PrintLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/UefiLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > +#include <Protocol/HiiConfigAccess.h> > +#include <Protocol/PciIo.h> > + > +#include "PlatformPcieDeviceConfigDxe.h" > +#include "PlatformPcieHelper.h" > + > +VOID *mPciProtocolNotifyRegistration; > +CHAR16 *mVariableName = VARSTORE_NAME; > +PCIE_NODE *mDeviceBuf[MAX_DEVICE] = {NULL}; > + > +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = { > + { > + { > + HARDWARE_DEVICE_PATH, > + HW_VENDOR_DP, > + { > + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), > + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) > + } > + }, > + PLATFORM_PCIE_DEVICE_CONFIG_FORMSET_GUID > + }, > + { > + END_DEVICE_PATH_TYPE, > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > + { > + (UINT8)(END_DEVICE_PATH_LENGTH), > + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) > + } > + } > +}; > + > +VOID > +FlushDeviceData ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_STATUS Status; > + PCIE_NODE *Node; > + PRIVATE_DATA *PrivateData; > + UINT8 Index; > + VARSTORE_DATA *LastVarStoreConfig; > + VARSTORE_DATA *VarStoreConfig; > + > + PrivateData = (PRIVATE_DATA *)Context; > + LastVarStoreConfig = &PrivateData->LastVarStoreConfig; > + VarStoreConfig = &PrivateData->VarStoreConfig; > + > + // > + // If config has changed, update NVRAM > + // > + if (CompareMem (VarStoreConfig, LastVarStoreConfig, sizeof > (VARSTORE_DATA)) != 0) { > + DEBUG ((DEBUG_INFO, "%a Update Device Config Variable\n", __FUNCTION__)); > + Status = gRT->SetVariable ( > + mVariableName, > + &gPlatformPcieDeviceConfigFormSetGuid, > + EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_BOOTSERVICE_ACCESS, > + sizeof (VARSTORE_DATA), > + VarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: Failed to set variable status %r", > + __FUNCTION__, > + Status > + )); > + return; > + } > + } > + > + // Iterate through the list, then write corresponding MPS MRR > + for (Index = 0; Index < MAX_DEVICE; Index++) { > + if (mDeviceBuf[Index] == NULL) { > + continue; > + } > + > + // Write MPS value > + WriteMps (mDeviceBuf[Index], VarStoreConfig->MPS[Index]); > + > + FOR_EACH (Node, mDeviceBuf[Index], Parent) { > + WriteMps (Node, VarStoreConfig->MPS[Index]); > + } > + > + FOR_EACH (Node, mDeviceBuf[Index], Brother) { > + WriteMps (Node, VarStoreConfig->MPS[Index]); > + } > + > + // Write MRR value > + // No need to update MRR of parent node > + WriteMrr (mDeviceBuf[Index], VarStoreConfig->MRR[Index]); > + > + FOR_EACH (Node, mDeviceBuf[Index], Brother) { > + WriteMrr (Node, VarStoreConfig->MRR[Index]); > + } > + } > + > + gBS->CloseEvent (Event); > +} > + > +EFI_STATUS > +UpdateDeviceForm ( > + UINT8 Index, > + PRIVATE_DATA *PrivateData > + ) > +{ > + CHAR16 Str[MAX_STRING_SIZE]; > + UINT8 MaxMps; > + > + VOID *StartOpCodeHandle; > + EFI_IFR_GUID_LABEL *StartLabel; > + VOID *EndOpCodeHandle; > + EFI_IFR_GUID_LABEL *EndLabel; > + VOID *MpsOpCodeHandle; > + VOID *MrrOpCodeHandle; > + PCIE_NODE *Node; > + > + if (mDeviceBuf[Index] == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + MaxMps = mDeviceBuf[Index]->MaxMps; > + FOR_EACH (Node, mDeviceBuf[Index], Parent) { > + if (Node->MaxMps < MaxMps) { > + MaxMps = Node->MaxMps; > + } > + } > + > + UnicodeSPrint ( > + Str, > + sizeof (Str), > + L"PCIe Device 0x%04x:0x%04x", > + mDeviceBuf[Index]->Vid, > + mDeviceBuf[Index]->Did > + ); > + > + HiiSetString ( > + PrivateData->HiiHandle, > + STRING_TOKEN (STR_DEVICE_FORM), > + Str, > + NULL > + ); > + > + // > + // Initialize the container for dynamic opcodes > + // > + StartOpCodeHandle = HiiAllocateOpCodeHandle (); > + ASSERT (StartOpCodeHandle != NULL); > + > + EndOpCodeHandle = HiiAllocateOpCodeHandle (); > + ASSERT (EndOpCodeHandle != NULL); > + > + // > + // Create Hii Extend Label OpCode as the start opcode > + // > + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( > + StartOpCodeHandle, > + &gEfiIfrTianoGuid, > + NULL, > + sizeof (EFI_IFR_GUID_LABEL) > + ); > + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; > + StartLabel->Number = DEVICE_LABEL_UPDATE; > + > + // > + // Create Hii Extend Label OpCode as the end opcode > + // > + EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( > + EndOpCodeHandle, > + &gEfiIfrTianoGuid, > + NULL, > + sizeof (EFI_IFR_GUID_LABEL) > + ); > + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; > + EndLabel->Number = DEVICE_LABEL_END; > + > + // Create Option OpCode for MPS selection > + MpsOpCodeHandle = HiiAllocateOpCodeHandle (); > + ASSERT (MpsOpCodeHandle != NULL); > + > + switch (MaxMps) { > + case 5: > + HiiCreateOneOfOptionOpCode ( > + MpsOpCodeHandle, > + STRING_TOKEN (STR_4096), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 5 > + ); > + > + case 4: > + HiiCreateOneOfOptionOpCode ( > + MpsOpCodeHandle, > + STRING_TOKEN (STR_2048), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 4 > + ); > + > + case 3: > + HiiCreateOneOfOptionOpCode ( > + MpsOpCodeHandle, > + STRING_TOKEN (STR_1024), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 3 > + ); > + > + case 2: > + HiiCreateOneOfOptionOpCode ( > + MpsOpCodeHandle, > + STRING_TOKEN (STR_512), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 2 > + ); > + > + case 1: > + HiiCreateOneOfOptionOpCode ( > + MpsOpCodeHandle, > + STRING_TOKEN (STR_256), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 1 > + ); > + > + case 0: > + HiiCreateOneOfOptionOpCode ( > + MpsOpCodeHandle, > + STRING_TOKEN (STR_128), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 0 > + ); > + } > + > + // Create MPS OneOf > + HiiCreateOneOfOpCode ( > + StartOpCodeHandle, // Container for dynamic created > opcodes > + (MPS_ONE_OF_KEY + Index), // Question ID (or call it "key") > + VARSTORE_ID, // VarStore ID > + Index, // Offset in Buffer Storage > + STRING_TOKEN (STR_PCIE_MPS), // Question prompt text > + STRING_TOKEN (STR_PCIE_MPS_HELP), // Question help text > + EFI_IFR_FLAG_CALLBACK, // Question flag > + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value > + MpsOpCodeHandle, // Option Opcode list > + NULL // Default Opcode is NULl > + ); > + > + // Create Option OpCode for MRR selection > + MrrOpCodeHandle = HiiAllocateOpCodeHandle (); > + ASSERT (MrrOpCodeHandle != NULL); > + > + HiiCreateOneOfOptionOpCode ( > + MrrOpCodeHandle, > + STRING_TOKEN (STR_4096), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 5 > + ); > + > + HiiCreateOneOfOptionOpCode ( > + MrrOpCodeHandle, > + STRING_TOKEN (STR_2048), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 4 > + ); > + > + HiiCreateOneOfOptionOpCode ( > + MrrOpCodeHandle, > + STRING_TOKEN (STR_1024), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 3 > + ); > + > + HiiCreateOneOfOptionOpCode ( > + MrrOpCodeHandle, > + STRING_TOKEN (STR_512), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 2 > + ); > + > + HiiCreateOneOfOptionOpCode ( > + MrrOpCodeHandle, > + STRING_TOKEN (STR_256), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 1 > + ); > + > + HiiCreateOneOfOptionOpCode ( > + MrrOpCodeHandle, > + STRING_TOKEN (STR_128), > + 0, > + EFI_IFR_NUMERIC_SIZE_1, > + 0 > + ); > + > + // Create MRR OneOf > + HiiCreateOneOfOpCode ( > + StartOpCodeHandle, // Container for dynamic created > opcodes > + (MRR_ONE_OF_KEY + Index), // Question ID (or call it "key") > + VARSTORE_ID, // VarStore ID > + MAX_DEVICE + Index, // Offset in Buffer Storage > + STRING_TOKEN (STR_PCIE_MRR), // Question prompt text > + STRING_TOKEN (STR_PCIE_MRR_HELP), // Question help text > + EFI_IFR_FLAG_CALLBACK, // Question flag > + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value > + MrrOpCodeHandle, // Option Opcode list > + NULL // Default Opcode is NULl > + ); > + > + HiiUpdateForm ( > + PrivateData->HiiHandle, // HII handle > + &gPlatformPcieDeviceConfigFormSetGuid, // Formset GUID > + DEVICE_FORM_ID, // Form ID > + StartOpCodeHandle, // Label for where to insert opcodes > + EndOpCodeHandle // Insert data > + ); > + > + HiiFreeOpCodeHandle (StartOpCodeHandle); > + HiiFreeOpCodeHandle (EndOpCodeHandle); > + HiiFreeOpCodeHandle (MpsOpCodeHandle); > + HiiFreeOpCodeHandle (MrrOpCodeHandle); > + return EFI_SUCCESS; > +} > + > +VOID > +OnPciIoProtocolNotify ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_PCI_IO_PROTOCOL *PciIo; > + EFI_STATUS Status; > + EFI_HANDLE HandleBuffer; > + PCI_TYPE00 Pci; > + > + UINTN BufferSize; > + UINTN PciBusNumber; > + UINTN PciDeviceNumber; > + UINTN PciFunctionNumber; > + UINTN PciSegment; > + > + UINT8 Idx; > + UINT8 CapabilityPtr; > + UINT16 TmpValue; > + UINT64 SlotInfo; > + > + PCIE_NODE *Node; > + PRIVATE_DATA *PrivateData; > + STATIC PCIE_NODE *LastNode; > + STATIC UINT8 Index; > + STATIC UINT8 LastBus; > + > + VARSTORE_DATA *LastVarStoreConfig; > + VARSTORE_DATA *VarStoreConfig; > + > + PrivateData = (PRIVATE_DATA *)Context; > + LastVarStoreConfig = &PrivateData->LastVarStoreConfig; > + VarStoreConfig = &PrivateData->VarStoreConfig; > + > + while (TRUE) { > + BufferSize = sizeof (EFI_HANDLE); > + Status = gBS->LocateHandle ( > + ByRegisterNotify, > + NULL, > + mPciProtocolNotifyRegistration, > + &BufferSize, > + &HandleBuffer > + ); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + Status = gBS->HandleProtocol ( > + HandleBuffer, > + &gEfiPciIoProtocolGuid, > + (VOID **)&PciIo > + ); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + // Get device bus location > + Status = PciIo->GetLocation ( > + PciIo, > + &PciSegment, > + &PciBusNumber, > + &PciDeviceNumber, > + &PciFunctionNumber > + ); > + if (EFI_ERROR (Status) || > + ((PciBusNumber == 0) && (PciDeviceNumber == 0))) > + { > + // Filter out Host Bridge > + DEBUG ((DEBUG_INFO, "Filter out Host Bridge %x\n", PciSegment)); > + continue; > + } > + > + DEBUG (( > + DEBUG_INFO, > + ">> Dev 0x%04x:0x%02x:0x%02x:0x%02x\n", > + PciSegment, > + PciBusNumber, > + PciDeviceNumber, > + PciFunctionNumber > + )); > + > + Status = FindCapabilityPtr (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP, > &CapabilityPtr); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: PCI Express Capability not found\n", > + __FUNCTION__ > + )); > + continue; > + } > + > + // Get Device's max MPS support > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + CapabilityPtr + > PCI_EXPRESS_CAPABILITY_DEVICE_CAPABILITIES_REG, > + 1, > + &TmpValue > + ); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + // Read device's VID:PID > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint32, > + 0, > + sizeof (Pci) / sizeof (UINT32), > + &Pci > + ); > + if (EFI_ERROR (Status)) { > + continue; > + } > + DEBUG (( > + DEBUG_INFO, > + "VendorId 0x%04x - DeviceId 0x%04x\n", > + Pci.Hdr.VendorId, > + Pci.Hdr.DeviceId > + )); > + > + Node = AllocateZeroPool (sizeof (*Node)); > + Node->MaxMps = TmpValue & PCIE_MAX_PAYLOAD_MASK; > + Node->PcieCapOffset = CapabilityPtr; > + Node->PciIo = PciIo; > + Node->Seg = PciSegment; > + Node->Bus = PciBusNumber; > + Node->Dev = PciDeviceNumber; > + Node->Fun = PciFunctionNumber; > + Node->Vid = Pci.Hdr.VendorId; > + Node->Did = Pci.Hdr.DeviceId; > + SlotInfo = PCIE_ADD (Node->Vid, Node->Did, Node->Seg, Node->Bus, > Node->Dev); > + > + // Presume child devices were registered follow root port > + if (PciBusNumber != 0) { > + if (LastBus == 0) { > + Node->Parent = LastNode; > + mDeviceBuf[Index] = Node; > + > + VarStoreConfig->MPS[Index] = DEFAULT_MPS; > + VarStoreConfig->MRR[Index] = DEFAULT_MRR; > + VarStoreConfig->SlotInfo[Index] = SlotInfo; > + > + // Retrieve setting from previous variable > + for (Idx = 0; Idx < MAX_DEVICE; Idx++) { > + if (SlotInfo == LastVarStoreConfig->SlotInfo[Idx]) { > + VarStoreConfig->MPS[Index] = LastVarStoreConfig->MPS[Idx]; > + VarStoreConfig->MRR[Index] = LastVarStoreConfig->MRR[Idx]; > + break; > + } > + } > + > + Index++; > + } else if (PciBusNumber == LastBus) { > + LastNode->Brother = Node; > + } else { > + // Ignore devices don't stay under root port > + continue; > + } > + } > + > + LastBus = PciBusNumber; > + LastNode = Node; > + } > +} > + > +VOID > +UpdateMainForm ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + UINTN Index; > + EFI_STRING_ID StrId; > + CHAR16 Str[MAX_STRING_SIZE]; > + VOID *StartOpCodeHandle; > + EFI_IFR_GUID_LABEL *StartLabel; > + VOID *EndOpCodeHandle; > + EFI_IFR_GUID_LABEL *EndLabel; > + PRIVATE_DATA *PrivateData; > + > + DEBUG ((DEBUG_INFO, "%a Entry ...\n", __FUNCTION__)); > + > + PrivateData = (PRIVATE_DATA *)Context; > + > + // > + // Initialize the container for dynamic opcodes > + // > + StartOpCodeHandle = HiiAllocateOpCodeHandle (); > + ASSERT (StartOpCodeHandle != NULL); > + > + EndOpCodeHandle = HiiAllocateOpCodeHandle (); > + ASSERT (EndOpCodeHandle != NULL); > + > + // > + // Create Hii Extend Label OpCode as the start opcode > + // > + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( > + StartOpCodeHandle, > + &gEfiIfrTianoGuid, > + NULL, > + sizeof (EFI_IFR_GUID_LABEL) > + ); > + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; > + StartLabel->Number = MAIN_LABEL_UPDATE; > + > + // > + // Create Hii Extend Label OpCode as the end opcode > + // > + EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( > + EndOpCodeHandle, > + &gEfiIfrTianoGuid, > + NULL, > + sizeof (EFI_IFR_GUID_LABEL) > + ); > + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; > + EndLabel->Number = MAIN_LABEL_END; > + > + for (Index = 0; Index < MAX_DEVICE; Index++) { > + if (mDeviceBuf[Index] == NULL) { > + break; > + } > + DEBUG ((DEBUG_INFO, ">> Add item %d\n", Index)); > + > + UnicodeSPrint ( > + Str, > + sizeof (Str), > + L"PCIe Device 0x%04x:0x%04x - %04x:%02x:%02x", > + mDeviceBuf[Index]->Vid, > + mDeviceBuf[Index]->Did, > + mDeviceBuf[Index]->Seg, > + mDeviceBuf[Index]->Bus, > + mDeviceBuf[Index]->Dev > + ); > + > + StrId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL); > + > + // > + // Create a Goto OpCode to device configuration > + // > + HiiCreateGotoOpCode ( > + StartOpCodeHandle, // Container for dynamic created > opcodes > + DEVICE_FORM_ID, // Target Form ID > + StrId, // Prompt text > + STRING_TOKEN (STR_DEVICE_GOTO_HELP), // Help text > + EFI_IFR_FLAG_CALLBACK, // Question flag > + (DEVICE_KEY + Index) // Question ID > + ); > + } > + > + HiiUpdateForm ( > + PrivateData->HiiHandle, // HII handle > + &gPlatformPcieDeviceConfigFormSetGuid, // Formset GUID > + MAIN_FORM_ID, // Form ID > + StartOpCodeHandle, // Label for where to insert opcodes > + EndOpCodeHandle // Insert data > + ); > + > + HiiFreeOpCodeHandle (StartOpCodeHandle); > + HiiFreeOpCodeHandle (EndOpCodeHandle); > + > + gBS->CloseEvent (Event); > +} > + > +EFI_STATUS > +EFIAPI > +ExtractConfig ( > + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, > + IN CONST EFI_STRING Request, > + OUT EFI_STRING *Progress, > + OUT EFI_STRING *Results > + ) > +{ > + EFI_STATUS Status; > + UINTN BufferSize; > + PRIVATE_DATA *PrivateData; > + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; > + EFI_STRING ConfigRequest; > + EFI_STRING ConfigRequestHdr; > + UINTN Size; > + CHAR16 *StrPointer; > + BOOLEAN AllocatedRequest; > + VARSTORE_DATA *VarStoreConfig; > + > + if (Progress == NULL || Results == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + // > + // Initialize the local variables. > + // > + ConfigRequestHdr = NULL; > + ConfigRequest = NULL; > + Size = 0; > + *Progress = Request; > + AllocatedRequest = FALSE; > + > + PrivateData = PRIVATE_DATA_FROM_THIS (This); > + HiiConfigRouting = PrivateData->HiiConfigRouting; > + VarStoreConfig = &PrivateData->VarStoreConfig; > + ASSERT (VarStoreConfig != NULL); > + > + BufferSize = sizeof (VARSTORE_DATA); > + > + if (Request == NULL) { > + // > + // Request is set to NULL, construct full request string. > + // > + > + // > + // Allocate and fill a buffer large enough to hold the <ConfigHdr> > template > + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a > + // Null-terminator > + // > + ConfigRequestHdr = HiiConstructConfigHdr ( > + &gPlatformPcieDeviceConfigFormSetGuid, > + mVariableName, > + PrivateData->DriverHandle > + ); > + if (ConfigRequestHdr == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); > + ConfigRequest = AllocateZeroPool (Size); > + ASSERT (ConfigRequest != NULL); > + AllocatedRequest = TRUE; > + UnicodeSPrint ( > + ConfigRequest, > + Size, > + L"%s&OFFSET=0&WIDTH=%016LX", > + ConfigRequestHdr, > + (UINT64)BufferSize > + ); > + FreePool (ConfigRequestHdr); > + ConfigRequestHdr = NULL; > + } else { > + // > + // Check routing data in <ConfigHdr>. > + // Note: if only one Storage is used, then this checking could be > skipped. > + // > + if (!HiiIsConfigHdrMatch (Request, > &gPlatformPcieDeviceConfigFormSetGuid, NULL)) { > + return EFI_NOT_FOUND; > + } > + // > + // Set Request to the unified request string. > + // > + ConfigRequest = Request; > + > + // > + // Check whether Request includes Request Element. > + // > + if (StrStr (Request, L"OFFSET") == NULL) { > + // > + // Check Request Element does exist in Request String > + // > + StrPointer = StrStr (Request, L"PATH"); > + if (StrPointer == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + if (StrStr (StrPointer, L"&") == NULL) { > + Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16); > + ConfigRequest = AllocateZeroPool (Size); > + ASSERT (ConfigRequest != NULL); > + AllocatedRequest = TRUE; > + UnicodeSPrint ( > + ConfigRequest, > + Size, > + L"%s&OFFSET=0&WIDTH=%016LX", > + Request, > + (UINT64)BufferSize > + ); > + } > + } > + } > + // > + // Check if requesting Name/Value storage > + // > + if (StrStr (ConfigRequest, L"OFFSET") == NULL) { > + // > + // Don't have any Name/Value storage names > + // > + Status = EFI_SUCCESS; > + } else { > + // > + // Convert buffer data to <ConfigResp> by helper function BlockToConfig() > + // > + Status = HiiConfigRouting->BlockToConfig ( > + HiiConfigRouting, > + ConfigRequest, > + (UINT8 *)VarStoreConfig, > + BufferSize, > + Results, > + Progress > + ); > + } > + // > + // Free the allocated config request string. > + // > + if (AllocatedRequest) { > + FreePool (ConfigRequest); > + } > + if (ConfigRequestHdr != NULL) { > + FreePool (ConfigRequestHdr); > + } > + // > + // Set Progress string to the original request string. > + // > + if (Request == NULL) { > + *Progress = NULL; > + } else if (StrStr (Request, L"OFFSET") == NULL) { > + *Progress = Request + StrLen (Request); > + } > + return Status; > +} > + > +/** > + This function processes the results of changes in configuration. > + @param This Points to the > EFI_HII_CONFIG_ACCESS_PROTOCOL. > + @param Configuration A null-terminated Unicode string in > <ConfigResp> > + format. > + @param Progress A pointer to a string filled in with the > offset of > + the most recent '&' before the first failing > + name/value pair (or the beginning of the > string if > + the failure is in the first name/value > pair) or > + the terminating NULL if all was successful. > + @retval EFI_SUCCESS The Results is processed successfully. > + @retval EFI_INVALID_PARAMETER Configuration is NULL. > + @retval EFI_NOT_FOUND Routing data doesn't match any storage in > this > + driver. > +**/ > +EFI_STATUS > +EFIAPI > +RouteConfig ( > + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, > + IN CONST EFI_STRING Configuration, > + OUT EFI_STRING *Progress > + ) > +{ > + EFI_STATUS Status; > + UINTN BufferSize; > + PRIVATE_DATA *PrivateData; > + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; > + VARSTORE_DATA *VarStoreConfig; > + > + if (Configuration == NULL || Progress == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + PrivateData = PRIVATE_DATA_FROM_THIS (This); > + HiiConfigRouting = PrivateData->HiiConfigRouting; > + *Progress = Configuration; > + VarStoreConfig = &PrivateData->VarStoreConfig; > + ASSERT (VarStoreConfig != NULL); > + > + // > + // Check routing data in <ConfigHdr>. > + // Note: if only one Storage is used, then this checking could be skipped. > + // > + if (!HiiIsConfigHdrMatch ( > + Configuration, > + &gPlatformPcieDeviceConfigFormSetGuid, > + NULL > + )) > + { > + return EFI_NOT_FOUND; > + } > + > + // > + // Check if configuring Name/Value storage > + // > + if (StrStr (Configuration, L"OFFSET") == NULL) { > + // > + // Don't have any Name/Value storage names > + // > + return EFI_SUCCESS; > + } > + // > + // Convert <ConfigResp> to buffer data by helper function ConfigToBlock() > + // > + BufferSize = sizeof (VARSTORE_DATA); > + Status = HiiConfigRouting->ConfigToBlock ( > + HiiConfigRouting, > + Configuration, > + (UINT8 *)VarStoreConfig, > + &BufferSize, > + Progress > + ); > + > + return Status; > +} > + > +/** > + This function processes the results of changes in configuration. > + @param This Points to the > EFI_HII_CONFIG_ACCESS_PROTOCOL. > + @param Action Specifies the type of action taken by the > browser. > + @param QuestionId A unique value which is sent to the original > + exporting driver so that it can identify > the type > + of data to expect. > + @param Type The type of value for the question. > + @param Value A pointer to the data being sent to the > original > + exporting driver. > + @param ActionRequest On return, points to the action requested > by the > + callback function. > + @retval EFI_SUCCESS The callback successfully handled the > action. > + @retval EFI_INVALID_PARAMETER Configuration is NULL. > + @retval EFI_UNSUPPORTED The specified Action is not supported by the > + callback. > +**/ > +EFI_STATUS > +EFIAPI > +DriverCallback ( > + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, > + IN EFI_BROWSER_ACTION Action, > + IN EFI_QUESTION_ID QuestionId, > + IN UINT8 Type, > + IN EFI_IFR_TYPE_VALUE *Value, > + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest > + ) > +{ > + EFI_STATUS Status; > + PRIVATE_DATA *PrivateData; > + > + if (((Value == NULL) && > + (Action != EFI_BROWSER_ACTION_FORM_OPEN) && > + (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) || > + (ActionRequest == NULL)) > + { > + return EFI_INVALID_PARAMETER; > + } > + > + PrivateData = PRIVATE_DATA_FROM_THIS (This); > + > + switch (Action) { > + case EFI_BROWSER_ACTION_CHANGING: > + if ((QuestionId >= DEVICE_KEY) > + & (QuestionId <= (DEVICE_KEY + MAX_DEVICE))) > + { > + Status = UpdateDeviceForm (QuestionId - DEVICE_KEY, PrivateData); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } > + break; > + > + case EFI_BROWSER_ACTION_DEFAULT_STANDARD: > + case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING: > + if ((QuestionId >= MPS_ONE_OF_KEY) > + & (QuestionId <= (MPS_ONE_OF_KEY + MAX_DEVICE))) > + { > + Value->u8 = DEFAULT_MPS; > + } > + > + if ((QuestionId >= MRR_ONE_OF_KEY) > + & (QuestionId <= (MRR_ONE_OF_KEY + MAX_DEVICE))) > + { > + Value->u8 = DEFAULT_MRR; > + } > + break; > + > + case EFI_BROWSER_ACTION_SUBMITTED: > + break; > + } > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +EFIAPI > +PlatformPcieDeviceConfigEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_HANDLE DriverHandle; > + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; > + EFI_HII_HANDLE HiiHandle; > + EFI_STATUS Status; > + EFI_EVENT PlatformUiEntryEvent; > + EFI_EVENT FlushDeviceEvent; > + EFI_EVENT PciProtocolNotifyEvent; > + PRIVATE_DATA *PrivateData; > + UINTN BufferSize; > + > + DriverHandle = NULL; > + PrivateData = AllocateZeroPool (sizeof (*PrivateData)); > + if (PrivateData == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + PrivateData->Signature = PRIVATE_DATA_SIGNATURE; > + > + PrivateData->ConfigAccess.ExtractConfig = ExtractConfig; > + PrivateData->ConfigAccess.RouteConfig = RouteConfig; > + PrivateData->ConfigAccess.Callback = DriverCallback; > + > + // > + // Locate ConfigRouting protocol > + // > + Status = gBS->LocateProtocol ( > + &gEfiHiiConfigRoutingProtocolGuid, > + NULL, > + (VOID **)&HiiConfigRouting > + ); > + if (EFI_ERROR (Status)) { > + goto Exit; > + } > + PrivateData->HiiConfigRouting = HiiConfigRouting; > + > + Status = gBS->InstallMultipleProtocolInterfaces ( > + &DriverHandle, > + &gEfiDevicePathProtocolGuid, > + &mHiiVendorDevicePath, > + &gEfiHiiConfigAccessProtocolGuid, > + &PrivateData->ConfigAccess, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + goto Exit; > + } > + > + PrivateData->DriverHandle = DriverHandle; > + > + // > + // Publish our HII data > + // > + HiiHandle = HiiAddPackages ( > + &gPlatformPcieDeviceConfigFormSetGuid, > + DriverHandle, > + PlatformPcieDeviceConfigDxeStrings, > + PlatformPcieDeviceConfigVfrBin, > + NULL > + ); > + if (HiiHandle == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + goto Exit; > + } > + PrivateData->HiiHandle = HiiHandle; > + > + // Event to fixup screen > + Status = gBS->CreateEventEx ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + UpdateMainForm, > + (VOID *)PrivateData, > + &gPlatformManagerEntryEventGuid, > + &PlatformUiEntryEvent > + ); > + if (EFI_ERROR (Status)) { > + goto Exit; > + } > + > + // Event to collect PciIo > + PciProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( > + &gEfiPciIoProtocolGuid, > + TPL_CALLBACK, > + OnPciIoProtocolNotify, > + (VOID *)PrivateData, > + &mPciProtocolNotifyRegistration > + ); > + ASSERT (PciProtocolNotifyEvent != NULL); > + > + // Event to flush device data > + Status = gBS->CreateEventEx ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + FlushDeviceData, > + (VOID *)PrivateData, > + &gEfiEventReadyToBootGuid, > + &FlushDeviceEvent > + ); > + if (EFI_ERROR (Status)) { > + goto Exit; > + } > + > + // Verify varstore > + BufferSize = sizeof (VARSTORE_DATA); > + Status = gRT->GetVariable ( > + mVariableName, > + &gPlatformPcieDeviceConfigFormSetGuid, > + NULL, > + &BufferSize, > + &PrivateData->LastVarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Last config is not found\n", __FUNCTION__)); > + } > + > + return EFI_SUCCESS; > + > +Exit: > + FreePool (PrivateData); > + return Status; > +} > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.c > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.c > new file mode 100644 > index 000000000000..6bd753ef327f > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieHelper.c > @@ -0,0 +1,191 @@ > +/** @file > + > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <Library/DebugLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > +#include <IndustryStandard/Pci.h> > +#include <Protocol/PciIo.h> > + > +#include "PlatformPcieDeviceConfigDxe.h" > +#include "PlatformPcieHelper.h" > + > +EFI_STATUS > +FindCapabilityPtr ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 CapabilityId, > + OUT UINT8 *CapabilityPtr > + ) > +{ > + EFI_STATUS Status; > + UINT8 NextPtr; > + UINT16 TmpValue; > + > + ASSERT (PciIo != NULL); > + > + // > + // Get pointer to first PCI Capability header > + // > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint8, > + PCI_CAPBILITY_POINTER_OFFSET, > + 1, > + &NextPtr > + ); > + if (EFI_ERROR (Status)) { > + goto Exit; > + } > + > + while (TRUE) { > + if (NextPtr == 0x00) { > + Status = EFI_NOT_FOUND; > + goto Exit; > + } > + > + // > + // Retrieve PCI Capability header > + // > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + NextPtr, > + 1, > + &TmpValue > + ); > + if (EFI_ERROR (Status)) { > + goto Exit; > + } > + > + if ((TmpValue & 0xFF) == CapabilityId) { > + *CapabilityPtr = NextPtr; > + Status = EFI_SUCCESS; > + goto Exit; > + } > + > + NextPtr = (TmpValue >> 8) & 0xFF; > + } > + > +Exit: > + return Status; > +} > + > +EFI_STATUS > +WriteMps ( > + PCIE_NODE *Node, > + UINT8 Value > + ) > +{ > + EFI_PCI_IO_PROTOCOL *PciIo; > + EFI_STATUS Status; > + UINT16 TmpValue; > + UINT8 PcieCapOffset; > + > + if (Node == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + PciIo = Node->PciIo; > + PcieCapOffset = Node->PcieCapOffset; > + > + // Get current device control reg > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + PcieCapOffset + > PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG, > + 1, > + &TmpValue > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // Update value and write to device > + TmpValue = (TmpValue & ~(PCIE_MAX_PAYLOAD_MASK << > PCIE_CONTROL_MAX_PAYLOAD_OFF)) > + | Value << PCIE_CONTROL_MAX_PAYLOAD_OFF; > + Status = PciIo->Pci.Write ( > + PciIo, > + EfiPciIoWidthUint16, > + PcieCapOffset + > PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG, > + 1, > + &TmpValue > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + DEBUG (( > + DEBUG_INFO, > + "%a: Write MPS %d to device 0x%04x:0x%02x:0x%02x:0x%02x\n", > + __FUNCTION__, > + Value, > + Node->Seg, > + Node->Bus, > + Node->Dev, > + Node->Fun > + )); > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +WriteMrr ( > + PCIE_NODE *Node, > + UINT8 Value > + ) > +{ > + EFI_PCI_IO_PROTOCOL *PciIo; > + EFI_STATUS Status; > + UINT16 TmpValue; > + UINT8 PcieCapOffset; > + > + if (Node == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + PciIo = Node->PciIo; > + PcieCapOffset = Node->PcieCapOffset; > + > + // Get current device control reg > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + PcieCapOffset + > PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG, > + 1, > + &TmpValue > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // Update value and write to device > + TmpValue = (TmpValue & ~(PCIE_MAX_READ_REQUEST_MASK << > PCIE_CONTROL_READ_REQUEST_OFF)) > + | Value << PCIE_CONTROL_READ_REQUEST_OFF; > + Status = PciIo->Pci.Write ( > + PciIo, > + EfiPciIoWidthUint16, > + PcieCapOffset + > PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG, > + 1, > + &TmpValue > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + DEBUG (( > + DEBUG_INFO, > + "%a: Write MRR %d to device 0x%04x:0x%02x:0x%02x:0x%02x\n", > + __FUNCTION__, > + Value, > + Node->Seg, > + Node->Bus, > + Node->Dev, > + Node->Fun > + )); > + > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.uni > > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.uni > new file mode 100644 > index 000000000000..f6cd94ffee36 > --- /dev/null > +++ > b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformPcieDeviceConfigDxe/PlatformPcieDeviceConfigDxe.uni > @@ -0,0 +1,24 @@ > +// > +// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> > +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > + > +#langdef en-US "English" // English > + > +#string STR_DEVICE_CONFIG_FORM #language en-US "PCIE Device Configuration" > +#string STR_DEVICE_CONFIG_HELP #language en-US "PCIE Device Configuration" > + > +#string STR_DEVICE_FORM #language en-US "PCIE Device Form" > +#string STR_DEVICE_GOTO_HELP #language en-US "PCIE Device Configuration" > + > +#string STR_PCIE_MPS #language en-US "Max Payload Size" > +#string STR_PCIE_MPS_HELP #language en-US "Max Payload Size" > +#string STR_PCIE_MRR #language en-US "Max Read Request Size" > +#string STR_PCIE_MRR_HELP #language en-US "Max Read Request Size" > +#string STR_128 #language en-US "128 bytes" > +#string STR_256 #language en-US "256 bytes" > +#string STR_512 #language en-US "512 bytes" > +#string STR_1024 #language en-US "1024 bytes" > +#string STR_2048 #language en-US "2048 bytes" > +#string STR_4096 #language en-US "4096 bytes" > -- > 2.17.1 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#81102): https://edk2.groups.io/g/devel/message/81102 Mute This Topic: https://groups.io/mt/85631216/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-