public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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
> 


      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