]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
OvmfPkg/CpuHotplugSmm: add hotplug register block helper functions
[mirror_edk2.git] / OvmfPkg / CpuHotplugSmm / QemuCpuhp.c
1 /** @file
2 Simple wrapper functions that access QEMU's modern CPU hotplug register
3 block.
4
5 These functions thinly wrap some of the registers described in
6 "docs/specs/acpi_cpu_hotplug.txt" in the QEMU source. IO Ports are accessed
7 via EFI_MM_CPU_IO_PROTOCOL. If a protocol call fails, these functions don't
8 return.
9
10 Copyright (c) 2020, Red Hat, Inc.
11
12 SPDX-License-Identifier: BSD-2-Clause-Patent
13 **/
14
15 #include <IndustryStandard/Q35MchIch9.h> // ICH9_CPU_HOTPLUG_BASE
16 #include <IndustryStandard/QemuCpuHotplug.h> // QEMU_CPUHP_R_CMD_DATA2
17 #include <Library/BaseLib.h> // CpuDeadLoop()
18 #include <Library/DebugLib.h> // DEBUG()
19
20 #include "QemuCpuhp.h"
21
22 UINT32
23 QemuCpuhpReadCommandData2 (
24 IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo
25 )
26 {
27 UINT32 CommandData2;
28 EFI_STATUS Status;
29
30 CommandData2 = 0;
31 Status = MmCpuIo->Io.Read (
32 MmCpuIo,
33 MM_IO_UINT32,
34 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_R_CMD_DATA2,
35 1,
36 &CommandData2
37 );
38 if (EFI_ERROR (Status)) {
39 DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
40 ASSERT (FALSE);
41 CpuDeadLoop ();
42 }
43 return CommandData2;
44 }
45
46 UINT8
47 QemuCpuhpReadCpuStatus (
48 IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo
49 )
50 {
51 UINT8 CpuStatus;
52 EFI_STATUS Status;
53
54 CpuStatus = 0;
55 Status = MmCpuIo->Io.Read (
56 MmCpuIo,
57 MM_IO_UINT8,
58 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_R_CPU_STAT,
59 1,
60 &CpuStatus
61 );
62 if (EFI_ERROR (Status)) {
63 DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
64 ASSERT (FALSE);
65 CpuDeadLoop ();
66 }
67 return CpuStatus;
68 }
69
70 UINT32
71 QemuCpuhpReadCommandData (
72 IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo
73 )
74 {
75 UINT32 CommandData;
76 EFI_STATUS Status;
77
78 CommandData = 0;
79 Status = MmCpuIo->Io.Read (
80 MmCpuIo,
81 MM_IO_UINT32,
82 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_RW_CMD_DATA,
83 1,
84 &CommandData
85 );
86 if (EFI_ERROR (Status)) {
87 DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
88 ASSERT (FALSE);
89 CpuDeadLoop ();
90 }
91 return CommandData;
92 }
93
94 VOID
95 QemuCpuhpWriteCpuSelector (
96 IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo,
97 IN UINT32 Selector
98 )
99 {
100 EFI_STATUS Status;
101
102 Status = MmCpuIo->Io.Write (
103 MmCpuIo,
104 MM_IO_UINT32,
105 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_W_CPU_SEL,
106 1,
107 &Selector
108 );
109 if (EFI_ERROR (Status)) {
110 DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
111 ASSERT (FALSE);
112 CpuDeadLoop ();
113 }
114 }
115
116 VOID
117 QemuCpuhpWriteCommand (
118 IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo,
119 IN UINT8 Command
120 )
121 {
122 EFI_STATUS Status;
123
124 Status = MmCpuIo->Io.Write (
125 MmCpuIo,
126 MM_IO_UINT8,
127 ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_W_CMD,
128 1,
129 &Command
130 );
131 if (EFI_ERROR (Status)) {
132 DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
133 ASSERT (FALSE);
134 CpuDeadLoop ();
135 }
136 }