mirror of https://github.com/xemu-project/xemu.git
target/i386: Move APIC related code to cpu-apic.c
Move APIC related code split in cpu-sysemu.c and monitor.c to cpu-apic.c. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Message-Id: <20240321154838.95771-4-philmd@linaro.org>
This commit is contained in:
parent
6c3b78532c
commit
63073574e8
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* QEMU x86 CPU <-> APIC
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003-2004 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "qapi/qmp/qdict.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
#include "monitor/monitor.h"
|
||||||
|
#include "monitor/hmp-target.h"
|
||||||
|
#include "sysemu/hw_accel.h"
|
||||||
|
#include "sysemu/kvm.h"
|
||||||
|
#include "sysemu/xen.h"
|
||||||
|
#include "exec/address-spaces.h"
|
||||||
|
#include "hw/qdev-properties.h"
|
||||||
|
#include "hw/i386/apic_internal.h"
|
||||||
|
#include "cpu-internal.h"
|
||||||
|
|
||||||
|
APICCommonClass *apic_get_class(Error **errp)
|
||||||
|
{
|
||||||
|
const char *apic_type = "apic";
|
||||||
|
|
||||||
|
/* TODO: in-kernel irqchip for hvf */
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
if (!kvm_irqchip_in_kernel()) {
|
||||||
|
error_setg(errp, "KVM does not support userspace APIC");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
apic_type = "kvm-apic";
|
||||||
|
} else if (xen_enabled()) {
|
||||||
|
apic_type = "xen-apic";
|
||||||
|
} else if (whpx_apic_in_platform()) {
|
||||||
|
apic_type = "whpx-apic";
|
||||||
|
}
|
||||||
|
|
||||||
|
return APIC_COMMON_CLASS(object_class_by_name(apic_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
|
||||||
|
{
|
||||||
|
APICCommonState *apic;
|
||||||
|
APICCommonClass *apic_class = apic_get_class(errp);
|
||||||
|
|
||||||
|
if (!apic_class) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu->apic_state = DEVICE(object_new_with_class(OBJECT_CLASS(apic_class)));
|
||||||
|
object_property_add_child(OBJECT(cpu), "lapic",
|
||||||
|
OBJECT(cpu->apic_state));
|
||||||
|
object_unref(OBJECT(cpu->apic_state));
|
||||||
|
|
||||||
|
/* TODO: convert to link<> */
|
||||||
|
apic = APIC_COMMON(cpu->apic_state);
|
||||||
|
apic->cpu = cpu;
|
||||||
|
apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* apic_common_set_id needs to check if the CPU has x2APIC
|
||||||
|
* feature in case APIC ID >= 255, so we need to set apic->cpu
|
||||||
|
* before setting APIC ID
|
||||||
|
*/
|
||||||
|
qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
|
||||||
|
{
|
||||||
|
APICCommonState *apic;
|
||||||
|
static bool apic_mmio_map_once;
|
||||||
|
|
||||||
|
if (cpu->apic_state == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qdev_realize(DEVICE(cpu->apic_state), NULL, errp);
|
||||||
|
|
||||||
|
/* Map APIC MMIO area */
|
||||||
|
apic = APIC_COMMON(cpu->apic_state);
|
||||||
|
if (!apic_mmio_map_once) {
|
||||||
|
memory_region_add_subregion_overlap(get_system_memory(),
|
||||||
|
apic->apicbase &
|
||||||
|
MSR_IA32_APICBASE_BASE,
|
||||||
|
&apic->io_memory,
|
||||||
|
0x1000);
|
||||||
|
apic_mmio_map_once = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
CPUState *cs;
|
||||||
|
|
||||||
|
if (qdict_haskey(qdict, "apic-id")) {
|
||||||
|
int id = qdict_get_try_int(qdict, "apic-id", 0);
|
||||||
|
|
||||||
|
cs = cpu_by_arch_id(id);
|
||||||
|
if (cs) {
|
||||||
|
cpu_synchronize_state(cs);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cs = mon_get_cpu(mon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!cs) {
|
||||||
|
monitor_printf(mon, "No CPU available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
|
||||||
|
}
|
|
@ -19,19 +19,12 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "sysemu/kvm.h"
|
|
||||||
#include "sysemu/xen.h"
|
|
||||||
#include "sysemu/whpx.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-visit-run-state.h"
|
#include "qapi/qapi-visit-run-state.h"
|
||||||
#include "qapi/qmp/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
#include "qapi/qobject-input-visitor.h"
|
#include "qapi/qobject-input-visitor.h"
|
||||||
#include "qom/qom-qobject.h"
|
#include "qom/qom-qobject.h"
|
||||||
#include "qapi/qapi-commands-machine-target.h"
|
#include "qapi/qapi-commands-machine-target.h"
|
||||||
#include "hw/qdev-properties.h"
|
|
||||||
|
|
||||||
#include "exec/address-spaces.h"
|
|
||||||
#include "hw/i386/apic_internal.h"
|
|
||||||
|
|
||||||
#include "cpu-internal.h"
|
#include "cpu-internal.h"
|
||||||
|
|
||||||
|
@ -273,75 +266,6 @@ void x86_cpu_machine_reset_cb(void *opaque)
|
||||||
cpu_reset(CPU(cpu));
|
cpu_reset(CPU(cpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
APICCommonClass *apic_get_class(Error **errp)
|
|
||||||
{
|
|
||||||
const char *apic_type = "apic";
|
|
||||||
|
|
||||||
/* TODO: in-kernel irqchip for hvf */
|
|
||||||
if (kvm_enabled()) {
|
|
||||||
if (!kvm_irqchip_in_kernel()) {
|
|
||||||
error_setg(errp, "KVM does not support userspace APIC");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
apic_type = "kvm-apic";
|
|
||||||
} else if (xen_enabled()) {
|
|
||||||
apic_type = "xen-apic";
|
|
||||||
} else if (whpx_apic_in_platform()) {
|
|
||||||
apic_type = "whpx-apic";
|
|
||||||
}
|
|
||||||
|
|
||||||
return APIC_COMMON_CLASS(object_class_by_name(apic_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
|
|
||||||
{
|
|
||||||
APICCommonState *apic;
|
|
||||||
APICCommonClass *apic_class = apic_get_class(errp);
|
|
||||||
|
|
||||||
if (!apic_class) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpu->apic_state = DEVICE(object_new_with_class(OBJECT_CLASS(apic_class)));
|
|
||||||
object_property_add_child(OBJECT(cpu), "lapic",
|
|
||||||
OBJECT(cpu->apic_state));
|
|
||||||
object_unref(OBJECT(cpu->apic_state));
|
|
||||||
|
|
||||||
/* TODO: convert to link<> */
|
|
||||||
apic = APIC_COMMON(cpu->apic_state);
|
|
||||||
apic->cpu = cpu;
|
|
||||||
apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* apic_common_set_id needs to check if the CPU has x2APIC
|
|
||||||
* feature in case APIC ID >= 255, so we need to set apic->cpu
|
|
||||||
* before setting APIC ID
|
|
||||||
*/
|
|
||||||
qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
|
|
||||||
{
|
|
||||||
APICCommonState *apic;
|
|
||||||
static bool apic_mmio_map_once;
|
|
||||||
|
|
||||||
if (cpu->apic_state == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qdev_realize(DEVICE(cpu->apic_state), NULL, errp);
|
|
||||||
|
|
||||||
/* Map APIC MMIO area */
|
|
||||||
apic = APIC_COMMON(cpu->apic_state);
|
|
||||||
if (!apic_mmio_map_once) {
|
|
||||||
memory_region_add_subregion_overlap(get_system_memory(),
|
|
||||||
apic->apicbase &
|
|
||||||
MSR_IA32_APICBASE_BASE,
|
|
||||||
&apic->io_memory,
|
|
||||||
0x1000);
|
|
||||||
apic_mmio_map_once = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
|
GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
|
||||||
{
|
{
|
||||||
X86CPU *cpu = X86_CPU(cs);
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
|
@ -385,4 +309,3 @@ void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
|
||||||
errp);
|
errp);
|
||||||
qapi_free_GuestPanicInformation(panic_info);
|
qapi_free_GuestPanicInformation(panic_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ i386_system_ss.add(files(
|
||||||
'arch_memory_mapping.c',
|
'arch_memory_mapping.c',
|
||||||
'machine.c',
|
'machine.c',
|
||||||
'monitor.c',
|
'monitor.c',
|
||||||
|
'cpu-apic.c',
|
||||||
'cpu-sysemu.c',
|
'cpu-sysemu.c',
|
||||||
))
|
))
|
||||||
i386_system_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c'))
|
i386_system_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c'))
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "monitor/hmp-target.h"
|
#include "monitor/hmp-target.h"
|
||||||
#include "monitor/hmp.h"
|
#include "monitor/hmp.h"
|
||||||
#include "qapi/qmp/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
#include "sysemu/hw_accel.h"
|
|
||||||
#include "sysemu/kvm.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-commands-misc-target.h"
|
#include "qapi/qapi-commands-misc-target.h"
|
||||||
#include "qapi/qapi-commands-misc.h"
|
#include "qapi/qapi-commands-misc.h"
|
||||||
|
@ -647,26 +645,3 @@ const MonitorDef *target_monitor_defs(void)
|
||||||
{
|
{
|
||||||
return monitor_defs;
|
return monitor_defs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
|
|
||||||
{
|
|
||||||
CPUState *cs;
|
|
||||||
|
|
||||||
if (qdict_haskey(qdict, "apic-id")) {
|
|
||||||
int id = qdict_get_try_int(qdict, "apic-id", 0);
|
|
||||||
|
|
||||||
cs = cpu_by_arch_id(id);
|
|
||||||
if (cs) {
|
|
||||||
cpu_synchronize_state(cs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cs = mon_get_cpu(mon);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!cs) {
|
|
||||||
monitor_printf(mon, "No CPU available\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue