@@ -7,6 +7,12 @@
#define ACPI_CPU_HOTPLUG_REG_LEN 12
#define ACPI_CPU_SELECTOR_OFFSET_WR 0
#define ACPI_CPU_FLAGS_OFFSET_RW 4
+#define ACPI_CPU_CMD_OFFSET_WR 5
+#define ACPI_CPU_CMD_DATA_OFFSET_RW 8
+
+enum {
+ CPHP_CMD_MAX
+};
static uint64_t cpu_hotplug_rd(void *opaque, hwaddr addr, unsigned size)
{
@@ -27,6 +33,12 @@ static uint64_t cpu_hotplug_rd(void *opaque, hwaddr addr, unsigned size)
val |= cdev->is_removing ? 4 : 0;
trace_cpuhp_acpi_read_flags(cpu_st->selector, val);
break;
+ case ACPI_CPU_CMD_DATA_OFFSET_RW:
+ switch (cpu_st->command) {
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -80,6 +92,12 @@ static void cpu_hotplug_wr(void *opaque, hwaddr addr, uint64_t data,
}
}
break;
+ case ACPI_CPU_CMD_OFFSET_WR:
+ trace_cpuhp_acpi_write_cmd(cpu_st->selector, data);
+ if (data < CPHP_CMD_MAX) {
+ cpu_st->command = data;
+ }
+ break;
default:
break;
}
@@ -211,6 +229,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(selector, CPUHotplugState),
+ VMSTATE_UINT32(command, CPUHotplugState),
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs, CPUHotplugState, dev_count,
vmstate_cpuhp_sts, AcpiCpuStatus),
VMSTATE_END_OF_LIST()
@@ -230,6 +249,8 @@ const VMStateDescription vmstate_cpu_hotplug = {
#define CPU_EJECT_EVENT "CEJ0"
#define CPU_INSERT_EVENT "CINS"
#define CPU_REMOVE_EVENT "CRMV"
+#define CPU_COMMAND "CCMD"
+#define CPU_DATA "CDAT"
void build_cpus_aml(Aml *table, MachineState *machine, bool acpi1_compat,
const char *res_root, const char *event_handler_method,
@@ -281,11 +302,16 @@ void build_cpus_aml(Aml *table, MachineState *machine, bool acpi1_compat,
aml_append(field, aml_named_field(CPU_REMOVE_EVENT, 1));
/* initiates device eject, write only */
aml_append(field, aml_named_field(CPU_EJECT_EVENT, 1));
+ aml_append(field, aml_reserved_field(4));
+ aml_append(field, aml_named_field(CPU_COMMAND, 8));
aml_append(cpu_ctrl_dev, field);
field = aml_field("PRST", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
/* CPU selector, write only */
aml_append(field, aml_named_field(CPU_SELECTOR, 32));
+ /* flags + cmd + 2byte align */
+ aml_append(field, aml_reserved_field(4 * 8));
+ aml_append(field, aml_named_field(CPU_DATA, 32));
aml_append(cpu_ctrl_dev, field);
}
@@ -29,6 +29,7 @@ typedef struct CPUHotplugState {
MemoryRegion ctrl_reg;
bool is_enabled;
uint32_t selector;
+ uint32_t command;
uint32_t dev_count;
AcpiCpuStatus *devs;
} CPUHotplugState;
@@ -1916,5 +1916,6 @@ cpuhp_acpi_read_flags(uint32_t idx, uint8_t flags) "idx[0x%"PRIx32"] flags: 0x%"
cpuhp_acpi_clear_inserting_evt(uint32_t idx) "idx[0x%"PRIx32"]"
cpuhp_acpi_clear_remove_evt(uint32_t idx) "idx[0x%"PRIx32"]"
cpuhp_acpi_write_idx(uint32_t idx) "set active cpu idx: 0x%"PRIx32
+cpuhp_acpi_write_cmd(uint32_t idx, uint8_t cmd) "idx[0x%"PRIx32"] cmd: 0x%"PRIx8
cpuhp_acpi_ejecting_invalid_cpu(uint32_t idx) "0x%"PRIx32
cpuhp_acpi_ejecting_cpu(uint32_t idx) "0x%"PRIx32
CPU device has a lot of optional methods that might be needed to be added in future in QEMU, so instead of reserving/consuming IO/MMIO register for each of it introduce a generic DATA read-write register which is multiplexed by additional COMMAND write-only register. currently that registers will be used for getting CPU's _PXM value and setting _OST.event/_OST.status values that OSPM reports to QEMU. Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- hw/acpi/cpu.c | 26 ++++++++++++++++++++++++++ include/hw/acpi/cpu.h | 1 + trace-events | 1 + 3 files changed, 28 insertions(+)