PropertyTypeUart,\r
PropertyTypeTimer,\r
PropertyTypePsci,\r
+ PropertyTypeFwCfg,\r
} PROPERTY_TYPE;\r
\r
typedef struct {\r
{ PropertyTypeTimer, "arm,armv7-timer" },\r
{ PropertyTypeTimer, "arm,armv8-timer" },\r
{ PropertyTypePsci, "arm,psci-0.2" },\r
+ { PropertyTypeFwCfg, "qemu,fw-cfg-mmio" },\r
{ PropertyTypeUnknown, "" }\r
};\r
\r
CONST INTERRUPT_PROPERTY *InterruptProp;\r
INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum;\r
CONST CHAR8 *PsciMethod;\r
+ UINT64 FwCfgSelectorAddress;\r
+ UINT64 FwCfgSelectorSize;\r
+ UINT64 FwCfgDataAddress;\r
+ UINT64 FwCfgDataSize;\r
\r
DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);\r
ASSERT (DeviceTreeBase != NULL);\r
(PropType == PropertyTypePsci));\r
\r
switch (PropType) {\r
+ case PropertyTypeFwCfg:\r
+ ASSERT (Len == 2 * sizeof (UINT64));\r
+\r
+ FwCfgDataAddress = fdt64_to_cpu (((UINT64 *)RegProp)[0]);\r
+ FwCfgDataSize = 8;\r
+ FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize;\r
+ FwCfgSelectorSize = 2;\r
+\r
+ //\r
+ // The following ASSERT()s express\r
+ //\r
+ // Address + Size - 1 <= MAX_UINTN\r
+ //\r
+ // for both registers, that is, that the last byte in each MMIO range is\r
+ // expressible as a MAX_UINTN. The form below is mathematically\r
+ // equivalent, and it also prevents any unsigned overflow before the\r
+ // comparison.\r
+ //\r
+ ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1);\r
+ ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1);\r
+\r
+ PcdSet64 (PcdFwCfgSelectorAddress, FwCfgSelectorAddress);\r
+ PcdSet64 (PcdFwCfgDataAddress, FwCfgDataAddress);\r
+\r
+ DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress,\r
+ FwCfgDataAddress));\r
+ break;\r
+\r
case PropertyTypeVirtio:\r
ASSERT (Len == 16);\r
//\r