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 "system/system.h" 15 #include "hw/boards.h" 16 #include "system/hvf.h" 17 #include "accel/accel-cpu-target.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 env->cpuid_min_level = 25 hvf_get_supported_cpuid(0x0, 0, R_EAX); 26 env->cpuid_min_xlevel = 27 hvf_get_supported_cpuid(0x80000000, 0, R_EAX); 28 env->cpuid_min_xlevel2 = 29 hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); 30 } 31 32 static void hvf_cpu_xsave_init(void) 33 { 34 static bool first = true; 35 int i; 36 37 if (!first) { 38 return; 39 } 40 first = false; 41 42 /* x87 and SSE states are in the legacy region of the XSAVE area. */ 43 x86_ext_save_areas[XSTATE_FP_BIT].offset = 0; 44 x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0; 45 46 for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { 47 ExtSaveArea *esa = &x86_ext_save_areas[i]; 48 49 if (esa->size) { 50 int sz = hvf_get_supported_cpuid(0xd, i, R_EAX); 51 if (sz != 0) { 52 assert(esa->size == sz); 53 esa->offset = hvf_get_supported_cpuid(0xd, i, R_EBX); 54 } 55 } 56 } 57 } 58 59 static void hvf_cpu_instance_init(CPUState *cs) 60 { 61 X86CPU *cpu = X86_CPU(cs); 62 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); 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 (xcc->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, const void *data) 77 { 78 AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); 79 80 acc->cpu_target_realize = 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