diff options
author | Laszlo Ersek <lersek@redhat.com> | 2015-01-02 12:04:05 +0000 |
---|---|---|
committer | lersek <lersek@Edk2> | 2015-01-02 12:04:05 +0000 |
commit | ad652d46941c6a1e0f828cb084fb6829c3abb68d (patch) | |
tree | 134f329f3bb35c68cfe45fdaf43306cf40cc06ca /ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | |
parent | 931aae946fd301cc0b49a60edcde7680d5ceaf45 (diff) | |
download | edk2-platforms-ad652d46941c6a1e0f828cb084fb6829c3abb68d.tar.xz |
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 <lersek@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16566 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c')
-rw-r--r-- | ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 34 |
1 files changed, 34 insertions, 0 deletions
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);
//
|