hvf-cpu.c (2337B)
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 19static 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 33static 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 60static 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 76static 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 84static 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 92static void hvf_cpu_accel_register_types(void) 93{ 94 type_register_static(&hvf_cpu_accel_type_info); 95} 96 97type_init(hvf_cpu_accel_register_types);