xref: /qemu/cpu-target.c (revision 8d535c312ca5944622b3b74177eb12d8f6b7a7fa)
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"
21*8d535c31SPierrick 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"
2742508261SPhilippe Mathieu-Daudé #include "exec/tswap.h"
285b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h"
29d9f24bf5SPaolo Bonzini #include "exec/log.h"
30b12a0f85SPhilippe Mathieu-Daudé #include "accel/accel-cpu-target.h"
31ad1a706fSRichard Henderson #include "trace/trace-root.h"
32d9f24bf5SPaolo Bonzini 
33*8d535c31SPierrick Bouvier /* Validate correct placement of CPUArchState. */
34*8d535c31SPierrick Bouvier QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0);
35*8d535c31SPierrick Bouvier QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
36*8d535c31SPierrick Bouvier 
37445946f4SGavin Shan char *cpu_model_from_type(const char *typename)
38445946f4SGavin Shan {
39445946f4SGavin Shan     const char *suffix = "-" CPU_RESOLVING_TYPE;
40445946f4SGavin Shan 
41445946f4SGavin Shan     if (!object_class_by_name(typename)) {
42445946f4SGavin Shan         return NULL;
43445946f4SGavin Shan     }
44445946f4SGavin Shan 
45445946f4SGavin Shan     if (g_str_has_suffix(typename, suffix)) {
46445946f4SGavin Shan         return g_strndup(typename, strlen(typename) - strlen(suffix));
47445946f4SGavin Shan     }
48445946f4SGavin Shan 
49445946f4SGavin Shan     return g_strdup(typename);
50445946f4SGavin Shan }
51445946f4SGavin Shan 
52d9f24bf5SPaolo Bonzini const char *parse_cpu_option(const char *cpu_option)
53d9f24bf5SPaolo Bonzini {
54d9f24bf5SPaolo Bonzini     ObjectClass *oc;
55d9f24bf5SPaolo Bonzini     CPUClass *cc;
56d9f24bf5SPaolo Bonzini     gchar **model_pieces;
57d9f24bf5SPaolo Bonzini     const char *cpu_type;
58d9f24bf5SPaolo Bonzini 
59d9f24bf5SPaolo Bonzini     model_pieces = g_strsplit(cpu_option, ",", 2);
60d9f24bf5SPaolo Bonzini     if (!model_pieces[0]) {
61d9f24bf5SPaolo Bonzini         error_report("-cpu option cannot be empty");
62d9f24bf5SPaolo Bonzini         exit(1);
63d9f24bf5SPaolo Bonzini     }
64d9f24bf5SPaolo Bonzini 
65d9f24bf5SPaolo Bonzini     oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]);
66d9f24bf5SPaolo Bonzini     if (oc == NULL) {
67d9f24bf5SPaolo Bonzini         error_report("unable to find CPU model '%s'", model_pieces[0]);
68d9f24bf5SPaolo Bonzini         g_strfreev(model_pieces);
69d9f24bf5SPaolo Bonzini         exit(EXIT_FAILURE);
70d9f24bf5SPaolo Bonzini     }
71d9f24bf5SPaolo Bonzini 
72d9f24bf5SPaolo Bonzini     cpu_type = object_class_get_name(oc);
73d9f24bf5SPaolo Bonzini     cc = CPU_CLASS(oc);
74d9f24bf5SPaolo Bonzini     cc->parse_features(cpu_type, model_pieces[1], &error_fatal);
75d9f24bf5SPaolo Bonzini     g_strfreev(model_pieces);
76d9f24bf5SPaolo Bonzini     return cpu_type;
77d9f24bf5SPaolo Bonzini }
78d9f24bf5SPaolo Bonzini 
79dfa47531SGavin Shan #ifndef cpu_list
80dfa47531SGavin Shan static void cpu_list_entry(gpointer data, gpointer user_data)
81dfa47531SGavin Shan {
82dfa47531SGavin Shan     CPUClass *cc = CPU_CLASS(OBJECT_CLASS(data));
83dfa47531SGavin Shan     const char *typename = object_class_get_name(OBJECT_CLASS(data));
84dfa47531SGavin Shan     g_autofree char *model = cpu_model_from_type(typename);
85dfa47531SGavin Shan 
86dfa47531SGavin Shan     if (cc->deprecation_note) {
87dfa47531SGavin Shan         qemu_printf("  %s (deprecated)\n", model);
88dfa47531SGavin Shan     } else {
89dfa47531SGavin Shan         qemu_printf("  %s\n", model);
90dfa47531SGavin Shan     }
91dfa47531SGavin Shan }
92dfa47531SGavin Shan 
93dfa47531SGavin Shan static void cpu_list(void)
94dfa47531SGavin Shan {
95dfa47531SGavin Shan     GSList *list;
96dfa47531SGavin Shan 
97dfa47531SGavin Shan     list = object_class_get_list_sorted(TYPE_CPU, false);
98dfa47531SGavin Shan     qemu_printf("Available CPUs:\n");
99dfa47531SGavin Shan     g_slist_foreach(list, cpu_list_entry, NULL);
100dfa47531SGavin Shan     g_slist_free(list);
101dfa47531SGavin Shan }
102dfa47531SGavin Shan #endif
103dfa47531SGavin Shan 
104c138c3b8SThomas Huth void list_cpus(void)
105377bf6f3SPhilippe Mathieu-Daudé {
106377bf6f3SPhilippe Mathieu-Daudé     cpu_list();
107377bf6f3SPhilippe Mathieu-Daudé }
108377bf6f3SPhilippe Mathieu-Daudé 
109d9f24bf5SPaolo Bonzini /* enable or disable single step mode. EXCP_DEBUG is returned by the
110d9f24bf5SPaolo Bonzini    CPU loop after each instruction */
111d9f24bf5SPaolo Bonzini void cpu_single_step(CPUState *cpu, int enabled)
112d9f24bf5SPaolo Bonzini {
113d9f24bf5SPaolo Bonzini     if (cpu->singlestep_enabled != enabled) {
114d9f24bf5SPaolo Bonzini         cpu->singlestep_enabled = enabled;
115412ae126SMads Ynddal 
116412ae126SMads Ynddal #if !defined(CONFIG_USER_ONLY)
117412ae126SMads Ynddal         const AccelOpsClass *ops = cpus_get_accel();
118412ae126SMads Ynddal         if (ops->update_guest_debug) {
119412ae126SMads Ynddal             ops->update_guest_debug(cpu);
120d9f24bf5SPaolo Bonzini         }
121412ae126SMads Ynddal #endif
122412ae126SMads Ynddal 
123ad1a706fSRichard Henderson         trace_breakpoint_singlestep(cpu->cpu_index, enabled);
124d9f24bf5SPaolo Bonzini     }
125d9f24bf5SPaolo Bonzini }
126d9f24bf5SPaolo Bonzini 
127d9f24bf5SPaolo Bonzini void cpu_abort(CPUState *cpu, const char *fmt, ...)
128d9f24bf5SPaolo Bonzini {
129d9f24bf5SPaolo Bonzini     va_list ap;
130d9f24bf5SPaolo Bonzini     va_list ap2;
131d9f24bf5SPaolo Bonzini 
132d9f24bf5SPaolo Bonzini     va_start(ap, fmt);
133d9f24bf5SPaolo Bonzini     va_copy(ap2, ap);
134d9f24bf5SPaolo Bonzini     fprintf(stderr, "qemu: fatal: ");
135d9f24bf5SPaolo Bonzini     vfprintf(stderr, fmt, ap);
136d9f24bf5SPaolo Bonzini     fprintf(stderr, "\n");
137d9f24bf5SPaolo Bonzini     cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP);
138d9f24bf5SPaolo Bonzini     if (qemu_log_separate()) {
139c60f599bSRichard Henderson         FILE *logfile = qemu_log_trylock();
14078b54858SRichard Henderson         if (logfile) {
14178b54858SRichard Henderson             fprintf(logfile, "qemu: fatal: ");
14278b54858SRichard Henderson             vfprintf(logfile, fmt, ap2);
14378b54858SRichard Henderson             fprintf(logfile, "\n");
14478b54858SRichard Henderson             cpu_dump_state(cpu, logfile, CPU_DUMP_FPU | CPU_DUMP_CCOP);
145d9f24bf5SPaolo Bonzini             qemu_log_unlock(logfile);
14678b54858SRichard Henderson         }
147d9f24bf5SPaolo Bonzini     }
148d9f24bf5SPaolo Bonzini     va_end(ap2);
149d9f24bf5SPaolo Bonzini     va_end(ap);
150d9f24bf5SPaolo Bonzini     replay_finish();
151d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY)
152d9f24bf5SPaolo Bonzini     {
153d9f24bf5SPaolo Bonzini         struct sigaction act;
154d9f24bf5SPaolo Bonzini         sigfillset(&act.sa_mask);
155d9f24bf5SPaolo Bonzini         act.sa_handler = SIG_DFL;
156d9f24bf5SPaolo Bonzini         act.sa_flags = 0;
157d9f24bf5SPaolo Bonzini         sigaction(SIGABRT, &act, NULL);
158d9f24bf5SPaolo Bonzini     }
159d9f24bf5SPaolo Bonzini #endif
160d9f24bf5SPaolo Bonzini     abort();
161d9f24bf5SPaolo Bonzini }
162d9f24bf5SPaolo Bonzini 
163cfac5cdfSPierrick Bouvier #undef target_words_bigendian
164d9f24bf5SPaolo Bonzini bool target_words_bigendian(void)
165d9f24bf5SPaolo Bonzini {
166ded625e7SThomas Huth     return TARGET_BIG_ENDIAN;
167d9f24bf5SPaolo Bonzini }
168d9f24bf5SPaolo Bonzini 
1691077f50bSThomas Huth const char *target_name(void)
1701077f50bSThomas Huth {
1711077f50bSThomas Huth     return TARGET_NAME;
1721077f50bSThomas Huth }
173