From: Leif Lindholm <leif.lindholm@linaro.org>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: edk2-devel@lists.01.org
Subject: Re: [PATCH edk2-platforms v3] Silicon/Socionext/SynQuacer: implement menu option to set max PCIe speed
Date: Thu, 25 Jan 2018 18:46:29 +0000 [thread overview]
Message-ID: <20180125184629.w67rwfam5wpal7rb@bivouac.eciton.net> (raw)
In-Reply-To: <20180125171317.29346-1-ard.biesheuvel@linaro.org>
On Thu, Jan 25, 2018 at 05:13:17PM +0000, Ard Biesheuvel wrote:
> Add menu options to the SynQuacer Platform menu screen to limit the
> maximum PCIe link speed for each slot individually. This may be useful
> to work around potential PCIe issues.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> v3:
> deobfuscate the slot speed limit check, using a switch rather than a
> convoluted if(), and a comment that describes what goes on
Thanks for this.
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> v2:
> Make the speed limit per-slot instead of per-RC. That does make this
> implementation more specific to DeveloperBox than it was before, but
> given the special knowledge about the on-board ASM1184e switch and the
> need for enabling spread-spectrum on the ASM1061, we're already past the
> point where PlatformDxe is a generic SynQuacer driver, and we may need to
> move it into Platform/Socionext (and clone it for each platform) in the
> future.
>
> Platform/Socionext/DeveloperBox/DeveloperBox.dsc | 2 +
> Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc | 2 +
> Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c | 35 ++++++-
> Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c | 107 ++++++++++++++++++++
> Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h | 13 +++
> Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf | 11 ++
> Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni | 29 ++++++
> Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr | 69 +++++++++++++
> Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h | 23 +++++
> Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h | 5 +
> Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h | 29 ++++++
> Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf | 2 +
> Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c | 40 +++++++-
> Silicon/Socionext/SynQuacer/SynQuacer.dec | 5 +
> 14 files changed, 365 insertions(+), 7 deletions(-)
>
> diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
> index 86685d1dec3b..2d46b4515749 100644
> --- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
> +++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
> @@ -405,6 +405,8 @@ [PcdsDynamicExDefault.common.DEFAULT]
> [PcdsDynamicHii]
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|30
>
> + gSynQuacerTokenSpaceGuid.PcdPlatformSettings|L"SynQuacerPlatformSettings"|gSynQuacerPlatformFormSetGuid|0x0|0x0|NV,BS
> +
> [PcdsDynamicDefault]
> gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0000000000000000
> gArmTokenSpaceGuid.PcdSystemMemorySize|0xFFFFFFFFFFFFFFFF
> diff --git a/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc b/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
> index b4b9239143bc..263b6454ff72 100644
> --- a/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
> +++ b/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
> @@ -397,6 +397,8 @@ [PcdsDynamicExDefault.common.DEFAULT]
> [PcdsDynamicHii]
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|30
>
> + gSynQuacerTokenSpaceGuid.PcdPlatformSettings|L"SynQuacerPlatformSettings"|gSynQuacerPlatformFormSetGuid|0x0|0x0|NV,BS
> +
> [PcdsDynamicDefault]
> gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0000000000000000
> gArmTokenSpaceGuid.PcdSystemMemorySize|0xFFFFFFFFFFFFFFFF
> diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c
> index 9af3dd942cdd..7c69a8051a56 100644
> --- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c
> +++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c
> @@ -45,6 +45,11 @@ RetrainAsm1184eDownstreamPort (
> EFI_STATUS Status;
> PCIE_CAP Cap;
> PCI_REG_PCIE_LINK_CONTROL LinkControl;
> + UINTN SegmentNumber;
> + UINTN BusNumber;
> + UINTN DeviceNumber;
> + UINTN FunctionNumber;
> + UINT8 MaxSpeed;
>
> //
> // The upstream and downstream ports share the same PID/VID, so check
> @@ -64,8 +69,34 @@ RetrainAsm1184eDownstreamPort (
> return;
> }
>
> - DEBUG ((DEBUG_INFO, "%a: retraining ASM118x downstream PCIe port\n",
> - __FUNCTION__));
> + Status = PciIo->GetLocation (PciIo, &SegmentNumber, &BusNumber, &DeviceNumber,
> + &FunctionNumber);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Check whether this downstream port is described by any of our 'slot'
> + // definitions, and get the maximum speed if this is the case.
> + //
> + switch (SYNQUACER_PCI_LOCATION (SegmentNumber, BusNumber, DeviceNumber)) {
> + case SYNQUACER_PCI_SLOT0_LOCATION:
> + MaxSpeed = mHiiSettings->PcieSlot0MaxSpeed;
> + break;
> + case SYNQUACER_PCI_SLOT1_LOCATION:
> + MaxSpeed = mHiiSettings->PcieSlot1MaxSpeed;
> + break;
> + case SYNQUACER_PCI_SLOT2_LOCATION:
> + MaxSpeed = mHiiSettings->PcieSlot2MaxSpeed;
> + break;
> + default:
> + MaxSpeed = PCIE_MAX_SPEED_UNLIMITED;
> + }
> + if (MaxSpeed == PCIE_MAX_SPEED_GEN1) {
> + return;
> + }
> +
> + DEBUG ((DEBUG_INFO,
> + "%a: retraining ASM118x downstream PCIe port at %04x:%02x:%02x to Gen2\n",
> + __FUNCTION__, SegmentNumber, BusNumber, DeviceNumber));
>
> Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
> ASM118x_PCIE_LINK_CONTROL_OFFSET, 1, &LinkControl);
> diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c
> index 91c1b66ea1f8..b60607d05861 100644
> --- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c
> +++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c
> @@ -14,6 +14,36 @@
>
> #include "PlatformDxe.h"
>
> +UINT64 mHiiSettingsVal;
> +SYNQUACER_PLATFORM_VARSTORE_DATA *mHiiSettings;
> +
> +typedef struct {
> + VENDOR_DEVICE_PATH VendorDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +STATIC HII_VENDOR_DEVICE_PATH mPlatformDxeHiiVendorDevicePath = {
> + {
> + {
> + HARDWARE_DEVICE_PATH,
> + HW_VENDOR_DP,
> + {
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
> + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> + }
> + },
> + SYNQUACER_PLATFORM_FORMSET_GUID
> + },
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + (UINT8) (END_DEVICE_PATH_LENGTH),
> + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
> + }
> + }
> +};
> +
> STATIC EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR mNetsecDesc[] = {
> {
> ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc
> @@ -144,6 +174,77 @@ SmmuEnableCoherentDma (
> SMMU_SCR0_SHCFG_INNER | SMMU_SCR0_MTCFG | SMMU_SCR0_MEMATTR_INNER_OUTER_WB);
> }
>
> +STATIC
> +EFI_STATUS
> +InstallHiiPages (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HII_HANDLE HiiHandle;
> + EFI_HANDLE DriverHandle;
> +
> + DriverHandle = NULL;
> + Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,
> + &gEfiDevicePathProtocolGuid,
> + &mPlatformDxeHiiVendorDevicePath,
> + NULL);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + HiiHandle = HiiAddPackages (&gSynQuacerPlatformFormSetGuid,
> + DriverHandle,
> + PlatformDxeStrings,
> + PlatformDxeHiiBin,
> + NULL);
> +
> + if (HiiHandle == NULL) {
> + gBS->UninstallMultipleProtocolInterfaces (DriverHandle,
> + &gEfiDevicePathProtocolGuid,
> + &mPlatformDxeHiiVendorDevicePath,
> + NULL);
> + return EFI_OUT_OF_RESOURCES;
> + }
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +EnableSettingsForm (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + UINTN VarSize;
> + SYNQUACER_PLATFORM_VARSTORE_DATA Settings;
> +
> + VarSize = sizeof (Settings);
> + Status = gRT->GetVariable (SYNQUACER_PLATFORM_VARIABLE_NAME,
> + &gSynQuacerPlatformFormSetGuid, NULL, &VarSize, &Settings);
> + if (Status == EFI_NOT_FOUND) {
> + //
> + // Variable does not exist yet - create it
> + //
> + SetMem (&Settings, sizeof (Settings), 0);
> + Status = gRT->SetVariable (SYNQUACER_PLATFORM_VARIABLE_NAME,
> + &gSynQuacerPlatformFormSetGuid,
> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
> + sizeof (Settings), &Settings);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_WARN, "%a: EfiSetVariable failed - %r\n", __FUNCTION__,
> + Status));
> + return Status;
> + }
> + } else if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_WARN, "%a: EfiGetVariable failed - %r\n", __FUNCTION__,
> + Status));
> + return Status;
> + }
> +
> + return InstallHiiPages ();
> +}
> +
> EFI_STATUS
> EFIAPI
> PlatformDxeEntryPoint (
> @@ -156,6 +257,9 @@ PlatformDxeEntryPoint (
> UINTN DtbSize;
> EFI_HANDLE Handle;
>
> + mHiiSettingsVal = PcdGet64 (PcdPlatformSettings);
> + mHiiSettings = (SYNQUACER_PLATFORM_VARSTORE_DATA *)&mHiiSettingsVal;
> +
> Dtb = NULL;
> Status = DtPlatformLoadDtb (&Dtb, &DtbSize);
> if (!EFI_ERROR (Status)) {
> @@ -197,5 +301,8 @@ PlatformDxeEntryPoint (
> Status = RegisterPcieNotifier ();
> ASSERT_EFI_ERROR (Status);
>
> + Status = EnableSettingsForm ();
> + ASSERT_EFI_ERROR (Status);
> +
> return EFI_SUCCESS;
> }
> diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h
> index d1dad2a3eace..53898b5828d4 100644
> --- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h
> +++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h
> @@ -16,18 +16,31 @@
> #define __PLATFORM_DXE_H__
>
> #include <PiDxe.h>
> +#include <Guid/SynQuacerPlatformFormSet.h>
> #include <IndustryStandard/Pci.h>
> #include <Library/BaseMemoryLib.h>
> #include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> #include <Library/DtPlatformDtbLoaderLib.h>
> +#include <Library/HiiLib.h>
> #include <Library/IoLib.h>
> #include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> #include <Library/UefiBootServicesTableLib.h>
> #include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> #include <Platform/MemoryMap.h>
> +#include <Platform/Pcie.h>
> +#include <Platform/VarStore.h>
> #include <Protocol/NonDiscoverableDevice.h>
> #include <Protocol/PciIo.h>
>
> +extern UINT8 PlatformDxeHiiBin[];
> +extern UINT8 PlatformDxeStrings[];
> +
> +extern UINT64 mHiiSettingsVal;
> +extern SYNQUACER_PLATFORM_VARSTORE_DATA *mHiiSettings;
> +
> EFI_STATUS
> EFIAPI
> RegisterPcieNotifier (
> diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf
> index f075957d7456..de21ba33df75 100644
> --- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf
> +++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf
> @@ -25,6 +25,8 @@ [Defines]
> [Sources]
> Pci.c
> PlatformDxe.c
> + PlatformDxeHii.uni
> + PlatformDxeHii.vfr
>
> [Packages]
> EmbeddedPkg/EmbeddedPkg.dec
> @@ -37,18 +39,24 @@ [Packages]
> [LibraryClasses]
> BaseMemoryLib
> DebugLib
> + DevicePathLib
> DtPlatformDtbLoaderLib
> + HiiLib
> IoLib
> MemoryAllocationLib
> + PcdLib
> UefiBootServicesTableLib
> UefiDriverEntryPoint
> UefiLib
> + UefiRuntimeServicesTableLib
>
> [Guids]
> + gEfiHiiPlatformSetupFormsetGuid
> gFdtTableGuid
> gNetsecNonDiscoverableDeviceGuid
> gSynQuacerNonDiscoverableI2cMasterGuid
> gSynQuacerNonDiscoverableRuntimeI2cMasterGuid
> + gSynQuacerPlatformFormSetGuid
>
> [Protocols]
> gEdkiiNonDiscoverableDeviceProtocolGuid ## PRODUCES
> @@ -59,5 +67,8 @@ [FixedPcd]
> gSynQuacerTokenSpaceGuid.PcdNetsecEepromBase
> gSynQuacerTokenSpaceGuid.PcdNetsecPhyAddress
>
> +[Pcd]
> + gSynQuacerTokenSpaceGuid.PcdPlatformSettings
> +
> [Depex]
> TRUE
> diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni
> new file mode 100644
> index 000000000000..b274d12ed2c6
> --- /dev/null
> +++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni
> @@ -0,0 +1,29 @@
> +/** @file
> +*
> +* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
> +*
> +* This program and the accompanying materials are licensed and made available
> +* under the terms and conditions of the BSD License which accompanies this
> +* distribution. The full text of the license may be found at
> +* http://opensource.org/licenses/bsd-license.php
> +*
> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#langdef en-US "English"
> +
> +#string STR_FORM_SET_TITLE #language en-US "SynQuacer Platform Settings"
> +#string STR_FORM_SET_TITLE_HELP #language en-US "Press <Enter> to set platform specific options."
> +
> +#string STR_MAIN_FORM_TITLE #language en-US "SynQuacer Platform Settings"
> +#string STR_NULL_STRING #language en-US ""
> +
> +#string STR_PCIE0_MAX_SPEED_PROMPT #language en-US "PCIe x4 slot max speed"
> +#string STR_PCIE1_MAX_SPEED_PROMPT #language en-US "PCIe x1 slot 1 max speed"
> +#string STR_PCIE2_MAX_SPEED_PROMPT #language en-US "PCIe x1 slot 2 max speed"
> +#string STR_PCIE_MAX_SPEED_HELP #language en-US "The maximum speed the PCIe downstream port is allowed to negotiate"
> +
> +#string STR_PCIE_MAX_SPEED_UNLIMITED #language en-US "Unlimited"
> +#string STR_PCIE_MAX_SPEED_GEN1 #language en-US "Gen1 (2.5 GT/s)"
> diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr
> new file mode 100644
> index 000000000000..52f554b61e3c
> --- /dev/null
> +++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr
> @@ -0,0 +1,69 @@
> +/** @file
> +*
> +* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
> +*
> +* This program and the accompanying materials are licensed and made available
> +* under the terms and conditions of the BSD License which accompanies this
> +* distribution. The full text of the license may be found at
> +* http://opensource.org/licenses/bsd-license.php
> +*
> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#include <Guid/HiiPlatformSetupFormset.h>
> +#include <Guid/SynQuacerPlatformFormSet.h>
> +#include <Platform/VarStore.h>
> +
> +//
> +// EFI Variable attributes
> +//
> +#define EFI_VARIABLE_NON_VOLATILE 0x00000001
> +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
> +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
> +#define EFI_VARIABLE_READ_ONLY 0x00000008
> +
> +formset
> + guid = SYNQUACER_PLATFORM_FORMSET_GUID,
> + title = STRING_TOKEN(STR_FORM_SET_TITLE),
> + help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
> + classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
> +
> + efivarstore SYNQUACER_PLATFORM_VARSTORE_DATA,
> + attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attributes
> + name = SynQuacerPlatformSettings,
> + guid = SYNQUACER_PLATFORM_FORMSET_GUID;
> +
> + form formid = 0x1000,
> + title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
> +
> + oneof varid = SynQuacerPlatformSettings.PcieSlot0MaxSpeed,
> + prompt = STRING_TOKEN(STR_PCIE0_MAX_SPEED_PROMPT),
> + help = STRING_TOKEN(STR_PCIE_MAX_SPEED_HELP),
> + flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
> + option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_UNLIMITED), value = PCIE_MAX_SPEED_UNLIMITED, flags = DEFAULT;
> + option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_GEN1), value = PCIE_MAX_SPEED_GEN1, flags = 0;
> + endoneof;
> +
> + oneof varid = SynQuacerPlatformSettings.PcieSlot1MaxSpeed,
> + prompt = STRING_TOKEN(STR_PCIE1_MAX_SPEED_PROMPT),
> + help = STRING_TOKEN(STR_PCIE_MAX_SPEED_HELP),
> + flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
> + option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_UNLIMITED), value = PCIE_MAX_SPEED_UNLIMITED, flags = DEFAULT;
> + option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_GEN1), value = PCIE_MAX_SPEED_GEN1, flags = 0;
> + endoneof;
> +
> + oneof varid = SynQuacerPlatformSettings.PcieSlot2MaxSpeed,
> + prompt = STRING_TOKEN(STR_PCIE2_MAX_SPEED_PROMPT),
> + help = STRING_TOKEN(STR_PCIE_MAX_SPEED_HELP),
> + flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
> + option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_UNLIMITED), value = PCIE_MAX_SPEED_UNLIMITED, flags = DEFAULT;
> + option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_GEN1), value = PCIE_MAX_SPEED_GEN1, flags = 0;
> + endoneof;
> +
> + subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> + endform;
> +
> +endformset;
> diff --git a/Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h b/Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h
> new file mode 100644
> index 000000000000..9a70bb873056
> --- /dev/null
> +++ b/Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h
> @@ -0,0 +1,23 @@
> +/** @file
> +*
> +* Copyright (c) 2017, Linaro Limited. All rights reserved.
> +*
> +* This program and the accompanying materials are licensed and made available
> +* under the terms and conditions of the BSD License which accompanies this
> +* distribution. The full text of the license may be found at
> +* http://opensource.org/licenses/bsd-license.php
> +*
> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#ifndef __SYNQUACER_PLATFORM_FORMSET_H__
> +#define __SYNQUACER_PLATFORM_FORMSET_H__
> +
> +#define SYNQUACER_PLATFORM_FORMSET_GUID \
> + { 0xe9cd576a, 0xaf9a, 0x4d41, { 0xbf, 0x1a, 0x29, 0xe1, 0xbc, 0x99, 0x99, 0x54 } }
> +
> +extern EFI_GUID gSynQuacerPlatformFormSetGuid;
> +
> +#endif
> diff --git a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
> index d2a3f9acbf49..ee2357be9a06 100644
> --- a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
> +++ b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
> @@ -60,4 +60,9 @@
> #define SYNQUACER_PCI_SEG1_MMIO64_MAX 0x3fffffffff
> #define SYNQUACER_PCI_SEG1_MMIO64_SIZE 0x100000000
>
> +#define SYNQUACER_PCI_LOCATION(s,b,d) (((s) << 16) | ((b) << 8) | (d))
> +#define SYNQUACER_PCI_SLOT0_LOCATION SYNQUACER_PCI_LOCATION(1, 0, 0)
> +#define SYNQUACER_PCI_SLOT1_LOCATION SYNQUACER_PCI_LOCATION(0, 1, 7)
> +#define SYNQUACER_PCI_SLOT2_LOCATION SYNQUACER_PCI_LOCATION(0, 1, 3)
> +
> #endif
> diff --git a/Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h b/Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h
> new file mode 100644
> index 000000000000..5944613e7465
> --- /dev/null
> +++ b/Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h
> @@ -0,0 +1,29 @@
> +/** @file
> +
> + Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
> +
> + This program and the accompanying materials are licensed and made available
> + under the terms and conditions of the BSD License which accompanies this
> + distribution. The full text of the license may be found at
> + http://opensource.org/licenses/bsd-license.php
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +**/
> +
> +#ifndef __VARSTORE_H__
> +#define __VARSTORE_H__
> +
> +#define SYNQUACER_PLATFORM_VARIABLE_NAME L"SynQuacerPlatformSettings"
> +
> +#define PCIE_MAX_SPEED_UNLIMITED 0x0
> +#define PCIE_MAX_SPEED_GEN1 0x1
> +
> +typedef struct {
> + UINT8 PcieSlot0MaxSpeed;
> + UINT8 PcieSlot1MaxSpeed;
> + UINT8 PcieSlot2MaxSpeed;
> + UINT8 Reserved[5];
> +} SYNQUACER_PLATFORM_VARSTORE_DATA;
> +
> +#endif
> diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf
> index 27fcba034418..e475529eaf58 100644
> --- a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf
> +++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf
> @@ -45,6 +45,7 @@ [LibraryClasses]
> DebugLib
> DevicePathLib
> MemoryAllocationLib
> + PcdLib
> UefiBootServicesTableLib
>
> [FixedPcd]
> @@ -52,3 +53,4 @@ [FixedPcd]
>
> [Pcd]
> gSynQuacerTokenSpaceGuid.PcdPcieEnableMask
> + gSynQuacerTokenSpaceGuid.PcdPlatformSettings
> diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
> index bea40e3dcfe8..eb91457b7b99 100644
> --- a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
> +++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
> @@ -18,9 +18,11 @@
> #include <Library/ArmLib.h>
> #include <Library/DebugLib.h>
> #include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> #include <Library/PciHostBridgeLib.h>
> #include <Library/UefiBootServicesTableLib.h>
> #include <Platform/Pcie.h>
> +#include <Platform/VarStore.h>
> #include <Protocol/PciHostBridgeResourceAllocation.h>
>
> #define IATU_VIEWPORT_OFF 0x900
> @@ -268,7 +270,8 @@ PciInitControllerPost (
> IN EFI_PHYSICAL_ADDRESS DbiBase,
> IN EFI_PHYSICAL_ADDRESS ConfigBase,
> IN EFI_PHYSICAL_ADDRESS IoMemBase,
> - IN CONST PCI_ROOT_BRIDGE *RootBridge
> + IN CONST PCI_ROOT_BRIDGE *RootBridge,
> + IN BOOLEAN EnableGen2Speed
> )
> {
> // 4: Set Bifurcation 1=disable 4=able
> @@ -312,8 +315,10 @@ PciInitControllerPost (
> EFI_PCI_COMMAND_MEMORY_SPACE |
> EFI_PCI_COMMAND_BUS_MASTER);
>
> - // Force link speed change to Gen2 at link up
> - MmioOr32 (DbiBase + GEN2_CONTROL_OFF, DIRECT_SPEED_CHANGE);
> + if (EnableGen2Speed) {
> + // Force link speed change to Gen2 at link up
> + MmioOr32 (DbiBase + GEN2_CONTROL_OFF, DIRECT_SPEED_CHANGE);
> + }
>
> // Region 0: MMIO32 range
> ConfigureWindow (DbiBase, 0,
> @@ -392,7 +397,13 @@ SynQuacerPciHostBridgeLibConstructor (
> IN EFI_SYSTEM_TABLE *SystemTable
> )
> {
> - UINTN Idx;
> + UINTN Idx;
> + UINT64 SettingsVal;
> + SYNQUACER_PLATFORM_VARSTORE_DATA *Settings;
> + UINT8 MaxSpeed;
> +
> + SettingsVal = PcdGet64 (PcdPlatformSettings);
> + Settings = (SYNQUACER_PLATFORM_VARSTORE_DATA *)&SettingsVal;
>
> for (Idx = 0; Idx < ARRAY_SIZE (mBaseAddresses); Idx++) {
> if (PcdGet8 (PcdPcieEnableMask) & (1 << Idx)) {
> @@ -409,12 +420,31 @@ SynQuacerPciHostBridgeLibConstructor (
> gBS->Stall (150 * 1000);
>
> for (Idx = 0; Idx < ARRAY_SIZE (mBaseAddresses); Idx++) {
> + //
> + // Check whether this root port is described by any of our 'slot'
> + // definitions, and get the maximum speed if this is the case.
> + //
> + switch (SYNQUACER_PCI_LOCATION (Idx, 0, 0)) {
> + case SYNQUACER_PCI_SLOT0_LOCATION:
> + MaxSpeed = Settings->PcieSlot0MaxSpeed;
> + break;
> + case SYNQUACER_PCI_SLOT1_LOCATION:
> + MaxSpeed = Settings->PcieSlot1MaxSpeed;
> + break;
> + case SYNQUACER_PCI_SLOT2_LOCATION:
> + MaxSpeed = Settings->PcieSlot2MaxSpeed;
> + break;
> + default:
> + MaxSpeed = PCIE_MAX_SPEED_UNLIMITED;
> + }
> +
> if (PcdGet8 (PcdPcieEnableMask) & (1 << Idx)) {
> PciInitControllerPost (mBaseAddresses[Idx].ExsBase,
> mBaseAddresses[Idx].DbiBase,
> mBaseAddresses[Idx].ConfigBase,
> mBaseAddresses[Idx].IoMemBase,
> - &mPciRootBridges[Idx]);
> + &mPciRootBridges[Idx],
> + (MaxSpeed != PCIE_MAX_SPEED_GEN1));
> }
> }
>
> diff --git a/Silicon/Socionext/SynQuacer/SynQuacer.dec b/Silicon/Socionext/SynQuacer/SynQuacer.dec
> index 76529e3c2164..eb4fc4ace2f7 100644
> --- a/Silicon/Socionext/SynQuacer/SynQuacer.dec
> +++ b/Silicon/Socionext/SynQuacer/SynQuacer.dec
> @@ -27,6 +27,8 @@ [Guids]
>
> gSynQuacerPlatformDxeFileGuid = { 0xac422cc1, 0xd916, 0x489a, { 0xb1, 0x65, 0x53, 0x6f, 0xdf, 0xc6, 0x33, 0xc2 } }
>
> + gSynQuacerPlatformFormSetGuid = { 0xe9cd576a, 0xaf9a, 0x4d41, { 0xbf, 0x1a, 0x29, 0xe1, 0xbc, 0x99, 0x99, 0x54 } }
> +
> [Ppis]
> gSynQuacerDramInfoPpiGuid = { 0x3e1d7356, 0xdda4, 0x4b1a, { 0x93, 0x46, 0xbf, 0x89, 0x1c, 0x86, 0x46, 0xcc } }
>
> @@ -45,3 +47,6 @@ [PcdsFixedAtBuild]
> [PcdsPatchableInModule, PcdsDynamic]
> # Enable both RC #0 and RC #1 by default
> gSynQuacerTokenSpaceGuid.PcdPcieEnableMask|0x3|UINT8|0x00000007
> +
> +[PcdsDynamic]
> + gSynQuacerTokenSpaceGuid.PcdPlatformSettings|0x0|UINT64|0x00000008
> --
> 2.11.0
>
prev parent reply other threads:[~2018-01-25 18:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-25 17:13 [PATCH edk2-platforms v3] Silicon/Socionext/SynQuacer: implement menu option to set max PCIe speed Ard Biesheuvel
2018-01-25 18:46 ` Leif Lindholm [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180125184629.w67rwfam5wpal7rb@bivouac.eciton.net \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox