/* * x86 HVF CPU type initialization * * Copyright 2021 SUSE LLC * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" #include "cpu.h" #include "host-cpu.h" #include "qapi/error.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "sysemu/hvf.h" #include "hw/core/accel-cpu.h" static void hvf_cpu_max_instance_init(X86CPU *cpu) { CPUX86State *env = &cpu->env; host_cpu_max_instance_init(cpu); env->cpuid_min_level = hvf_get_supported_cpuid(0x0, 0, R_EAX); env->cpuid_min_xlevel = hvf_get_supported_cpuid(0x80000000, 0, R_EAX); env->cpuid_min_xlevel2 = hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); } static void hvf_cpu_xsave_init(void) { static bool first = true; int i; if (!first) { return; } first = false; /* x87 and SSE states are in the legacy region of the XSAVE area. */ x86_ext_save_areas[XSTATE_FP_BIT].offset = 0; x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0; for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { ExtSaveArea *esa = &x86_ext_save_areas[i]; if (esa->size) { int sz = hvf_get_supported_cpuid(0xd, i, R_EAX); if (sz != 0) { assert(esa->size == sz); esa->offset = hvf_get_supported_cpuid(0xd, i, R_EBX); } } } } static void hvf_cpu_instance_init(CPUState *cs) { X86CPU *cpu = X86_CPU(cs); host_cpu_instance_init(cpu); /* Special cases not set in the X86CPUDefinition structs: */ /* TODO: in-kernel irqchip for hvf */ if (cpu->max_features) { hvf_cpu_max_instance_init(cpu); } hvf_cpu_xsave_init(); } static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data) { AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); acc->cpu_realizefn = host_cpu_realizefn; acc->cpu_instance_init = hvf_cpu_instance_init; } static const TypeInfo hvf_cpu_accel_type_info = { .name = ACCEL_CPU_NAME("hvf"), .parent = TYPE_ACCEL_CPU, .class_init = hvf_cpu_accel_class_init, .abstract = true, }; static void hvf_cpu_accel_register_types(void) { type_register_static(&hvf_cpu_accel_type_info); } type_init(hvf_cpu_accel_register_types);