1 /* 2 * x86 HVF CPU type initialization 3 * 4 * Copyright 2021 SUSE LLC 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "cpu.h" 12 #include "host-cpu.h" 13 #include "qapi/error.h" 14 #include "sysemu/sysemu.h" 15 #include "hw/boards.h" 16 #include "sysemu/hvf.h" 17 #include "hw/core/accel-cpu.h" 18 #include "hvf-i386.h" 19 20 static void hvf_cpu_max_instance_init(X86CPU *cpu) 21 { 22 CPUX86State *env = &cpu->env; 23 24 host_cpu_max_instance_init(cpu); 25 26 env->cpuid_min_level = 27 hvf_get_supported_cpuid(0x0, 0, R_EAX); 28 env->cpuid_min_xlevel = 29 hvf_get_supported_cpuid(0x80000000, 0, R_EAX); 30 env->cpuid_min_xlevel2 = 31 hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); 32 } 33 34 static void hvf_cpu_xsave_init(void) 35 { 36 static bool first = true; 37 int i; 38 39 if (!first) { 40 return; 41 } 42 first = false; 43 44 /* x87 and SSE states are in the legacy region of the XSAVE area. */ 45 x86_ext_save_areas[XSTATE_FP_BIT].offset = 0; 46 x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0; 47 48 for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { 49 ExtSaveArea *esa = &x86_ext_save_areas[i]; 50 51 if (esa->size) { 52 int sz = hvf_get_supported_cpuid(0xd, i, R_EAX); 53 if (sz != 0) { 54 assert(esa->size == sz); 55 esa->offset = hvf_get_supported_cpuid(0xd, i, R_EBX); 56 } 57 } 58 } 59 } 60 61 static void hvf_cpu_instance_init(CPUState *cs) 62 { 63 X86CPU *cpu = X86_CPU(cs); 64 65 host_cpu_instance_init(cpu); 66 67 /* Special cases not set in the X86CPUDefinition structs: */ 68 /* TODO: in-kernel irqchip for hvf */ 69 70 if (cpu->max_features) { 71 hvf_cpu_max_instance_init(cpu); 72 } 73 74 hvf_cpu_xsave_init(); 75 } 76 77 static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data) 78 { 79 AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); 80 81 acc->cpu_target_realize = host_cpu_realizefn; 82 acc->cpu_instance_init = hvf_cpu_instance_init; 83 } 84 85 static const TypeInfo hvf_cpu_accel_type_info = { 86 .name = ACCEL_CPU_NAME("hvf"), 87 88 .parent = TYPE_ACCEL_CPU, 89 .class_init = hvf_cpu_accel_class_init, 90 .abstract = true, 91 }; 92 93 static void hvf_cpu_accel_register_types(void) 94 { 95 type_register_static(&hvf_cpu_accel_type_info); 96 } 97 98 type_init(hvf_cpu_accel_register_types); 99