Eduardo Habkost | a1a9cb0 | 2014-09-26 17:45:17 -0300 | [diff] [blame] | 1 | /* |
Claudio Fontana | 940e43a | 2021-02-04 17:39:24 +0100 | [diff] [blame] | 2 | * QEMU accel class, components common to system emulation and user mode |
Eduardo Habkost | a1a9cb0 | 2014-09-26 17:45:17 -0300 | [diff] [blame] | 3 | * |
| 4 | * Copyright (c) 2003-2008 Fabrice Bellard |
| 5 | * Copyright (c) 2014 Red Hat Inc. |
| 6 | * |
| 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 8 | * of this software and associated documentation files (the "Software"), to deal |
| 9 | * in the Software without restriction, including without limitation the rights |
| 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 11 | * copies of the Software, and to permit persons to whom the Software is |
| 12 | * furnished to do so, subject to the following conditions: |
| 13 | * |
| 14 | * The above copyright notice and this permission notice shall be included in |
| 15 | * all copies or substantial portions of the Software. |
| 16 | * |
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 23 | * THE SOFTWARE. |
| 24 | */ |
| 25 | |
Peter Maydell | d38ea87 | 2016-01-29 17:50:05 +0000 | [diff] [blame] | 26 | #include "qemu/osdep.h" |
Claudio Fontana | 940e43a | 2021-02-04 17:39:24 +0100 | [diff] [blame] | 27 | #include "qemu/accel.h" |
Eduardo Habkost | a1a9cb0 | 2014-09-26 17:45:17 -0300 | [diff] [blame] | 28 | |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 29 | #include "cpu.h" |
| 30 | #include "hw/core/accel-cpu.h" |
| 31 | |
Claudio Fontana | b86f59c | 2021-02-04 17:39:25 +0100 | [diff] [blame] | 32 | #ifndef CONFIG_USER_ONLY |
Philippe Mathieu-Daudé | 0017c64 | 2023-10-04 11:06:21 +0200 | [diff] [blame] | 33 | #include "accel-system.h" |
Claudio Fontana | b86f59c | 2021-02-04 17:39:25 +0100 | [diff] [blame] | 34 | #endif /* !CONFIG_USER_ONLY */ |
| 35 | |
Eduardo Habkost | b14a0b7 | 2014-09-26 17:45:21 -0300 | [diff] [blame] | 36 | static const TypeInfo accel_type = { |
| 37 | .name = TYPE_ACCEL, |
| 38 | .parent = TYPE_OBJECT, |
| 39 | .class_size = sizeof(AccelClass), |
| 40 | .instance_size = sizeof(AccelState), |
Eduardo Habkost | a1a9cb0 | 2014-09-26 17:45:17 -0300 | [diff] [blame] | 41 | }; |
| 42 | |
Eduardo Habkost | b14a0b7 | 2014-09-26 17:45:21 -0300 | [diff] [blame] | 43 | /* Lookup AccelClass from opt_name. Returns NULL if not found */ |
Paolo Bonzini | 28a0961 | 2019-11-13 09:59:04 +0100 | [diff] [blame] | 44 | AccelClass *accel_find(const char *opt_name) |
Eduardo Habkost | a224655 | 2014-09-26 17:45:20 -0300 | [diff] [blame] | 45 | { |
Eduardo Habkost | b14a0b7 | 2014-09-26 17:45:21 -0300 | [diff] [blame] | 46 | char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name); |
Gerd Hoffmann | f934907 | 2021-06-24 12:38:27 +0200 | [diff] [blame] | 47 | AccelClass *ac = ACCEL_CLASS(module_object_class_by_name(class_name)); |
Eduardo Habkost | b14a0b7 | 2014-09-26 17:45:21 -0300 | [diff] [blame] | 48 | g_free(class_name); |
| 49 | return ac; |
Eduardo Habkost | a224655 | 2014-09-26 17:45:20 -0300 | [diff] [blame] | 50 | } |
| 51 | |
Alexander Graf | 55bd445 | 2022-06-24 15:42:56 +0100 | [diff] [blame] | 52 | /* Return the name of the current accelerator */ |
| 53 | const char *current_accel_name(void) |
| 54 | { |
| 55 | AccelClass *ac = ACCEL_GET_CLASS(current_accel()); |
| 56 | |
| 57 | return ac->name; |
| 58 | } |
| 59 | |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 60 | static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque) |
| 61 | { |
| 62 | CPUClass *cc = CPU_CLASS(klass); |
| 63 | AccelCPUClass *accel_cpu = opaque; |
| 64 | |
Claudio Fontana | cc3f2be | 2021-03-22 14:27:59 +0100 | [diff] [blame] | 65 | /* |
| 66 | * The first callback allows accel-cpu to run initializations |
| 67 | * for the CPU, customizing CPU behavior according to the accelerator. |
| 68 | * |
| 69 | * The second one allows the CPU to customize the accel-cpu |
| 70 | * behavior according to the CPU. |
| 71 | * |
| 72 | * The second is currently only used by TCG, to specialize the |
| 73 | * TCGCPUOps depending on the CPU type. |
| 74 | */ |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 75 | cc->accel_cpu = accel_cpu; |
| 76 | if (accel_cpu->cpu_class_init) { |
| 77 | accel_cpu->cpu_class_init(cc); |
| 78 | } |
Claudio Fontana | cc3f2be | 2021-03-22 14:27:59 +0100 | [diff] [blame] | 79 | if (cc->init_accel_cpu) { |
| 80 | cc->init_accel_cpu(accel_cpu, cc); |
| 81 | } |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | /* initialize the arch-specific accel CpuClass interfaces */ |
| 85 | static void accel_init_cpu_interfaces(AccelClass *ac) |
| 86 | { |
| 87 | const char *ac_name; /* AccelClass name */ |
| 88 | char *acc_name; /* AccelCPUClass name */ |
| 89 | ObjectClass *acc; /* AccelCPUClass */ |
| 90 | |
| 91 | ac_name = object_class_get_name(OBJECT_CLASS(ac)); |
| 92 | g_assert(ac_name != NULL); |
| 93 | |
| 94 | acc_name = g_strdup_printf("%s-%s", ac_name, CPU_RESOLVING_TYPE); |
| 95 | acc = object_class_by_name(acc_name); |
| 96 | g_free(acc_name); |
| 97 | |
| 98 | if (acc) { |
| 99 | object_class_foreach(accel_init_cpu_int_aux, |
| 100 | CPU_RESOLVING_TYPE, false, acc); |
| 101 | } |
| 102 | } |
| 103 | |
Claudio Fontana | b86f59c | 2021-02-04 17:39:25 +0100 | [diff] [blame] | 104 | void accel_init_interfaces(AccelClass *ac) |
| 105 | { |
| 106 | #ifndef CONFIG_USER_ONLY |
Philippe Mathieu-Daudé | 463b006 | 2024-01-10 10:00:53 +0100 | [diff] [blame] | 107 | accel_system_init_ops_interfaces(ac); |
Claudio Fontana | b86f59c | 2021-02-04 17:39:25 +0100 | [diff] [blame] | 108 | #endif /* !CONFIG_USER_ONLY */ |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 109 | |
| 110 | accel_init_cpu_interfaces(ac); |
Claudio Fontana | b86f59c | 2021-02-04 17:39:25 +0100 | [diff] [blame] | 111 | } |
| 112 | |
Claudio Fontana | bb883fd | 2021-03-22 14:27:42 +0100 | [diff] [blame] | 113 | void accel_cpu_instance_init(CPUState *cpu) |
| 114 | { |
| 115 | CPUClass *cc = CPU_GET_CLASS(cpu); |
| 116 | |
| 117 | if (cc->accel_cpu && cc->accel_cpu->cpu_instance_init) { |
| 118 | cc->accel_cpu->cpu_instance_init(cpu); |
| 119 | } |
| 120 | } |
| 121 | |
Philippe Mathieu-Daudé | bd684b2 | 2023-10-03 14:30:21 +0200 | [diff] [blame] | 122 | bool accel_cpu_common_realize(CPUState *cpu, Error **errp) |
Claudio Fontana | bb883fd | 2021-03-22 14:27:42 +0100 | [diff] [blame] | 123 | { |
| 124 | CPUClass *cc = CPU_GET_CLASS(cpu); |
Philippe Mathieu-Daudé | 5985186 | 2023-10-03 14:30:23 +0200 | [diff] [blame] | 125 | AccelState *accel = current_accel(); |
| 126 | AccelClass *acc = ACCEL_GET_CLASS(accel); |
Claudio Fontana | bb883fd | 2021-03-22 14:27:42 +0100 | [diff] [blame] | 127 | |
Philippe Mathieu-Daudé | 5985186 | 2023-10-03 14:30:23 +0200 | [diff] [blame] | 128 | /* target specific realization */ |
| 129 | if (cc->accel_cpu && cc->accel_cpu->cpu_target_realize |
| 130 | && !cc->accel_cpu->cpu_target_realize(cpu, errp)) { |
| 131 | return false; |
Claudio Fontana | bb883fd | 2021-03-22 14:27:42 +0100 | [diff] [blame] | 132 | } |
Philippe Mathieu-Daudé | 5985186 | 2023-10-03 14:30:23 +0200 | [diff] [blame] | 133 | |
| 134 | /* generic realization */ |
| 135 | if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) { |
| 136 | return false; |
| 137 | } |
| 138 | |
Claudio Fontana | 9ea057d | 2021-03-22 14:27:44 +0100 | [diff] [blame] | 139 | return true; |
Claudio Fontana | bb883fd | 2021-03-22 14:27:42 +0100 | [diff] [blame] | 140 | } |
| 141 | |
Philippe Mathieu-Daudé | 1aa1d83 | 2023-10-03 14:30:22 +0200 | [diff] [blame] | 142 | void accel_cpu_common_unrealize(CPUState *cpu) |
| 143 | { |
Philippe Mathieu-Daudé | 5985186 | 2023-10-03 14:30:23 +0200 | [diff] [blame] | 144 | AccelState *accel = current_accel(); |
| 145 | AccelClass *acc = ACCEL_GET_CLASS(accel); |
| 146 | |
| 147 | /* generic unrealization */ |
| 148 | if (acc->cpu_common_unrealize) { |
| 149 | acc->cpu_common_unrealize(cpu); |
| 150 | } |
Philippe Mathieu-Daudé | 1aa1d83 | 2023-10-03 14:30:22 +0200 | [diff] [blame] | 151 | } |
| 152 | |
Alex Bennée | 3b7a938 | 2022-09-29 12:42:23 +0100 | [diff] [blame] | 153 | int accel_supported_gdbstub_sstep_flags(void) |
| 154 | { |
| 155 | AccelState *accel = current_accel(); |
| 156 | AccelClass *acc = ACCEL_GET_CLASS(accel); |
| 157 | if (acc->gdbstub_supported_sstep_flags) { |
| 158 | return acc->gdbstub_supported_sstep_flags(); |
| 159 | } |
| 160 | return 0; |
| 161 | } |
| 162 | |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 163 | static const TypeInfo accel_cpu_type = { |
| 164 | .name = TYPE_ACCEL_CPU, |
| 165 | .parent = TYPE_OBJECT, |
| 166 | .abstract = true, |
| 167 | .class_size = sizeof(AccelCPUClass), |
| 168 | }; |
| 169 | |
Eduardo Habkost | b14a0b7 | 2014-09-26 17:45:21 -0300 | [diff] [blame] | 170 | static void register_accel_types(void) |
| 171 | { |
| 172 | type_register_static(&accel_type); |
Claudio Fontana | fb6916d | 2021-02-04 17:39:26 +0100 | [diff] [blame] | 173 | type_register_static(&accel_cpu_type); |
Eduardo Habkost | b14a0b7 | 2014-09-26 17:45:21 -0300 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | type_init(register_accel_types); |