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 19 static void hvf_cpu_max_instance_init(X86CPU *cpu) 20 { 21 CPUX86State *env = &cpu->env; 22 23 host_cpu_max_instance_init(cpu); 24 25 env->cpuid_min_level = 26 hvf_get_supported_cpuid(0x0, 0, R_EAX); 27 env->cpuid_min_xlevel = 28 hvf_get_supported_cpuid(0x80000000, 0, R_EAX); 29 env->cpuid_min_xlevel2 = 30 hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); 31 } 32 33 static void hvf_cpu_xsave_init(void) 34 { 35 static bool first = true; 36 int i; 37 38 if (!first) { 39 return; 40 } 41 first = false; 42 43 /* x87 and SSE states are in the legacy region of the XSAVE area. */ 44 x86_ext_save_areas[XSTATE_FP_BIT].offset = 0; 45 x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0; 46 47 for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { 48 ExtSaveArea *esa = &x86_ext_save_areas[i]; 49 50 if (esa->size) { 51 int sz = hvf_get_supported_cpuid(0xd, i, R_EAX); 52 if (sz != 0) { 53 assert(esa->size == sz); 54 esa->offset = hvf_get_supported_cpuid(0xd, i, R_EBX); 55 } 56 } 57 } 58 } 59 60 static void hvf_cpu_instance_init(CPUState *cs) 61 { 62 X86CPU *cpu = X86_CPU(cs); 63 64 host_cpu_instance_init(cpu); 65 66 /* Special cases not set in the X86CPUDefinition structs: */ 67 /* TODO: in-kernel irqchip for hvf */ 68 69 if (cpu->max_features) { 70 hvf_cpu_max_instance_init(cpu); 71 } 72 73 hvf_cpu_xsave_init(); 74 } 75 76 static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data) 77 { 78 AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); 79 80 acc->cpu_realizefn = host_cpu_realizefn; 81 acc->cpu_instance_init = hvf_cpu_instance_init; 82 } 83 84 static const TypeInfo hvf_cpu_accel_type_info = { 85 .name = ACCEL_CPU_NAME("hvf"), 86 87 .parent = TYPE_ACCEL_CPU, 88 .class_init = hvf_cpu_accel_class_init, 89 .abstract = true, 90 }; 91 92 static void hvf_cpu_accel_register_types(void) 93 { 94 type_register_static(&hvf_cpu_accel_type_info); 95 } 96 97 type_init(hvf_cpu_accel_register_types); 98