+EFI_STATUS\r
+GetNamedFwCfgBoolean (\r
+ IN CHAR8 *FwCfgFileName,\r
+ OUT BOOLEAN *Setting\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ FIRMWARE_CONFIG_ITEM FwCfgItem;\r
+ UINTN FwCfgSize;\r
+ UINT8 Value[3];\r
+\r
+ Status = QemuFwCfgFindFile (FwCfgFileName, &FwCfgItem, &FwCfgSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if (FwCfgSize > sizeof Value) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+ QemuFwCfgSelectItem (FwCfgItem);\r
+ QemuFwCfgReadBytes (FwCfgSize, Value);\r
+\r
+ if ((FwCfgSize == 1) ||\r
+ (FwCfgSize == 2 && Value[1] == '\n') ||\r
+ (FwCfgSize == 3 && Value[1] == '\r' && Value[2] == '\n')) {\r
+ switch (Value[0]) {\r
+ case '0':\r
+ case 'n':\r
+ case 'N':\r
+ *Setting = FALSE;\r
+ return EFI_SUCCESS;\r
+\r
+ case '1':\r
+ case 'y':\r
+ case 'Y':\r
+ *Setting = TRUE;\r
+ return EFI_SUCCESS;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ return EFI_PROTOCOL_ERROR;\r
+}\r
+\r
+#define UPDATE_BOOLEAN_PCD_FROM_FW_CFG(TokenName) \\r
+ do { \\r
+ BOOLEAN Setting; \\r
+ \\r
+ if (!EFI_ERROR (GetNamedFwCfgBoolean ( \\r
+ "opt/ovmf/" #TokenName, &Setting))) { \\r
+ PcdSetBool (TokenName, Setting); \\r
+ } \\r
+ } while (0)\r
+\r
+VOID\r
+NoexecDxeInitialization (\r
+ VOID\r
+ )\r
+{\r
+ UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdPropertiesTableEnable);\r
+ UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdSetNxForStack);\r
+}\r
+\r
+VOID\r
+PciExBarInitialization (\r
+ VOID\r
+ )\r
+{\r
+ union {\r
+ UINT64 Uint64;\r
+ UINT32 Uint32[2];\r
+ } PciExBarBase;\r
+\r
+ //\r
+ // We only support the 256MB size for the MMCONFIG area:\r
+ // 256 buses * 32 devices * 8 functions * 4096 bytes config space.\r
+ //\r
+ // The masks used below enforce the Q35 requirements that the MMCONFIG area\r
+ // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.\r
+ //\r
+ // Note that (b) also ensures that the minimum address width we have\r
+ // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice\r
+ // for DXE's page tables to cover the MMCONFIG area.\r
+ //\r
+ PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);\r
+ ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);\r
+ ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);\r
+\r
+ //\r
+ // Clear the PCIEXBAREN bit first, before programming the high register.\r
+ //\r
+ PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);\r
+\r
+ //\r
+ // Program the high register. Then program the low register, setting the\r
+ // MMCONFIG area size and enabling decoding at once.\r
+ //\r
+ PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);\r
+ PciWrite32 (\r
+ DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),\r
+ PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN\r
+ );\r
+}\r