23QemuCpuhpReadCommandData2 (
31 Status = MmCpuIo->Io.Read (
34 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_R_CMD_DATA2,
38 if (EFI_ERROR (Status)) {
39 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, Status));
48QemuCpuhpReadCpuStatus (
56 Status = MmCpuIo->Io.Read (
59 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_R_CPU_STAT,
63 if (EFI_ERROR (Status)) {
64 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, Status));
73QemuCpuhpReadCommandData (
81 Status = MmCpuIo->Io.Read (
84 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_RW_CMD_DATA,
88 if (EFI_ERROR (Status)) {
89 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, Status));
98QemuCpuhpWriteCpuSelector (
105 Status = MmCpuIo->Io.Write (
108 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_W_CPU_SEL,
112 if (EFI_ERROR (Status)) {
113 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, Status));
120QemuCpuhpWriteCpuStatus (
127 Status = MmCpuIo->Io.Write (
130 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_R_CPU_STAT,
134 if (EFI_ERROR (Status)) {
135 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, Status));
142QemuCpuhpWriteCommand (
149 Status = MmCpuIo->Io.Write (
152 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_W_CMD,
156 if (EFI_ERROR (Status)) {
157 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, Status));
213 IN UINT32 PossibleCpuCount,
214 IN UINT32 ApicIdCount,
215 OUT APIC_ID *PluggedApicIds,
216 OUT UINT32 *PluggedCount,
217 OUT APIC_ID *ToUnplugApicIds,
218 OUT UINT32 *ToUnplugSelectors,
219 OUT UINT32 *ToUnplugCount
222 UINT32 CurrentSelector;
224 if ((PossibleCpuCount == 0) || (ApicIdCount == 0)) {
225 return EFI_INVALID_PARAMETER;
233 UINT32 PendingSelector;
249 QemuCpuhpWriteCpuSelector (MmCpuIo, CurrentSelector);
262 QemuCpuhpWriteCommand (MmCpuIo, QEMU_CPUHP_CMD_GET_PENDING);
263 PendingSelector = QemuCpuhpReadCommandData (MmCpuIo);
264 if (PendingSelector < CurrentSelector) {
267 "%a: CurrentSelector=%u PendingSelector=%u: "
276 CurrentSelector = PendingSelector;
281 CpuStatus = QemuCpuhpReadCpuStatus (MmCpuIo);
282 if ((CpuStatus & QEMU_CPUHP_STAT_INSERT) != 0) {
287 if (((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0) ||
288 ((CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0))
292 "%a: CurrentSelector=%u CpuStatus=0x%x: "
293 "inconsistent CPU status\n",
298 return EFI_PROTOCOL_ERROR;
303 "%a: CurrentSelector=%u: insert\n",
308 ExtendIds = PluggedApicIds;
310 ExtendCount = PluggedCount;
311 }
else if ((CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) {
315 if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0) {
318 "%a: CurrentSelector=%u CpuStatus=0x%x: "
319 "inconsistent CPU status\n",
324 return EFI_PROTOCOL_ERROR;
329 "%a: CurrentSelector=%u: fw_remove\n",
334 ExtendIds = ToUnplugApicIds;
335 ExtendSels = ToUnplugSelectors;
336 ExtendCount = ToUnplugCount;
337 }
else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {
343 "%a: CurrentSelector=%u: remove (ignored)\n",
354 "%a: CurrentSelector=%u: no event\n",
361 ASSERT ((ExtendIds ==
NULL) == (ExtendCount ==
NULL));
362 ASSERT ((ExtendSels ==
NULL) || (ExtendIds !=
NULL));
364 if (ExtendIds !=
NULL) {
370 if (*ExtendCount == ApicIdCount) {
371 DEBUG ((DEBUG_ERROR,
"%a: APIC ID array too small\n", __func__));
372 return EFI_BUFFER_TOO_SMALL;
375 QemuCpuhpWriteCommand (MmCpuIo, QEMU_CPUHP_CMD_GET_ARCH_ID);
376 NewApicId = QemuCpuhpReadCommandData (MmCpuIo);
379 "%a: ApicId=" FMT_APIC_ID
"\n",
383 if (ExtendSels !=
NULL) {
384 ExtendSels[(*ExtendCount)] = CurrentSelector;
387 ExtendIds[(*ExtendCount)++] = NewApicId;
397 }
while (CurrentSelector < PossibleCpuCount);
401 "%a: PluggedCount=%u ToUnplugCount=%u\n",
VOID EFIAPI CpuDeadLoop(VOID)
#define DEBUG(Expression)
EFI_STATUS QemuCpuhpCollectApicIds(IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo, IN UINT32 PossibleCpuCount, IN UINT32 ApicIdCount, OUT APIC_ID *PluggedApicIds, OUT UINT32 *PluggedCount, OUT APIC_ID *ToUnplugApicIds, OUT UINT32 *ToUnplugSelectors, OUT UINT32 *ToUnplugCount)