From: Vu Nguyen <vungu...@os.amperecomputing.com> Provides basic features like: * Screen menu to change the bifurcation setting of each Root Complex. Note that we can only make change for the Root Complex which doesn't come with a default value in the BoardSetting. * Parsing the BoardSetting and coordinate with saved setting to enable corresponding PCIe controller of each Root Complex. * Config speed and lane of enabled controller.
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> --- Platform/Ampere/JadePkg/Jade.dsc | 7 +- Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf | 59 + Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.h | 45 + Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.h | 114 ++ Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.h | 99 ++ Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.vfr | 217 ++++ Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.c | 436 +++++++ Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieCommon.c | 329 ++++++ Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.c | 1244 ++++++++++++++++++++ Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.uni | 102 ++ 10 files changed, 2651 insertions(+), 1 deletion(-) diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc index 118c03eab42f..afea3407a256 100644 --- a/Platform/Ampere/JadePkg/Jade.dsc +++ b/Platform/Ampere/JadePkg/Jade.dsc @@ -52,7 +52,7 @@ [Defines] DEFINE EDK2_SKIP_PEICORE = TRUE DEFINE SECURE_BOOT_ENABLE = FALSE DEFINE INCLUDE_TFTP_COMMAND = TRUE - DEFINE NVRAM_UUID = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5 + DEFINE NVRAM_UUID = 27AF4DFF-028B-4237-80B9-828FA74132F4 # # Network definition @@ -88,6 +88,11 @@ [LibraryClasses] # AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf + # + # Pcie Board + # + BoardPcieLib|Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf + ################################################################################ # # Specific Platform Pcds diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf new file mode 100644 index 000000000000..75e3560f4fca --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf @@ -0,0 +1,59 @@ +## @file +# +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = BoardPcieLib + FILE_GUID = 062191A6-E113-4FD6-84C7-E400B4B34759 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = BoardPcieLib + +[Sources] + BoardPcie.c + BoardPcieCommon.c + BoardPcieScreen.c + BoardPcieScreen.h + BoardPcieScreen.uni + BoardPcieVfr.h + BoardPcieVfr.vfr + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec + +[LibraryClasses] + AmpereCpuLib + BaseLib + DevicePathLib + GpioLib + HiiLib + HobLib + MemoryAllocationLib + SystemFirmwareInterfaceLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiHiiStringProtocolGuid ## CONSUMES + gEfiHiiConfigRoutingProtocolGuid ## CONSUMES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiHiiDatabaseProtocolGuid ## CONSUMES + gEfiConfigKeywordHandlerProtocolGuid ## CONSUMES + +[Guids] + gEfiIfrTianoGuid ## CONSUMES + gPlatformManagerFormsetGuid ## CONSUMES + gPlatformHobGuid ## CONSUMES + +[Depex] + TRUE diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.h b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.h new file mode 100644 index 000000000000..73ba3ee83ac2 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.h @@ -0,0 +1,45 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef BOARD_PCIE_H_ +#define BOARD_PCIE_H_ + +#include <Ac01PcieCommon.h> + +#define BITS_PER_BYTE 8 +#define BYTE_MASK 0xFF +#define PCIE_ERRATA_SPEED1 0x0001 // Limited speed errata + +enum DEV_MAP_MODE { + DEV_MAP_1_CONTROLLER = 0, + DEV_MAP_2_CONTROLLERS, + DEV_MAP_3_CONTROLLERS, + DEV_MAP_4_CONTROLLERS, +}; + +BOOLEAN +IsEmptyRC ( + IN AC01_RC *RC + ); + +VOID +BoardPcieSetupDevmap ( + IN AC01_RC *RC + ); + +VOID +BoardPcieGetLaneAllocation ( + IN AC01_RC *RC + ); + +VOID +BoardPcieGetSpeed ( + IN AC01_RC *RC + ); + +#endif /* BOARD_PCIE_H_ */ diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.h b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.h new file mode 100644 index 000000000000..b95c99588a56 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.h @@ -0,0 +1,114 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef BOARD_PCIE_SCREEN_H_ +#define BOARD_PCIE_SCREEN_H_ + +#include "BoardPcieVfr.h" + +// +// 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 BoardPcieVfrBin[]; + +// +// 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 BoardPcieLibStrings[]; + +#define MAX_EDITABLE_ELEMENTS 3 +#define RC0_STATUS_OFFSET \ + OFFSET_OF (VARSTORE_DATA, RCStatus[0]) +#define RC0_BIFUR_LO_OFFSET \ + OFFSET_OF (VARSTORE_DATA, RCBifurcationLow[0]) +#define RC0_BIFUR_HI_OFFSET \ + OFFSET_OF (VARSTORE_DATA, RCBifurcationHigh[0]) +#define SMMU_PMU_OFFSET \ + OFFSET_OF (VARSTORE_DATA, SmmuPmu) + +#define STRONG_ODERING_OFFSET \ + OFFSET_OF (NVPARAM_VARSTORE_DATA, PcieStrongOrdering) + +// +// Signature: Ampere Computing PCIe Screen +// +#define SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('A', 'C', 'P', 'S') + +#define MAX_STRING_SIZE 32 + +#define STRONG_ORDERING_DEFAULT_OPTION_VALUE 1 +#define STRONG_ORDERING_DEFAULT_NVPARAM_VALUE 0xFFFFFFFF + +typedef struct { + UINTN Signature; + + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + VARSTORE_DATA VarStoreConfig; + NVPARAM_VARSTORE_DATA NVParamVarStoreConfig; + + // + // Consumed protocol + // + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HII_STRING_PROTOCOL *HiiString; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; + + // + // Produced protocol + // + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; +} SCREEN_PRIVATE_DATA; + +typedef struct { + UINTN PciDevIdx; + EFI_STRING_ID GotoStringId; + EFI_STRING_ID GotoHelpStringId; + UINT16 GotoKey; + BOOLEAN ShowItem; +} SETUP_GOTO_DATA; + +#define SCREEN_PRIVATE_FROM_THIS(a) \ + CR (a, SCREEN_PRIVATE_DATA, ConfigAccess, SCREEN_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() + +UINT8 +PcieRCDevMapLowDefaultSetting ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ); + +UINT8 +PcieRCDevMapHighDefaultSetting ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ); + +BOOLEAN +PcieRCActiveDefaultSetting ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ); + +#endif /* BOARD_PCIE_SCREEN_H_ */ diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.h b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.h new file mode 100644 index 000000000000..badb1c80f9ab --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.h @@ -0,0 +1,99 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef BOARD_PCIE_VFR_H_ +#define BOARD_PCIE_VFR_H_ + +#include <Platform/Ac01.h> + +#define VARSTORE_NAME L"PcieIfrNVData" +#define VARSTORE_ID 0x1234 +#define FORM_ID 0x1235 +#define RC0_FORM_ID 0x1236 +#define RC1_FORM_ID 0x1237 +#define RC2_FORM_ID 0x1238 +#define RC3_FORM_ID 0x1239 +#define RC4_FORM_ID 0x123A +#define RC5_FORM_ID 0x123B +#define RC6_FORM_ID 0x123C +#define RC7_FORM_ID 0x123D +#define RC8_FORM_ID 0x123E +#define RC9_FORM_ID 0x123F +#define RC10_FORM_ID 0x1240 +#define RC11_FORM_ID 0x1241 +#define RC12_FORM_ID 0x1242 +#define RC13_FORM_ID 0x1243 +#define RC14_FORM_ID 0x1244 +#define RC15_FORM_ID 0x1245 +#define FORM_SET_GUID { 0xe84e70d6, 0xe4b2, 0x4c6e, { 0x98, 0x51, 0xcb, 0x2b, 0xac, 0x77, 0x7d, 0xbb } } + +#define GOTO_ID_BASE 0x8040 + +#define NVPARAM_VARSTORE_NAME L"PcieIfrNVParamData" +#define NVPARAM_VARSTORE_ID 0x1233 + +#pragma pack(1) + +// +// NV data structure definition +// +typedef struct { + BOOLEAN RCStatus[AC01_MAX_PCIE_ROOT_COMPLEX]; + UINT8 RCBifurcationLow[AC01_MAX_PCIE_ROOT_COMPLEX]; + UINT8 RCBifurcationHigh[AC01_MAX_PCIE_ROOT_COMPLEX]; + UINT32 SmmuPmu; +} VARSTORE_DATA; + +// +// NVParam data structure definition +// +typedef struct { + BOOLEAN PcieStrongOrdering; +} NVPARAM_VARSTORE_DATA; + +#pragma pack() + +// +// Labels definition +// +#define LABEL_UPDATE 0x2223 +#define LABEL_END 0x2224 +#define LABEL_RC0_UPDATE 0x2225 +#define LABEL_RC0_END 0x2226 +#define LABEL_RC1_UPDATE 0x2227 +#define LABEL_RC1_END 0x2228 +#define LABEL_RC2_UPDATE 0x2229 +#define LABEL_RC2_END 0x222A +#define LABEL_RC3_UPDATE 0x222B +#define LABEL_RC3_END 0x222C +#define LABEL_RC4_UPDATE 0x222D +#define LABEL_RC4_END 0x222E +#define LABEL_RC5_UPDATE 0x222F +#define LABEL_RC5_END 0x2230 +#define LABEL_RC6_UPDATE 0x2231 +#define LABEL_RC6_END 0x2232 +#define LABEL_RC7_UPDATE 0x2233 +#define LABEL_RC7_END 0x2234 +#define LABEL_RC8_UPDATE 0x2235 +#define LABEL_RC8_END 0x2236 +#define LABEL_RC9_UPDATE 0x2237 +#define LABEL_RC9_END 0x2238 +#define LABEL_RC10_UPDATE 0x2239 +#define LABEL_RC10_END 0x223A +#define LABEL_RC11_UPDATE 0x223B +#define LABEL_RC11_END 0x223C +#define LABEL_RC12_UPDATE 0x223D +#define LABEL_RC12_END 0x223E +#define LABEL_RC13_UPDATE 0x223F +#define LABEL_RC13_END 0x2240 +#define LABEL_RC14_UPDATE 0x2241 +#define LABEL_RC14_END 0x2242 +#define LABEL_RC15_UPDATE 0x2243 +#define LABEL_RC15_END 0x2244 + +#endif /* BOARD_PCIE_VFR_H_ */ diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.vfr b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.vfr new file mode 100644 index 000000000000..7fb9adb67030 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieVfr.vfr @@ -0,0 +1,217 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "BoardPcieVfr.h" + +formset + guid = FORM_SET_GUID, + title = STRING_TOKEN(STR_PCIE_FORM), + help = STRING_TOKEN(STR_PCIE_FORM_HELP), + classguid = gPlatformManagerFormsetGuid, + + // + // Define a variable Storage + // + varstore VARSTORE_DATA, + varid = VARSTORE_ID, + name = PcieIfrNVData, + guid = FORM_SET_GUID; + + varstore NVPARAM_VARSTORE_DATA, + varid = NVPARAM_VARSTORE_ID, + name = PcieIfrNVParamData, + guid = FORM_SET_GUID; + + form + formid = FORM_ID, + title = STRING_TOKEN(STR_PCIE_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_FORM); + + label LABEL_UPDATE; + // dynamic content here + label LABEL_END; + endform; + + form + formid = RC0_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC0_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC0_FORM); + + label LABEL_RC0_UPDATE; + // dynamic content here + label LABEL_RC0_END; + endform; + + form + formid = RC1_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC1_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC1_FORM); + + label LABEL_RC1_UPDATE; + // dynamic content here + label LABEL_RC1_END; + endform; + + form + formid = RC2_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC2_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC2_FORM); + + label LABEL_RC2_UPDATE; + // dynamic content here + label LABEL_RC2_END; + endform; + + form + formid = RC3_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC3_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC3_FORM); + + label LABEL_RC3_UPDATE; + // dynamic content here + label LABEL_RC3_END; + endform; + + form + formid = RC4_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC4_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC4_FORM); + + label LABEL_RC4_UPDATE; + // dynamic content here + label LABEL_RC4_END; + endform; + + form + formid = RC5_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC5_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC5_FORM); + + label LABEL_RC5_UPDATE; + // dynamic content here + label LABEL_RC5_END; + endform; + + form + formid = RC6_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC6_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC6_FORM); + + label LABEL_RC6_UPDATE; + // dynamic content here + label LABEL_RC6_END; + endform; + + form + formid = RC7_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC7_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC7_FORM); + + label LABEL_RC7_UPDATE; + // dynamic content here + label LABEL_RC7_END; + endform; + + form + formid = RC8_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC8_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC8_FORM); + + label LABEL_RC8_UPDATE; + // dynamic content here + label LABEL_RC8_END; + endform; + + form + formid = RC9_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC9_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC9_FORM); + + label LABEL_RC9_UPDATE; + // dynamic content here + label LABEL_RC9_END; + endform; + + form + formid = RC10_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC10_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC10_FORM); + + label LABEL_RC10_UPDATE; + // dynamic content here + label LABEL_RC10_END; + endform; + + form + formid = RC11_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC11_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC11_FORM); + + label LABEL_RC11_UPDATE; + // dynamic content here + label LABEL_RC11_END; + endform; + + form + formid = RC12_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC12_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC12_FORM); + + label LABEL_RC12_UPDATE; + // dynamic content here + label LABEL_RC12_END; + endform; + + form + formid = RC13_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC13_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC13_FORM); + + label LABEL_RC13_UPDATE; + // dynamic content here + label LABEL_RC13_END; + endform; + + form + formid = RC14_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC14_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC14_FORM); + + label LABEL_RC14_UPDATE; + // dynamic content here + label LABEL_RC14_END; + endform; + + form + formid = RC15_FORM_ID, + title = STRING_TOKEN(STR_PCIE_RC15_FORM); + + subtitle text = STRING_TOKEN(STR_PCIE_RC15_FORM); + + label LABEL_RC15_UPDATE; + // dynamic content here + label LABEL_RC15_END; + endform; + +endformset; diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.c b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.c new file mode 100644 index 000000000000..bb4c1863b54b --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcie.c @@ -0,0 +1,436 @@ +/** @file + + Pcie board specific driver to handle asserting PERST signal to Endpoint + card and parsing NVPARAM board settings for bifurcation programming. + + PERST asserting is via group of GPIO pins to CPLD as Platform Specification. + + NVPARAM board settings is spec-ed within Firmware Interface Requirement. + Bifuration devmap is programmed before at SCP following the rule + + Root Complex Type-A devmap settings (RP == Root Port) + ----------------------------------------- + | RP0 | RP1 | RP2 | RP3 | Devmap | + | (x16) | (x4) | (x8) | (x4) | (output) | + ------------------------------------------- + | Y | N | N | N | 0 | + | Y | N | Y | N | 1 | + | Y | N | Y | Y | 2 | + | Y | Y | Y | Y | 3 | + ----------------------------------------- + + Root Complex Type-B LO (aka RCBxA) devmap settings (RP == Root Port) + ---------------------------------------- + | RP0 | RP1 | RP2 | RP3 | Devmap | + | (x8) | (x2) | (x4) | (x3) | (output) | + ---------------------------------------- + | Y | N | N | N | 0 | + | Y | N | Y | N | 1 | + | Y | N | Y | Y | 2 | + | Y | Y | Y | Y | 3 | + ---------------------------------------- + + Root Complex Type-B LO (aka RCBxB) devmap settings (RP == Root Port) + ---------------------------------------- + | RP4 | RP5 | RP6 | RP7 | Devmap | + | (x8) | (x2) | (x4) | (x3) | (output) | + ---------------------------------------- + | Y | N | N | N | 0 | + | Y | N | Y | N | 1 | + | Y | N | Y | Y | 2 | + | Y | Y | Y | Y | 3 | + ---------------------------------------- + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Guid/PlatformInfoHobGuid.h> +#include <Library/AmpereCpuLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/GpioLib.h> +#include <Library/HobLib.h> +#include <Library/IoLib.h> +#include <Library/NVParamLib.h> +#include <Library/TimerLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <NVParamDef.h> +#include <Platform/Ac01.h> +#include <PlatformInfoHob.h> + +#include "BoardPcie.h" +#include "BoardPcieVfr.h" + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +#define RCA_MAX_PERST_GROUPVAL 62 +#define RCB_MAX_PERST_GROUPVAL 46 + +extern CHAR16 gPcieVarstoreName[]; +extern EFI_GUID gPcieFormSetGuid; + +VOID +EFIAPI +BoardPcieLoadPreset ( + IN AC01_RC *RC + ) +{ + UINT32 Nv; + INTN NvParam; + INTN Ret; + INTN Index; + + // Load default value + for (Index = 0; Index < MAX_PCIE_B; Index++) { + RC->PresetGen3[Index] = PRESET_INVALID; + RC->PresetGen4[Index] = PRESET_INVALID; + } + + // Load override value + if (RC->Socket == 0) { + if (RC->Type == RCA) { + if (RC->ID < MAX_RCA) { + NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET + RC->ID * NV_PARAM_ENTRYSIZE; + } else { + NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET + (RC->ID - MAX_RCA) * NV_PARAM_ENTRYSIZE; + } + } else { + // + // There're two NVParam entries per RCB + // + NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET + (RC->ID - MAX_RCA) * (NV_PARAM_ENTRYSIZE * 2); + } + } else if (RC->Type == RCA) { + if (RC->ID < MAX_RCA) { + NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET + (RC->ID - 2) * NV_PARAM_ENTRYSIZE; + } else { + NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET + (RC->ID - MAX_RCA) * NV_PARAM_ENTRYSIZE; + } + } else { + // + // There're two NVParam entries per RCB + // + NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET + (RC->ID - MAX_RCA) * (NV_PARAM_ENTRYSIZE * 2); + } + + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret == EFI_SUCCESS) { + for (Index = 0; Index < MAX_PCIE_A; Index++) { + RC->PresetGen3[Index] = (Nv >> (Index * BITS_PER_BYTE)) & BYTE_MASK; + } + } + + if (RC->Type == RCB) { + NvParam += NV_PARAM_ENTRYSIZE; + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret == EFI_SUCCESS) { + for (Index = MAX_PCIE_A; Index < MAX_PCIE; Index++) { + RC->PresetGen3[Index] = (Nv >> ((Index - MAX_PCIE_A) * BITS_PER_BYTE)) & BYTE_MASK; + } + } + } + + if (RC->Socket == 0) { + if (RC->Type == RCA) { + if (RC->ID < MAX_RCA) { + NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET + RC->ID * NV_PARAM_ENTRYSIZE; + } else { + NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET + (RC->ID - MAX_RCA) * NV_PARAM_ENTRYSIZE; + } + } else { + // + // There're two NVParam entries per RCB + // + NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET + (RC->ID - MAX_RCA) * (NV_PARAM_ENTRYSIZE * 2); + } + } else if (RC->Type == RCA) { + if (RC->ID < MAX_RCA) { + NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET + (RC->ID - 2) * NV_PARAM_ENTRYSIZE; + } else { + NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET + (RC->ID - MAX_RCA) * NV_PARAM_ENTRYSIZE; + } + } else { + // + // There're two NVParam entries per RCB + // + NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET + (RC->ID - MAX_RCA) * (NV_PARAM_ENTRYSIZE * 2); + } + + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret == EFI_SUCCESS) { + for (Index = 0; Index < MAX_PCIE_A; Index++) { + RC->PresetGen4[Index] = (Nv >> (Index * BITS_PER_BYTE)) & BYTE_MASK; + } + } + + if (RC->Type == RCB) { + NvParam += NV_PARAM_ENTRYSIZE; + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret == EFI_SUCCESS) { + for (Index = MAX_PCIE_A; Index < MAX_PCIE; Index++) { + RC->PresetGen4[Index] = (Nv >> ((Index - MAX_PCIE_A) * BITS_PER_BYTE)) & BYTE_MASK; + } + } + } +} + +/** + Parse platform Root Complex information. + + @param[out] RC Root Complex instance to store the platform information. + + @retval EFI_SUCCESS The operation is successful. + @retval Others An error occurred. +**/ +EFI_STATUS +EFIAPI +BoardPcieParseRCParams ( + OUT AC01_RC *RC + ) +{ + UINT32 Efuse; + PLATFORM_INFO_HOB *PlatformHob; + UINT8 PlatRCId; + EFI_STATUS Status; + VOID *Hob; + UINTN BufferSize; + VARSTORE_DATA VarStoreConfig = { + .RCStatus = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE}, + .RCBifurcationLow = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .RCBifurcationHigh = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .SmmuPmu = 0 + }; + + DEBUG ((DEBUG_INFO, "%a - Socket%d RC%d\n", __FUNCTION__, RC->Socket, RC->ID)); + + PlatRCId = RC->Socket * AC01_MAX_RCS_PER_SOCKET + RC->ID; + // Get RC activation status + BufferSize = sizeof (VARSTORE_DATA); + Status = gRT->GetVariable ( + gPcieVarstoreName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + &VarStoreConfig + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a - Failed to read PCIE variable data from config store.\n", __FUNCTION__)); + } + + RC->Active = VarStoreConfig.RCStatus[PlatRCId]; + RC->DevMapLow = VarStoreConfig.RCBifurcationLow[PlatRCId]; + RC->DevMapHigh = VarStoreConfig.RCBifurcationHigh[PlatRCId]; + + DEBUG (( + DEBUG_INFO, + "%a - Socket%d RC%d is %s\n", + __FUNCTION__, + RC->Socket, + RC->ID, + (RC->Active) ? "ACTIVE" : "INACTIVE" + )); + + if (!IsSlaveSocketActive () && RC->Socket == 1) { + RC->Active = FALSE; + } + + if (RC->Active) { + // + // Consolidate with E-fuse + // + Efuse = 0; + Hob = GetFirstGuidHob (&gPlatformHobGuid); + if (Hob != NULL) { + PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); + Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << AC01_MAX_RCS_PER_SOCKET); + DEBUG (( + DEBUG_INFO, + "RcDisableMask[0]: 0x%x [1]: 0x%x\n", + PlatformHob->RcDisableMask[0], + PlatformHob->RcDisableMask[1] + )); + + // Update errata flags for Ampere Altra + if ((PlatformHob->ScuProductId[0] & 0xff) == 0x01) { + if (PlatformHob->AHBCId[0] == 0x20100 + || PlatformHob->AHBCId[0] == 0x21100 + || (IsSlaveSocketActive () + && (PlatformHob->AHBCId[1] == 0x20100 + || PlatformHob->AHBCId[1] == 0x21100))) + { + RC->Flags |= PCIE_ERRATA_SPEED1; + DEBUG ((DEBUG_INFO, "RC[%d]: Flags 0x%x\n", RC->ID, RC->Flags)); + } + } + } + + RC->Active = (RC->Active && !(Efuse & BIT (PlatRCId))) ? TRUE : FALSE; + } + + /* Load Gen3/Gen4 preset */ + BoardPcieLoadPreset (RC); + BoardPcieGetLaneAllocation (RC); + BoardPcieSetupDevmap (RC); + BoardPcieGetSpeed (RC); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +BoardPcieReleaseAllPerst ( + IN UINT8 SocketId + ) +{ + UINT32 GpioIndex, GpioPin; + + // Write 1 to all GPIO[16..21] to release all PERST + GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * SocketId + 16; + for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) { + GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI); + } +} + +/** + Assert PERST of input PCIe controller + + @param[in] RC Root Complex instance. + @param[in] PcieIndex PCIe controller index of input Root Complex. + @param[in] Bifurcation Bifurcation mode of input Root Complex. + @param[in] IsPullToHigh Target status for the PERST. + + @retval EFI_SUCCESS The operation is successful. + @retval Others An error occurred. +**/ +EFI_STATUS +EFIAPI +BoardPcieAssertPerst ( + IN AC01_RC *RC, + IN UINT32 PcieIndex, + IN UINT8 Bifurcation, + IN BOOLEAN IsPullToHigh + ) +{ + UINT32 GpioGroupVal, Val, GpioIndex, GpioPin; + + if (!IsPullToHigh) { // Pull PERST to Low + if (RC->Type == RCA) { // RCA: RC->ID: 0->3 ; PcieIndex: 0->3 + GpioGroupVal = RCA_MAX_PERST_GROUPVAL - RC->ID * MAX_PCIE_A - PcieIndex; + } else { // RCB: RC->ID: 4->7 ; PcieIndex: 0->7 + GpioGroupVal = RCB_MAX_PERST_GROUPVAL - (RC->ID - MAX_RCA) * MAX_PCIE_B - PcieIndex; + } + + // Update the value of GPIO[16..21]. Corresponding PERST line will be decoded by CPLD. + GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * RC->Socket + 16; + for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) { + Val = (GpioGroupVal & 0x3F) & (1 << GpioIndex); + if (Val == 0) { + GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_LOW); + } else { + GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI); + } + } + + // Keep reset as low as 100 ms as specification + MicroSecondDelay (100 * 1000); + } else { // Pull PERST to High + BoardPcieReleaseAllPerst (RC->Socket); + } + + return EFI_SUCCESS; +} + +/** + Override the segment number for a root complex with a board specific number. + + @param[in] RC Root Complex instance with properties. + @param[out] SegmentNumber Return segment number. + + @retval EFI_SUCCESS The operation is successful. + @retval Others An error occurred. +**/ +EFI_STATUS +EFIAPI +BoardPcieGetRCSegmentNumber ( + IN AC01_RC *RC, + OUT UINTN *SegmentNumber + ) +{ + if (RC->Socket == 0) { + if (RC->Type == RCA) { + switch (RC->ID) { + case RCA0: + *SegmentNumber = 12; + break; + + case RCA1: + *SegmentNumber = 13; + break; + + case RCA2: + *SegmentNumber = 1; + break; + + case RCA3: + *SegmentNumber = 0; + break; + + default: + *SegmentNumber = 16; + } + } else { /* Socket0, CCIX: RCA0 and RCA1 */ + *SegmentNumber = RC->ID - 2; + } + } else { /* Socket1, CCIX: RCA0 and RCA1 */ + if (RC->ID == RCA0 || RC->ID == RCA1) { + *SegmentNumber = 16; + } else { + *SegmentNumber = 4 + RC->ID; + } + } + + return EFI_SUCCESS; +} + +/** + Check if SMM PMU enabled in board screen. + + @param[out] IsSmmuPmuEnabled TRUE if the SMMU PMU enabled, otherwise FALSE. + + @retval EFI_SUCCESS The operation is successful. + @retval Others An error occurred. +**/ +EFI_STATUS +EFIAPI +BoardPcieCheckSmmuPmuEnabled ( + OUT BOOLEAN *IsSmmuPmuEnabled + ) +{ + VARSTORE_DATA VarStoreConfig; + UINTN BufferSize; + EFI_STATUS Status; + + *IsSmmuPmuEnabled = FALSE; + + // Get Buffer Storage data from EFI variable + BufferSize = sizeof (VARSTORE_DATA); + Status = gRT->GetVariable ( + gPcieVarstoreName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + &VarStoreConfig + ); + if (!EFI_ERROR (Status)) { + *IsSmmuPmuEnabled = VarStoreConfig.SmmuPmu; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieCommon.c b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieCommon.c new file mode 100644 index 000000000000..05fff88ba601 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieCommon.c @@ -0,0 +1,329 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/DebugLib.h> +#include <Library/NVParamLib.h> +#include <Library/SystemFirmwareInterfaceLib.h> +#include <NVParamDef.h> + +#include "BoardPcie.h" + +/* Host bridge registers */ +#define RCA_DEV_MAP_OFFSET 0x0 +#define RCB_DEV_MAP_OFFSET 0x4 + +/* RCA_DEV_MAP_OFFSET */ +#define RCA_DEV_MAP_SET(dst, src) \ + (((dst) & ~0x7) | (((UINT32)(src)) & 0x7)) + +/* RCB_DEV_MAP_OFFSET */ +#define RCB_DEV_MAP_LOW_SET(dst, src) \ + (((dst) & ~0x7) | (((UINT32)(src)) & 0x7)) +#define RCB_DEV_MAP_HIGH_SET(dst, src) \ + (((dst) & ~0x70) | (((UINT32)(src) << 4) & 0x70)) + +#define PCIE_GET_MAX_WIDTH(Pcie, Max) \ + !((Pcie).MaxWidth) ? (Max) : MIN((Pcie).MaxWidth, (Max)) + +BOOLEAN +IsEmptyRC ( + IN AC01_RC *RC + ) +{ + INTN Idx; + + for (Idx = PCIE_0; Idx < MAX_PCIE; Idx++) { + if (RC->Pcie[Idx].Active) { + return FALSE; + } + } + + return TRUE; +} + +VOID +BoardPcieSetRCBifurcation ( + IN AC01_RC *RC, + IN UINT8 RPStart, + IN UINT8 DevMap + ) +{ + UINT8 MaxWidth; + + if (RPStart != PCIE_0 && RPStart != PCIE_4) { + return; + } + + if (RC->Type != RCB && RPStart == PCIE_4) { + return; + } + + if (RC->Type == RCA && RC->Pcie[RPStart].MaxWidth == LNKW_X16) { + RC->Pcie[RPStart + 1].MaxWidth = LNKW_X4; + RC->Pcie[RPStart + 2].MaxWidth = LNKW_X8; + RC->Pcie[RPStart + 3].MaxWidth = LNKW_X4; + } + + if (RC->Type == RCB && RC->Pcie[RPStart].MaxWidth == LNKW_X8) { + RC->Pcie[RPStart + 1].MaxWidth = LNKW_X2; + RC->Pcie[RPStart + 2].MaxWidth = LNKW_X4; + RC->Pcie[RPStart + 3].MaxWidth = LNKW_X2; + } + + switch (DevMap) { + case DEV_MAP_2_CONTROLLERS: + MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4; + RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth); + RC->Pcie[RPStart + 1].Active = FALSE; + RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth); + RC->Pcie[RPStart + 2].Active = TRUE; + RC->Pcie[RPStart + 3].Active = FALSE; + break; + + case DEV_MAP_3_CONTROLLERS: + MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4; + RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth); + RC->Pcie[RPStart + 1].Active = FALSE; + MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2; + RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth); + RC->Pcie[RPStart + 2].Active = TRUE; + RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth); + RC->Pcie[RPStart + 3].Active = TRUE; + break; + + case DEV_MAP_4_CONTROLLERS: + MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2; + RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth); + RC->Pcie[RPStart + 1].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 1], MaxWidth); + RC->Pcie[RPStart + 1].Active = TRUE; + RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth); + RC->Pcie[RPStart + 2].Active = TRUE; + RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth); + RC->Pcie[RPStart + 3].Active = TRUE; + break; + + case DEV_MAP_1_CONTROLLER: + default: + MaxWidth = (RC->Type == RCA) ? LNKW_X16 : LNKW_X8; + RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth); + RC->Pcie[RPStart + 1].Active = FALSE; + RC->Pcie[RPStart + 2].Active = FALSE; + RC->Pcie[RPStart + 3].Active = FALSE; + break; + } +} + +VOID +BoardPcieGetLaneAllocation ( + IN AC01_RC *RC + ) +{ + INTN RPIndex, Ret; + UINT32 Nv, Width; + NVPARAM NvParam; + + // Retrieve lane allocation and capabilities for each controller + if (RC->Type == RCA) { + NvParam = ((RC->Socket == 0) ? NV_SI_RO_BOARD_S0_RCA0_CFG : NV_SI_RO_BOARD_S1_RCA0_CFG) + + RC->ID * NV_PARAM_ENTRYSIZE; + } else { + // + // There're two NVParam entries per RCB + // + NvParam = ((RC->Socket == 0) ? NV_SI_RO_BOARD_S0_RCB0_LO_CFG : NV_SI_RO_BOARD_S1_RCB0_LO_CFG) + + (RC->ID - MAX_RCA) * (NV_PARAM_ENTRYSIZE * 2); + } + + Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv); + Nv = (Ret != EFI_SUCCESS) ? 0 : Nv; + + for (RPIndex = 0; RPIndex < MAX_PCIE_A; RPIndex++) { + Width = (Nv >> (RPIndex * BITS_PER_BYTE)) & BYTE_MASK; + switch (Width) { + case 1: + case 2: + case 3: + case 4: + RC->Pcie[RPIndex].MaxWidth = 1 << Width; + RC->Pcie[RPIndex].MaxGen = SPEED_GEN3; + RC->Pcie[RPIndex].Active = TRUE; + break; + + case 0: + default: + RC->Pcie[RPIndex].MaxWidth = LNKW_NONE; + RC->Pcie[RPIndex].MaxGen = SPEED_NONE; + RC->Pcie[RPIndex].Active = FALSE; + break; + } + } + + if (RC->Type == RCB) { + NvParam += NV_PARAM_ENTRYSIZE; + Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv); + Nv = (Ret != EFI_SUCCESS) ? 0 : Nv; + + for (RPIndex = MAX_PCIE_A; RPIndex < MAX_PCIE; RPIndex++) { + Width = (Nv >> ((RPIndex - MAX_PCIE_A) * BITS_PER_BYTE)) & BYTE_MASK; + switch (Width) { + case 1: + case 2: + case 3: + case 4: + RC->Pcie[RPIndex].MaxWidth = 1 << Width; + RC->Pcie[RPIndex].MaxGen = SPEED_GEN3; + RC->Pcie[RPIndex].Active = TRUE; + break; + + case 0: + default: + RC->Pcie[RPIndex].MaxWidth = LNKW_NONE; + RC->Pcie[RPIndex].MaxGen = SPEED_NONE; + RC->Pcie[RPIndex].Active = FALSE; + break; + } + } + } + + // Do not proceed if no Root Port enabled + if (IsEmptyRC (RC)) { + RC->Active = FALSE; + } +} + +VOID +BoardPcieSetupDevmap ( + IN AC01_RC *RC + ) +{ + UINT32 Val; + + if (RC->Pcie[PCIE_0].Active + && RC->Pcie[PCIE_1].Active + && RC->Pcie[PCIE_2].Active + && RC->Pcie[PCIE_3].Active) + { + RC->DefaultDevMapLow = DEV_MAP_4_CONTROLLERS; + } else if (RC->Pcie[PCIE_0].Active + && RC->Pcie[PCIE_2].Active + && RC->Pcie[PCIE_3].Active) + { + RC->DefaultDevMapLow = DEV_MAP_3_CONTROLLERS; + } else if (RC->Pcie[PCIE_0].Active + && RC->Pcie[PCIE_2].Active) + { + RC->DefaultDevMapLow = DEV_MAP_2_CONTROLLERS; + } else { + RC->DefaultDevMapLow = DEV_MAP_1_CONTROLLER; + } + + if (RC->Pcie[PCIE_4].Active + && RC->Pcie[PCIE_5].Active + && RC->Pcie[PCIE_6].Active + && RC->Pcie[PCIE_7].Active) + { + RC->DefaultDevMapHigh = DEV_MAP_4_CONTROLLERS; + } else if (RC->Pcie[PCIE_4].Active + && RC->Pcie[PCIE_6].Active + && RC->Pcie[PCIE_7].Active) + { + RC->DefaultDevMapHigh = DEV_MAP_3_CONTROLLERS; + } else if (RC->Pcie[PCIE_4].Active + && RC->Pcie[PCIE_6].Active) + { + RC->DefaultDevMapHigh = DEV_MAP_2_CONTROLLERS; + } else { + RC->DefaultDevMapHigh = DEV_MAP_1_CONTROLLER; + } + + if (RC->DevMapLow == DEV_MAP_1_CONTROLLER) { + RC->DevMapLow = RC->DefaultDevMapLow; + } + + if (RC->Type == RCB && RC->DevMapHigh == DEV_MAP_1_CONTROLLER) { + RC->DevMapHigh = RC->DefaultDevMapHigh; + } + + BoardPcieSetRCBifurcation (RC, PCIE_0, RC->DevMapLow); + if (RC->Type == RCB) { + BoardPcieSetRCBifurcation (RC, PCIE_4, RC->DevMapHigh); + } + + if (RC->Active) { + if (RC->Type == RCA) { + if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + RCA_DEV_MAP_OFFSET, &Val))) { + Val = RCA_DEV_MAP_SET (Val, RC->DevMapLow); + MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + RCA_DEV_MAP_OFFSET, Val); + } + } else { + if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + RCB_DEV_MAP_OFFSET, &Val))) { + Val = RCB_DEV_MAP_LOW_SET (Val, RC->DevMapLow); + Val = RCB_DEV_MAP_HIGH_SET (Val, RC->DevMapHigh); + MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + RCB_DEV_MAP_OFFSET, Val); + } + } + } +} + +VOID +BoardPcieGetSpeed ( + IN AC01_RC *RC + ) +{ + UINT8 MaxGenTbl[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN4, SPEED_GEN4 }; // Bifurcation 0: RCA x16 / RCB x8 + UINT8 MaxGenTblX8X4X4[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN1, SPEED_GEN1 }; // Bifurcation 2: x8 x4 x4 (PCIE_ERRATA_SPEED1) + UINT8 MaxGenTblX4X4X4X4[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 }; // Bifurcation 3: x4 x4 x4 x4 (PCIE_ERRATA_SPEED1) + UINT8 MaxGenTblRCB[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 }; // RCB PCIE_ERRATA_SPEED1 + INTN RPIdx; + UINT8 *MaxGen; + + ASSERT (MAX_PCIE_A == 4); + ASSERT (MAX_PCIE == 8); + + // + // Due to hardware errata, for A0/A1* + // RCB is limited to Gen1 speed. + // RCA x16, x8 port supports up to Gen4, + // RCA x4 port only supports Gen1. + // + MaxGen = MaxGenTbl; + if (RC->Type == RCB) { + if (RC->Flags & PCIE_ERRATA_SPEED1) { + MaxGen = MaxGenTblRCB; + } + } else { + switch (RC->DevMapLow) { + case DEV_MAP_3_CONTROLLERS: /* x8 x4 x4 */ + if (RC->Flags & PCIE_ERRATA_SPEED1) { + MaxGen = MaxGenTblX8X4X4; + } + break; + + case DEV_MAP_4_CONTROLLERS: /* X4 x4 x4 x4 */ + if (RC->Flags & PCIE_ERRATA_SPEED1) { + MaxGen = MaxGenTblX4X4X4X4; + } + break; + + case DEV_MAP_2_CONTROLLERS: /* x8 x8 */ + default: + break; + } + } + + for (RPIdx = 0; RPIdx < MAX_PCIE_A; RPIdx++) { + RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ? MaxGen[RPIdx] : SPEED_NONE; + } + + if (RC->Type == RCB) { + for (RPIdx = MAX_PCIE_A; RPIdx < MAX_PCIE; RPIdx++) { + RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ? + MaxGen[RPIdx - MAX_PCIE_A] : SPEED_NONE; + } + } +} diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.c b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.c new file mode 100644 index 000000000000..eed53c6abed7 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.c @@ -0,0 +1,1244 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Guid/MdeModuleHii.h> +#include <Guid/PlatformInfoHobGuid.h> +#include <Library/AmpereCpuLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/DevicePathLib.h> +#include <Library/HiiLib.h> +#include <Library/HobLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/NVParamLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <NVParamDef.h> +#include <Platform/Ac01.h> +#include <PlatformInfoHob.h> +#include <Protocol/HiiConfigAccess.h> +#include <Protocol/HiiConfigKeyword.h> +#include <Protocol/HiiConfigRouting.h> +#include <Protocol/HiiDatabase.h> +#include <Protocol/HiiString.h> + +#include "BoardPcie.h" +#include "BoardPcieScreen.h" + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +BOOLEAN mReadOnlyStrongOrdering; +CHAR16 mPcieNvparamVarstoreName[] = NVPARAM_VARSTORE_NAME; +CHAR16 gPcieVarstoreName[] = VARSTORE_NAME; +EFI_GUID gPcieFormSetGuid = FORM_SET_GUID; + +SCREEN_PRIVATE_DATA *mPrivateData = NULL; + +AC01_RC RCList[AC01_MAX_PCIE_ROOT_COMPLEX]; + +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + FORM_SET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Request A null-terminated Unicode string in + <ConfigRequest> format. + @param Progress On return, points to a character in the Request + string. Points to the string's null terminator if + request was successful. Points to 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) if the request was not + successful. + @param Results A null-terminated Unicode string in + <ConfigAltResp> format which has all values filled + in for the names in the Request string. String to + be allocated by the called function. + @retval EFI_SUCCESS The Results is filled with the requested values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. +**/ +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; + SCREEN_PRIVATE_DATA *PrivateData; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_STRING ConfigRequest; + UINTN Size; + CHAR16 *StrPointer; + BOOLEAN AllocatedRequest; + UINT8 *VarStoreConfig; + UINT32 Value; + + if (Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Request == NULL) { + return EFI_NOT_FOUND; + } + + // + // Initialize the local variables. + // + ConfigRequest = NULL; + Size = 0; + *Progress = Request; + AllocatedRequest = FALSE; + + PrivateData = SCREEN_PRIVATE_FROM_THIS (This); + HiiConfigRouting = PrivateData->HiiConfigRouting; + + // + // Check routing data in <ConfigHdr>. + // Note: if only one Storage is used, then this checking could be skipped. + // + if (HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, mPcieNvparamVarstoreName)) { + VarStoreConfig = (UINT8 *)&PrivateData->NVParamVarStoreConfig; + ASSERT (VarStoreConfig != NULL); + + Status = NVParamGet ( + NV_SI_MESH_S0_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + &Value + ); + ASSERT_EFI_ERROR (Status); + if (Value != 0) { + PrivateData->NVParamVarStoreConfig.PcieStrongOrdering = TRUE; + } + + Status = NVParamGet ( + NV_SI_MESH_S1_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + &Value + ); + ASSERT_EFI_ERROR (Status); + if (Value != 0) { + PrivateData->NVParamVarStoreConfig.PcieStrongOrdering = TRUE; + } + + BufferSize = sizeof (NVPARAM_VARSTORE_DATA); + + } else if (HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, gPcieVarstoreName)) { + VarStoreConfig = (UINT8 *)&PrivateData->VarStoreConfig; + ASSERT (VarStoreConfig != NULL); + + // + // Get Buffer Storage data from EFI variable. + // Try to get the current setting from variable. + // + BufferSize = sizeof (VARSTORE_DATA); + Status = gRT->GetVariable ( + gPcieVarstoreName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + VarStoreConfig + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + } else { + 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) { + // + // Allocate and fill a buffer large enough to hold the <ConfigHdr> template + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator + // + 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 + ); + } + } + + // + // Convert buffer data to <ConfigResp> by helper function BlockToConfig() + // + Status = HiiConfigRouting->BlockToConfig ( + HiiConfigRouting, + ConfigRequest, + VarStoreConfig, + BufferSize, + Results, + Progress + ); + + // + // Free the allocated config request string. + // + if (AllocatedRequest) { + FreePool (ConfigRequest); + } + + // + // 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; + SCREEN_PRIVATE_DATA *PrivateData; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + UINT8 *VarStoreConfig; + UINT32 Value; + + if (Configuration == NULL || Progress == NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = SCREEN_PRIVATE_FROM_THIS (This); + HiiConfigRouting = PrivateData->HiiConfigRouting; + *Progress = Configuration; + + if (HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, mPcieNvparamVarstoreName)) { + VarStoreConfig = (UINT8 *)&PrivateData->NVParamVarStoreConfig; + BufferSize = sizeof (NVPARAM_VARSTORE_DATA); + } else if (HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, gPcieVarstoreName)) { + BufferSize = sizeof (VARSTORE_DATA); + VarStoreConfig = (UINT8 *)&PrivateData->VarStoreConfig; + } + ASSERT (VarStoreConfig != NULL); + + // + // 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() + // + Status = HiiConfigRouting->ConfigToBlock ( + HiiConfigRouting, + Configuration, + (UINT8 *)VarStoreConfig, + &BufferSize, + Progress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check routing data in <ConfigHdr>. + // + if (HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, mPcieNvparamVarstoreName)) { + Value = PrivateData->NVParamVarStoreConfig.PcieStrongOrdering ? STRONG_ORDERING_DEFAULT_NVPARAM_VALUE : 0; + + if (!mReadOnlyStrongOrdering) { + // + // Update whole 16 RCs. + // + Status = NVParamSet ( + NV_SI_MESH_S0_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + NV_PERM_BIOS | NV_PERM_MANU, + Value + ); + ASSERT_EFI_ERROR (Status); + + // + // No need to check slave present + // + Status = NVParamSet ( + NV_SI_MESH_S1_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + NV_PERM_BIOS | NV_PERM_MANU, + Value + ); + ASSERT_EFI_ERROR (Status); + } + } else if (HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, gPcieVarstoreName)) { + // + // Store Buffer Storage back to variable + // + Status = gRT->SetVariable ( + gPcieVarstoreName, + &gPcieFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (VARSTORE_DATA), + (VARSTORE_DATA *)VarStoreConfig + ); + } + + 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_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @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 + ) +{ + SCREEN_PRIVATE_DATA *PrivateData; + EFI_STATUS Status; + + if (((Value == NULL) && + (Action != EFI_BROWSER_ACTION_FORM_OPEN) && + (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) || + (ActionRequest == NULL)) + { + return EFI_INVALID_PARAMETER; + } + + PrivateData = SCREEN_PRIVATE_FROM_THIS (This); + + Status = EFI_SUCCESS; + + switch (Action) { + case EFI_BROWSER_ACTION_FORM_OPEN: + break; + + case EFI_BROWSER_ACTION_FORM_CLOSE: + break; + + case EFI_BROWSER_ACTION_DEFAULT_STANDARD: + case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING: + if (QuestionId == 0x9000) { + // + // SMMU PMU + // + Value->u32 = 0; + break; + } + + if (QuestionId == 0x9001) { + // + // Strong Ordering + // + Value->u8 = STRONG_ORDERING_DEFAULT_OPTION_VALUE; + break; + } + + switch ((QuestionId - 0x8002) % MAX_EDITABLE_ELEMENTS) { + case 0: + Value->u8 = PcieRCActiveDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData); + break; + + case 1: + Value->u8 = PcieRCDevMapLowDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData); + break; + + case 2: + Value->u8 = PcieRCDevMapHighDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData); + break; + } + break; + + case EFI_BROWSER_ACTION_RETRIEVE: + case EFI_BROWSER_ACTION_CHANGING: + case EFI_BROWSER_ACTION_SUBMITTED: + break; + + default: + Status = EFI_UNSUPPORTED; + break; + } + + return Status; +} + +/** + This function return default settings for Dev Map LO. + @param RC Root Complex ID. + @param PrivateData Private data. + + @retval Default dev settings. +**/ +UINT8 +PcieRCDevMapLowDefaultSetting ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ) +{ + AC01_RC *RC = &RCList[RCIndex]; + + return RC->DefaultDevMapLow; +} + +/** + This function return default settings for Dev Map HI. + @param RC Root Complex ID. + @param PrivateData Private data. + + @retval Default dev settings. +**/ +UINT8 +PcieRCDevMapHighDefaultSetting ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ) +{ + AC01_RC *RC = &RCList[RCIndex]; + + return RC->DefaultDevMapHigh; +} + +BOOLEAN +PcieRCActiveDefaultSetting ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ) +{ + PLATFORM_INFO_HOB *PlatformHob; + VOID *Hob; + UINT32 Efuse; + + Hob = GetFirstGuidHob (&gPlatformHobGuid); + if (Hob != NULL) { + PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); + Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << AC01_MAX_RCS_PER_SOCKET); + return (!(Efuse & BIT (RCIndex))) ? TRUE : FALSE; + } + + return FALSE; +} + +/** + This function sets up the first elements of the form. + @param RC Root Complex ID. + @param PrivateData Private data. + @retval EFI_SUCCESS The form is set up successfully. +**/ +EFI_STATUS +PcieRCScreenSetup ( + IN UINTN RCIndex, + IN SCREEN_PRIVATE_DATA *PrivateData + ) +{ + VOID *StartOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *EndLabel; + VOID *OptionsOpCodeHandle; + VOID *OptionsHiOpCodeHandle; + CHAR16 Str[MAX_STRING_SIZE]; + UINT16 DisabledStatusVarOffset; + UINT16 BifurLoVarOffset; + UINT16 BifurHiVarOffset; + UINT8 QuestionFlags, QuestionFlagsSubItem; + AC01_RC *RC; + + RC = &RCList[RCIndex]; + + // 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 = LABEL_RC0_UPDATE + 2 * RCIndex; + + // 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 = LABEL_RC0_END + 2 * RCIndex; + + // Create textbox to tell socket + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_PCIE_SOCKET), + STRING_TOKEN (STR_PCIE_SOCKET_HELP), + HiiSetString ( + PrivateData->HiiHandle, + 0, + (RC->Socket) ? L"1" : L"0", + NULL + ) + ); + + // Create textbox to tell Root Complex type + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_PCIE_RC_TYPE), + STRING_TOKEN (STR_PCIE_RC_TYPE_HELP), + HiiSetString ( + PrivateData->HiiHandle, + 0, + (RC->Type == RCA) ? L"Root Complex Type-A" : L"Root Complex Type-B", + NULL + ) + ); + + UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RCIndex); + + DisabledStatusVarOffset = (UINT16)RC0_STATUS_OFFSET + + sizeof (BOOLEAN) * RCIndex; + BifurLoVarOffset = (UINT16)RC0_BIFUR_LO_OFFSET + + sizeof (UINT8) * RCIndex; + BifurHiVarOffset = (UINT16)RC0_BIFUR_HI_OFFSET + + sizeof (UINT8) * RCIndex; + + QuestionFlags = EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_CALLBACK; + if (IsEmptyRC (RC) + || (GetNumberOfActiveSockets () == 1 && RC->Socket == 1)) + { + // + // Do not allow changing if none of Root Port underneath enabled + // or slave Root Complex on 1P system. + // + QuestionFlags |= EFI_IFR_FLAG_READ_ONLY; + } + // Create the RC disabled checkbox + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8002 + MAX_EDITABLE_ELEMENTS * RCIndex, // QuestionId (or "key") + VARSTORE_ID, // VarStoreId + DisabledStatusVarOffset, // VarOffset in Buffer Storage + HiiSetString ( + PrivateData->HiiHandle, + 0, + Str, + NULL + ), // Prompt + STRING_TOKEN (STR_PCIE_RC_STATUS_HELP), // Help + QuestionFlags, // QuestionFlags + 0, // CheckBoxFlags + NULL // DefaultsOpCodeHandle + ); + + if (RC->Type == RCA) { + // Create Option OpCode to display bifurcation for RCA + OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle != NULL); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE0), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 0 // Devmap=0 + ); + + + if (RC->DefaultDevMapLow != 0) { + QuestionFlags |= EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE1), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 // Devmap=1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE2), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 // Devmap=2 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE3), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 3 // Devmap=3 + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it "key") + VARSTORE_ID, // VarStore ID + BifurLoVarOffset, // Offset in Buffer Storage + STRING_TOKEN (STR_PCIE_RCA_BIFUR), // Question prompt text + STRING_TOKEN (STR_PCIE_RCA_BIFUR_HELP), // Question help text + QuestionFlags, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + } else { + // Create Option OpCode to display bifurcation for RCB-Lo + OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle != NULL); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 0 // Devmap=0 + ); + + QuestionFlagsSubItem = QuestionFlags; + if (RC->DefaultDevMapLow != 0) { + QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 // Devmap=1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 // Devmap=2 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 3 // Devmap=3 + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it "key") + VARSTORE_ID, // VarStore ID + BifurLoVarOffset, // Offset in Buffer Storage + STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR), // Question prompt text + STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR_HELP), // Question help text + QuestionFlagsSubItem, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + + // Create Option OpCode to display bifurcation for RCB-Hi + OptionsHiOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (OptionsHiOpCodeHandle != NULL); + + QuestionFlagsSubItem = QuestionFlags; + if (RC->DefaultDevMapHigh != 0) { + QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 0 // Devmap=0 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 // Devmap=1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 // Devmap=2 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 3 // Devmap=3 + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8004 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it "key") + VARSTORE_ID, // VarStore ID + BifurHiVarOffset, // Offset in Buffer Storage + STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR), // Question prompt text + STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR_HELP), // Question help text + QuestionFlagsSubItem, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value + OptionsHiOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + } + + HiiUpdateForm ( + PrivateData->HiiHandle, // HII handle + &gPcieFormSetGuid, // Formset GUID + RC0_FORM_ID + RCIndex, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + + return EFI_SUCCESS; +} + +/** + This function sets up the first elements of the form. + @param PrivateData Private data. + @retval EFI_SUCCESS The form is set up successfully. +**/ +EFI_STATUS +PcieMainScreenSetup ( + IN SCREEN_PRIVATE_DATA *PrivateData + ) +{ + VOID *StartOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *EndLabel; + CHAR16 Str[MAX_STRING_SIZE]; + UINTN RC; + SETUP_GOTO_DATA *GotoItem = NULL; + EFI_QUESTION_ID GotoId; + UINT8 QuestionFlags; + + // 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 = 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 = LABEL_END; + + QuestionFlags = EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED; + + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x9000, // Question ID + VARSTORE_ID, // VarStore ID + (UINT16)SMMU_PMU_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_PCIE_SMMU_PMU_PROMPT), // Question prompt text + STRING_TOKEN (STR_PCIE_SMMU_PMU_HELP), // Question help text + QuestionFlags, + 0, + NULL + ); + + if (mReadOnlyStrongOrdering) { + QuestionFlags |= EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x9001, // Question ID + NVPARAM_VARSTORE_ID, // VarStore ID + (UINT16)STRONG_ODERING_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_PCIE_STRONG_ORDERING_PROMPT), // Question prompt text + STRING_TOKEN (STR_PCIE_STRONG_ORDERING_HELP), // Question help text + QuestionFlags, + STRONG_ORDERING_DEFAULT_OPTION_VALUE, + NULL + ); + + // + // Create the a seperated line + // + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE), + STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE), + STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE) + ); + + // Create Goto form for each RC + for (RC = 0; RC < AC01_MAX_PCIE_ROOT_COMPLEX; RC++) { + + GotoItem = AllocateZeroPool (sizeof (SETUP_GOTO_DATA)); + if (GotoItem == NULL) { + return EFI_OUT_OF_RESOURCES; + } + GotoItem->PciDevIdx = RC; + + GotoId = GOTO_ID_BASE + (UINT16)RC; + + // Update HII string + UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RC); + GotoItem->GotoStringId = HiiSetString ( + PrivateData->HiiHandle, + 0, + Str, + NULL + ); + GotoItem->GotoHelpStringId = STRING_TOKEN (STR_PCIE_GOTO_HELP); + GotoItem->ShowItem = TRUE; + + // Add goto control + HiiCreateGotoOpCode ( + StartOpCodeHandle, + RC0_FORM_ID + RC, + GotoItem->GotoStringId, + GotoItem->GotoHelpStringId, + EFI_IFR_FLAG_CALLBACK, + GotoId + ); + } + + HiiUpdateForm ( + PrivateData->HiiHandle, // HII handle + &gPcieFormSetGuid, // Formset GUID + FORM_ID, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + + return EFI_SUCCESS; +} + +VOID +NVParamVarstoreInit ( + VOID + ) +{ + BOOLEAN BoardSettingValid; + BOOLEAN UserSettingValid; + BOOLEAN Update; + EFI_STATUS Status; + UINT32 UserValue; + UINT32 InitValue; + + mReadOnlyStrongOrdering = FALSE; + + // S0 + UserSettingValid = FALSE; + Status = NVParamGet ( + NV_SI_MESH_S0_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + &UserValue + ); + if (!EFI_ERROR (Status)) { + UserSettingValid = TRUE; + } + + // + // InitValue will be default value or board setting value. + // + BoardSettingValid = FALSE; + Status = NVParamGet ( + NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + &InitValue + ); + if (!EFI_ERROR (Status) && InitValue > 0) { + BoardSettingValid = TRUE; + mReadOnlyStrongOrdering = TRUE; + } else { + InitValue = STRONG_ORDERING_DEFAULT_NVPARAM_VALUE; + } + + Update = TRUE; + if ((UserSettingValid && (UserValue == InitValue)) + || (!BoardSettingValid && UserSettingValid && (UserValue == 0))) + { + Update = FALSE; + } + + if (Update) { + Status = NVParamSet ( + NV_SI_MESH_S0_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + NV_PERM_BIOS | NV_PERM_MANU, + InitValue + ); + ASSERT_EFI_ERROR (Status); + } + + // + // No need to check slave present. + // + UserSettingValid = FALSE; + Status = NVParamGet ( + NV_SI_MESH_S1_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + &UserValue + ); + if (!EFI_ERROR (Status)) { + UserSettingValid = TRUE; + } + + // + // InitValue will be default value or board setting value. + // + BoardSettingValid = FALSE; + Status = NVParamGet ( + NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + &InitValue + ); + if (!EFI_ERROR (Status) && InitValue > 0) { + BoardSettingValid = TRUE; + mReadOnlyStrongOrdering = TRUE; + } else { + InitValue = STRONG_ORDERING_DEFAULT_NVPARAM_VALUE; + } + + Update = TRUE; + if ((UserSettingValid && (UserValue == InitValue)) + || (!BoardSettingValid && UserSettingValid && (UserValue == 0))) + { + Update = FALSE; + } + + if (Update) { + Status = NVParamSet ( + NV_SI_MESH_S1_CXG_RC_STRONG_ORDERING_EN, + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, + NV_PERM_BIOS | NV_PERM_MANU, + InitValue + ); + ASSERT_EFI_ERROR (Status); + } +} + +/** + Build PCIe menu screen. + + @param[in] RCList List of Root Complex with properties. + + @retval EFI_SUCCESS The operation is successful. + @retval Others An error occurred. +**/ +EFI_STATUS +EFIAPI +BoardPcieScreenInitialize ( + IN AC01_RC *NewRCList + ) +{ + EFI_STATUS Status; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HII_STRING_PROTOCOL *HiiString; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; + UINTN BufferSize; + BOOLEAN IsUpdated; + VARSTORE_DATA *VarStoreConfig; + UINT8 RCIndex; + AC01_RC *RC; + + // + // Initialize driver private data + // + mPrivateData = AllocateZeroPool (sizeof (SCREEN_PRIVATE_DATA)); + if (mPrivateData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->Signature = SCREEN_PRIVATE_DATA_SIGNATURE; + + mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig; + mPrivateData->ConfigAccess.RouteConfig = RouteConfig; + mPrivateData->ConfigAccess.Callback = DriverCallback; + + // + // Locate Hii Database protocol + // + Status = gBS->LocateProtocol ( + &gEfiHiiDatabaseProtocolGuid, + NULL, + (VOID **)&HiiDatabase + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiDatabase = HiiDatabase; + + // + // Locate HiiString protocol + // + Status = gBS->LocateProtocol ( + &gEfiHiiStringProtocolGuid, + NULL, + (VOID **)&HiiString + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiString = HiiString; + + // + // Locate ConfigRouting protocol + // + Status = gBS->LocateProtocol ( + &gEfiHiiConfigRoutingProtocolGuid, + NULL, + (VOID **)&HiiConfigRouting + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiConfigRouting = HiiConfigRouting; + + // + // Locate keyword handler protocol + // + Status = gBS->LocateProtocol ( + &gEfiConfigKeywordHandlerProtocolGuid, + NULL, + (VOID **)&HiiKeywordHandler + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiKeywordHandler = HiiKeywordHandler; + + DriverHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + + mPrivateData->DriverHandle = DriverHandle; + + // + // Publish our HII data + // + HiiHandle = HiiAddPackages ( + &gPcieFormSetGuid, + DriverHandle, + BoardPcieLibStrings, + BoardPcieVfrBin, + NULL + ); + if (HiiHandle == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->HiiHandle = HiiHandle; + + // Make a shadow copy all Root Complexes' properties + CopyMem ((VOID *)RCList, (VOID *)NewRCList, sizeof (RCList)); + + // + // Initialize NVParam varstore configuration data + // + NVParamVarstoreInit (); + + // + // Initialize efi varstore configuration data + // + VarStoreConfig = &mPrivateData->VarStoreConfig; + ZeroMem (VarStoreConfig, sizeof (VARSTORE_DATA)); + + // Get Buffer Storage data from EFI variable + BufferSize = sizeof (VARSTORE_DATA); + Status = gRT->GetVariable ( + gPcieVarstoreName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + VarStoreConfig + ); + + IsUpdated = FALSE; + + if (EFI_ERROR (Status)) { + VarStoreConfig->SmmuPmu = 0; /* Disable by default */ + IsUpdated = TRUE; + } + // Update board settings to menu + for (RCIndex = 0; RCIndex < AC01_MAX_PCIE_ROOT_COMPLEX; RCIndex++) { + RC = &RCList[RCIndex]; + + if (EFI_ERROR (Status)) { + VarStoreConfig->RCBifurcationLow[RCIndex] = RC->DevMapLow; + VarStoreConfig->RCBifurcationHigh[RCIndex] = RC->DevMapHigh; + VarStoreConfig->RCStatus[RCIndex] = RC->Active; + IsUpdated = TRUE; + } + } + + if (IsUpdated) { + // Update Buffer Storage + Status = gRT->SetVariable ( + gPcieVarstoreName, + &gPcieFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (VARSTORE_DATA), + VarStoreConfig + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + Status = PcieMainScreenSetup (mPrivateData); + ASSERT_EFI_ERROR (Status); + + for (RCIndex = 0; RCIndex < AC01_MAX_PCIE_ROOT_COMPLEX; RCIndex++) { + Status = PcieRCScreenSetup (RCIndex, mPrivateData); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.uni b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.uni new file mode 100644 index 000000000000..5739a35b4ee5 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieScreen.uni @@ -0,0 +1,102 @@ +// +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// + +#langdef en-US "English" + +#string STR_PCIE_FORM #language en-US "PCIE Root Complex Configuration" +#string STR_PCIE_FORM_HELP #language en-US "Configure Root Complex" + +#string STR_PCIE_FORM_SEPERATE_LINE #language en-US "" + +///// + +#string STR_PCIE_GOTO #language en-US "" +#string STR_PCIE_GOTO_HELP #language en-US "Change On Board Root Complex Settings." + +#string STR_PCIE_RC_STATUS #language en-US "" +#string STR_PCIE_RC_STATUS_HELP #language en-US "Enable / Disable Root Complex" + +#string STR_PCIE_RCA_BIFUR #language en-US "Bifurcation x16" +#string STR_PCIE_RCA_BIFUR_HELP #language en-US "Set bifurcation mode for x16 Root Complex Type-A" + +#string STR_PCIE_RCB_LO_BIFUR #language en-US "Bifurcation 1st x8" +#string STR_PCIE_RCB_LO_BIFUR_HELP #language en-US "Set bifurcation mode for 1st x8 Root Complex Type-B" + +#string STR_PCIE_RCB_HI_BIFUR #language en-US "Bifurcation 2nd x8" +#string STR_PCIE_RCB_HI_BIFUR_HELP #language en-US "Set bifurcation mode for 2nd x8 Root Complex Type-B" + +///// + +#string STR_PCIE_RC0_FORM #language en-US "Root Complex 0 Configuration" +#string STR_PCIE_RC0_FORM_HELP #language en-US "Root Complex 0 Configuration" + +#string STR_PCIE_RC1_FORM #language en-US "Root Complex 1 Configuration" +#string STR_PCIE_RC1_FORM_HELP #language en-US "Root Complex 1 Configuration" + +#string STR_PCIE_RC2_FORM #language en-US "Root Complex 2 Configuration" +#string STR_PCIE_RC2_FORM_HELP #language en-US "Root Complex 2 Configuration" + +#string STR_PCIE_RC3_FORM #language en-US "Root Complex 3 Configuration" +#string STR_PCIE_RC3_FORM_HELP #language en-US "Root Complex 3 Configuration" + +#string STR_PCIE_RC4_FORM #language en-US "Root Complex 4 Configuration" +#string STR_PCIE_RC4_FORM_HELP #language en-US "Root Complex 4 Configuration" + +#string STR_PCIE_RC5_FORM #language en-US "Root Complex 5 Configuration" +#string STR_PCIE_RC5_FORM_HELP #language en-US "Root Complex 5 Configuration" + +#string STR_PCIE_RC6_FORM #language en-US "Root Complex 6 Configuration" +#string STR_PCIE_RC6_FORM_HELP #language en-US "Root Complex 6 Configuration" + +#string STR_PCIE_RC7_FORM #language en-US "Root Complex 7 Configuration" +#string STR_PCIE_RC7_FORM_HELP #language en-US "Root Complex 7 Configuration" + +#string STR_PCIE_RC8_FORM #language en-US "Root Complex 8 Configuration" +#string STR_PCIE_RC8_FORM_HELP #language en-US "Root Complex 8 Configuration" + +#string STR_PCIE_RC9_FORM #language en-US "Root Complex 9 Configuration" +#string STR_PCIE_RC9_FORM_HELP #language en-US "Root Complex 9 Configuration" + +#string STR_PCIE_RC10_FORM #language en-US "Root Complex 10 Configuration" +#string STR_PCIE_RC10_FORM_HELP #language en-US "Root Complex 10 Configuration" + +#string STR_PCIE_RC11_FORM #language en-US "Root Complex 11 Configuration" +#string STR_PCIE_RC11_FORM_HELP #language en-US "Root Complex 11 Configuration" + +#string STR_PCIE_RC12_FORM #language en-US "Root Complex 12 Configuration" +#string STR_PCIE_RC12_FORM_HELP #language en-US "Root Complex 12 Configuration" + +#string STR_PCIE_RC13_FORM #language en-US "Root Complex 13 Configuration" +#string STR_PCIE_RC13_FORM_HELP #language en-US "Root Complex 13 Configuration" + +#string STR_PCIE_RC14_FORM #language en-US "Root Complex 14 Configuration" +#string STR_PCIE_RC14_FORM_HELP #language en-US "Root Complex 14 Configuration" + +#string STR_PCIE_RC15_FORM #language en-US "Root Complex 15 Configuration" +#string STR_PCIE_RC15_FORM_HELP #language en-US "Root Complex 15 Configuration" + +#string STR_PCIE_BIFUR_SELECT_VALUE0 #language en-US "x16" +#string STR_PCIE_BIFUR_SELECT_VALUE1 #language en-US "x8+x8" +#string STR_PCIE_BIFUR_SELECT_VALUE2 #language en-US "x8+x4+x4" +#string STR_PCIE_BIFUR_SELECT_VALUE3 #language en-US "x4+x4+x4+x4" +#string STR_PCIE_BIFUR_SELECT_VALUE4 #language en-US "x8" +#string STR_PCIE_BIFUR_SELECT_VALUE5 #language en-US "x4+x4" +#string STR_PCIE_BIFUR_SELECT_VALUE6 #language en-US "x4+x2+x2" +#string STR_PCIE_BIFUR_SELECT_VALUE7 #language en-US "x2+x2+x2+x2" + +#string STR_PCIE_SOCKET #language en-US "Socket" +#string STR_PCIE_SOCKET_HELP #language en-US "Socket 0 - Master; Socket 1 - Slave" +#string STR_PCIE_SOCKET_VALUE #language en-US "" + +#string STR_PCIE_RC_TYPE #language en-US "Type" +#string STR_PCIE_RC_TYPE_HELP #language en-US "Type-A: x16 lanes bifurcated down to x4; Type-B: 2 of x8 lanes, each bifurcated down to x2" +#string STR_PCIE_RC_TYPE_VALUE #language en-US "" + +#string STR_PCIE_SMMU_PMU_PROMPT #language en-US "SMMU Pmu" +#string STR_PCIE_SMMU_PMU_HELP #language en-US "Enable/Disable PMU feature for SMMU" + +#string STR_PCIE_STRONG_ORDERING_PROMPT #language en-US "PCIe Strong Ordering" +#string STR_PCIE_STRONG_ORDERING_HELP #language en-US "Enable/disable PCIe Strong Ordering with internal bus" -- 2.17.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#80713): https://edk2.groups.io/g/devel/message/80713 Mute This Topic: https://groups.io/mt/85631176/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-