From ad652d46941c6a1e0f828cb084fb6829c3abb68d Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Fri, 2 Jan 2015 12:04:05 +0000 Subject: [PATCH] ArmVirtualizationPkg: VirtFdtDxe: forward FwCfg addresses from DTB to PCDs Qemu's firmware configuration interface for ARM consists of two MMIO registers, a 16-bit selector, and a 64-bit data register that allows the guest to transfer data with 8, 16, 32, and 64-bit wide accesses. Parse the base address from the DTB, and expose the registers to the rest of DXE via dynamic PCDs. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16566 6f19259b-4bc3-4df7-8a09-765794883524 --- .../ArmVirtualizationPkg.dec | 3 ++ .../ArmVirtualizationQemu.dsc | 3 ++ .../VirtFdtDxe/VirtFdtDxe.c | 34 +++++++++++++++++++ .../VirtFdtDxe/VirtFdtDxe.inf | 2 ++ 4 files changed, 42 insertions(+) diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec index b581add024..99411548af 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec @@ -53,3 +53,6 @@ # PcdArmPsciMethod == 2 : use SMC # gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod|0|UINT32|0x00000003 + + gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0|UINT64|0x00000004 + gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress|0x0|UINT64|0x00000005 diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc index 66052f56ab..d23832fc01 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc @@ -173,6 +173,9 @@ gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod|0 + gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0 + gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress|0x0 + ################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c index d002e668aa..95e91eb822 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c @@ -44,6 +44,7 @@ typedef enum { PropertyTypeUart, PropertyTypeTimer, PropertyTypePsci, + PropertyTypeFwCfg, } PROPERTY_TYPE; typedef struct { @@ -59,6 +60,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = { { PropertyTypeTimer, "arm,armv7-timer" }, { PropertyTypeTimer, "arm,armv8-timer" }, { PropertyTypePsci, "arm,psci-0.2" }, + { PropertyTypeFwCfg, "qemu,fw-cfg-mmio" }, { PropertyTypeUnknown, "" } }; @@ -115,6 +117,10 @@ InitializeVirtFdtDxe ( CONST INTERRUPT_PROPERTY *InterruptProp; INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum; CONST CHAR8 *PsciMethod; + UINT64 FwCfgSelectorAddress; + UINT64 FwCfgSelectorSize; + UINT64 FwCfgDataAddress; + UINT64 FwCfgDataSize; DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); ASSERT (DeviceTreeBase != NULL); @@ -160,6 +166,34 @@ InitializeVirtFdtDxe ( (PropType == PropertyTypePsci)); switch (PropType) { + case PropertyTypeFwCfg: + ASSERT (Len == 2 * sizeof (UINT64)); + + FwCfgDataAddress = fdt64_to_cpu (((UINT64 *)RegProp)[0]); + FwCfgDataSize = 8; + FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize; + FwCfgSelectorSize = 2; + + // + // The following ASSERT()s express + // + // Address + Size - 1 <= MAX_UINTN + // + // for both registers, that is, that the last byte in each MMIO range is + // expressible as a MAX_UINTN. The form below is mathematically + // equivalent, and it also prevents any unsigned overflow before the + // comparison. + // + ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1); + ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1); + + PcdSet64 (PcdFwCfgSelectorAddress, FwCfgSelectorAddress); + PcdSet64 (PcdFwCfgDataAddress, FwCfgDataAddress); + + DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress, + FwCfgDataAddress)); + break; + case PropertyTypeVirtio: ASSERT (Len == 16); // diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf index 1c9dd20580..daafe6cb5a 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf @@ -47,6 +47,8 @@ [Pcd] gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod + gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress + gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum