**/\r
\r
#include <IndustryStandard/Q35MchIch9.h> // ICH9_APM_CNT\r
+#include <IndustryStandard/QemuCpuHotplug.h> // QEMU_CPUHP_CMD_GET_PENDING\r
#include <Library/BaseLib.h> // CpuDeadLoop()\r
#include <Library/DebugLib.h> // ASSERT()\r
#include <Library/MmServicesTableLib.h> // gMmst\r
#include <Protocol/MmCpuIo.h> // EFI_MM_CPU_IO_PROTOCOL\r
#include <Uefi/UefiBaseType.h> // EFI_STATUS\r
\r
+#include "QemuCpuhp.h" // QemuCpuhpWriteCpuSelector()\r
+\r
//\r
// We use this protocol for accessing IO Ports.\r
//\r
goto Fatal;\r
}\r
\r
+ //\r
+ // Sanity-check the CPU hotplug interface.\r
+ //\r
+ // Both of the following features are part of QEMU 5.0, introduced primarily\r
+ // in commit range 3e08b2b9cb64..3a61c8db9d25:\r
+ //\r
+ // (a) the QEMU_CPUHP_CMD_GET_ARCH_ID command of the modern CPU hotplug\r
+ // interface,\r
+ //\r
+ // (b) the "SMRAM at default SMBASE" feature.\r
+ //\r
+ // From these, (b) is restricted to 5.0+ machine type versions, while (a)\r
+ // does not depend on machine type version. Because we ensured the stricter\r
+ // condition (b) through PcdQ35SmramAtDefaultSmbase above, the (a)\r
+ // QEMU_CPUHP_CMD_GET_ARCH_ID command must now be available too. While we\r
+ // can't verify the presence of precisely that command, we can still verify\r
+ // (sanity-check) that the modern interface is active, at least.\r
+ //\r
+ // Consult the "Typical usecases | Detecting and enabling modern CPU hotplug\r
+ // interface" section in QEMU's "docs/specs/acpi_cpu_hotplug.txt", on the\r
+ // following.\r
+ //\r
+ QemuCpuhpWriteCpuSelector (mMmCpuIo, 0);\r
+ QemuCpuhpWriteCpuSelector (mMmCpuIo, 0);\r
+ QemuCpuhpWriteCommand (mMmCpuIo, QEMU_CPUHP_CMD_GET_PENDING);\r
+ if (QemuCpuhpReadCommandData2 (mMmCpuIo) != 0) {\r
+ Status = EFI_NOT_FOUND;\r
+ DEBUG ((DEBUG_ERROR, "%a: modern CPU hotplug interface: %r\n",\r
+ __FUNCTION__, Status));\r
+ goto Fatal;\r
+ }\r
+\r
//\r
// Register the handler for the CPU Hotplug MMI.\r
//\r