From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) by mx.groups.io with SMTP id smtpd.web08.4978.1623105963607805672 for ; Mon, 07 Jun 2021 15:46:04 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=G7FRJbb2; spf=pass (domain: nuviainc.com, ip: 209.85.128.47, mailfrom: leif@nuviainc.com) Received: by mail-wm1-f47.google.com with SMTP id d184so653782wmd.0 for ; Mon, 07 Jun 2021 15:46:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=evAQXDr8BL5rWdk8wwfTatOLlSdFolMwm5Z5sI1uLB8=; b=G7FRJbb2Nhc004EUB1IQ2donikAbdFSOaqHDaUK+JbXzxBeQ/FYnIvzexVIMyGOpQd wdeqZWp8g/kHh9xadxeXWEYhmBXkDQNPr9Kz2/h9TEJUc1SSp7uiOdDPU/FvBFIOTx8Y 7hOmGYbym1//Cdss6coeFEyyeSU6sGG7kkg/fYCxn3+KpBxWuijQdBhgw3L+mOVWrnvq H9+lfEIdtNQ7ZXGDhz8WcUJZzhW/TwjPw+gi9Llz9jLAzrPYvo0A/uVQpDFL7xqkjdSV 3Ohhi17uiQxYY3jpDLOQaUYIE1iKDvgNOwLfwuWh21BvKfdJ7LTJpP6XPHe6ESuaHQUz jcpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=evAQXDr8BL5rWdk8wwfTatOLlSdFolMwm5Z5sI1uLB8=; b=ba07de3j9tJ+0aQ2odctl6CJLONsmtxUCc2uS/7t61RbaYU0685/yD+f6eP631ylxi dfqQlMIQ41r386/VCiAKVcyNX8FP1p4NPjrgyFtXG7XkyEiIl3CurITBpayCtnQLWBM+ d2DnSqzfGW/aps/4qKOXS5y5grSAHBNlKSK8npLTMHS/dBRjhmNvUoJsu1/esZnIj/1R jWhSNuI2kzMJsj4nY+dDFlASjQxH7KGJVW5nsJA/hsPa7plLUOrBzoiFpzlHGqizCzz4 KFKmm4MRPCWj5Yr0sl/PXRsNwQP0W7U8C2F9qdg1xb7AQgFD/xg+uTYKvrLk8ZzXaaVD JDGA== X-Gm-Message-State: AOAM533xRA6hCORHsTG4+EdXLZjUvNdbhFxV2xkuSf7duvX1nUxEUeyq g5hl1fcBV/Ku7XCbbtMgZfdazg== X-Google-Smtp-Source: ABdhPJxeIOSTZBt/CPhNZGXmH4GdDqRpyy7ww1ZoVqGAkhvdbuuHzNnhtMQZtDFd8Zj0kIbWxUo6Rg== X-Received: by 2002:a1c:a3c3:: with SMTP id m186mr19482972wme.154.1623105961728; Mon, 07 Jun 2021 15:46:01 -0700 (PDT) Return-Path: Received: from leviathan (cpc1-cmbg19-2-0-cust915.5-4.cable.virginm.net. [82.27.183.148]) by smtp.gmail.com with ESMTPSA id m23sm16288304wmc.29.2021.06.07.15.46.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 15:46:01 -0700 (PDT) Date: Mon, 7 Jun 2021 23:45:59 +0100 From: "Leif Lindholm" To: Nhi Pham Cc: devel@edk2.groups.io, Vu Nguyen , Thang Nguyen , Chuong Tran , Phong Vo , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: Re: [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib library instance Message-ID: <20210607224559.iyxafgcby7g6tqpg@leviathan> References: <20210526100724.5359-1-nhi@os.amperecomputing.com> <20210526100724.5359-17-nhi@os.amperecomputing.com> MIME-Version: 1.0 In-Reply-To: <20210526100724.5359-17-nhi@os.amperecomputing.com> Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, May 26, 2021 at 17:07:07 +0700, Nhi Pham wrote: > From: Vu Nguyen > > Provides basic features like: > * Screen menu to change bifurcation setting of each Root Complex. Note > that we can only change the option for Root Complex which doesn't have > 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 > Cc: Chuong Tran > Cc: Phong Vo > Cc: Leif Lindholm > Cc: Michael D Kinney > Cc: Ard Biesheuvel > Cc: Nate DeSimone > > Signed-off-by: Vu Nguyen > --- > Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 + > Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf | 60 ++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h | 89 ++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h | 138 +++ > Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h | 102 ++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr | 212 ++++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c | 438 ++++++++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c | 327 ++++++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c | 1120 ++++++++++++++++++++ > Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni | 99 ++ > 10 files changed, 2588 insertions(+) > > diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > index 0d79673ce50a..a372a4e0078b 100644 > --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > @@ -40,6 +40,9 @@ [LibraryClasses] > ## @libraryclass Defines a set of methods to initialize Pcie > PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h > > + ## @libraryclass Defines a set of miscellaneous PCIe functions > + PcieBoardLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h > + > ## @libraryclass Defines a set of methods to access flash memory. > FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h > > diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf > new file mode 100644 > index 000000000000..6be78f8936d7 > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf > @@ -0,0 +1,60 @@ > +## @file > +# > +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = PcieBoardLib > + FILE_GUID = 062191A6-E113-4FD6-84C7-E400B4B34759 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = PcieBoardLib > + > +[Sources] > + PcieBoard.c > + PcieBoardCommon.c > + PcieBoardScreen.c > + PcieBoardScreen.h > + PcieBoardScreen.uni > + NVDataStruc.h > + Vfr.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 > + UefiLib > + 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/PcieBoardLib/NVDataStruc.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h > new file mode 100644 > index 000000000000..f94f12d968fd > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h (Should this not be NVDataStruct.h? > @@ -0,0 +1,89 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef NVDATASTRUC_H_ > +#define NVDATASTRUC_H_ > + > +#define MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX 16 > + > +#define PCIE_VARSTORE_NAME L"PcieIfrNVData" > +#define PCIE_VARSTORE_ID 0x1234 > +#define PCIE_FORM_ID 0x1235 > +#define PCIE_RC0_FORM_ID 0x1236 > +#define PCIE_RC1_FORM_ID 0x1237 > +#define PCIE_RC2_FORM_ID 0x1238 > +#define PCIE_RC3_FORM_ID 0x1239 > +#define PCIE_RC4_FORM_ID 0x123A > +#define PCIE_RC5_FORM_ID 0x123B > +#define PCIE_RC6_FORM_ID 0x123C > +#define PCIE_RC7_FORM_ID 0x123D > +#define PCIE_RC8_FORM_ID 0x123E > +#define PCIE_RC9_FORM_ID 0x123F > +#define PCIE_RC10_FORM_ID 0x1240 > +#define PCIE_RC11_FORM_ID 0x1241 > +#define PCIE_RC12_FORM_ID 0x1242 > +#define PCIE_RC13_FORM_ID 0x1243 > +#define PCIE_RC14_FORM_ID 0x1244 > +#define PCIE_RC15_FORM_ID 0x1245 > +#define PCIE_FORM_SET_GUID { 0xe84e70d6, 0xe4b2, 0x4c6e, { 0x98, 0x51, 0xcb, 0x2b, 0xac, 0x77, 0x7d, 0xbb } } > + > +#define PCIE_GOTO_ID_BASE 0x8040 Would recommend prefix before PCIE. Or, given this is a fully local include - dropping the PCIE prefix. > + > +#pragma pack(1) > + > +// > +// NV data structure definition > +// > +typedef struct { > + BOOLEAN RCStatus[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX]; > + UINT8 RCBifurLo[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX]; > + UINT8 RCBifurHi[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX]; > + UINT32 SmmuPmu; > +} PCIE_VARSTORE_DATA; Same. > + > +// > +// 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 > + > +#pragma pack() Move this to just after the struct? Nothing to pack beyond that. > + > +#endif > diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h > new file mode 100644 > index 000000000000..c5c50060870c > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h > @@ -0,0 +1,138 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PCIE_SCREEN_H_ > +#define PCIE_SCREEN_H_ Needs to not start with PCIE - additional prefix is fine. > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Move all include statements not needed by this header file to the .c file that actually uses them. > + > +#include "NVDataStruc.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 VfrBin[]; Add some descriptive prefix. PcieBoardVfrBin? > + > +// > +// 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 PcieDxeStrings[]; Not part of PCIE or PI spec - add "Platform" or something prefix. > + > +#define MAX_EDITABLE_ELEMENTS 3 > +#define PCIE_RC0_STATUS_OFFSET \ > + OFFSET_OF (PCIE_VARSTORE_DATA, RCStatus[0]) > +#define PCIE_RC0_BIFUR_LO_OFFSET \ > + OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurLo[0]) > +#define PCIE_RC0_BIFUR_HI_OFFSET \ > + OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurHi[0]) > +#define PCIE_SMMU_PMU_OFFSET \ > + OFFSET_OF (PCIE_VARSTORE_DATA, SmmuPmu) > + > +#define PCIE_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'E') This signature is supposed to be at least potentially unique. > + > +typedef struct { > + UINTN Signature; > + > + EFI_HANDLE DriverHandle; > + EFI_HII_HANDLE HiiHandle; > + PCIE_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; > + > + // > + // Produced protocol > + // > + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; > +} PCIE_SCREEN_PRIVATE_DATA; Structs need more unique prefixes. > + > +typedef union { > + UINT16 VAR_ID; > + struct _PCIE_VAR_ID { > + UINT16 PciDevIndex : 12; > + UINT16 DataType : 3; > + UINT16 Always1 : 1; > + } IdField; > +} PCIE_VAR_ID; > + > +typedef struct { > + UINTN PciDevIdx; > + EFI_STRING_ID GotoStringId; > + EFI_STRING_ID GotoHelpStringId; > + UINT16 GotoKey; > + BOOLEAN ShowItem; > +} PCIE_SETUP_GOTO_DATA; > + > +typedef struct { > + VOID *StartOpCodeHandle; > + VOID *EndOpCodeHandle; > + EFI_IFR_GUID_LABEL *StartLabel; > + EFI_IFR_GUID_LABEL *EndLabel; > + > +} PCIE_IFR_INFO; > + > +#define PCIE_SCREEN_PRIVATE_FROM_THIS(a) \ > + CR (a, PCIE_SCREEN_PRIVATE_DATA, ConfigAccess, PCIE_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 > +PcieRCDevMapLoDefaultSetting ( > + IN UINTN RCIndex, > + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData > + ); > + > +UINT8 > +PcieRCDevMapHiDefaultSetting ( > + IN UINTN RCIndex, > + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData > + ); > + > +BOOLEAN > +PcieRCActiveDefaultSetting ( > + IN UINTN RCIndex, > + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData > + ); > + > +#endif /* PCIE_SCREEN_H_ */ > diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h > new file mode 100644 > index 000000000000..bff5b62ba13b > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h > @@ -0,0 +1,102 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PCIE_BOARD_LIB_H_ > +#define PCIE_BOARD_LIB_H_ > + > +#include "Pcie.h" OK, I'm going to stop pointing this out from this point on, but anything that is not referencing a direct aspect of the PCIe specification should not be named PCIE*/Pcie*, ... These names are reserved. Since most of these symbols are internal anyway, and reference only settings inside the PCIE configuration screen, I think the cleanest thing would be to drop the PCIE/Pcie prefixes altogether. > + > +/** > + > + Check if a PCIE port enabled in the board configuration. > + > + @param Index The port index. > + > + @retval TRUE if the port enabled, otherwise FALSE. > + > +**/ > +BOOLEAN > +PcieBoardCheckSysSlotEnabled ( > + IN UINTN Index > + ); > + > +VOID > +PcieBoardGetRCSegmentNumber ( > + IN AC01_RC *RC, > + OUT UINTN *SegmentNumber > + ); > + > +/** > + > + Check if SMM PMU enabled in board screen > + > + @retval TRUE if the SMMU PMU enabled, otherwise FALSE. > + > +**/ > +BOOLEAN > +PcieBoardCheckSmmuPmuEnabled ( > + VOID > + ); > + > +/** > + > + Build UEFI menu. > + > + @param ImageHandle Handle. > + @param SystemTable Pointer to System Table. > + @param RCList List of Root Complex with properties. > + > + @retval EFI_SUCCESS if successful, otherwise EFI_ERROR. > + > +**/ > +EFI_STATUS > +PcieBoardScreenInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable, > + IN AC01_RC *RCList > + ); > + > +BOOLEAN > +IsEmptyRC ( > + IN AC01_RC *RC > + ); > + > +VOID > +PcieBoardSetupDevmap ( > + IN AC01_RC *RC > + ); > + > +VOID > +PcieBoardGetLaneAllocation ( > + IN AC01_RC *RC > + ); > + > +VOID > +PcieBoardGetSpeed ( > + IN AC01_RC *RC > + ); > + > +VOID > +PcieBoardParseRCParams ( > + IN AC01_RC *RC > + ); > + > +VOID > +PcieBoardAssertPerst ( > + AC01_RC *RC, > + UINT32 PcieIndex, > + UINT8 Bifurcation, > + BOOLEAN isPullToHigh > + ); > + > +BOOLEAN > +PcieBoardCheckSmmuPmuEnabled ( > + VOID > + ); > + > +#endif /* PCIE_BOARD_LIB_H_ */ > diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr > new file mode 100644 > index 000000000000..a596d5ac9a92 > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr > @@ -0,0 +1,212 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "NVDataStruc.h" > + > +formset > + guid = PCIE_FORM_SET_GUID, > + title = STRING_TOKEN(STR_PCIE_FORM), > + help = STRING_TOKEN(STR_PCIE_FORM_HELP), > + classguid = gPlatformManagerFormsetGuid, > + > + // > + // Define a variable Storage > + // > + varstore PCIE_VARSTORE_DATA, > + varid = PCIE_VARSTORE_ID, > + name = PcieIfrNVData, > + guid = PCIE_FORM_SET_GUID; > + > + form > + formid = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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 = PCIE_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/PcieBoardLib/PcieBoard.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c > new file mode 100644 > index 000000000000..c0c94d349b5b > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c > @@ -0,0 +1,438 @@ > +/** @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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#ifndef BIT > +#define BIT(nr) (1 << (nr)) > +#endif > + > +extern CHAR16 VariableName[]; > +extern EFI_GUID gPcieFormSetGuid; > + > +VOID > +EFIAPI > +PcieBoardLoadPreset ( > + IN AC01_RC *RC > + ) > +{ > + UINT32 Nv; > + INTN NvParam; > + INTN Ret; > + INTN i; > + > + // Load default value > + for (i = 0; i < MAX_PCIE_B; i++) { > + RC->PresetGen3[i] = PRESET_INVALID; > + RC->PresetGen4[i] = PRESET_INVALID; > + } > + > + // Load override value > + if (RC->Socket == 0) { > + if (RC->Type == RCA) { > + if (RC->ID < 4) { There are various live-coded values of 4 and 2 in this function. Please replace them with #defines with descriptive names to improve readability. > + NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET + RC->ID * NVPARAM_SIZE; > + } else { > + NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE; > + } > + } else { > + NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE); > + } > + } else if (RC->Type == RCA) { > + if (RC->ID < 4) { > + NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET + (RC->ID - 2) * NVPARAM_SIZE; > + } else { > + NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE; > + } > + } else { > + NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE); > + } > + > + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); > + if (Ret == EFI_SUCCESS) { > + for (i = 0; i < 4; i++) { > + RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF; > + } > + } > + > + if (RC->Type == RCB) { > + NvParam += NVPARAM_SIZE; > + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); > + if (Ret == EFI_SUCCESS) { > + for (i = 0; i < 4; i++) { > + RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF; > + } > + } > + } > + > + if (RC->Socket == 0) { > + if (RC->Type == RCA) { > + if (RC->ID < 4) { > + NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET + RC->ID * NVPARAM_SIZE; > + } else { > + NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE; > + } > + } else { > + NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE); > + } > + } else if (RC->Type == RCA) { > + if (RC->ID < 4) { > + NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET + (RC->ID - 2) * NVPARAM_SIZE; > + } else { > + NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE; > + } > + } else { > + NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE); > + } > + > + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); > + if (Ret == EFI_SUCCESS) { > + for (i = 0; i < 4; i++) { > + RC->PresetGen4[i] = (Nv >> (8 * i)) & 0xFF; > + } > + } > + > + if (RC->Type == RCB) { > + NvParam += NVPARAM_SIZE; > + Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); > + if (Ret == EFI_SUCCESS) { > + for (i = 0; i < 4; i++) { > + RC->PresetGen4[i + 4] = (Nv >> (8 * i)) & 0xFF; > + } > + } > + } > +} > + > +VOID > +EFIAPI > +PcieBoardParseRCParams ( > + IN AC01_RC *RC > + ) > +{ > + UINT32 Efuse; > + PLATFORM_INFO_HOB *PlatformHob; > + UINT8 PlatRCId; > + EFI_STATUS Status; > + VOID *Hob; > + UINTN BufferSize; > + PCIE_VARSTORE_DATA VarStoreConfig = { > + .RCStatus = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, > + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE}, > + .RCBifurLo = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, > + .RCBifurHi = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, > + .SmmuPmu = 0 > + }; > + > + PCIE_DEBUG ("%a - Socket%d RC%d\n", __FUNCTION__, RC->Socket, RC->ID); > + > + PlatRCId = RC->Socket * RCS_PER_SOCKET + RC->ID; > + // Get RC activation status > + BufferSize = sizeof (PCIE_VARSTORE_DATA); > + Status = gRT->GetVariable ( > + VariableName, > + &gPcieFormSetGuid, > + NULL, > + &BufferSize, > + &VarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + PCIE_DEBUG ("%a - Failed to read PCIE variable data from config store.\n", __FUNCTION__); > + } > + > + RC->Active = VarStoreConfig.RCStatus[PlatRCId]; > + RC->DevMapLo = VarStoreConfig.RCBifurLo[PlatRCId]; > + RC->DevMapHi = VarStoreConfig.RCBifurHi[PlatRCId]; > + > + PCIE_DEBUG ( > + "%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] << RCS_PER_SOCKET); > + PCIE_DEBUG ( > + "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; > + PCIE_DEBUG ("RC[%d]: Flags 0x%x\n", RC->ID, RC->Flags); > + } > + } > + } > + > + RC->Active = (RC->Active && !(Efuse & BIT (PlatRCId))) ? TRUE : FALSE; > + } > + > + /* Load Gen3/Gen4 preset */ > + PcieBoardLoadPreset (RC); > + PcieBoardGetLaneAllocation (RC); > + PcieBoardSetupDevmap (RC); > + PcieBoardGetSpeed (RC); > +} > + > +VOID > +EFIAPI > +PcieBoardReleaseAllPerst ( > + 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); > + } > +} > + > +VOID > +EFIAPI > +PcieBoardAssertPerst ( > + AC01_RC *RC, > + UINT32 PcieIndex, > + UINT8 Bifurcation, > + BOOLEAN isPullToHigh CamelCase uses leading capital letter. > + ) > +{ > + UINT32 GpioGroupVal, Val, GpioIndex, GpioPin; > + > + /* > + * For Post-silicon, Fansipan board is using GPIO combination (GPIO[16..21]) > + * to control CPLD. > + * It should be follow PCIE RESET TABLE in Fansipan schematic. > + * > + * Depend on Bifurcation settings, will active corresponding PERST pin or not > + */ > + > + if (RC->Type == RCA) { > + switch (Bifurcation) { > + case 0: // RCA_BIFURCATION_ONE_X16: > + if (PcieIndex != 0) { // 1,2,3 > + } > + break; > + > + case 1: // RCA_BIFURCATION_TWO_X8: Wouldn't this look an awful lot better as case RCA_BIFURCATION_TWO_X8: than with a live-coded integer, followed by a comment explaining what that integer means? This appplies throughout this function. > + if ((PcieIndex == 1) || (PcieIndex == 3)) { // 1,3 > + } > + break; > + > + case 2: // RCA_BIFURCATION_ONE_X8_TWO_X4: > + if (PcieIndex == 1) { // 1 > + } > + break; > + > + case 3: // RCA_BIFURCATION_FOUR_X4: > + break; > + > + default: > + PCIE_DEBUG ("Invalid Bifurcation setting\n"); > + break; > + } > + } else { // RCB > + switch (Bifurcation) { > + case 0: // RCB_BIFURCATION_ONE_X8: > + if ((PcieIndex != 0) && (PcieIndex != 4)) { // 1,2,3,5,6,7 > + } > + break; > + > + case 1: // RCB_BIFURCATION_TWO_X4: > + if ((PcieIndex % 2) != 0) { // 1,3,5,7 > + } > + break; > + > + case 2: // RCB_BIFURCATION_ONE_X4_TWO_X2: > + if ((PcieIndex == 1) || (PcieIndex == 5)) { > + } > + break; > + > + case 3: // RCB_BIFURCATION_FOUR_X2: > + break; > + > + default: > + PCIE_DEBUG ("Invalid Bifurcation setting\n"); > + break; > + } > + } > + > + if (!isPullToHigh) { // Pull PERST to Low > + if (RC->Type == RCA) { // RCA: RC->ID: 0->3 ; PcieIndex: 0->3 > + GpioGroupVal = 62 - RC->ID*4 - PcieIndex; That 62 needs to be a #define. > + } > + else { // RCB: RC->ID: 4->7 ; PcieIndex: 0->7 else on same line as } > + GpioGroupVal = 46 - (RC->ID - 4)*8 - PcieIndex; > + } > + > + GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * RC->Socket + 16; > + for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) { > + // 6: Number of GPIO pins to control via CPLD > + 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 > + PcieBoardReleaseAllPerst (RC->Socket); > + } > +} > + > +/** > + * Overrride the segment number for a root complex with > + * a board specific number. > + **/ > +VOID > +EFIAPI > +PcieBoardGetRCSegmentNumber ( > + IN AC01_RC *RC, > + OUT UINTN *SegmentNumber > + ) > +{ > + if (RC->Socket == 0) { > + if (RC->Type == RCA) { > + switch (RC->ID) { > + case 0: > + *SegmentNumber = 12; > + break; > + > + case 1: > + *SegmentNumber = 13; > + break; > + > + case 2: > + *SegmentNumber = 1; > + break; > + > + case 3: > + *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 == 0 || RC->ID == 1) { > + *SegmentNumber = 16; > + } else { > + *SegmentNumber = 4 + RC->ID; > + } > + } > +} > + > +BOOLEAN > +EFIAPI > +PcieBoardCheckSmmuPmuEnabled ( > + VOID > + ) > +{ > + EFI_GUID PcieFormSetGuid = PCIE_FORM_SET_GUID; > + PCIE_VARSTORE_DATA VarStoreConfig; > + UINTN BufferSize; > + EFI_STATUS Status; > + > + // Get Buffer Storage data from EFI variable > + BufferSize = sizeof (PCIE_VARSTORE_DATA); > + Status = gRT->GetVariable ( > + PCIE_VARSTORE_NAME, > + &PcieFormSetGuid, > + NULL, > + &BufferSize, > + &VarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + return FALSE; > + } > + > + return VarStoreConfig.SmmuPmu; > +} > diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c > new file mode 100644 > index 000000000000..a8accbf53047 > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c > @@ -0,0 +1,327 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > + > +#include "Pcie.h" > + > +/* Host bridge registers */ > +#define HBRCAPDMR 0x0 > +#define HBRCBPDMR 0x4 Inappropriate names for this codebase. Are these the actual register names as described in hardware manuals for this device? If so, they can be permitted. But every file where these names are used need to contain a glossary section at the start of it, explaining what these actually are. Applies also below. > + > +/* HBRCAPDMR */ > +#define RCAPCIDEVMAP_SET(dst, src) \ > + (((dst) & ~0x7) | (((UINT32)(src)) & 0x7)) > + > +/* HBRCBPDMR */ > +#define RCBPCIDEVMAPLO_SET(dst, src) \ > + (((dst) & ~0x7) | (((UINT32)(src)) & 0x7)) > +#define RCBPCIDEVMAPHI_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 > +PcieBoardSetRCBifur ( > + 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 1: Would benefit from #defines with descriptive names rather than just live-coded integers. (All cases in switch.) > + 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 = 0; > + RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth); > + RC->Pcie[RPStart + 2].Active = 1; > + RC->Pcie[RPStart + 3].Active = 0; > + break; > + > + case 2: > + 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 = 0; > + 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 = 1; > + RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth); > + RC->Pcie[RPStart + 3].Active = 1; > + break; > + > + case 3: > + 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 = 1; > + RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth); > + RC->Pcie[RPStart + 2].Active = 1; > + RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth); > + RC->Pcie[RPStart + 3].Active = 1; > + break; > + > + case 0: > + 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 = 0; > + RC->Pcie[RPStart + 2].Active = 0; > + RC->Pcie[RPStart + 3].Active = 0; > + break; > + } > +} > + > +VOID > +PcieBoardGetLaneAllocation ( > + 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 = NV_SI_RO_BOARD_S0_RCA0_CFG + RC->Socket * 96 + > + RC->ID * 8; > + } else { > + NvParam = NV_SI_RO_BOARD_S0_RCB0_LO_CFG + RC->Socket * 96 + > + (RC->ID - MAX_RCA) * 16; > + } Please create descriptively named #defines for that 96, 16, and 8. > + > + Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv); > + Nv = (Ret != EFI_SUCCESS) ? 0 : Nv; > + > + for (RPIndex = 0; RPIndex < MAX_PCIE_A; RPIndex++) { > + Width = (Nv >> (RPIndex * 8)) & 0xF; > + 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 = 0; > + RC->Pcie[RPIndex].Active = FALSE; > + break; > + } > + } > + > + if (RC->Type == RCB) { > + // Processing Hi > + NvParam += 8; > + 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) * 8)) & 0xF; Same 8? > + 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 = 0; > + RC->Pcie[RPIndex].Active = FALSE; > + break; > + } > + } > + } > + > + // Do not proceed if no Root Port enabled > + if (IsEmptyRC (RC)) { > + RC->Active = FALSE; > + } > +} > + > +VOID > +PcieBoardSetupDevmap ( > + 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->DefaultDevMapLo = 3; What's a DefaultDevMapLo? The *only* benefit of SuperLongCamelCaseNames is that they actually completely spell out what things are. This makes abbreviating them extremely unfortunate, except where the abbreviation is completely obvious regardless of context. I also have a feeling these 0, 1, 2, 3 could benefit from being replaced by descriptively named #defines. > + } else if (RC->Pcie[PCIE_0].Active > + && RC->Pcie[PCIE_2].Active > + && RC->Pcie[PCIE_3].Active) > + { > + RC->DefaultDevMapLo = 2; > + } else if (RC->Pcie[PCIE_0].Active > + && RC->Pcie[PCIE_2].Active) > + { > + RC->DefaultDevMapLo = 1; > + } else { > + RC->DefaultDevMapLo = 0; > + } > + > + if (RC->Pcie[PCIE_4].Active > + && RC->Pcie[PCIE_5].Active > + && RC->Pcie[PCIE_6].Active > + && RC->Pcie[PCIE_7].Active) > + { > + RC->DefaultDevMapHi = 3; > + } else if (RC->Pcie[PCIE_4].Active > + && RC->Pcie[PCIE_6].Active > + && RC->Pcie[PCIE_7].Active) > + { > + RC->DefaultDevMapHi = 2; > + } else if (RC->Pcie[PCIE_4].Active > + && RC->Pcie[PCIE_6].Active) > + { > + RC->DefaultDevMapHi = 1; > + } else { > + RC->DefaultDevMapHi = 0; > + } > + > + if (RC->DevMapLo == 0) { > + RC->DevMapLo = RC->DefaultDevMapLo; > + } > + > + if (RC->Type == RCB && RC->DevMapHi == 0) { > + RC->DevMapHi = RC->DefaultDevMapHi; > + } > + > + PcieBoardSetRCBifur (RC, PCIE_0, RC->DevMapLo); > + if (RC->Type == RCB) { > + PcieBoardSetRCBifur (RC, PCIE_4, RC->DevMapHi); > + } > + > + if (RC->Active) { > + if (RC->Type == RCA) { > + if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCAPDMR, &Val))) { > + Val = RCAPCIDEVMAP_SET (Val, RC->DevMapLo & 0x7); Is this actively trying to obscure away runtime errors, or are there valid situations where RC->DevMapLo may be higher than 7 and only the bottom 3 bits should be respected? If so, a comment should explain. > + MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCAPDMR, Val); > + } > + } else { > + if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCBPDMR, &Val))) { > + Val = RCBPCIDEVMAPLO_SET (Val, RC->DevMapLo & 0x7); > + Val = RCBPCIDEVMAPHI_SET (Val, RC->DevMapHi & 0x7); Is this actively trying to obscure away runtime errors, or are there valid situations where RC->DevMapLo or RC->DevMapHi may be higher than 7 and only the bottom 3 bits should be respected? If so, a comment should explain. > + MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCBPDMR, Val); > + } > + } > + } > +} > + > +VOID > +PcieBoardGetSpeed ( > + 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->DevMapLo) { > + case 2: /* x8 x4 x4 */ #define for these 2, 3, and 1. > + if (RC->Flags & PCIE_ERRATA_SPEED1) { > + MaxGen = MaxGenTblX8X4X4; > + } > + break; > + > + case 3: /* X4 x4 x4 x4 */ > + if (RC->Flags & PCIE_ERRATA_SPEED1) { > + MaxGen = MaxGenTblX4X4X4X4; > + } > + break; > + > + case 1: /* x8 x8 */ > + default: > + break; > + } > + } > + > + for (RPIdx = 0; RPIdx < MAX_PCIE_A; RPIdx++) { > + RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ? MaxGen[RPIdx] : 0; > + } > + > + 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] : 0; > + } > + } > +} > diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c > new file mode 100644 > index 000000000000..309cc8857b8c > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c > @@ -0,0 +1,1120 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PcieBoardScreen.h" > + > +#ifndef BIT > +#define BIT(nr) (1 << (nr)) > +#endif > + > +#define MAX_STRING_SIZE 32 > + > +CHAR16 VariableName[] = PCIE_VARSTORE_NAME; > +EFI_GUID gPcieFormSetGuid = PCIE_FORM_SET_GUID; > + > +EFI_HANDLE DriverHandle = NULL; > +PCIE_SCREEN_PRIVATE_DATA *mPrivateData = NULL; > + > +AC01_RC RCList[MAX_AC01_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) > + } > + }, > + PCIE_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 > + 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 > + 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; > + PCIE_SCREEN_PRIVATE_DATA *PrivateData; > + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; > + EFI_STRING ConfigRequest; > + EFI_STRING ConfigRequestHdr; > + UINTN Size; > + CHAR16 *StrPointer; > + BOOLEAN AllocatedRequest; > + PCIE_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 = PCIE_SCREEN_PRIVATE_FROM_THIS (This); > + HiiConfigRouting = PrivateData->HiiConfigRouting; > + VarStoreConfig = &PrivateData->VarStoreConfig; > + ASSERT (VarStoreConfig != NULL); > + > + // > + // Get Buffer Storage data from EFI variable. > + // Try to get the current setting from variable. > + // > + BufferSize = sizeof (PCIE_VARSTORE_DATA); > + Status = gRT->GetVariable ( > + VariableName, > + &gPcieFormSetGuid, > + NULL, > + &BufferSize, > + VarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + return EFI_NOT_FOUND; > + } > + > + if (Request == NULL) { > + // > + // Request is set to NULL, construct full request string. > + // > + > + // > + // Allocate and fill a buffer large enough to hold the template > + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a > + // Null-terminator > + // > + ConfigRequestHdr = HiiConstructConfigHdr ( > + &gPcieFormSetGuid, > + VariableName, > + 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 . > + // Note: if only one Storage is used, then this checking could be skipped. > + // > + if (!HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, 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); What is 32? > + 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 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 > + 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; > + PCIE_SCREEN_PRIVATE_DATA *PrivateData; > + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; > + PCIE_VARSTORE_DATA *VarStoreConfig; > + > + if (Configuration == NULL || Progress == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This); > + HiiConfigRouting = PrivateData->HiiConfigRouting; > + *Progress = Configuration; > + VarStoreConfig = &PrivateData->VarStoreConfig; > + ASSERT (VarStoreConfig != NULL); > + > + // > + // Check routing data in . > + // Note: if only one Storage is used, then this checking could be skipped. > + // > + if (!HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, NULL)) { > + return EFI_NOT_FOUND; > + } > + > + // > + // Get Buffer Storage data from EFI variable > + // > + BufferSize = sizeof (PCIE_VARSTORE_DATA); > + Status = gRT->GetVariable ( > + VariableName, > + &gPcieFormSetGuid, > + NULL, > + &BufferSize, > + VarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Check if configuring Name/Value storage > + // > + if (StrStr (Configuration, L"OFFSET") == NULL) { > + // > + // Don't have any Name/Value storage names > + // > + return EFI_SUCCESS; > + } > + > + // > + // Convert to buffer data by helper function ConfigToBlock() > + // > + BufferSize = sizeof (PCIE_VARSTORE_DATA); > + Status = HiiConfigRouting->ConfigToBlock ( > + HiiConfigRouting, > + Configuration, > + (UINT8 *)VarStoreConfig, > + &BufferSize, > + Progress > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Store Buffer Storage back to variable > + // > + Status = gRT->SetVariable ( > + VariableName, > + &gPcieFormSetGuid, > + EFI_VARIABLE_NON_VOLATILE | > + EFI_VARIABLE_BOOTSERVICE_ACCESS | > + EFI_VARIABLE_RUNTIME_ACCESS, > + sizeof (PCIE_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 > + ) > +{ > + PCIE_VARSTORE_DATA *VarStoreConfig; > + PCIE_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 = PCIE_SCREEN_PRIVATE_FROM_THIS (This); > + VarStoreConfig = &PrivateData->VarStoreConfig; > + ASSERT (VarStoreConfig != NULL); > + > + 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; /* default disable */ > + break; > + } > + > + switch ((QuestionId - 0x8002) % MAX_EDITABLE_ELEMENTS) { > + case 0: > + Value->u8 = PcieRCActiveDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData); > + break; > + > + case 1: > + Value->u8 = PcieRCDevMapLoDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData); > + break; > + > + case 2: > + Value->u8 = PcieRCDevMapHiDefaultSetting ((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; > +} > + > +EFI_STATUS > +PcieScreenUnload ( > + IN EFI_HANDLE ImageHandle > + ) > +{ > + ASSERT (mPrivateData != NULL); > + > + if (DriverHandle != NULL) { > + gBS->UninstallMultipleProtocolInterfaces ( > + DriverHandle, > + &gEfiDevicePathProtocolGuid, > + &mHiiVendorDevicePath, > + &gEfiHiiConfigAccessProtocolGuid, > + &mPrivateData->ConfigAccess, > + NULL > + ); > + DriverHandle = NULL; > + } > + > + if (mPrivateData->HiiHandle != NULL) { > + HiiRemovePackages (mPrivateData->HiiHandle); > + } > + > + FreePool (mPrivateData); > + mPrivateData = NULL; > + > + return EFI_SUCCESS; > +} > + > +/** > + This function return default settings for Dev Map LO. > + @param RC Root Complex ID. > + @param PrivateData Private data. > + > + @retval Default dev settings. > +**/ > +UINT8 > +PcieRCDevMapLoDefaultSetting ( > + IN UINTN RCIndex, > + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData > + ) > +{ > + AC01_RC *RC = &RCList[RCIndex]; > + > + return RC->DefaultDevMapLo; > +} > + > +/** > + This function return default settings for Dev Map HI. > + @param RC Root Complex ID. > + @param PrivateData Private data. > + > + @retval Default dev settings. > +**/ > +UINT8 > +PcieRCDevMapHiDefaultSetting ( > + IN UINTN RCIndex, > + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData > + ) > +{ > + AC01_RC *RC = &RCList[RCIndex]; > + > + return RC->DefaultDevMapHi; > +} > + > +BOOLEAN > +PcieRCActiveDefaultSetting ( > + IN UINTN RCIndex, > + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData > + ) > +{ > + PLATFORM_INFO_HOB *PlatformHob; > + VOID *Hob; > + UINT32 Efuse; > + > + // FIXME: Disable Root Complex 6 (USB and VGA) as default Please get rid of the FIXME > + if (RCIndex == 6) { > + return FALSE; > + } > + > + Hob = GetFirstGuidHob (&gPlatformHobGuid); > + if (Hob != NULL) { > + PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); > + Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << 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 PCIE_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)PCIE_RC0_STATUS_OFFSET + > + sizeof (BOOLEAN) * RCIndex; > + BifurLoVarOffset = (UINT16)PCIE_RC0_BIFUR_LO_OFFSET + > + sizeof (UINT8) * RCIndex; > + BifurHiVarOffset = (UINT16)PCIE_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") > + PCIE_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->DefaultDevMapLo != 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") > + PCIE_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->DefaultDevMapLo != 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") > + PCIE_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->DefaultDevMapHi != 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") > + PCIE_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 > + PCIE_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 PCIE_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; > + PCIE_SETUP_GOTO_DATA *GotoItem = NULL; > + EFI_QUESTION_ID GotoId; > + > + // 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; > + > + HiiCreateCheckBoxOpCode ( > + StartOpCodeHandle, // Container for dynamic created opcodes > + 0x9000, // Question ID > + PCIE_VARSTORE_ID, // VarStore ID > + (UINT16)PCIE_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 > + EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, > + 0, > + 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 < MAX_AC01_PCIE_ROOT_COMPLEX; RC++) { > + > + GotoItem = AllocateZeroPool (sizeof (PCIE_SETUP_GOTO_DATA)); > + if (GotoItem == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + GotoItem->PciDevIdx = RC; > + > + GotoId = PCIE_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, > + PCIE_RC0_FORM_ID + RC, > + GotoItem->GotoStringId, > + GotoItem->GotoHelpStringId, > + EFI_IFR_FLAG_CALLBACK, > + GotoId > + ); > + } > + > + HiiUpdateForm ( > + PrivateData->HiiHandle, // HII handle > + &gPcieFormSetGuid, // Formset GUID > + PCIE_FORM_ID, // Form ID > + StartOpCodeHandle, // Label for where to insert opcodes > + EndOpCodeHandle // Insert data > + ); > + > + HiiFreeOpCodeHandle (StartOpCodeHandle); > + HiiFreeOpCodeHandle (EndOpCodeHandle); > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +PcieBoardScreenInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable, > + IN AC01_RC *NewRCList > + ) > +{ > + EFI_STATUS Status; > + 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; > + PCIE_VARSTORE_DATA *VarStoreConfig; > + UINT8 RCIndex; > + AC01_RC *RC; > + > + // > + // Initialize driver private data > + // > + mPrivateData = AllocateZeroPool (sizeof (PCIE_SCREEN_PRIVATE_DATA)); > + if (mPrivateData == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + mPrivateData->Signature = PCIE_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; > + > + 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, > + PcieBoardLibStrings, > + VfrBin, > + 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 efi varstore configuration data > + // > + VarStoreConfig = &mPrivateData->VarStoreConfig; > + ZeroMem (VarStoreConfig, sizeof (PCIE_VARSTORE_DATA)); > + > + // Get Buffer Storage data from EFI variable > + BufferSize = sizeof (PCIE_VARSTORE_DATA); > + Status = gRT->GetVariable ( > + VariableName, > + &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 < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) { > + RC = &RCList[RCIndex]; > + > + if (EFI_ERROR (Status)) { > + VarStoreConfig->RCBifurLo[RCIndex] = RC->DevMapLo; > + VarStoreConfig->RCBifurHi[RCIndex] = RC->DevMapHi; > + VarStoreConfig->RCStatus[RCIndex] = RC->Active; > + IsUpdated = TRUE; > + } > + // FIXME: Disable Root Complex 6 (USB and VGA) as default Please get rid of the FIXME. / Leif > + if (EFI_ERROR (Status) && RCIndex == 6) { > + VarStoreConfig->RCStatus[RCIndex] = 0; > + } > + } > + > + if (IsUpdated) { > + // Update Buffer Storage > + Status = gRT->SetVariable ( > + VariableName, > + &gPcieFormSetGuid, > + EFI_VARIABLE_NON_VOLATILE | > + EFI_VARIABLE_BOOTSERVICE_ACCESS | > + EFI_VARIABLE_RUNTIME_ACCESS, > + sizeof (PCIE_VARSTORE_DATA), > + VarStoreConfig > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } > + Status = PcieMainScreenSetup (mPrivateData); > + ASSERT_EFI_ERROR (Status); > + > + for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) { > + Status = PcieRCScreenSetup (RCIndex, mPrivateData); > + ASSERT_EFI_ERROR (Status); > + } > + > + return Status; > +} > diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni > new file mode 100644 > index 000000000000..776eaa476787 > --- /dev/null > +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni > @@ -0,0 +1,99 @@ > +// > +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> +// > +// 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" > -- > 2.17.1 >