The patches add a new device configuration protocol and use it to configure a Marvell Yukon controller on the Juno platform with a valid MAC address.
The device configuration protocol will enable a driver to reconfigure device specific settings before driver is started. As an example, the Juno Marvell Yukon NIC MAC address which has to be configured before the driver bound to the controller. The device configuration protocol defined as generic and supports multiple controllers per driver and multiple types of configuration per controller. Depending on the driver's protocol implementation, the configuration can be defined as "read/write" or "read only" and set to or get from a driver based on specified controller and its supported configuration type.
Daniil Egranov (2): ArmPlatformPkg/ArmJunoDxe: Configure Marvell Yukon MAC address on Juno EmbeddedPkg: Added device configure protocol
.../ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c | 100 +++++++++++++++- .../ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf | 1 + .../Drivers/ArmJunoDxe/ArmJunoDxeInternal.h | 3 + EmbeddedPkg/EmbeddedPkg.dec | 1 + .../Include/Protocol/EmbeddedDeviceConfig.h | 127 +++++++++++++++++++++ 5 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 EmbeddedPkg/Include/Protocol/EmbeddedDeviceConfig.h
The patch is using device configuration protocol to push new MAC address to the Marvell Yukon NIC. A MAC address has been read from FPGA registers and pushed to the NIC before its driver started by BDS.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com --- .../ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c | 100 ++++++++++++++++++++- .../ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf | 1 + .../Drivers/ArmJunoDxe/ArmJunoDxeInternal.h | 3 + 3 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c index dba1fcd..4acfbb4 100644 --- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c +++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c @@ -17,6 +17,10 @@
#include <Protocol/DevicePathFromText.h> #include <Protocol/PciRootBridgeIo.h> +#include <Protocol/EmbeddedDeviceConfig.h> +#include <Protocol/PciIo.h> + +#include <IndustryStandard/Pci.h>
#include <Guid/EventGroup.h> #include <Guid/GlobalVariable.h> @@ -97,9 +101,22 @@ OnEndOfDxe ( IN VOID *Context ) { - EFI_DEVICE_PATH_PROTOCOL* PciRootComplexDevicePath; - EFI_HANDLE Handle; - EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *PciRootComplexDevicePath; + EFI_HANDLE Handle; + EFI_STATUS Status; + EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL *DeviceConfig; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN HIndex; + UINTN CIndex; + UINTN TIndex; + EFI_PCI_IO_PROTOCOL* PciIo; + UINT64 PciID; + EFI_DEVICE_CONFIGURATION_RECORD *ConfigBuffer; + UINTN ConfigBufferSize; + EFI_MAC_ADDRESS MacAddress; + UINT32 MacHigh; + UINT32 MacLow;
// // PCI Root Complex initialization @@ -114,6 +131,83 @@ OnEndOfDxe (
Status = gBS->ConnectController (Handle, NULL, PciRootComplexDevicePath, FALSE); ASSERT_EFI_ERROR (Status); + + // + // Apply platform specific device configurations through the device configuration + // protocol before switching to the BDS + // + Status = gBS->LocateHandleBuffer (ByProtocol, + &gEfiEmbeddedDeviceConfigProtocolGuid, + NULL, &HandleCount, &HandleBuffer); + + if (!EFI_ERROR (Status)) { + for (HIndex = 0; HIndex < HandleCount; ++HIndex) { + Status = gBS->OpenProtocol ( + HandleBuffer[HIndex], + &gEfiEmbeddedDeviceConfigProtocolGuid, + (VOID **) &DeviceConfig, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (EFI_ERROR (Status)) { + continue; + } + + Status = DeviceConfig->Supported (DeviceConfig, + &ConfigBuffer, + &ConfigBufferSize); + + if (!EFI_ERROR (Status)) { + if (ConfigBufferSize > 0 && ConfigBuffer != NULL) { + for (CIndex = 0; CIndex < ConfigBufferSize; CIndex++) { + + //check for the Juno Marvell Yukon controller + Status = gBS->OpenProtocol ( + ConfigBuffer[CIndex].Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR (Status)) { + continue; + } + + Status = PciIo->Pci.Read (PciIo, + EfiPciIoWidthUint32, + PCI_VENDOR_ID_OFFSET, + 1, + &PciID); + if (EFI_ERROR (Status)) { + continue; + } + + for (TIndex = 0; TIndex < ConfigBuffer[CIndex].SupportedConfigs; TIndex++) { + if ((PciID & 0x00000000FFFFFFFF) == JUNO_MARVELL_YUKON_ID && + ConfigBuffer[CIndex].ConfigList[TIndex].Type == EfiConfigMacAddress) { + + MacHigh= MmioRead32 (ARM_JUNO_SYS_PCIGBE_H); + MacLow = MmioRead32 (ARM_JUNO_SYS_PCIGBE_L); + CopyMem((VOID *) &MacAddress.Addr[0], (CONST VOID *)&MacLow, 4); + CopyMem((VOID *) &MacAddress.Addr[4], (CONST VOID *)&MacHigh, 2); + + Status = DeviceConfig->Set (DeviceConfig, + ConfigBuffer[CIndex].Controller, + EfiConfigMacAddress, + (VOID *)&MacAddress); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ArmJunoDxe: Failed to configure Marvell Yukon controller\n")); + } + } + } + } + FreePool(ConfigBuffer); + } + } + } + FreePool(HandleBuffer); + } }
STATIC diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf index a261798..fe07a15 100644 --- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf +++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf @@ -62,6 +62,7 @@ gEfiPciRootBridgeIoProtocolGuid gEfiSimpleFileSystemProtocolGuid gEfiAcpiTableProtocolGuid + gEfiEmbeddedDeviceConfigProtocolGuid
[FixedPcd] gArmTokenSpaceGuid.PcdSystemMemoryBase diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h index 662c413..e0f503e 100644 --- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h +++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h @@ -29,6 +29,9 @@
#include <IndustryStandard/Acpi.h>
+#define JUNO_MARVELL_YUKON_ID 0x438011AB + + EFI_STATUS PciEmulationEntryPoint ( VOID
The device configuration protocol definition.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com --- EmbeddedPkg/EmbeddedPkg.dec | 1 + .../Include/Protocol/EmbeddedDeviceConfig.h | 127 +++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 EmbeddedPkg/Include/Protocol/EmbeddedDeviceConfig.h
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index 775d863..7e1d9ed 100644 --- a/EmbeddedPkg/EmbeddedPkg.dec +++ b/EmbeddedPkg/EmbeddedPkg.dec @@ -69,6 +69,7 @@ gAndroidFastbootPlatformProtocolGuid = { 0x524685a0, 0x89a0, 0x11e3, {0x9d, 0x4d, 0xbf, 0xa9, 0xf6, 0xa4, 0x03, 0x08}} gUsbDeviceProtocolGuid = { 0x021bd2ca, 0x51d2, 0x11e3, {0x8e, 0x56, 0xb7, 0x54, 0x17, 0xc7, 0x0b, 0x44 }} gPlatformGpioProtocolGuid = { 0x52ce9845, 0x5af4, 0x43e2, {0xba, 0xfd, 0x23, 0x08, 0x12, 0x54, 0x7a, 0xc2 }} + gEfiEmbeddedDeviceConfigProtocolGuid = { 0x735F8C64, 0xD696, 0x44D0, { 0xBD, 0xF2, 0x44, 0x7F, 0xD0, 0x5A, 0x54, 0x06 }}
[PcdsFeatureFlag.common] gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|FALSE|BOOLEAN|0x00000001 diff --git a/EmbeddedPkg/Include/Protocol/EmbeddedDeviceConfig.h b/EmbeddedPkg/Include/Protocol/EmbeddedDeviceConfig.h new file mode 100644 index 0000000..f397036 --- /dev/null +++ b/EmbeddedPkg/Include/Protocol/EmbeddedDeviceConfig.h @@ -0,0 +1,127 @@ +/** @file +* +* Copyright (c) 2016, ARM 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 __EMBEDDED_DEVICE_CONFIG_H__ +#define __EMBEDDED_DEVICE_CONFIG_H__ + +// +// Protocol GUID +// +#define EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL_GUID { 0x735F8C64, 0xD696, 0x44D0, { 0xBD, 0xF2, 0x44, 0x7F, 0xD0, 0x5A, 0x54, 0x06 }} + +// +// Protocol interface structure +// +typedef struct _EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL; + +#define EFI_EMBEDDED_DEVICE_CONFIG_REVISION 0x00010000 + +// Device configuration types and structures +typedef enum { + EfiConfigMacAddress, + EfiMaxDeviceConfigurationType +} EFI_DEVICE_CONFIGURATION_TYPE; + +typedef struct { + BOOLEAN Writable; + EFI_DEVICE_CONFIGURATION_TYPE Type; +} EFI_DEVICE_CONFIGURATION_BLOCK; + +typedef struct { + EFI_HANDLE Controller; + UINT32 SupportedConfigs; + EFI_DEVICE_CONFIGURATION_BLOCK ConfigList[EfiMaxDeviceConfigurationType]; +} EFI_DEVICE_CONFIGURATION_RECORD; + +// +// Function Prototypes +// + +/** + Check for device configuration support. + + @param This Instance pointer for this protocol + + @retval Buffer Array of configuration records. + @retval RecordCount Number of configuration records. + @retval EFI_SUCCESS Device supports external configuration. + @retval EFI_UNSUPPORTED Device does not support external configuration. + @retval EFI_DEVICE_ERROR Device configuration read error. +**/ + +typedef +EFI_STATUS +(EFIAPI *EFI_EMBEDDED_DEVICE_CONFIG_SUPPORTED) ( + IN EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL *This, + OUT EFI_DEVICE_CONFIGURATION_RECORD **Buffer, + OUT UINTN *RecordCount + ); + +/** + Set device configuration. + + @param This Instance pointer for this protocol. + @param Controller Handle of device to configure. + @param ConfigType Configuration type. + @param Buffer Configuration data. + + @retval EFI_SUCCESS Device configured successfully. + @retval EFI_UNSUPPORTED Device does not support specified configuration or + device configuration is read only. + @retval EFI_DEVICE_ERROR Device configuration failed. + +**/ + +typedef +EFI_STATUS +(EFIAPI *EFI_EMBEDDED_DEVICE_CONFIG_SET) ( + IN EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_CONFIGURATION_TYPE ConfigType, + IN VOID *Buffer + ); + +/** + Get device configuration. + + @param This Instance pointer for this protocol + @param Controller Handle of device to get a configuration. + @param ConfigType Configuration type to update. + + @retval Buffer Configuration data. + @retval EFI_SUCCESS Configuration data is available. + @retval EFI_UNSUPPORTED Device does not support specified configuration. + @retval EFI_DEVICE_ERROR Device configuration read error. + +**/ + +typedef +EFI_STATUS +(EFIAPI *EFI_EMBEDDED_DEVICE_CONFIG_GET) ( + IN EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_CONFIGURATION_TYPE ConfigType, + OUT VOID **Buffer + ); + +struct _EFI_EMBEDDED_DEVICE_CONFIG_PROTOCOL { + UINT64 Revision; + EFI_EMBEDDED_DEVICE_CONFIG_SUPPORTED Supported; + EFI_EMBEDDED_DEVICE_CONFIG_SET Set; + EFI_EMBEDDED_DEVICE_CONFIG_GET Get; +}; + +extern EFI_GUID gEfiEmbeddedDeviceConfigProtocolGuid; + +#endif // __EMBEDDED_DEVICE_CONFIG_H__
On 7 June 2016 at 01:22, Daniil Egranov daniil.egranov@arm.com wrote:
The patches add a new device configuration protocol and use it to configure a Marvell Yukon controller on the Juno platform with a valid MAC address.
The device configuration protocol will enable a driver to reconfigure device specific settings before driver is started. As an example, the Juno Marvell Yukon NIC MAC address which has to be configured before the driver bound to the controller. The device configuration protocol defined as generic and supports multiple controllers per driver and multiple types of configuration per controller. Depending on the driver's protocol implementation, the configuration can be defined as "read/write" or "read only" and set to or get from a driver based on specified controller and its supported configuration type.
Daniil Egranov (2): ArmPlatformPkg/ArmJunoDxe: Configure Marvell Yukon MAC address on Juno EmbeddedPkg: Added device configure protocol
.../ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c | 100 +++++++++++++++- .../ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf | 1 + .../Drivers/ArmJunoDxe/ArmJunoDxeInternal.h | 3 + EmbeddedPkg/EmbeddedPkg.dec | 1 + .../Include/Protocol/EmbeddedDeviceConfig.h | 127 +++++++++++++++++++++ 5 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 EmbeddedPkg/Include/Protocol/EmbeddedDeviceConfig.h
For the series:
Tested-by: Ryan Harkin ryan.harkin@linaro.org
I tested this in conjunction with the driver that Daniil has posted to the OpenPlatformPkg tree. I used Juno R0, R1 and R2 to run the code, where only R1 and R2 have the Marvell device.
-- 2.7.4
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi