qemu/target-i386/cpu-qom.h
Eduardo Habkost d940ee9b78 target-i386: X86CPU model subclasses
Register separate QOM types for each x86 CPU model.

This will allow management code to more easily probe what each CPU model
provides, by simply creating objects using the appropriate class name,
without having to restart QEMU.

This also allows us to eliminate the qdev_prop_set_globals_for_type()
hack to set CPU-model-specific global properties.

Instead of creating separate class_init functions for each class, I just
used class_data to store a pointer to the X86CPUDefinition struct for
each CPU model. This should make the patch shorter and easier to review.
Later we can gradually convert each X86CPUDefinition field to lists of
per-class property defaults.

The "host" CPU model is special, as the feature flags depend on KVM
being initialized. So it has its own class_init and instance_init
function, and feature flags are set on instance_init instead of
class_init.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Tested-by: Eduardo Habkost <ehabkost@redhat.com>
[AF: Limit the host CPU type to CONFIG_KVM as build fix]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-03-13 19:20:07 +01:00

149 lines
4.2 KiB
C

/*
* QEMU x86 CPU
*
* Copyright (c) 2012 SUSE LINUX Products GmbH
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>
*/
#ifndef QEMU_I386_CPU_QOM_H
#define QEMU_I386_CPU_QOM_H
#include "qom/cpu.h"
#include "cpu.h"
#include "qapi/error.h"
#ifdef TARGET_X86_64
#define TYPE_X86_CPU "x86_64-cpu"
#else
#define TYPE_X86_CPU "i386-cpu"
#endif
#define X86_CPU_CLASS(klass) \
OBJECT_CLASS_CHECK(X86CPUClass, (klass), TYPE_X86_CPU)
#define X86_CPU(obj) \
OBJECT_CHECK(X86CPU, (obj), TYPE_X86_CPU)
#define X86_CPU_GET_CLASS(obj) \
OBJECT_GET_CLASS(X86CPUClass, (obj), TYPE_X86_CPU)
/**
* X86CPUDefinition:
*
* CPU model definition data that was not converted to QOM per-subclass
* property defaults yet.
*/
typedef struct X86CPUDefinition X86CPUDefinition;
/**
* X86CPUClass:
* @cpu_def: CPU model definition
* @kvm_required: Whether CPU model requires KVM to be enabled.
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* An x86 CPU model or family.
*/
typedef struct X86CPUClass {
/*< private >*/
CPUClass parent_class;
/*< public >*/
/* Should be eventually replaced by subclass-specific property defaults. */
X86CPUDefinition *cpu_def;
bool kvm_required;
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} X86CPUClass;
/**
* X86CPU:
* @env: #CPUX86State
*
* An x86 CPU.
*/
typedef struct X86CPU {
/*< private >*/
CPUState parent_obj;
/*< public >*/
CPUX86State env;
bool hyperv_vapic;
bool hyperv_relaxed_timing;
int hyperv_spinlock_attempts;
bool hyperv_time;
bool check_cpuid;
bool enforce_cpuid;
/* if true the CPUID code directly forward host cache leaves to the guest */
bool cache_info_passthrough;
/* Features that were filtered out because of missing host capabilities */
uint32_t filtered_features[FEATURE_WORDS];
/* Enable PMU CPUID bits. This can't be enabled by default yet because
* it doesn't have ABI stability guarantees, as it passes all PMU CPUID
* bits returned by GET_SUPPORTED_CPUID (that depend on host CPU and kernel
* capabilities) directly to the guest.
*/
bool enable_pmu;
/* in order to simplify APIC support, we leave this pointer to the
user */
struct DeviceState *apic_state;
} X86CPU;
static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
{
return container_of(env, X86CPU, env);
}
#define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
#define ENV_OFFSET offsetof(X86CPU, env)
#ifndef CONFIG_USER_ONLY
extern const struct VMStateDescription vmstate_x86_cpu;
#endif
/**
* x86_cpu_do_interrupt:
* @cpu: vCPU the interrupt is to be handled by.
*/
void x86_cpu_do_interrupt(CPUState *cpu);
int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
int cpuid, void *opaque);
int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
int cpuid, void *opaque);
int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
void *opaque);
int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
void *opaque);
void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
Error **errp);
void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags);
hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
#endif