1802c4dafSPhilippe Mathieu-Daudé /* 2802c4dafSPhilippe Mathieu-Daudé * QEMU accel class, components common to system emulation and user mode 3802c4dafSPhilippe Mathieu-Daudé * 4802c4dafSPhilippe Mathieu-Daudé * Copyright (c) 2003-2008 Fabrice Bellard 5802c4dafSPhilippe Mathieu-Daudé * Copyright (c) 2014 Red Hat Inc. 6802c4dafSPhilippe Mathieu-Daudé * 7802c4dafSPhilippe Mathieu-Daudé * SPDX-License-Identifier: MIT 8802c4dafSPhilippe Mathieu-Daudé */ 9802c4dafSPhilippe Mathieu-Daudé 10802c4dafSPhilippe Mathieu-Daudé #include "qemu/osdep.h" 11802c4dafSPhilippe Mathieu-Daudé #include "qemu/accel.h" 12802c4dafSPhilippe Mathieu-Daudé #include "qemu/target-info.h" 13*f7a7e7ddSPhilippe Mathieu-Daudé #include "accel/accel-ops.h" 14802c4dafSPhilippe Mathieu-Daudé #include "accel/accel-cpu.h" 15*f7a7e7ddSPhilippe Mathieu-Daudé #include "accel/accel-cpu-ops.h" 16802c4dafSPhilippe Mathieu-Daudé #include "accel-internal.h" 17802c4dafSPhilippe Mathieu-Daudé 18802c4dafSPhilippe Mathieu-Daudé /* Lookup AccelClass from opt_name. Returns NULL if not found */ 19802c4dafSPhilippe Mathieu-Daudé AccelClass *accel_find(const char *opt_name) 20802c4dafSPhilippe Mathieu-Daudé { 21802c4dafSPhilippe Mathieu-Daudé char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name); 22802c4dafSPhilippe Mathieu-Daudé AccelClass *ac = ACCEL_CLASS(module_object_class_by_name(class_name)); 23802c4dafSPhilippe Mathieu-Daudé g_free(class_name); 24802c4dafSPhilippe Mathieu-Daudé return ac; 25802c4dafSPhilippe Mathieu-Daudé } 26802c4dafSPhilippe Mathieu-Daudé 27802c4dafSPhilippe Mathieu-Daudé /* Return the name of the current accelerator */ 28802c4dafSPhilippe Mathieu-Daudé const char *current_accel_name(void) 29802c4dafSPhilippe Mathieu-Daudé { 30802c4dafSPhilippe Mathieu-Daudé AccelClass *ac = ACCEL_GET_CLASS(current_accel()); 31802c4dafSPhilippe Mathieu-Daudé 32802c4dafSPhilippe Mathieu-Daudé return ac->name; 33802c4dafSPhilippe Mathieu-Daudé } 34802c4dafSPhilippe Mathieu-Daudé 35802c4dafSPhilippe Mathieu-Daudé static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque) 36802c4dafSPhilippe Mathieu-Daudé { 37802c4dafSPhilippe Mathieu-Daudé CPUClass *cc = CPU_CLASS(klass); 38802c4dafSPhilippe Mathieu-Daudé AccelCPUClass *accel_cpu = opaque; 39802c4dafSPhilippe Mathieu-Daudé 40802c4dafSPhilippe Mathieu-Daudé /* 41802c4dafSPhilippe Mathieu-Daudé * The first callback allows accel-cpu to run initializations 42802c4dafSPhilippe Mathieu-Daudé * for the CPU, customizing CPU behavior according to the accelerator. 43802c4dafSPhilippe Mathieu-Daudé * 44802c4dafSPhilippe Mathieu-Daudé * The second one allows the CPU to customize the accel-cpu 45802c4dafSPhilippe Mathieu-Daudé * behavior according to the CPU. 46802c4dafSPhilippe Mathieu-Daudé * 47802c4dafSPhilippe Mathieu-Daudé * The second is currently only used by TCG, to specialize the 48802c4dafSPhilippe Mathieu-Daudé * TCGCPUOps depending on the CPU type. 49802c4dafSPhilippe Mathieu-Daudé */ 50802c4dafSPhilippe Mathieu-Daudé cc->accel_cpu = accel_cpu; 51802c4dafSPhilippe Mathieu-Daudé if (accel_cpu->cpu_class_init) { 52802c4dafSPhilippe Mathieu-Daudé accel_cpu->cpu_class_init(cc); 53802c4dafSPhilippe Mathieu-Daudé } 54802c4dafSPhilippe Mathieu-Daudé if (cc->init_accel_cpu) { 55802c4dafSPhilippe Mathieu-Daudé cc->init_accel_cpu(accel_cpu, cc); 56802c4dafSPhilippe Mathieu-Daudé } 57802c4dafSPhilippe Mathieu-Daudé } 58802c4dafSPhilippe Mathieu-Daudé 59802c4dafSPhilippe Mathieu-Daudé /* initialize the arch-specific accel CpuClass interfaces */ 60802c4dafSPhilippe Mathieu-Daudé static void accel_init_cpu_interfaces(AccelClass *ac) 61802c4dafSPhilippe Mathieu-Daudé { 62802c4dafSPhilippe Mathieu-Daudé const char *ac_name; /* AccelClass name */ 63802c4dafSPhilippe Mathieu-Daudé char *acc_name; /* AccelCPUClass name */ 64802c4dafSPhilippe Mathieu-Daudé ObjectClass *acc; /* AccelCPUClass */ 65802c4dafSPhilippe Mathieu-Daudé const char *cpu_resolving_type = target_cpu_type(); 66802c4dafSPhilippe Mathieu-Daudé 67802c4dafSPhilippe Mathieu-Daudé ac_name = object_class_get_name(OBJECT_CLASS(ac)); 68802c4dafSPhilippe Mathieu-Daudé g_assert(ac_name != NULL); 69802c4dafSPhilippe Mathieu-Daudé 70802c4dafSPhilippe Mathieu-Daudé acc_name = g_strdup_printf("%s-%s", ac_name, cpu_resolving_type); 71802c4dafSPhilippe Mathieu-Daudé acc = object_class_by_name(acc_name); 72802c4dafSPhilippe Mathieu-Daudé g_free(acc_name); 73802c4dafSPhilippe Mathieu-Daudé 74802c4dafSPhilippe Mathieu-Daudé if (acc) { 75802c4dafSPhilippe Mathieu-Daudé object_class_foreach(accel_init_cpu_int_aux, 76802c4dafSPhilippe Mathieu-Daudé cpu_resolving_type, false, acc); 77802c4dafSPhilippe Mathieu-Daudé } 78802c4dafSPhilippe Mathieu-Daudé } 79802c4dafSPhilippe Mathieu-Daudé 80802c4dafSPhilippe Mathieu-Daudé void accel_init_interfaces(AccelClass *ac) 81802c4dafSPhilippe Mathieu-Daudé { 82802c4dafSPhilippe Mathieu-Daudé accel_init_ops_interfaces(ac); 83802c4dafSPhilippe Mathieu-Daudé accel_init_cpu_interfaces(ac); 84802c4dafSPhilippe Mathieu-Daudé } 85802c4dafSPhilippe Mathieu-Daudé 86802c4dafSPhilippe Mathieu-Daudé void accel_cpu_instance_init(CPUState *cpu) 87802c4dafSPhilippe Mathieu-Daudé { 88802c4dafSPhilippe Mathieu-Daudé if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) { 89802c4dafSPhilippe Mathieu-Daudé cpu->cc->accel_cpu->cpu_instance_init(cpu); 90802c4dafSPhilippe Mathieu-Daudé } 91802c4dafSPhilippe Mathieu-Daudé } 92802c4dafSPhilippe Mathieu-Daudé 93802c4dafSPhilippe Mathieu-Daudé bool accel_cpu_common_realize(CPUState *cpu, Error **errp) 94802c4dafSPhilippe Mathieu-Daudé { 95802c4dafSPhilippe Mathieu-Daudé AccelState *accel = current_accel(); 96802c4dafSPhilippe Mathieu-Daudé AccelClass *acc = ACCEL_GET_CLASS(accel); 97802c4dafSPhilippe Mathieu-Daudé 98802c4dafSPhilippe Mathieu-Daudé /* target specific realization */ 99802c4dafSPhilippe Mathieu-Daudé if (cpu->cc->accel_cpu 100802c4dafSPhilippe Mathieu-Daudé && cpu->cc->accel_cpu->cpu_target_realize 101802c4dafSPhilippe Mathieu-Daudé && !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) { 102802c4dafSPhilippe Mathieu-Daudé return false; 103802c4dafSPhilippe Mathieu-Daudé } 104802c4dafSPhilippe Mathieu-Daudé 105802c4dafSPhilippe Mathieu-Daudé /* generic realization */ 106802c4dafSPhilippe Mathieu-Daudé if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) { 107802c4dafSPhilippe Mathieu-Daudé return false; 108802c4dafSPhilippe Mathieu-Daudé } 109802c4dafSPhilippe Mathieu-Daudé 110802c4dafSPhilippe Mathieu-Daudé return true; 111802c4dafSPhilippe Mathieu-Daudé } 112802c4dafSPhilippe Mathieu-Daudé 113802c4dafSPhilippe Mathieu-Daudé void accel_cpu_common_unrealize(CPUState *cpu) 114802c4dafSPhilippe Mathieu-Daudé { 115802c4dafSPhilippe Mathieu-Daudé AccelState *accel = current_accel(); 116802c4dafSPhilippe Mathieu-Daudé AccelClass *acc = ACCEL_GET_CLASS(accel); 117802c4dafSPhilippe Mathieu-Daudé 118802c4dafSPhilippe Mathieu-Daudé /* generic unrealization */ 119802c4dafSPhilippe Mathieu-Daudé if (acc->cpu_common_unrealize) { 120802c4dafSPhilippe Mathieu-Daudé acc->cpu_common_unrealize(cpu); 121802c4dafSPhilippe Mathieu-Daudé } 122802c4dafSPhilippe Mathieu-Daudé } 123802c4dafSPhilippe Mathieu-Daudé 124802c4dafSPhilippe Mathieu-Daudé int accel_supported_gdbstub_sstep_flags(void) 125802c4dafSPhilippe Mathieu-Daudé { 126802c4dafSPhilippe Mathieu-Daudé AccelState *accel = current_accel(); 127802c4dafSPhilippe Mathieu-Daudé AccelClass *acc = ACCEL_GET_CLASS(accel); 128802c4dafSPhilippe Mathieu-Daudé if (acc->gdbstub_supported_sstep_flags) { 129842e7eecSPhilippe Mathieu-Daudé return acc->gdbstub_supported_sstep_flags(accel); 130802c4dafSPhilippe Mathieu-Daudé } 131802c4dafSPhilippe Mathieu-Daudé return 0; 132802c4dafSPhilippe Mathieu-Daudé } 133802c4dafSPhilippe Mathieu-Daudé 134802c4dafSPhilippe Mathieu-Daudé static const TypeInfo accel_types[] = { 135802c4dafSPhilippe Mathieu-Daudé { 136802c4dafSPhilippe Mathieu-Daudé .name = TYPE_ACCEL, 137802c4dafSPhilippe Mathieu-Daudé .parent = TYPE_OBJECT, 138802c4dafSPhilippe Mathieu-Daudé .class_size = sizeof(AccelClass), 139802c4dafSPhilippe Mathieu-Daudé .instance_size = sizeof(AccelState), 140802c4dafSPhilippe Mathieu-Daudé .abstract = true, 141802c4dafSPhilippe Mathieu-Daudé }, 142802c4dafSPhilippe Mathieu-Daudé }; 143802c4dafSPhilippe Mathieu-Daudé 144802c4dafSPhilippe Mathieu-Daudé DEFINE_TYPES(accel_types) 145