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