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