1*802c4dafSPhilippe Mathieu-Daudé /* 2*802c4dafSPhilippe Mathieu-Daudé * QEMU accel class, components common to system emulation and user mode 3*802c4dafSPhilippe Mathieu-Daudé * 4*802c4dafSPhilippe Mathieu-Daudé * Copyright (c) 2003-2008 Fabrice Bellard 5*802c4dafSPhilippe Mathieu-Daudé * Copyright (c) 2014 Red Hat Inc. 6*802c4dafSPhilippe Mathieu-Daudé * 7*802c4dafSPhilippe Mathieu-Daudé * SPDX-License-Identifier: MIT 8*802c4dafSPhilippe Mathieu-Daudé */ 9*802c4dafSPhilippe Mathieu-Daudé 10*802c4dafSPhilippe Mathieu-Daudé #include "qemu/osdep.h" 11*802c4dafSPhilippe Mathieu-Daudé #include "qemu/accel.h" 12*802c4dafSPhilippe Mathieu-Daudé #include "qemu/target-info.h" 13*802c4dafSPhilippe Mathieu-Daudé #include "accel/accel-cpu.h" 14*802c4dafSPhilippe Mathieu-Daudé #include "accel-internal.h" 15*802c4dafSPhilippe Mathieu-Daudé 16*802c4dafSPhilippe Mathieu-Daudé /* Lookup AccelClass from opt_name. Returns NULL if not found */ 17*802c4dafSPhilippe Mathieu-Daudé AccelClass *accel_find(const char *opt_name) 18*802c4dafSPhilippe Mathieu-Daudé { 19*802c4dafSPhilippe Mathieu-Daudé char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name); 20*802c4dafSPhilippe Mathieu-Daudé AccelClass *ac = ACCEL_CLASS(module_object_class_by_name(class_name)); 21*802c4dafSPhilippe Mathieu-Daudé g_free(class_name); 22*802c4dafSPhilippe Mathieu-Daudé return ac; 23*802c4dafSPhilippe Mathieu-Daudé } 24*802c4dafSPhilippe Mathieu-Daudé 25*802c4dafSPhilippe Mathieu-Daudé /* Return the name of the current accelerator */ 26*802c4dafSPhilippe Mathieu-Daudé const char *current_accel_name(void) 27*802c4dafSPhilippe Mathieu-Daudé { 28*802c4dafSPhilippe Mathieu-Daudé AccelClass *ac = ACCEL_GET_CLASS(current_accel()); 29*802c4dafSPhilippe Mathieu-Daudé 30*802c4dafSPhilippe Mathieu-Daudé return ac->name; 31*802c4dafSPhilippe Mathieu-Daudé } 32*802c4dafSPhilippe Mathieu-Daudé 33*802c4dafSPhilippe Mathieu-Daudé static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque) 34*802c4dafSPhilippe Mathieu-Daudé { 35*802c4dafSPhilippe Mathieu-Daudé CPUClass *cc = CPU_CLASS(klass); 36*802c4dafSPhilippe Mathieu-Daudé AccelCPUClass *accel_cpu = opaque; 37*802c4dafSPhilippe Mathieu-Daudé 38*802c4dafSPhilippe Mathieu-Daudé /* 39*802c4dafSPhilippe Mathieu-Daudé * The first callback allows accel-cpu to run initializations 40*802c4dafSPhilippe Mathieu-Daudé * for the CPU, customizing CPU behavior according to the accelerator. 41*802c4dafSPhilippe Mathieu-Daudé * 42*802c4dafSPhilippe Mathieu-Daudé * The second one allows the CPU to customize the accel-cpu 43*802c4dafSPhilippe Mathieu-Daudé * behavior according to the CPU. 44*802c4dafSPhilippe Mathieu-Daudé * 45*802c4dafSPhilippe Mathieu-Daudé * The second is currently only used by TCG, to specialize the 46*802c4dafSPhilippe Mathieu-Daudé * TCGCPUOps depending on the CPU type. 47*802c4dafSPhilippe Mathieu-Daudé */ 48*802c4dafSPhilippe Mathieu-Daudé cc->accel_cpu = accel_cpu; 49*802c4dafSPhilippe Mathieu-Daudé if (accel_cpu->cpu_class_init) { 50*802c4dafSPhilippe Mathieu-Daudé accel_cpu->cpu_class_init(cc); 51*802c4dafSPhilippe Mathieu-Daudé } 52*802c4dafSPhilippe Mathieu-Daudé if (cc->init_accel_cpu) { 53*802c4dafSPhilippe Mathieu-Daudé cc->init_accel_cpu(accel_cpu, cc); 54*802c4dafSPhilippe Mathieu-Daudé } 55*802c4dafSPhilippe Mathieu-Daudé } 56*802c4dafSPhilippe Mathieu-Daudé 57*802c4dafSPhilippe Mathieu-Daudé /* initialize the arch-specific accel CpuClass interfaces */ 58*802c4dafSPhilippe Mathieu-Daudé static void accel_init_cpu_interfaces(AccelClass *ac) 59*802c4dafSPhilippe Mathieu-Daudé { 60*802c4dafSPhilippe Mathieu-Daudé const char *ac_name; /* AccelClass name */ 61*802c4dafSPhilippe Mathieu-Daudé char *acc_name; /* AccelCPUClass name */ 62*802c4dafSPhilippe Mathieu-Daudé ObjectClass *acc; /* AccelCPUClass */ 63*802c4dafSPhilippe Mathieu-Daudé const char *cpu_resolving_type = target_cpu_type(); 64*802c4dafSPhilippe Mathieu-Daudé 65*802c4dafSPhilippe Mathieu-Daudé ac_name = object_class_get_name(OBJECT_CLASS(ac)); 66*802c4dafSPhilippe Mathieu-Daudé g_assert(ac_name != NULL); 67*802c4dafSPhilippe Mathieu-Daudé 68*802c4dafSPhilippe Mathieu-Daudé acc_name = g_strdup_printf("%s-%s", ac_name, cpu_resolving_type); 69*802c4dafSPhilippe Mathieu-Daudé acc = object_class_by_name(acc_name); 70*802c4dafSPhilippe Mathieu-Daudé g_free(acc_name); 71*802c4dafSPhilippe Mathieu-Daudé 72*802c4dafSPhilippe Mathieu-Daudé if (acc) { 73*802c4dafSPhilippe Mathieu-Daudé object_class_foreach(accel_init_cpu_int_aux, 74*802c4dafSPhilippe Mathieu-Daudé cpu_resolving_type, false, acc); 75*802c4dafSPhilippe Mathieu-Daudé } 76*802c4dafSPhilippe Mathieu-Daudé } 77*802c4dafSPhilippe Mathieu-Daudé 78*802c4dafSPhilippe Mathieu-Daudé void accel_init_interfaces(AccelClass *ac) 79*802c4dafSPhilippe Mathieu-Daudé { 80*802c4dafSPhilippe Mathieu-Daudé accel_init_ops_interfaces(ac); 81*802c4dafSPhilippe Mathieu-Daudé accel_init_cpu_interfaces(ac); 82*802c4dafSPhilippe Mathieu-Daudé } 83*802c4dafSPhilippe Mathieu-Daudé 84*802c4dafSPhilippe Mathieu-Daudé void accel_cpu_instance_init(CPUState *cpu) 85*802c4dafSPhilippe Mathieu-Daudé { 86*802c4dafSPhilippe Mathieu-Daudé if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) { 87*802c4dafSPhilippe Mathieu-Daudé cpu->cc->accel_cpu->cpu_instance_init(cpu); 88*802c4dafSPhilippe Mathieu-Daudé } 89*802c4dafSPhilippe Mathieu-Daudé } 90*802c4dafSPhilippe Mathieu-Daudé 91*802c4dafSPhilippe Mathieu-Daudé bool accel_cpu_common_realize(CPUState *cpu, Error **errp) 92*802c4dafSPhilippe Mathieu-Daudé { 93*802c4dafSPhilippe Mathieu-Daudé AccelState *accel = current_accel(); 94*802c4dafSPhilippe Mathieu-Daudé AccelClass *acc = ACCEL_GET_CLASS(accel); 95*802c4dafSPhilippe Mathieu-Daudé 96*802c4dafSPhilippe Mathieu-Daudé /* target specific realization */ 97*802c4dafSPhilippe Mathieu-Daudé if (cpu->cc->accel_cpu 98*802c4dafSPhilippe Mathieu-Daudé && cpu->cc->accel_cpu->cpu_target_realize 99*802c4dafSPhilippe Mathieu-Daudé && !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) { 100*802c4dafSPhilippe Mathieu-Daudé return false; 101*802c4dafSPhilippe Mathieu-Daudé } 102*802c4dafSPhilippe Mathieu-Daudé 103*802c4dafSPhilippe Mathieu-Daudé /* generic realization */ 104*802c4dafSPhilippe Mathieu-Daudé if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) { 105*802c4dafSPhilippe Mathieu-Daudé return false; 106*802c4dafSPhilippe Mathieu-Daudé } 107*802c4dafSPhilippe Mathieu-Daudé 108*802c4dafSPhilippe Mathieu-Daudé return true; 109*802c4dafSPhilippe Mathieu-Daudé } 110*802c4dafSPhilippe Mathieu-Daudé 111*802c4dafSPhilippe Mathieu-Daudé void accel_cpu_common_unrealize(CPUState *cpu) 112*802c4dafSPhilippe Mathieu-Daudé { 113*802c4dafSPhilippe Mathieu-Daudé AccelState *accel = current_accel(); 114*802c4dafSPhilippe Mathieu-Daudé AccelClass *acc = ACCEL_GET_CLASS(accel); 115*802c4dafSPhilippe Mathieu-Daudé 116*802c4dafSPhilippe Mathieu-Daudé /* generic unrealization */ 117*802c4dafSPhilippe Mathieu-Daudé if (acc->cpu_common_unrealize) { 118*802c4dafSPhilippe Mathieu-Daudé acc->cpu_common_unrealize(cpu); 119*802c4dafSPhilippe Mathieu-Daudé } 120*802c4dafSPhilippe Mathieu-Daudé } 121*802c4dafSPhilippe Mathieu-Daudé 122*802c4dafSPhilippe Mathieu-Daudé int accel_supported_gdbstub_sstep_flags(void) 123*802c4dafSPhilippe Mathieu-Daudé { 124*802c4dafSPhilippe Mathieu-Daudé AccelState *accel = current_accel(); 125*802c4dafSPhilippe Mathieu-Daudé AccelClass *acc = ACCEL_GET_CLASS(accel); 126*802c4dafSPhilippe Mathieu-Daudé if (acc->gdbstub_supported_sstep_flags) { 127*802c4dafSPhilippe Mathieu-Daudé return acc->gdbstub_supported_sstep_flags(); 128*802c4dafSPhilippe Mathieu-Daudé } 129*802c4dafSPhilippe Mathieu-Daudé return 0; 130*802c4dafSPhilippe Mathieu-Daudé } 131*802c4dafSPhilippe Mathieu-Daudé 132*802c4dafSPhilippe Mathieu-Daudé static const TypeInfo accel_types[] = { 133*802c4dafSPhilippe Mathieu-Daudé { 134*802c4dafSPhilippe Mathieu-Daudé .name = TYPE_ACCEL, 135*802c4dafSPhilippe Mathieu-Daudé .parent = TYPE_OBJECT, 136*802c4dafSPhilippe Mathieu-Daudé .class_size = sizeof(AccelClass), 137*802c4dafSPhilippe Mathieu-Daudé .instance_size = sizeof(AccelState), 138*802c4dafSPhilippe Mathieu-Daudé .abstract = true, 139*802c4dafSPhilippe Mathieu-Daudé }, 140*802c4dafSPhilippe Mathieu-Daudé }; 141*802c4dafSPhilippe Mathieu-Daudé 142*802c4dafSPhilippe Mathieu-Daudé DEFINE_TYPES(accel_types) 143