#include "hyperv.h"
+#include "hw/hw.h"
+
/* feature flags taken from "Intel Processor Identification and the CPUID
* Instruction" and AMD's "CPUID Specification". In cases of disagreement
* between feature naming conventions, aliases may be added.
"ds_cpl", "vmx", "smx", "est",
"tm2", "ssse3", "cid", NULL,
"fma", "cx16", "xtpr", "pdcm",
- NULL, NULL, "dca", "sse4.1|sse4_1",
+ NULL, "pcid", "dca", "sse4.1|sse4_1",
"sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
"tsc-deadline", "aes", "xsave", "osxsave",
"avx", NULL, NULL, "hypervisor",
env->dr[7] = DR7_FIXED_1;
cpu_breakpoint_remove_all(env, BP_CPU);
cpu_watchpoint_remove_all(env, BP_CPU);
+
+#if !defined(CONFIG_USER_ONLY)
+ /* We hard-wire the BSP to the first CPU. */
+ if (env->cpu_index == 0) {
+ apic_designate_bsp(env->apic_state);
+ }
+
+ env->halted = !cpu_is_bsp(cpu);
+#endif
+}
+
+#ifndef CONFIG_USER_ONLY
+bool cpu_is_bsp(X86CPU *cpu)
+{
+ return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
}
+/* TODO: remove me, when reset over QOM tree is implemented */
+static void x86_cpu_machine_reset_cb(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ cpu_reset(CPU(cpu));
+}
+#endif
+
static void mce_init(X86CPU *cpu)
{
CPUX86State *cenv = &cpu->env;
{
X86CPU *cpu = X86_CPU(obj);
+#ifndef CONFIG_USER_ONLY
+ qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
+#endif
+
mce_init(cpu);
qemu_init_vcpu(&cpu->env);
+ cpu_reset(CPU(cpu));
}
static void x86_cpu_initfn(Object *obj)
{
X86CPU *cpu = X86_CPU(obj);
CPUX86State *env = &cpu->env;
+ static int inited;
cpu_exec_init(env);
x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
env->cpuid_apic_id = env->cpu_index;
+
+ /* init various static tables used in TCG mode */
+ if (tcg_enabled() && !inited) {
+ inited = 1;
+ optimize_flags_init();
+#ifndef CONFIG_USER_ONLY
+ cpu_set_debug_excp_handler(breakpoint_handler);
+#endif
+ }
}
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)