xref: /qemu/cpu-target.c (revision d97c3b06de5bdd885f0ee3d8153326acd3db480e)
1d9f24bf5SPaolo Bonzini /*
2d9f24bf5SPaolo Bonzini  * Target-specific parts of the CPU object
3d9f24bf5SPaolo Bonzini  *
4d9f24bf5SPaolo Bonzini  *  Copyright (c) 2003 Fabrice Bellard
5d9f24bf5SPaolo Bonzini  *
6d9f24bf5SPaolo Bonzini  * This library is free software; you can redistribute it and/or
7d9f24bf5SPaolo Bonzini  * modify it under the terms of the GNU Lesser General Public
8d9f24bf5SPaolo Bonzini  * License as published by the Free Software Foundation; either
9d9f24bf5SPaolo Bonzini  * version 2 of the License, or (at your option) any later version.
10d9f24bf5SPaolo Bonzini  *
11d9f24bf5SPaolo Bonzini  * This library is distributed in the hope that it will be useful,
12d9f24bf5SPaolo Bonzini  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13d9f24bf5SPaolo Bonzini  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14d9f24bf5SPaolo Bonzini  * Lesser General Public License for more details.
15d9f24bf5SPaolo Bonzini  *
16d9f24bf5SPaolo Bonzini  * You should have received a copy of the GNU Lesser General Public
17d9f24bf5SPaolo Bonzini  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18d9f24bf5SPaolo Bonzini  */
19d9f24bf5SPaolo Bonzini 
20d9f24bf5SPaolo Bonzini #include "qemu/osdep.h"
218d535c31SPierrick Bouvier #include "cpu.h"
22d9f24bf5SPaolo Bonzini #include "qapi/error.h"
23d9f24bf5SPaolo Bonzini #include "qemu/error-report.h"
24dfa47531SGavin Shan #include "qemu/qemu-print.h"
250f66536aSPhilippe Mathieu-Daudé #include "system/accel-ops.h"
2632cad1ffSPhilippe Mathieu-Daudé #include "system/cpus.h"
27*d97c3b06SPierrick Bouvier #include "exec/cpu-common.h"
2842508261SPhilippe Mathieu-Daudé #include "exec/tswap.h"
295b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h"
30d9f24bf5SPaolo Bonzini #include "exec/log.h"
31b12a0f85SPhilippe Mathieu-Daudé #include "accel/accel-cpu-target.h"
32ad1a706fSRichard Henderson #include "trace/trace-root.h"
33d9f24bf5SPaolo Bonzini 
348d535c31SPierrick Bouvier /* Validate correct placement of CPUArchState. */
358d535c31SPierrick Bouvier QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0);
368d535c31SPierrick Bouvier QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
378d535c31SPierrick Bouvier 
38445946f4SGavin Shan char *cpu_model_from_type(const char *typename)
39445946f4SGavin Shan {
40445946f4SGavin Shan     const char *suffix = "-" CPU_RESOLVING_TYPE;
41445946f4SGavin Shan 
42445946f4SGavin Shan     if (!object_class_by_name(typename)) {
43445946f4SGavin Shan         return NULL;
44445946f4SGavin Shan     }
45445946f4SGavin Shan 
46445946f4SGavin Shan     if (g_str_has_suffix(typename, suffix)) {
47445946f4SGavin Shan         return g_strndup(typename, strlen(typename) - strlen(suffix));
48445946f4SGavin Shan     }
49445946f4SGavin Shan 
50445946f4SGavin Shan     return g_strdup(typename);
51445946f4SGavin Shan }
52445946f4SGavin Shan 
53d9f24bf5SPaolo Bonzini const char *parse_cpu_option(const char *cpu_option)
54d9f24bf5SPaolo Bonzini {
55d9f24bf5SPaolo Bonzini     ObjectClass *oc;
56d9f24bf5SPaolo Bonzini     CPUClass *cc;
57d9f24bf5SPaolo Bonzini     gchar **model_pieces;
58d9f24bf5SPaolo Bonzini     const char *cpu_type;
59d9f24bf5SPaolo Bonzini 
60d9f24bf5SPaolo Bonzini     model_pieces = g_strsplit(cpu_option, ",", 2);
61d9f24bf5SPaolo Bonzini     if (!model_pieces[0]) {
62d9f24bf5SPaolo Bonzini         error_report("-cpu option cannot be empty");
63d9f24bf5SPaolo Bonzini         exit(1);
64d9f24bf5SPaolo Bonzini     }
65d9f24bf5SPaolo Bonzini 
66d9f24bf5SPaolo Bonzini     oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]);
67d9f24bf5SPaolo Bonzini     if (oc == NULL) {
68d9f24bf5SPaolo Bonzini         error_report("unable to find CPU model '%s'", model_pieces[0]);
69d9f24bf5SPaolo Bonzini         g_strfreev(model_pieces);
70d9f24bf5SPaolo Bonzini         exit(EXIT_FAILURE);
71d9f24bf5SPaolo Bonzini     }
72d9f24bf5SPaolo Bonzini 
73d9f24bf5SPaolo Bonzini     cpu_type = object_class_get_name(oc);
74d9f24bf5SPaolo Bonzini     cc = CPU_CLASS(oc);
75d9f24bf5SPaolo Bonzini     cc->parse_features(cpu_type, model_pieces[1], &error_fatal);
76d9f24bf5SPaolo Bonzini     g_strfreev(model_pieces);
77d9f24bf5SPaolo Bonzini     return cpu_type;
78d9f24bf5SPaolo Bonzini }
79d9f24bf5SPaolo Bonzini 
80dfa47531SGavin Shan #ifndef cpu_list
81dfa47531SGavin Shan static void cpu_list_entry(gpointer data, gpointer user_data)
82dfa47531SGavin Shan {
83dfa47531SGavin Shan     CPUClass *cc = CPU_CLASS(OBJECT_CLASS(data));
84dfa47531SGavin Shan     const char *typename = object_class_get_name(OBJECT_CLASS(data));
85dfa47531SGavin Shan     g_autofree char *model = cpu_model_from_type(typename);
86dfa47531SGavin Shan 
87dfa47531SGavin Shan     if (cc->deprecation_note) {
88dfa47531SGavin Shan         qemu_printf("  %s (deprecated)\n", model);
89dfa47531SGavin Shan     } else {
90dfa47531SGavin Shan         qemu_printf("  %s\n", model);
91dfa47531SGavin Shan     }
92dfa47531SGavin Shan }
93dfa47531SGavin Shan 
94dfa47531SGavin Shan static void cpu_list(void)
95dfa47531SGavin Shan {
96dfa47531SGavin Shan     GSList *list;
97dfa47531SGavin Shan 
98dfa47531SGavin Shan     list = object_class_get_list_sorted(TYPE_CPU, false);
99dfa47531SGavin Shan     qemu_printf("Available CPUs:\n");
100dfa47531SGavin Shan     g_slist_foreach(list, cpu_list_entry, NULL);
101dfa47531SGavin Shan     g_slist_free(list);
102dfa47531SGavin Shan }
103dfa47531SGavin Shan #endif
104dfa47531SGavin Shan 
105c138c3b8SThomas Huth void list_cpus(void)
106377bf6f3SPhilippe Mathieu-Daudé {
107377bf6f3SPhilippe Mathieu-Daudé     cpu_list();
108377bf6f3SPhilippe Mathieu-Daudé }
109377bf6f3SPhilippe Mathieu-Daudé 
110d9f24bf5SPaolo Bonzini /* enable or disable single step mode. EXCP_DEBUG is returned by the
111d9f24bf5SPaolo Bonzini    CPU loop after each instruction */
112d9f24bf5SPaolo Bonzini void cpu_single_step(CPUState *cpu, int enabled)
113d9f24bf5SPaolo Bonzini {
114d9f24bf5SPaolo Bonzini     if (cpu->singlestep_enabled != enabled) {
115d9f24bf5SPaolo Bonzini         cpu->singlestep_enabled = enabled;
116412ae126SMads Ynddal 
117412ae126SMads Ynddal #if !defined(CONFIG_USER_ONLY)
118412ae126SMads Ynddal         const AccelOpsClass *ops = cpus_get_accel();
119412ae126SMads Ynddal         if (ops->update_guest_debug) {
120412ae126SMads Ynddal             ops->update_guest_debug(cpu);
121d9f24bf5SPaolo Bonzini         }
122412ae126SMads Ynddal #endif
123412ae126SMads Ynddal 
124ad1a706fSRichard Henderson         trace_breakpoint_singlestep(cpu->cpu_index, enabled);
125d9f24bf5SPaolo Bonzini     }
126d9f24bf5SPaolo Bonzini }
127d9f24bf5SPaolo Bonzini 
128d9f24bf5SPaolo Bonzini void cpu_abort(CPUState *cpu, const char *fmt, ...)
129d9f24bf5SPaolo Bonzini {
130d9f24bf5SPaolo Bonzini     va_list ap;
131d9f24bf5SPaolo Bonzini     va_list ap2;
132d9f24bf5SPaolo Bonzini 
133d9f24bf5SPaolo Bonzini     va_start(ap, fmt);
134d9f24bf5SPaolo Bonzini     va_copy(ap2, ap);
135d9f24bf5SPaolo Bonzini     fprintf(stderr, "qemu: fatal: ");
136d9f24bf5SPaolo Bonzini     vfprintf(stderr, fmt, ap);
137d9f24bf5SPaolo Bonzini     fprintf(stderr, "\n");
138d9f24bf5SPaolo Bonzini     cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP);
139d9f24bf5SPaolo Bonzini     if (qemu_log_separate()) {
140c60f599bSRichard Henderson         FILE *logfile = qemu_log_trylock();
14178b54858SRichard Henderson         if (logfile) {
14278b54858SRichard Henderson             fprintf(logfile, "qemu: fatal: ");
14378b54858SRichard Henderson             vfprintf(logfile, fmt, ap2);
14478b54858SRichard Henderson             fprintf(logfile, "\n");
14578b54858SRichard Henderson             cpu_dump_state(cpu, logfile, CPU_DUMP_FPU | CPU_DUMP_CCOP);
146d9f24bf5SPaolo Bonzini             qemu_log_unlock(logfile);
14778b54858SRichard Henderson         }
148d9f24bf5SPaolo Bonzini     }
149d9f24bf5SPaolo Bonzini     va_end(ap2);
150d9f24bf5SPaolo Bonzini     va_end(ap);
151d9f24bf5SPaolo Bonzini     replay_finish();
152d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY)
153d9f24bf5SPaolo Bonzini     {
154d9f24bf5SPaolo Bonzini         struct sigaction act;
155d9f24bf5SPaolo Bonzini         sigfillset(&act.sa_mask);
156d9f24bf5SPaolo Bonzini         act.sa_handler = SIG_DFL;
157d9f24bf5SPaolo Bonzini         act.sa_flags = 0;
158d9f24bf5SPaolo Bonzini         sigaction(SIGABRT, &act, NULL);
159d9f24bf5SPaolo Bonzini     }
160d9f24bf5SPaolo Bonzini #endif
161d9f24bf5SPaolo Bonzini     abort();
162d9f24bf5SPaolo Bonzini }
163d9f24bf5SPaolo Bonzini 
164cfac5cdfSPierrick Bouvier #undef target_words_bigendian
165d9f24bf5SPaolo Bonzini bool target_words_bigendian(void)
166d9f24bf5SPaolo Bonzini {
167ded625e7SThomas Huth     return TARGET_BIG_ENDIAN;
168d9f24bf5SPaolo Bonzini }
169d9f24bf5SPaolo Bonzini 
1701077f50bSThomas Huth const char *target_name(void)
1711077f50bSThomas Huth {
1721077f50bSThomas Huth     return TARGET_NAME;
1731077f50bSThomas Huth }
174