mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'afaerber/qom-cpu' into staging
* afaerber/qom-cpu: (37 commits) kvm: Pass CPUState to kvm_on_sigbus_vcpu() cpu: Unconditionalize CPUState fields target-m68k: Use type_register() instead of type_register_static() target-unicore32: Use type_register() instead of type_register_static() target-openrisc: Use type_register() instead of type_register_static() target-unicore32: Catch attempt to instantiate abstract type in cpu_init() target-openrisc: Catch attempt to instantiate abstract type in cpu_init() target-m68k: Catch attempt to instantiate abstract type in cpu_init() target-arm: Catch attempt to instantiate abstract type in cpu_init() target-alpha: Catch attempt to instantiate abstract type in cpu_init() qom: Introduce object_class_is_abstract() target-unicore32: Detect attempt to instantiate non-CPU type in cpu_init() target-openrisc: Detect attempt to instantiate non-CPU type in cpu_init() target-m68k: Detect attempt to instantiate non-CPU type in cpu_init() target-alpha: Detect attempt to instantiate non-CPU type in cpu_init() target-arm: Detect attempt to instantiate non-CPU type in cpu_init() cpu: Add model resolution support to CPUClass target-i386: Remove setting tsc-frequency from x86_def_t target-i386: Set custom features/properties without intermediate x86_def_t target-i386: Remove vendor_override field from CPUX86State ... Conflicts: tests/Makefile Resolved simple conflict caused by lack of context in Makefile Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
@@ -517,7 +517,7 @@ static void qemu_init_sigbus(void)
|
||||
prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
|
||||
}
|
||||
|
||||
static void qemu_kvm_eat_signals(CPUArchState *env)
|
||||
static void qemu_kvm_eat_signals(CPUState *cpu)
|
||||
{
|
||||
struct timespec ts = { 0, 0 };
|
||||
siginfo_t siginfo;
|
||||
@@ -538,7 +538,7 @@ static void qemu_kvm_eat_signals(CPUArchState *env)
|
||||
|
||||
switch (r) {
|
||||
case SIGBUS:
|
||||
if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
|
||||
if (kvm_on_sigbus_vcpu(cpu, siginfo.si_code, siginfo.si_addr)) {
|
||||
sigbus_reraise();
|
||||
}
|
||||
break;
|
||||
@@ -560,7 +560,7 @@ static void qemu_init_sigbus(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void qemu_kvm_eat_signals(CPUArchState *env)
|
||||
static void qemu_kvm_eat_signals(CPUState *cpu)
|
||||
{
|
||||
}
|
||||
#endif /* !CONFIG_LINUX */
|
||||
@@ -727,7 +727,7 @@ static void qemu_kvm_wait_io_event(CPUArchState *env)
|
||||
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
||||
}
|
||||
|
||||
qemu_kvm_eat_signals(env);
|
||||
qemu_kvm_eat_signals(cpu);
|
||||
qemu_wait_io_event_common(cpu);
|
||||
}
|
||||
|
||||
|
||||
@@ -504,7 +504,6 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
||||
fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
|
||||
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
|
||||
fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
|
||||
fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
|
||||
fw_cfg_bootsplash(s);
|
||||
fw_cfg_reboot(s);
|
||||
|
||||
@@ -551,6 +551,18 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Calculates the limit to CPU APIC ID values
|
||||
*
|
||||
* This function returns the limit for the APIC ID value, so that all
|
||||
* CPU APIC IDs are < pc_apic_id_limit().
|
||||
*
|
||||
* This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
|
||||
*/
|
||||
static unsigned int pc_apic_id_limit(unsigned int max_cpus)
|
||||
{
|
||||
return x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
|
||||
}
|
||||
|
||||
static void *bochs_bios_init(void)
|
||||
{
|
||||
void *fw_cfg;
|
||||
@@ -558,9 +570,24 @@ static void *bochs_bios_init(void)
|
||||
size_t smbios_len;
|
||||
uint64_t *numa_fw_cfg;
|
||||
int i, j;
|
||||
unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
|
||||
|
||||
fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
|
||||
|
||||
/* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
|
||||
*
|
||||
* SeaBIOS needs FW_CFG_MAX_CPUS for CPU hotplug, but the CPU hotplug
|
||||
* QEMU<->SeaBIOS interface is not based on the "CPU index", but on the APIC
|
||||
* ID of hotplugged CPUs[1]. This means that FW_CFG_MAX_CPUS is not the
|
||||
* "maximum number of CPUs", but the "limit to the APIC ID values SeaBIOS
|
||||
* may see".
|
||||
*
|
||||
* So, this means we must not use max_cpus, here, but the maximum possible
|
||||
* APIC ID value, plus one.
|
||||
*
|
||||
* [1] The only kind of "CPU identifier" used between SeaBIOS and QEMU is
|
||||
* the APIC ID, not the "CPU index"
|
||||
*/
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)apic_id_limit);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
|
||||
@@ -579,21 +606,24 @@ static void *bochs_bios_init(void)
|
||||
* of nodes, one word for each VCPU->node and one word for each node to
|
||||
* hold the amount of memory.
|
||||
*/
|
||||
numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes);
|
||||
numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes);
|
||||
numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
|
||||
for (i = 0; i < max_cpus; i++) {
|
||||
unsigned int apic_id = x86_cpu_apic_id_from_index(i);
|
||||
assert(apic_id < apic_id_limit);
|
||||
for (j = 0; j < nb_numa_nodes; j++) {
|
||||
if (test_bit(i, node_cpumask[j])) {
|
||||
numa_fw_cfg[i + 1] = cpu_to_le64(j);
|
||||
numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]);
|
||||
numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(node_mem[i]);
|
||||
}
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
|
||||
(1 + max_cpus + nb_numa_nodes) * sizeof(*numa_fw_cfg));
|
||||
(1 + apic_id_limit + nb_numa_nodes) *
|
||||
sizeof(*numa_fw_cfg));
|
||||
|
||||
return fw_cfg;
|
||||
}
|
||||
|
||||
+19
-7
@@ -235,10 +235,18 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
|
||||
|
||||
static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
|
||||
{
|
||||
enable_kvm_pv_eoi();
|
||||
enable_compat_apic_id_mode();
|
||||
pc_init_pci(args);
|
||||
}
|
||||
|
||||
/* PC machine init function for pc-0.14 to pc-1.2 */
|
||||
static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
|
||||
{
|
||||
disable_kvm_pv_eoi();
|
||||
pc_init_pci_1_3(args);
|
||||
}
|
||||
|
||||
/* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
|
||||
static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
|
||||
{
|
||||
ram_addr_t ram_size = args->ram_size;
|
||||
@@ -247,6 +255,8 @@ static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
|
||||
const char *kernel_cmdline = args->kernel_cmdline;
|
||||
const char *initrd_filename = args->initrd_filename;
|
||||
const char *boot_device = args->boot_device;
|
||||
disable_kvm_pv_eoi();
|
||||
enable_compat_apic_id_mode();
|
||||
pc_init1(get_system_memory(),
|
||||
get_system_io(),
|
||||
ram_size, boot_device,
|
||||
@@ -264,6 +274,8 @@ static void pc_init_isa(QEMUMachineInitArgs *args)
|
||||
const char *boot_device = args->boot_device;
|
||||
if (cpu_model == NULL)
|
||||
cpu_model = "486";
|
||||
disable_kvm_pv_eoi();
|
||||
enable_compat_apic_id_mode();
|
||||
pc_init1(get_system_memory(),
|
||||
get_system_io(),
|
||||
ram_size, boot_device,
|
||||
@@ -286,7 +298,7 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
|
||||
.name = "pc-i440fx-1.4",
|
||||
.alias = "pc",
|
||||
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
||||
.init = pc_init_pci_1_3,
|
||||
.init = pc_init_pci,
|
||||
.max_cpus = 255,
|
||||
.is_default = 1,
|
||||
DEFAULT_MACHINE_OPTIONS,
|
||||
@@ -342,7 +354,7 @@ static QEMUMachine pc_machine_v1_3 = {
|
||||
static QEMUMachine pc_machine_v1_2 = {
|
||||
.name = "pc-1.2",
|
||||
.desc = "Standard PC",
|
||||
.init = pc_init_pci,
|
||||
.init = pc_init_pci_1_2,
|
||||
.max_cpus = 255,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_1_2,
|
||||
@@ -386,7 +398,7 @@ static QEMUMachine pc_machine_v1_2 = {
|
||||
static QEMUMachine pc_machine_v1_1 = {
|
||||
.name = "pc-1.1",
|
||||
.desc = "Standard PC",
|
||||
.init = pc_init_pci,
|
||||
.init = pc_init_pci_1_2,
|
||||
.max_cpus = 255,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_1_1,
|
||||
@@ -422,7 +434,7 @@ static QEMUMachine pc_machine_v1_1 = {
|
||||
static QEMUMachine pc_machine_v1_0 = {
|
||||
.name = "pc-1.0",
|
||||
.desc = "Standard PC",
|
||||
.init = pc_init_pci,
|
||||
.init = pc_init_pci_1_2,
|
||||
.max_cpus = 255,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_1_0,
|
||||
@@ -438,7 +450,7 @@ static QEMUMachine pc_machine_v1_0 = {
|
||||
static QEMUMachine pc_machine_v0_15 = {
|
||||
.name = "pc-0.15",
|
||||
.desc = "Standard PC",
|
||||
.init = pc_init_pci,
|
||||
.init = pc_init_pci_1_2,
|
||||
.max_cpus = 255,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_0_15,
|
||||
@@ -471,7 +483,7 @@ static QEMUMachine pc_machine_v0_15 = {
|
||||
static QEMUMachine pc_machine_v0_14 = {
|
||||
.name = "pc-0.14",
|
||||
.desc = "Standard PC",
|
||||
.init = pc_init_pci,
|
||||
.init = pc_init_pci_1_2,
|
||||
.max_cpus = 255,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_0_14,
|
||||
|
||||
@@ -413,6 +413,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
||||
/* No PCI init: the BIOS will do it */
|
||||
|
||||
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
|
||||
|
||||
@@ -299,6 +299,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
|
||||
/* No PCI init: the BIOS will do it */
|
||||
|
||||
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
|
||||
|
||||
@@ -1021,6 +1021,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
|
||||
hwdef->ecc_version);
|
||||
|
||||
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
|
||||
@@ -1665,6 +1666,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
|
||||
"Sun4d");
|
||||
|
||||
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
|
||||
@@ -1865,6 +1867,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
|
||||
"Sun4c");
|
||||
|
||||
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
|
||||
|
||||
@@ -878,6 +878,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
|
||||
(uint8_t *)&nd_table[0].macaddr);
|
||||
|
||||
fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
|
||||
|
||||
+15
-2
@@ -40,6 +40,8 @@ typedef struct CPUState CPUState;
|
||||
|
||||
/**
|
||||
* CPUClass:
|
||||
* @class_by_name: Callback to map -cpu command line model name to an
|
||||
* instantiatable CPU type.
|
||||
* @reset: Callback to reset the #CPUState to its initial state.
|
||||
*
|
||||
* Represents a CPU family or model.
|
||||
@@ -49,6 +51,8 @@ typedef struct CPUClass {
|
||||
DeviceClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
ObjectClass *(*class_by_name)(const char *cpu_model);
|
||||
|
||||
void (*reset)(CPUState *cpu);
|
||||
} CPUClass;
|
||||
|
||||
@@ -89,10 +93,8 @@ struct CPUState {
|
||||
bool stop;
|
||||
bool stopped;
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
int kvm_fd;
|
||||
bool kvm_vcpu_dirty;
|
||||
#endif
|
||||
struct KVMState *kvm_state;
|
||||
struct kvm_run *kvm_run;
|
||||
|
||||
@@ -107,6 +109,17 @@ struct CPUState {
|
||||
*/
|
||||
void cpu_reset(CPUState *cpu);
|
||||
|
||||
/**
|
||||
* cpu_class_by_name:
|
||||
* @typename: The CPU base type.
|
||||
* @cpu_model: The model string without any parameters.
|
||||
*
|
||||
* Looks up a CPU #ObjectClass matching name @cpu_model.
|
||||
*
|
||||
* Returns: A #CPUClass or %NULL if not matching class is found.
|
||||
*/
|
||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
|
||||
|
||||
/**
|
||||
* qemu_cpu_has_work:
|
||||
* @cpu: The vCPU to check.
|
||||
|
||||
@@ -690,6 +690,14 @@ ObjectClass *object_class_get_parent(ObjectClass *klass);
|
||||
*/
|
||||
const char *object_class_get_name(ObjectClass *klass);
|
||||
|
||||
/**
|
||||
* object_class_is_abstract:
|
||||
* @klass: The class to obtain the abstractness for.
|
||||
*
|
||||
* Returns: %true if @klass is abstract, %false otherwise.
|
||||
*/
|
||||
bool object_class_is_abstract(ObjectClass *klass);
|
||||
|
||||
/**
|
||||
* object_class_by_name:
|
||||
* @typename: The QOM typename to obtain the class for.
|
||||
|
||||
@@ -13,9 +13,16 @@ void cpu_synchronize_all_post_init(void);
|
||||
|
||||
void qtest_clock_warp(int64_t dest);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* vl.c */
|
||||
extern int smp_cores;
|
||||
extern int smp_threads;
|
||||
#else
|
||||
/* *-user doesn't have configurable SMP topology */
|
||||
#define smp_cores 1
|
||||
#define smp_threads 1
|
||||
#endif
|
||||
|
||||
void set_numa_modes(void);
|
||||
void set_cpu_log(const char *optarg);
|
||||
void set_cpu_log_filename(const char *optarg);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#define KVM_FEATURE_ASYNC_PF 0
|
||||
#define KVM_FEATURE_STEAL_TIME 0
|
||||
#define KVM_FEATURE_PV_EOI 0
|
||||
#define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 0
|
||||
#endif
|
||||
|
||||
extern int kvm_allowed;
|
||||
@@ -158,7 +159,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
|
||||
int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset);
|
||||
#endif
|
||||
|
||||
int kvm_on_sigbus_vcpu(CPUArchState *env, int code, void *addr);
|
||||
int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
|
||||
int kvm_on_sigbus(int code, void *addr);
|
||||
|
||||
/* internal API */
|
||||
@@ -195,6 +196,9 @@ int kvm_arch_init(KVMState *s);
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *cpu);
|
||||
|
||||
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
|
||||
unsigned long kvm_arch_vcpu_id(CPUState *cpu);
|
||||
|
||||
void kvm_arch_reset_vcpu(CPUState *cpu);
|
||||
|
||||
int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
|
||||
|
||||
@@ -222,7 +222,7 @@ int kvm_init_vcpu(CPUState *cpu)
|
||||
|
||||
DPRINTF("kvm_init_vcpu\n");
|
||||
|
||||
ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, cpu->cpu_index);
|
||||
ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));
|
||||
if (ret < 0) {
|
||||
DPRINTF("kvm_create_vcpu failed\n");
|
||||
goto err;
|
||||
@@ -2026,9 +2026,8 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_on_sigbus_vcpu(CPUArchState *env, int code, void *addr)
|
||||
int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
return kvm_arch_on_sigbus_vcpu(cpu, code, addr);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign, uint
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int kvm_on_sigbus_vcpu(CPUArchState *env, int code, void *addr)
|
||||
int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,24 @@ static void cpu_common_reset(CPUState *cpu)
|
||||
{
|
||||
}
|
||||
|
||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(object_class_by_name(typename));
|
||||
|
||||
return cc->class_by_name(cpu_model);
|
||||
}
|
||||
|
||||
static ObjectClass *cpu_common_class_by_name(const char *cpu_model)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cpu_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CPUClass *k = CPU_CLASS(klass);
|
||||
|
||||
k->class_by_name = cpu_common_class_by_name;
|
||||
k->reset = cpu_common_reset;
|
||||
dc->no_user = 1;
|
||||
}
|
||||
|
||||
@@ -501,6 +501,11 @@ ObjectClass *object_get_class(Object *obj)
|
||||
return obj->class;
|
||||
}
|
||||
|
||||
bool object_class_is_abstract(ObjectClass *klass)
|
||||
{
|
||||
return klass->type->abstract;
|
||||
}
|
||||
|
||||
const char *object_class_get_name(ObjectClass *klass)
|
||||
{
|
||||
return klass->type->name;
|
||||
|
||||
+14
-2
@@ -96,14 +96,15 @@ static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)
|
||||
}
|
||||
|
||||
oc = object_class_by_name(cpu_model);
|
||||
if (oc != NULL) {
|
||||
if (oc != NULL && object_class_dynamic_cast(oc, TYPE_ALPHA_CPU) != NULL &&
|
||||
!object_class_is_abstract(oc)) {
|
||||
return oc;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(alpha_cpu_aliases); i++) {
|
||||
if (strcmp(cpu_model, alpha_cpu_aliases[i].alias) == 0) {
|
||||
oc = object_class_by_name(alpha_cpu_aliases[i].typename);
|
||||
assert(oc != NULL);
|
||||
assert(oc != NULL && !object_class_is_abstract(oc));
|
||||
return oc;
|
||||
}
|
||||
}
|
||||
@@ -111,6 +112,9 @@ static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)
|
||||
typename = g_strdup_printf("%s-" TYPE_ALPHA_CPU, cpu_model);
|
||||
oc = object_class_by_name(typename);
|
||||
g_free(typename);
|
||||
if (oc != NULL && object_class_is_abstract(oc)) {
|
||||
oc = NULL;
|
||||
}
|
||||
return oc;
|
||||
}
|
||||
|
||||
@@ -244,6 +248,13 @@ static void alpha_cpu_initfn(Object *obj)
|
||||
env->fen = 1;
|
||||
}
|
||||
|
||||
static void alpha_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
|
||||
cc->class_by_name = alpha_cpu_class_by_name;
|
||||
}
|
||||
|
||||
static const TypeInfo alpha_cpu_type_info = {
|
||||
.name = TYPE_ALPHA_CPU,
|
||||
.parent = TYPE_CPU,
|
||||
@@ -251,6 +262,7 @@ static const TypeInfo alpha_cpu_type_info = {
|
||||
.instance_init = alpha_cpu_initfn,
|
||||
.abstract = true,
|
||||
.class_size = sizeof(AlphaCPUClass),
|
||||
.class_init = alpha_cpu_class_init,
|
||||
};
|
||||
|
||||
static void alpha_cpu_register_types(void)
|
||||
|
||||
@@ -201,6 +201,22 @@ void arm_cpu_realize(ARMCPU *cpu)
|
||||
|
||||
/* CPU models */
|
||||
|
||||
static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
|
||||
if (!cpu_model) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oc = object_class_by_name(cpu_model);
|
||||
if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) ||
|
||||
object_class_is_abstract(oc)) {
|
||||
return NULL;
|
||||
}
|
||||
return oc;
|
||||
}
|
||||
|
||||
static void arm926_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@@ -766,6 +782,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
acc->parent_reset = cc->reset;
|
||||
cc->reset = arm_cpu_reset;
|
||||
|
||||
cc->class_by_name = arm_cpu_class_by_name;
|
||||
}
|
||||
|
||||
static void cpu_register(const ARMCPUInfo *info)
|
||||
|
||||
+4
-2
@@ -1262,12 +1262,14 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
|
||||
{
|
||||
ARMCPU *cpu;
|
||||
CPUARMState *env;
|
||||
ObjectClass *oc;
|
||||
static int inited = 0;
|
||||
|
||||
if (!object_class_by_name(cpu_model)) {
|
||||
oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
|
||||
if (!oc) {
|
||||
return NULL;
|
||||
}
|
||||
cpu = ARM_CPU(object_new(cpu_model));
|
||||
cpu = ARM_CPU(object_new(object_class_get_name(oc)));
|
||||
env = &cpu->env;
|
||||
env->cpu_model_str = cpu_model;
|
||||
arm_cpu_realize(cpu);
|
||||
|
||||
+172
-219
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user