]> Git Repo - qemu.git/blame - linux-user/main.c
linux-user: create a dummy per arch cpu_loop.c
[qemu.git] / linux-user / main.c
CommitLineData
31e31b8a 1/*
93ac68bc 2 * qemu user main
5fafdf24 3 *
68d0f70e 4 * Copyright (c) 2003-2008 Fabrice Bellard
31e31b8a
FB
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
8167ee88 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31e31b8a 18 */
d39594e9 19#include "qemu/osdep.h"
67a1de0d 20#include "qemu-version.h"
edf8e2af 21#include <sys/syscall.h>
703e0e89 22#include <sys/resource.h>
31e31b8a 23
daa76aa4 24#include "qapi/error.h"
3ef693a0 25#include "qemu.h"
f348b6d1 26#include "qemu/path.h"
6533dd6e 27#include "qemu/config-file.h"
f348b6d1
VB
28#include "qemu/cutils.h"
29#include "qemu/help_option.h"
2b41f10e 30#include "cpu.h"
63c91552 31#include "exec/exec-all.h"
9002ec79 32#include "tcg.h"
1de7afc9
PB
33#include "qemu/timer.h"
34#include "qemu/envlist.h"
d8fd2954 35#include "elf.h"
6533dd6e 36#include "trace/control.h"
542ca434 37#include "target_elf.h"
cd71c089 38#include "cpu_loop-common.h"
04a6dfeb 39
d088d664
AJ
40char *exec_path;
41
1b530a6d 42int singlestep;
8cb76755
SW
43static const char *filename;
44static const char *argv0;
45static int gdbstub_port;
46static envlist_t *envlist;
51fb256a 47static const char *cpu_model;
2278b939 48static const char *cpu_type;
379f6698
PB
49unsigned long mmap_min_addr;
50unsigned long guest_base;
51int have_guest_base;
120a9848 52
288e65b9
AG
53/*
54 * When running 32-on-64 we should make sure we can fit all of the possible
55 * guest address space into a contiguous chunk of virtual host memory.
56 *
57 * This way we will never overlap with our own libraries or binaries or stack
58 * or anything else that QEMU maps.
18e80c55
RH
59 *
60 * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
61 * of the address for the kernel. Some cpus rely on this and user space
62 * uses the high bit(s) for pointer tagging and the like. For them, we
63 * must preserve the expected address space.
288e65b9 64 */
18e80c55
RH
65#ifndef MAX_RESERVED_VA
66# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
67# if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
68 (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
69/* There are a number of places where we assign reserved_va to a variable
70 of type abi_ulong and expect it to fit. Avoid the last page. */
71# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
72# else
73# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
74# endif
314992b1 75# else
18e80c55 76# define MAX_RESERVED_VA 0
314992b1 77# endif
18e80c55
RH
78#endif
79
80/* That said, reserving *too* much vm space via mmap can run into problems
81 with rlimits, oom due to page table creation, etc. We will still try it,
82 if directed by the command-line option, but not by default. */
83#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
84unsigned long reserved_va = MAX_RESERVED_VA;
288e65b9 85#else
68a1c816 86unsigned long reserved_va;
379f6698 87#endif
1b530a6d 88
d03f9c32 89static void usage(int exitcode);
fc9c5412 90
7ee2822c 91static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
e586822a 92const char *qemu_uname_release;
586314f2 93
9de5e440
FB
94/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
95 we allocate a bigger stack. Need a better solution, for example
96 by remapping the process stack directly at the right place */
703e0e89 97unsigned long guest_stack_size = 8 * 1024 * 1024UL;
31e31b8a
FB
98
99void gemu_log(const char *fmt, ...)
100{
101 va_list ap;
102
103 va_start(ap, fmt);
104 vfprintf(stderr, fmt, ap);
105 va_end(ap);
106}
107
8fcd3692 108#if defined(TARGET_I386)
05390248 109int cpu_get_pic_interrupt(CPUX86State *env)
92ccca6a
FB
110{
111 return -1;
112}
8fcd3692 113#endif
92ccca6a 114
d5975363
PB
115/***********************************************************/
116/* Helper routines for implementing atomic operations. */
117
d5975363
PB
118/* Make sure everything is in a consistent state for calling fork(). */
119void fork_start(void)
120{
06065c45 121 start_exclusive();
d032d1b4 122 mmap_fork_start();
024949ca
PM
123 qemu_mutex_lock(&tb_ctx.tb_lock);
124 cpu_list_lock();
d5975363
PB
125}
126
127void fork_end(int child)
128{
d032d1b4 129 mmap_fork_end(child);
d5975363 130 if (child) {
bdc44640 131 CPUState *cpu, *next_cpu;
d5975363
PB
132 /* Child processes created by fork() only have a single thread.
133 Discard information about the parent threads. */
bdc44640
AF
134 CPU_FOREACH_SAFE(cpu, next_cpu) {
135 if (cpu != thread_cpu) {
014628a7 136 QTAILQ_REMOVE(&cpus, cpu, node);
bdc44640
AF
137 }
138 }
44ded3d0 139 qemu_mutex_init(&tb_ctx.tb_lock);
267f685b 140 qemu_init_cpu_list();
f7ec7f7b 141 gdbserver_fork(thread_cpu);
06065c45
PM
142 /* qemu_init_cpu_list() takes care of reinitializing the
143 * exclusive state, so we don't need to end_exclusive() here.
144 */
d5975363 145 } else {
44ded3d0 146 qemu_mutex_unlock(&tb_ctx.tb_lock);
267f685b 147 cpu_list_unlock();
06065c45 148 end_exclusive();
d5975363 149 }
d5975363
PB
150}
151
a541f297
FB
152#ifdef TARGET_I386
153/***********************************************************/
154/* CPUX86 core interface */
155
28ab0e2e
FB
156uint64_t cpu_get_tsc(CPUX86State *env)
157{
4a7428c5 158 return cpu_get_host_ticks();
28ab0e2e
FB
159}
160
5fafdf24 161static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
f4beb510 162 int flags)
6dbad63e 163{
f4beb510 164 unsigned int e1, e2;
53a5960a 165 uint32_t *p;
6dbad63e
FB
166 e1 = (addr << 16) | (limit & 0xffff);
167 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
f4beb510 168 e2 |= flags;
53a5960a 169 p = ptr;
d538e8f5 170 p[0] = tswap32(e1);
171 p[1] = tswap32(e2);
f4beb510
FB
172}
173
e441570f 174static uint64_t *idt_table;
eb38c52c 175#ifdef TARGET_X86_64
d2fd1af7
FB
176static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
177 uint64_t addr, unsigned int sel)
f4beb510 178{
4dbc422b 179 uint32_t *p, e1, e2;
f4beb510
FB
180 e1 = (addr & 0xffff) | (sel << 16);
181 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
53a5960a 182 p = ptr;
4dbc422b
FB
183 p[0] = tswap32(e1);
184 p[1] = tswap32(e2);
185 p[2] = tswap32(addr >> 32);
186 p[3] = 0;
6dbad63e 187}
d2fd1af7
FB
188/* only dpl matters as we do only user space emulation */
189static void set_idt(int n, unsigned int dpl)
190{
191 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
192}
193#else
d2fd1af7
FB
194static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
195 uint32_t addr, unsigned int sel)
196{
4dbc422b 197 uint32_t *p, e1, e2;
d2fd1af7
FB
198 e1 = (addr & 0xffff) | (sel << 16);
199 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
200 p = ptr;
4dbc422b
FB
201 p[0] = tswap32(e1);
202 p[1] = tswap32(e2);
d2fd1af7
FB
203}
204
f4beb510
FB
205/* only dpl matters as we do only user space emulation */
206static void set_idt(int n, unsigned int dpl)
207{
208 set_gate(idt_table + n, 0, dpl, 0, 0);
209}
d2fd1af7 210#endif
31e31b8a 211
89e957e7 212void cpu_loop(CPUX86State *env)
1b6b029e 213{
db6b81d4 214 CPUState *cs = CPU(x86_env_get_cpu(env));
bc8a22cc 215 int trapnr;
992f48a0 216 abi_ulong pc;
0284b03b 217 abi_ulong ret;
c227f099 218 target_siginfo_t info;
851e67a1 219
1b6b029e 220 for(;;) {
b040bc9c 221 cpu_exec_start(cs);
8642c1b8 222 trapnr = cpu_exec(cs);
b040bc9c 223 cpu_exec_end(cs);
d148d90e
SF
224 process_queued_cpu_work(cs);
225
bc8a22cc 226 switch(trapnr) {
f4beb510 227 case 0x80:
d2fd1af7 228 /* linux syscall from int $0x80 */
0284b03b
TB
229 ret = do_syscall(env,
230 env->regs[R_EAX],
231 env->regs[R_EBX],
232 env->regs[R_ECX],
233 env->regs[R_EDX],
234 env->regs[R_ESI],
235 env->regs[R_EDI],
236 env->regs[R_EBP],
237 0, 0);
238 if (ret == -TARGET_ERESTARTSYS) {
239 env->eip -= 2;
240 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
241 env->regs[R_EAX] = ret;
242 }
f4beb510 243 break;
d2fd1af7
FB
244#ifndef TARGET_ABI32
245 case EXCP_SYSCALL:
5ba18547 246 /* linux syscall from syscall instruction */
0284b03b
TB
247 ret = do_syscall(env,
248 env->regs[R_EAX],
249 env->regs[R_EDI],
250 env->regs[R_ESI],
251 env->regs[R_EDX],
252 env->regs[10],
253 env->regs[8],
254 env->regs[9],
255 0, 0);
256 if (ret == -TARGET_ERESTARTSYS) {
257 env->eip -= 2;
258 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
259 env->regs[R_EAX] = ret;
260 }
d2fd1af7
FB
261 break;
262#endif
f4beb510
FB
263 case EXCP0B_NOSEG:
264 case EXCP0C_STACK:
a86b3c64 265 info.si_signo = TARGET_SIGBUS;
f4beb510
FB
266 info.si_errno = 0;
267 info.si_code = TARGET_SI_KERNEL;
268 info._sifields._sigfault._addr = 0;
9d2803f7 269 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
f4beb510 270 break;
1b6b029e 271 case EXCP0D_GPF:
d2fd1af7 272 /* XXX: potential problem if ABI32 */
84409ddb 273#ifndef TARGET_X86_64
851e67a1 274 if (env->eflags & VM_MASK) {
89e957e7 275 handle_vm86_fault(env);
84409ddb
JM
276 } else
277#endif
278 {
a86b3c64 279 info.si_signo = TARGET_SIGSEGV;
f4beb510
FB
280 info.si_errno = 0;
281 info.si_code = TARGET_SI_KERNEL;
282 info._sifields._sigfault._addr = 0;
9d2803f7 283 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1b6b029e
FB
284 }
285 break;
b689bc57 286 case EXCP0E_PAGE:
a86b3c64 287 info.si_signo = TARGET_SIGSEGV;
b689bc57
FB
288 info.si_errno = 0;
289 if (!(env->error_code & 1))
290 info.si_code = TARGET_SEGV_MAPERR;
291 else
292 info.si_code = TARGET_SEGV_ACCERR;
970a87a6 293 info._sifields._sigfault._addr = env->cr[2];
9d2803f7 294 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
b689bc57 295 break;
9de5e440 296 case EXCP00_DIVZ:
84409ddb 297#ifndef TARGET_X86_64
bc8a22cc 298 if (env->eflags & VM_MASK) {
447db213 299 handle_vm86_trap(env, trapnr);
84409ddb
JM
300 } else
301#endif
302 {
bc8a22cc 303 /* division by zero */
a86b3c64 304 info.si_signo = TARGET_SIGFPE;
bc8a22cc
FB
305 info.si_errno = 0;
306 info.si_code = TARGET_FPE_INTDIV;
307 info._sifields._sigfault._addr = env->eip;
9d2803f7 308 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
bc8a22cc 309 }
9de5e440 310 break;
01df040b 311 case EXCP01_DB:
447db213 312 case EXCP03_INT3:
84409ddb 313#ifndef TARGET_X86_64
447db213
FB
314 if (env->eflags & VM_MASK) {
315 handle_vm86_trap(env, trapnr);
84409ddb
JM
316 } else
317#endif
318 {
a86b3c64 319 info.si_signo = TARGET_SIGTRAP;
447db213 320 info.si_errno = 0;
01df040b 321 if (trapnr == EXCP01_DB) {
447db213
FB
322 info.si_code = TARGET_TRAP_BRKPT;
323 info._sifields._sigfault._addr = env->eip;
324 } else {
325 info.si_code = TARGET_SI_KERNEL;
326 info._sifields._sigfault._addr = 0;
327 }
9d2803f7 328 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
447db213
FB
329 }
330 break;
9de5e440
FB
331 case EXCP04_INTO:
332 case EXCP05_BOUND:
84409ddb 333#ifndef TARGET_X86_64
bc8a22cc 334 if (env->eflags & VM_MASK) {
447db213 335 handle_vm86_trap(env, trapnr);
84409ddb
JM
336 } else
337#endif
338 {
a86b3c64 339 info.si_signo = TARGET_SIGSEGV;
bc8a22cc 340 info.si_errno = 0;
b689bc57 341 info.si_code = TARGET_SI_KERNEL;
bc8a22cc 342 info._sifields._sigfault._addr = 0;
9d2803f7 343 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
bc8a22cc 344 }
9de5e440
FB
345 break;
346 case EXCP06_ILLOP:
a86b3c64 347 info.si_signo = TARGET_SIGILL;
9de5e440
FB
348 info.si_errno = 0;
349 info.si_code = TARGET_ILL_ILLOPN;
350 info._sifields._sigfault._addr = env->eip;
9d2803f7 351 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
9de5e440
FB
352 break;
353 case EXCP_INTERRUPT:
354 /* just indicate that signals should be handled asap */
355 break;
1fddef4b
FB
356 case EXCP_DEBUG:
357 {
358 int sig;
359
db6b81d4 360 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1fddef4b
FB
361 if (sig)
362 {
363 info.si_signo = sig;
364 info.si_errno = 0;
365 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 366 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1fddef4b
FB
367 }
368 }
369 break;
fdbc2b57
RH
370 case EXCP_ATOMIC:
371 cpu_exec_step_atomic(cs);
372 break;
1b6b029e 373 default:
970a87a6 374 pc = env->segs[R_CS].base + env->eip;
120a9848
PB
375 EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
376 (long)pc, trapnr);
1b6b029e
FB
377 abort();
378 }
66fb9763 379 process_pending_signals(env);
1b6b029e
FB
380 }
381}
b346ff46
FB
382#endif
383
384#ifdef TARGET_ARM
385
49017bd8 386#define get_user_code_u32(x, gaddr, env) \
d8fd2954 387 ({ abi_long __r = get_user_u32((x), (gaddr)); \
f9fd40eb 388 if (!__r && bswap_code(arm_sctlr_b(env))) { \
d8fd2954
PB
389 (x) = bswap32(x); \
390 } \
391 __r; \
392 })
393
49017bd8 394#define get_user_code_u16(x, gaddr, env) \
d8fd2954 395 ({ abi_long __r = get_user_u16((x), (gaddr)); \
f9fd40eb 396 if (!__r && bswap_code(arm_sctlr_b(env))) { \
d8fd2954
PB
397 (x) = bswap16(x); \
398 } \
399 __r; \
400 })
401
c3ae85fc
PB
402#define get_user_data_u32(x, gaddr, env) \
403 ({ abi_long __r = get_user_u32((x), (gaddr)); \
404 if (!__r && arm_cpu_bswap_data(env)) { \
405 (x) = bswap32(x); \
406 } \
407 __r; \
408 })
409
410#define get_user_data_u16(x, gaddr, env) \
411 ({ abi_long __r = get_user_u16((x), (gaddr)); \
412 if (!__r && arm_cpu_bswap_data(env)) { \
413 (x) = bswap16(x); \
414 } \
415 __r; \
416 })
417
418#define put_user_data_u32(x, gaddr, env) \
419 ({ typeof(x) __x = (x); \
420 if (arm_cpu_bswap_data(env)) { \
421 __x = bswap32(__x); \
422 } \
423 put_user_u32(__x, (gaddr)); \
424 })
425
426#define put_user_data_u16(x, gaddr, env) \
427 ({ typeof(x) __x = (x); \
428 if (arm_cpu_bswap_data(env)) { \
429 __x = bswap16(__x); \
430 } \
431 put_user_u16(__x, (gaddr)); \
432 })
433
1861c454
PM
434#ifdef TARGET_ABI32
435/* Commpage handling -- there is no commpage for AArch64 */
436
97cc7560
DDAG
437/*
438 * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
439 * Input:
440 * r0 = pointer to oldval
441 * r1 = pointer to newval
442 * r2 = pointer to target value
443 *
444 * Output:
445 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
446 * C set if *ptr was changed, clear if no exchange happened
447 *
448 * Note segv's in kernel helpers are a bit tricky, we can set the
449 * data address sensibly but the PC address is just the entry point.
450 */
451static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
452{
453 uint64_t oldval, newval, val;
454 uint32_t addr, cpsr;
455 target_siginfo_t info;
456
457 /* Based on the 32 bit code in do_kernel_trap */
458
459 /* XXX: This only works between threads, not between processes.
460 It's probably possible to implement this with native host
461 operations. However things like ldrex/strex are much harder so
462 there's not much point trying. */
463 start_exclusive();
464 cpsr = cpsr_read(env);
465 addr = env->regs[2];
466
467 if (get_user_u64(oldval, env->regs[0])) {
abf1172f 468 env->exception.vaddress = env->regs[0];
97cc7560
DDAG
469 goto segv;
470 };
471
472 if (get_user_u64(newval, env->regs[1])) {
abf1172f 473 env->exception.vaddress = env->regs[1];
97cc7560
DDAG
474 goto segv;
475 };
476
477 if (get_user_u64(val, addr)) {
abf1172f 478 env->exception.vaddress = addr;
97cc7560
DDAG
479 goto segv;
480 }
481
482 if (val == oldval) {
483 val = newval;
484
485 if (put_user_u64(val, addr)) {
abf1172f 486 env->exception.vaddress = addr;
97cc7560
DDAG
487 goto segv;
488 };
489
490 env->regs[0] = 0;
491 cpsr |= CPSR_C;
492 } else {
493 env->regs[0] = -1;
494 cpsr &= ~CPSR_C;
495 }
50866ba5 496 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
97cc7560
DDAG
497 end_exclusive();
498 return;
499
500segv:
501 end_exclusive();
502 /* We get the PC of the entry address - which is as good as anything,
503 on a real kernel what you get depends on which mode it uses. */
a86b3c64 504 info.si_signo = TARGET_SIGSEGV;
97cc7560
DDAG
505 info.si_errno = 0;
506 /* XXX: check env->error_code */
507 info.si_code = TARGET_SEGV_MAPERR;
abf1172f 508 info._sifields._sigfault._addr = env->exception.vaddress;
9d2803f7 509 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
97cc7560
DDAG
510}
511
fbb4a2e3
PB
512/* Handle a jump to the kernel code page. */
513static int
514do_kernel_trap(CPUARMState *env)
515{
516 uint32_t addr;
517 uint32_t cpsr;
518 uint32_t val;
519
520 switch (env->regs[15]) {
521 case 0xffff0fa0: /* __kernel_memory_barrier */
522 /* ??? No-op. Will need to do better for SMP. */
523 break;
524 case 0xffff0fc0: /* __kernel_cmpxchg */
d5975363
PB
525 /* XXX: This only works between threads, not between processes.
526 It's probably possible to implement this with native host
527 operations. However things like ldrex/strex are much harder so
528 there's not much point trying. */
529 start_exclusive();
fbb4a2e3
PB
530 cpsr = cpsr_read(env);
531 addr = env->regs[2];
532 /* FIXME: This should SEGV if the access fails. */
533 if (get_user_u32(val, addr))
534 val = ~env->regs[0];
535 if (val == env->regs[0]) {
536 val = env->regs[1];
537 /* FIXME: Check for segfaults. */
538 put_user_u32(val, addr);
539 env->regs[0] = 0;
540 cpsr |= CPSR_C;
541 } else {
542 env->regs[0] = -1;
543 cpsr &= ~CPSR_C;
544 }
50866ba5 545 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
d5975363 546 end_exclusive();
fbb4a2e3
PB
547 break;
548 case 0xffff0fe0: /* __kernel_get_tls */
b8d43285 549 env->regs[0] = cpu_get_tls(env);
fbb4a2e3 550 break;
97cc7560
DDAG
551 case 0xffff0f60: /* __kernel_cmpxchg64 */
552 arm_kernel_cmpxchg64_helper(env);
553 break;
554
fbb4a2e3
PB
555 default:
556 return 1;
557 }
558 /* Jump back to the caller. */
559 addr = env->regs[14];
560 if (addr & 1) {
561 env->thumb = 1;
562 addr &= ~1;
563 }
564 env->regs[15] = addr;
565
566 return 0;
567}
568
b346ff46
FB
569void cpu_loop(CPUARMState *env)
570{
0315c31c 571 CPUState *cs = CPU(arm_env_get_cpu(env));
b346ff46
FB
572 int trapnr;
573 unsigned int n, insn;
c227f099 574 target_siginfo_t info;
b5ff1b31 575 uint32_t addr;
f0267ef7 576 abi_ulong ret;
3b46e624 577
b346ff46 578 for(;;) {
0315c31c 579 cpu_exec_start(cs);
8642c1b8 580 trapnr = cpu_exec(cs);
0315c31c 581 cpu_exec_end(cs);
d148d90e
SF
582 process_queued_cpu_work(cs);
583
b346ff46
FB
584 switch(trapnr) {
585 case EXCP_UDEF:
7517748e 586 case EXCP_NOCP:
e13886e3 587 case EXCP_INVSTATE:
c6981055 588 {
0429a971 589 TaskState *ts = cs->opaque;
c6981055 590 uint32_t opcode;
6d9a42be 591 int rc;
c6981055
FB
592
593 /* we handle the FPU emulation here, as Linux */
594 /* we get the opcode */
2f619698 595 /* FIXME - what to do if get_user() fails? */
49017bd8 596 get_user_code_u32(opcode, env->regs[15], env);
3b46e624 597
6d9a42be
AJ
598 rc = EmulateAll(opcode, &ts->fpa, env);
599 if (rc == 0) { /* illegal instruction */
a86b3c64 600 info.si_signo = TARGET_SIGILL;
c6981055
FB
601 info.si_errno = 0;
602 info.si_code = TARGET_ILL_ILLOPN;
603 info._sifields._sigfault._addr = env->regs[15];
9d2803f7 604 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
6d9a42be
AJ
605 } else if (rc < 0) { /* FP exception */
606 int arm_fpe=0;
607
608 /* translate softfloat flags to FPSR flags */
609 if (-rc & float_flag_invalid)
610 arm_fpe |= BIT_IOC;
611 if (-rc & float_flag_divbyzero)
612 arm_fpe |= BIT_DZC;
613 if (-rc & float_flag_overflow)
614 arm_fpe |= BIT_OFC;
615 if (-rc & float_flag_underflow)
616 arm_fpe |= BIT_UFC;
617 if (-rc & float_flag_inexact)
618 arm_fpe |= BIT_IXC;
619
620 FPSR fpsr = ts->fpa.fpsr;
621 //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
622
623 if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
a86b3c64 624 info.si_signo = TARGET_SIGFPE;
6d9a42be
AJ
625 info.si_errno = 0;
626
627 /* ordered by priority, least first */
628 if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
629 if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
630 if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
631 if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
632 if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
633
634 info._sifields._sigfault._addr = env->regs[15];
9d2803f7 635 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
6d9a42be
AJ
636 } else {
637 env->regs[15] += 4;
638 }
639
640 /* accumulate unenabled exceptions */
641 if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
642 fpsr |= BIT_IXC;
643 if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
644 fpsr |= BIT_UFC;
645 if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
646 fpsr |= BIT_OFC;
647 if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
648 fpsr |= BIT_DZC;
649 if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
650 fpsr |= BIT_IOC;
651 ts->fpa.fpsr=fpsr;
652 } else { /* everything OK */
c6981055
FB
653 /* increment PC */
654 env->regs[15] += 4;
655 }
656 }
b346ff46
FB
657 break;
658 case EXCP_SWI:
06c949e6 659 case EXCP_BKPT:
b346ff46 660 {
ce4defa0 661 env->eabi = 1;
b346ff46 662 /* system call */
06c949e6
PB
663 if (trapnr == EXCP_BKPT) {
664 if (env->thumb) {
2f619698 665 /* FIXME - what to do if get_user() fails? */
49017bd8 666 get_user_code_u16(insn, env->regs[15], env);
06c949e6
PB
667 n = insn & 0xff;
668 env->regs[15] += 2;
669 } else {
2f619698 670 /* FIXME - what to do if get_user() fails? */
49017bd8 671 get_user_code_u32(insn, env->regs[15], env);
06c949e6
PB
672 n = (insn & 0xf) | ((insn >> 4) & 0xff0);
673 env->regs[15] += 4;
674 }
192c7bd9 675 } else {
06c949e6 676 if (env->thumb) {
2f619698 677 /* FIXME - what to do if get_user() fails? */
49017bd8 678 get_user_code_u16(insn, env->regs[15] - 2, env);
06c949e6
PB
679 n = insn & 0xff;
680 } else {
2f619698 681 /* FIXME - what to do if get_user() fails? */
49017bd8 682 get_user_code_u32(insn, env->regs[15] - 4, env);
06c949e6
PB
683 n = insn & 0xffffff;
684 }
192c7bd9
FB
685 }
686
6f1f31c0 687 if (n == ARM_NR_cacheflush) {
dcfd14b3 688 /* nop */
a4f81979
FB
689 } else if (n == ARM_NR_semihosting
690 || n == ARM_NR_thumb_semihosting) {
691 env->regs[0] = do_arm_semihosting (env);
3a1363ac 692 } else if (n == 0 || n >= ARM_SYSCALL_BASE || env->thumb) {
b346ff46 693 /* linux syscall */
ce4defa0 694 if (env->thumb || n == 0) {
192c7bd9
FB
695 n = env->regs[7];
696 } else {
697 n -= ARM_SYSCALL_BASE;
ce4defa0 698 env->eabi = 0;
192c7bd9 699 }
fbb4a2e3
PB
700 if ( n > ARM_NR_BASE) {
701 switch (n) {
702 case ARM_NR_cacheflush:
dcfd14b3 703 /* nop */
fbb4a2e3
PB
704 break;
705 case ARM_NR_set_tls:
706 cpu_set_tls(env, env->regs[0]);
707 env->regs[0] = 0;
708 break;
d5355087
HL
709 case ARM_NR_breakpoint:
710 env->regs[15] -= env->thumb ? 2 : 4;
711 goto excp_debug;
fbb4a2e3
PB
712 default:
713 gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
714 n);
715 env->regs[0] = -TARGET_ENOSYS;
716 break;
717 }
718 } else {
f0267ef7
TB
719 ret = do_syscall(env,
720 n,
721 env->regs[0],
722 env->regs[1],
723 env->regs[2],
724 env->regs[3],
725 env->regs[4],
726 env->regs[5],
727 0, 0);
728 if (ret == -TARGET_ERESTARTSYS) {
729 env->regs[15] -= env->thumb ? 2 : 4;
730 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
731 env->regs[0] = ret;
732 }
fbb4a2e3 733 }
b346ff46
FB
734 } else {
735 goto error;
736 }
737 }
738 break;
19a6e31c
PM
739 case EXCP_SEMIHOST:
740 env->regs[0] = do_arm_semihosting(env);
741 break;
43fff238
FB
742 case EXCP_INTERRUPT:
743 /* just indicate that signals should be handled asap */
744 break;
68016c62
FB
745 case EXCP_PREFETCH_ABORT:
746 case EXCP_DATA_ABORT:
abf1172f 747 addr = env->exception.vaddress;
68016c62 748 {
a86b3c64 749 info.si_signo = TARGET_SIGSEGV;
68016c62
FB
750 info.si_errno = 0;
751 /* XXX: check env->error_code */
752 info.si_code = TARGET_SEGV_MAPERR;
b5ff1b31 753 info._sifields._sigfault._addr = addr;
9d2803f7 754 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
68016c62
FB
755 }
756 break;
1fddef4b 757 case EXCP_DEBUG:
d5355087 758 excp_debug:
1fddef4b
FB
759 {
760 int sig;
761
db6b81d4 762 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1fddef4b
FB
763 if (sig)
764 {
765 info.si_signo = sig;
766 info.si_errno = 0;
767 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 768 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1fddef4b
FB
769 }
770 }
771 break;
fbb4a2e3
PB
772 case EXCP_KERNEL_TRAP:
773 if (do_kernel_trap(env))
774 goto error;
775 break;
f911e0a3
PM
776 case EXCP_YIELD:
777 /* nothing to do here for user-mode, just resume guest code */
778 break;
fdbc2b57
RH
779 case EXCP_ATOMIC:
780 cpu_exec_step_atomic(cs);
781 break;
b346ff46
FB
782 default:
783 error:
120a9848 784 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
b346ff46
FB
785 abort();
786 }
787 process_pending_signals(env);
788 }
789}
790
1861c454
PM
791#else
792
793/* AArch64 main loop */
794void cpu_loop(CPUARMState *env)
795{
796 CPUState *cs = CPU(arm_env_get_cpu(env));
797 int trapnr, sig;
f0267ef7 798 abi_long ret;
1861c454 799 target_siginfo_t info;
1861c454
PM
800
801 for (;;) {
802 cpu_exec_start(cs);
8642c1b8 803 trapnr = cpu_exec(cs);
1861c454 804 cpu_exec_end(cs);
d148d90e 805 process_queued_cpu_work(cs);
1861c454
PM
806
807 switch (trapnr) {
808 case EXCP_SWI:
f0267ef7
TB
809 ret = do_syscall(env,
810 env->xregs[8],
811 env->xregs[0],
812 env->xregs[1],
813 env->xregs[2],
814 env->xregs[3],
815 env->xregs[4],
816 env->xregs[5],
817 0, 0);
818 if (ret == -TARGET_ERESTARTSYS) {
819 env->pc -= 4;
820 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
821 env->xregs[0] = ret;
822 }
1861c454
PM
823 break;
824 case EXCP_INTERRUPT:
825 /* just indicate that signals should be handled asap */
826 break;
827 case EXCP_UDEF:
a86b3c64 828 info.si_signo = TARGET_SIGILL;
1861c454
PM
829 info.si_errno = 0;
830 info.si_code = TARGET_ILL_ILLOPN;
831 info._sifields._sigfault._addr = env->pc;
9d2803f7 832 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1861c454
PM
833 break;
834 case EXCP_PREFETCH_ABORT:
1861c454 835 case EXCP_DATA_ABORT:
a86b3c64 836 info.si_signo = TARGET_SIGSEGV;
1861c454
PM
837 info.si_errno = 0;
838 /* XXX: check env->error_code */
839 info.si_code = TARGET_SEGV_MAPERR;
686581ad 840 info._sifields._sigfault._addr = env->exception.vaddress;
9d2803f7 841 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1861c454
PM
842 break;
843 case EXCP_DEBUG:
844 case EXCP_BKPT:
845 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
846 if (sig) {
847 info.si_signo = sig;
848 info.si_errno = 0;
849 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 850 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1861c454
PM
851 }
852 break;
8012c84f
PM
853 case EXCP_SEMIHOST:
854 env->xregs[0] = do_arm_semihosting(env);
855 break;
f911e0a3
PM
856 case EXCP_YIELD:
857 /* nothing to do here for user-mode, just resume guest code */
858 break;
fdbc2b57
RH
859 case EXCP_ATOMIC:
860 cpu_exec_step_atomic(cs);
861 break;
1861c454 862 default:
120a9848 863 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
1861c454
PM
864 abort();
865 }
866 process_pending_signals(env);
fa2ef212
MM
867 /* Exception return on AArch64 always clears the exclusive monitor,
868 * so any return to running guest code implies this.
fa2ef212
MM
869 */
870 env->exclusive_addr = -1;
1861c454
PM
871 }
872}
873#endif /* ndef TARGET_ABI32 */
874
b346ff46 875#endif
1b6b029e 876
93ac68bc 877#ifdef TARGET_SPARC
ed23fbd9 878#define SPARC64_STACK_BIAS 2047
93ac68bc 879
060366c5
FB
880//#define DEBUG_WIN
881
2623cbaf
FB
882/* WARNING: dealing with register windows _is_ complicated. More info
883 can be found at http://www.sics.se/~psm/sparcstack.html */
060366c5
FB
884static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
885{
1a14026e 886 index = (index + cwp * 16) % (16 * env->nwindows);
060366c5
FB
887 /* wrap handling : if cwp is on the last window, then we use the
888 registers 'after' the end */
1a14026e
BS
889 if (index < 8 && env->cwp == env->nwindows - 1)
890 index += 16 * env->nwindows;
060366c5
FB
891 return index;
892}
893
2623cbaf
FB
894/* save the register window 'cwp1' */
895static inline void save_window_offset(CPUSPARCState *env, int cwp1)
060366c5 896{
2623cbaf 897 unsigned int i;
992f48a0 898 abi_ulong sp_ptr;
3b46e624 899
53a5960a 900 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
ed23fbd9
BS
901#ifdef TARGET_SPARC64
902 if (sp_ptr & 3)
903 sp_ptr += SPARC64_STACK_BIAS;
904#endif
060366c5 905#if defined(DEBUG_WIN)
2daf0284
BS
906 printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
907 sp_ptr, cwp1);
060366c5 908#endif
2623cbaf 909 for(i = 0; i < 16; i++) {
2f619698
FB
910 /* FIXME - what to do if put_user() fails? */
911 put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
992f48a0 912 sp_ptr += sizeof(abi_ulong);
2623cbaf 913 }
060366c5
FB
914}
915
916static void save_window(CPUSPARCState *env)
917{
5ef54116 918#ifndef TARGET_SPARC64
2623cbaf 919 unsigned int new_wim;
1a14026e
BS
920 new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
921 ((1LL << env->nwindows) - 1);
922 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
2623cbaf 923 env->wim = new_wim;
5ef54116 924#else
1a14026e 925 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
5ef54116
FB
926 env->cansave++;
927 env->canrestore--;
928#endif
060366c5
FB
929}
930
931static void restore_window(CPUSPARCState *env)
932{
eda52953
BS
933#ifndef TARGET_SPARC64
934 unsigned int new_wim;
935#endif
936 unsigned int i, cwp1;
992f48a0 937 abi_ulong sp_ptr;
3b46e624 938
eda52953 939#ifndef TARGET_SPARC64
1a14026e
BS
940 new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
941 ((1LL << env->nwindows) - 1);
eda52953 942#endif
3b46e624 943
060366c5 944 /* restore the invalid window */
1a14026e 945 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
53a5960a 946 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
ed23fbd9
BS
947#ifdef TARGET_SPARC64
948 if (sp_ptr & 3)
949 sp_ptr += SPARC64_STACK_BIAS;
950#endif
060366c5 951#if defined(DEBUG_WIN)
2daf0284
BS
952 printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
953 sp_ptr, cwp1);
060366c5 954#endif
2623cbaf 955 for(i = 0; i < 16; i++) {
2f619698
FB
956 /* FIXME - what to do if get_user() fails? */
957 get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
992f48a0 958 sp_ptr += sizeof(abi_ulong);
2623cbaf 959 }
5ef54116
FB
960#ifdef TARGET_SPARC64
961 env->canrestore++;
1a14026e
BS
962 if (env->cleanwin < env->nwindows - 1)
963 env->cleanwin++;
5ef54116 964 env->cansave--;
eda52953
BS
965#else
966 env->wim = new_wim;
5ef54116 967#endif
060366c5
FB
968}
969
970static void flush_windows(CPUSPARCState *env)
971{
972 int offset, cwp1;
2623cbaf
FB
973
974 offset = 1;
060366c5
FB
975 for(;;) {
976 /* if restore would invoke restore_window(), then we can stop */
1a14026e 977 cwp1 = cpu_cwp_inc(env, env->cwp + offset);
eda52953 978#ifndef TARGET_SPARC64
060366c5
FB
979 if (env->wim & (1 << cwp1))
980 break;
eda52953
BS
981#else
982 if (env->canrestore == 0)
983 break;
984 env->cansave++;
985 env->canrestore--;
986#endif
2623cbaf 987 save_window_offset(env, cwp1);
060366c5
FB
988 offset++;
989 }
1a14026e 990 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
eda52953
BS
991#ifndef TARGET_SPARC64
992 /* set wim so that restore will reload the registers */
2623cbaf 993 env->wim = 1 << cwp1;
eda52953 994#endif
2623cbaf
FB
995#if defined(DEBUG_WIN)
996 printf("flush_windows: nb=%d\n", offset - 1);
80a9d035 997#endif
2623cbaf 998}
060366c5 999
93ac68bc
FB
1000void cpu_loop (CPUSPARCState *env)
1001{
878096ee 1002 CPUState *cs = CPU(sparc_env_get_cpu(env));
2cc20260
RH
1003 int trapnr;
1004 abi_long ret;
c227f099 1005 target_siginfo_t info;
3b46e624 1006
060366c5 1007 while (1) {
b040bc9c 1008 cpu_exec_start(cs);
8642c1b8 1009 trapnr = cpu_exec(cs);
b040bc9c 1010 cpu_exec_end(cs);
d148d90e 1011 process_queued_cpu_work(cs);
3b46e624 1012
20132b96
RH
1013 /* Compute PSR before exposing state. */
1014 if (env->cc_op != CC_OP_FLAGS) {
1015 cpu_get_psr(env);
1016 }
1017
060366c5 1018 switch (trapnr) {
5ef54116 1019#ifndef TARGET_SPARC64
5fafdf24 1020 case 0x88:
060366c5 1021 case 0x90:
5ef54116 1022#else
cb33da57 1023 case 0x110:
5ef54116
FB
1024 case 0x16d:
1025#endif
060366c5 1026 ret = do_syscall (env, env->gregs[1],
5fafdf24
TS
1027 env->regwptr[0], env->regwptr[1],
1028 env->regwptr[2], env->regwptr[3],
5945cfcb
PM
1029 env->regwptr[4], env->regwptr[5],
1030 0, 0);
c0bea68f
TB
1031 if (ret == -TARGET_ERESTARTSYS || ret == -TARGET_QEMU_ESIGRETURN) {
1032 break;
1033 }
2cc20260 1034 if ((abi_ulong)ret >= (abi_ulong)(-515)) {
992f48a0 1035#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
27908725
FB
1036 env->xcc |= PSR_CARRY;
1037#else
060366c5 1038 env->psr |= PSR_CARRY;
27908725 1039#endif
060366c5
FB
1040 ret = -ret;
1041 } else {
992f48a0 1042#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
27908725
FB
1043 env->xcc &= ~PSR_CARRY;
1044#else
060366c5 1045 env->psr &= ~PSR_CARRY;
27908725 1046#endif
060366c5
FB
1047 }
1048 env->regwptr[0] = ret;
1049 /* next instruction */
1050 env->pc = env->npc;
1051 env->npc = env->npc + 4;
1052 break;
1053 case 0x83: /* flush windows */
992f48a0
BS
1054#ifdef TARGET_ABI32
1055 case 0x103:
1056#endif
2623cbaf 1057 flush_windows(env);
060366c5
FB
1058 /* next instruction */
1059 env->pc = env->npc;
1060 env->npc = env->npc + 4;
1061 break;
3475187d 1062#ifndef TARGET_SPARC64
060366c5
FB
1063 case TT_WIN_OVF: /* window overflow */
1064 save_window(env);
1065 break;
1066 case TT_WIN_UNF: /* window underflow */
1067 restore_window(env);
1068 break;
61ff6f58
FB
1069 case TT_TFAULT:
1070 case TT_DFAULT:
1071 {
59f7182f 1072 info.si_signo = TARGET_SIGSEGV;
61ff6f58
FB
1073 info.si_errno = 0;
1074 /* XXX: check env->error_code */
1075 info.si_code = TARGET_SEGV_MAPERR;
1076 info._sifields._sigfault._addr = env->mmuregs[4];
9d2803f7 1077 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
61ff6f58
FB
1078 }
1079 break;
3475187d 1080#else
5ef54116
FB
1081 case TT_SPILL: /* window overflow */
1082 save_window(env);
1083 break;
1084 case TT_FILL: /* window underflow */
1085 restore_window(env);
1086 break;
7f84a729
BS
1087 case TT_TFAULT:
1088 case TT_DFAULT:
1089 {
59f7182f 1090 info.si_signo = TARGET_SIGSEGV;
7f84a729
BS
1091 info.si_errno = 0;
1092 /* XXX: check env->error_code */
1093 info.si_code = TARGET_SEGV_MAPERR;
1094 if (trapnr == TT_DFAULT)
96df2bc9 1095 info._sifields._sigfault._addr = env->dmmu.mmuregs[4];
7f84a729 1096 else
8194f35a 1097 info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
9d2803f7 1098 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
7f84a729
BS
1099 }
1100 break;
27524dc3 1101#ifndef TARGET_ABI32
5bfb56b2
BS
1102 case 0x16e:
1103 flush_windows(env);
1104 sparc64_get_context(env);
1105 break;
1106 case 0x16f:
1107 flush_windows(env);
1108 sparc64_set_context(env);
1109 break;
27524dc3 1110#endif
3475187d 1111#endif
48dc41eb
FB
1112 case EXCP_INTERRUPT:
1113 /* just indicate that signals should be handled asap */
1114 break;
75f22e4e
RH
1115 case TT_ILL_INSN:
1116 {
1117 info.si_signo = TARGET_SIGILL;
1118 info.si_errno = 0;
1119 info.si_code = TARGET_ILL_ILLOPC;
1120 info._sifields._sigfault._addr = env->pc;
9d2803f7 1121 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
75f22e4e
RH
1122 }
1123 break;
1fddef4b
FB
1124 case EXCP_DEBUG:
1125 {
1126 int sig;
1127
db6b81d4 1128 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1fddef4b
FB
1129 if (sig)
1130 {
1131 info.si_signo = sig;
1132 info.si_errno = 0;
1133 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 1134 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1fddef4b
FB
1135 }
1136 }
1137 break;
fdbc2b57
RH
1138 case EXCP_ATOMIC:
1139 cpu_exec_step_atomic(cs);
1140 break;
060366c5
FB
1141 default:
1142 printf ("Unhandled trap: 0x%x\n", trapnr);
878096ee 1143 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 1144 exit(EXIT_FAILURE);
060366c5
FB
1145 }
1146 process_pending_signals (env);
1147 }
93ac68bc
FB
1148}
1149
1150#endif
1151
67867308 1152#ifdef TARGET_PPC
05390248 1153static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
9fddaa0c 1154{
4a7428c5 1155 return cpu_get_host_ticks();
9fddaa0c 1156}
3b46e624 1157
05390248 1158uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
9fddaa0c 1159{
e3ea6529 1160 return cpu_ppc_get_tb(env);
9fddaa0c 1161}
3b46e624 1162
05390248 1163uint32_t cpu_ppc_load_tbu(CPUPPCState *env)
9fddaa0c
FB
1164{
1165 return cpu_ppc_get_tb(env) >> 32;
1166}
3b46e624 1167
05390248 1168uint64_t cpu_ppc_load_atbl(CPUPPCState *env)
9fddaa0c 1169{
b711de95 1170 return cpu_ppc_get_tb(env);
9fddaa0c 1171}
5fafdf24 1172
05390248 1173uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
9fddaa0c 1174{
a062e36c 1175 return cpu_ppc_get_tb(env) >> 32;
9fddaa0c 1176}
76a66253 1177
05390248 1178uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
76a66253
JM
1179__attribute__ (( alias ("cpu_ppc_load_tbu") ));
1180
05390248 1181uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
9fddaa0c 1182{
76a66253 1183 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
9fddaa0c 1184}
76a66253 1185
a750fc0b 1186/* XXX: to be fixed */
73b01960 1187int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
a750fc0b
JM
1188{
1189 return -1;
1190}
1191
73b01960 1192int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
a750fc0b
JM
1193{
1194 return -1;
1195}
1196
56f066bb
NF
1197static int do_store_exclusive(CPUPPCState *env)
1198{
1199 target_ulong addr;
1200 target_ulong page_addr;
e22c357b 1201 target_ulong val, val2 __attribute__((unused)) = 0;
56f066bb
NF
1202 int flags;
1203 int segv = 0;
1204
1205 addr = env->reserve_ea;
1206 page_addr = addr & TARGET_PAGE_MASK;
1207 start_exclusive();
1208 mmap_lock();
1209 flags = page_get_flags(page_addr);
1210 if ((flags & PAGE_READ) == 0) {
1211 segv = 1;
1212 } else {
1213 int reg = env->reserve_info & 0x1f;
4b1daa72 1214 int size = env->reserve_info >> 5;
56f066bb
NF
1215 int stored = 0;
1216
1217 if (addr == env->reserve_addr) {
1218 switch (size) {
1219 case 1: segv = get_user_u8(val, addr); break;
1220 case 2: segv = get_user_u16(val, addr); break;
1221 case 4: segv = get_user_u32(val, addr); break;
1222#if defined(TARGET_PPC64)
1223 case 8: segv = get_user_u64(val, addr); break;
27b95bfe
TM
1224 case 16: {
1225 segv = get_user_u64(val, addr);
1226 if (!segv) {
1227 segv = get_user_u64(val2, addr + 8);
1228 }
1229 break;
1230 }
56f066bb
NF
1231#endif
1232 default: abort();
1233 }
1234 if (!segv && val == env->reserve_val) {
1235 val = env->gpr[reg];
1236 switch (size) {
1237 case 1: segv = put_user_u8(val, addr); break;
1238 case 2: segv = put_user_u16(val, addr); break;
1239 case 4: segv = put_user_u32(val, addr); break;
1240#if defined(TARGET_PPC64)
1241 case 8: segv = put_user_u64(val, addr); break;
27b95bfe
TM
1242 case 16: {
1243 if (val2 == env->reserve_val2) {
e22c357b
DK
1244 if (msr_le) {
1245 val2 = val;
1246 val = env->gpr[reg+1];
1247 } else {
1248 val2 = env->gpr[reg+1];
1249 }
27b95bfe
TM
1250 segv = put_user_u64(val, addr);
1251 if (!segv) {
1252 segv = put_user_u64(val2, addr + 8);
1253 }
1254 }
1255 break;
1256 }
56f066bb
NF
1257#endif
1258 default: abort();
1259 }
1260 if (!segv) {
1261 stored = 1;
1262 }
1263 }
1264 }
1265 env->crf[0] = (stored << 1) | xer_so;
1266 env->reserve_addr = (target_ulong)-1;
1267 }
1268 if (!segv) {
1269 env->nip += 4;
1270 }
1271 mmap_unlock();
1272 end_exclusive();
1273 return segv;
1274}
1275
67867308
FB
1276void cpu_loop(CPUPPCState *env)
1277{
0315c31c 1278 CPUState *cs = CPU(ppc_env_get_cpu(env));
c227f099 1279 target_siginfo_t info;
61190b14 1280 int trapnr;
9e0e2f96 1281 target_ulong ret;
3b46e624 1282
67867308 1283 for(;;) {
0315c31c 1284 cpu_exec_start(cs);
8642c1b8 1285 trapnr = cpu_exec(cs);
0315c31c 1286 cpu_exec_end(cs);
d148d90e
SF
1287 process_queued_cpu_work(cs);
1288
67867308 1289 switch(trapnr) {
e1833e1f
JM
1290 case POWERPC_EXCP_NONE:
1291 /* Just go on */
67867308 1292 break;
e1833e1f 1293 case POWERPC_EXCP_CRITICAL: /* Critical input */
a47dddd7 1294 cpu_abort(cs, "Critical interrupt while in user mode. "
e1833e1f 1295 "Aborting\n");
61190b14 1296 break;
e1833e1f 1297 case POWERPC_EXCP_MCHECK: /* Machine check exception */
a47dddd7 1298 cpu_abort(cs, "Machine check exception while in user mode. "
e1833e1f
JM
1299 "Aborting\n");
1300 break;
1301 case POWERPC_EXCP_DSI: /* Data storage exception */
e1833e1f 1302 /* XXX: check this. Seems bugged */
2be0071f
FB
1303 switch (env->error_code & 0xFF000000) {
1304 case 0x40000000:
ba4a8df8 1305 case 0x42000000:
61190b14
FB
1306 info.si_signo = TARGET_SIGSEGV;
1307 info.si_errno = 0;
1308 info.si_code = TARGET_SEGV_MAPERR;
1309 break;
2be0071f 1310 case 0x04000000:
61190b14
FB
1311 info.si_signo = TARGET_SIGILL;
1312 info.si_errno = 0;
1313 info.si_code = TARGET_ILL_ILLADR;
1314 break;
2be0071f 1315 case 0x08000000:
61190b14
FB
1316 info.si_signo = TARGET_SIGSEGV;
1317 info.si_errno = 0;
1318 info.si_code = TARGET_SEGV_ACCERR;
1319 break;
61190b14
FB
1320 default:
1321 /* Let's send a regular segfault... */
e1833e1f
JM
1322 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1323 env->error_code);
61190b14
FB
1324 info.si_signo = TARGET_SIGSEGV;
1325 info.si_errno = 0;
1326 info.si_code = TARGET_SEGV_MAPERR;
1327 break;
1328 }
15e692a6 1329 info._sifields._sigfault._addr = env->spr[SPR_DAR];
9d2803f7 1330 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
67867308 1331 break;
e1833e1f 1332 case POWERPC_EXCP_ISI: /* Instruction storage exception */
e1833e1f 1333 /* XXX: check this */
2be0071f
FB
1334 switch (env->error_code & 0xFF000000) {
1335 case 0x40000000:
61190b14 1336 info.si_signo = TARGET_SIGSEGV;
67867308 1337 info.si_errno = 0;
61190b14
FB
1338 info.si_code = TARGET_SEGV_MAPERR;
1339 break;
2be0071f
FB
1340 case 0x10000000:
1341 case 0x08000000:
61190b14
FB
1342 info.si_signo = TARGET_SIGSEGV;
1343 info.si_errno = 0;
1344 info.si_code = TARGET_SEGV_ACCERR;
1345 break;
1346 default:
1347 /* Let's send a regular segfault... */
e1833e1f
JM
1348 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1349 env->error_code);
61190b14
FB
1350 info.si_signo = TARGET_SIGSEGV;
1351 info.si_errno = 0;
1352 info.si_code = TARGET_SEGV_MAPERR;
1353 break;
1354 }
1355 info._sifields._sigfault._addr = env->nip - 4;
9d2803f7 1356 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
67867308 1357 break;
e1833e1f 1358 case POWERPC_EXCP_EXTERNAL: /* External input */
a47dddd7 1359 cpu_abort(cs, "External interrupt while in user mode. "
e1833e1f
JM
1360 "Aborting\n");
1361 break;
1362 case POWERPC_EXCP_ALIGN: /* Alignment exception */
e1833e1f 1363 /* XXX: check this */
61190b14 1364 info.si_signo = TARGET_SIGBUS;
67867308 1365 info.si_errno = 0;
61190b14 1366 info.si_code = TARGET_BUS_ADRALN;
6bb9a0a9 1367 info._sifields._sigfault._addr = env->nip;
9d2803f7 1368 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
67867308 1369 break;
e1833e1f 1370 case POWERPC_EXCP_PROGRAM: /* Program exception */
9b2fadda 1371 case POWERPC_EXCP_HV_EMU: /* HV emulation */
e1833e1f 1372 /* XXX: check this */
61190b14 1373 switch (env->error_code & ~0xF) {
e1833e1f 1374 case POWERPC_EXCP_FP:
61190b14
FB
1375 info.si_signo = TARGET_SIGFPE;
1376 info.si_errno = 0;
1377 switch (env->error_code & 0xF) {
e1833e1f 1378 case POWERPC_EXCP_FP_OX:
61190b14
FB
1379 info.si_code = TARGET_FPE_FLTOVF;
1380 break;
e1833e1f 1381 case POWERPC_EXCP_FP_UX:
61190b14
FB
1382 info.si_code = TARGET_FPE_FLTUND;
1383 break;
e1833e1f
JM
1384 case POWERPC_EXCP_FP_ZX:
1385 case POWERPC_EXCP_FP_VXZDZ:
61190b14
FB
1386 info.si_code = TARGET_FPE_FLTDIV;
1387 break;
e1833e1f 1388 case POWERPC_EXCP_FP_XX:
61190b14
FB
1389 info.si_code = TARGET_FPE_FLTRES;
1390 break;
e1833e1f 1391 case POWERPC_EXCP_FP_VXSOFT:
61190b14
FB
1392 info.si_code = TARGET_FPE_FLTINV;
1393 break;
7c58044c 1394 case POWERPC_EXCP_FP_VXSNAN:
e1833e1f
JM
1395 case POWERPC_EXCP_FP_VXISI:
1396 case POWERPC_EXCP_FP_VXIDI:
1397 case POWERPC_EXCP_FP_VXIMZ:
1398 case POWERPC_EXCP_FP_VXVC:
1399 case POWERPC_EXCP_FP_VXSQRT:
1400 case POWERPC_EXCP_FP_VXCVI:
61190b14
FB
1401 info.si_code = TARGET_FPE_FLTSUB;
1402 break;
1403 default:
e1833e1f
JM
1404 EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
1405 env->error_code);
1406 break;
61190b14 1407 }
e1833e1f
JM
1408 break;
1409 case POWERPC_EXCP_INVAL:
61190b14
FB
1410 info.si_signo = TARGET_SIGILL;
1411 info.si_errno = 0;
1412 switch (env->error_code & 0xF) {
e1833e1f 1413 case POWERPC_EXCP_INVAL_INVAL:
61190b14
FB
1414 info.si_code = TARGET_ILL_ILLOPC;
1415 break;
e1833e1f 1416 case POWERPC_EXCP_INVAL_LSWX:
a750fc0b 1417 info.si_code = TARGET_ILL_ILLOPN;
61190b14 1418 break;
e1833e1f 1419 case POWERPC_EXCP_INVAL_SPR:
61190b14
FB
1420 info.si_code = TARGET_ILL_PRVREG;
1421 break;
e1833e1f 1422 case POWERPC_EXCP_INVAL_FP:
61190b14
FB
1423 info.si_code = TARGET_ILL_COPROC;
1424 break;
1425 default:
e1833e1f
JM
1426 EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
1427 env->error_code & 0xF);
61190b14
FB
1428 info.si_code = TARGET_ILL_ILLADR;
1429 break;
1430 }
1431 break;
e1833e1f 1432 case POWERPC_EXCP_PRIV:
61190b14
FB
1433 info.si_signo = TARGET_SIGILL;
1434 info.si_errno = 0;
1435 switch (env->error_code & 0xF) {
e1833e1f 1436 case POWERPC_EXCP_PRIV_OPC:
61190b14
FB
1437 info.si_code = TARGET_ILL_PRVOPC;
1438 break;
e1833e1f 1439 case POWERPC_EXCP_PRIV_REG:
61190b14 1440 info.si_code = TARGET_ILL_PRVREG;
e1833e1f 1441 break;
61190b14 1442 default:
e1833e1f
JM
1443 EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
1444 env->error_code & 0xF);
61190b14
FB
1445 info.si_code = TARGET_ILL_PRVOPC;
1446 break;
1447 }
1448 break;
e1833e1f 1449 case POWERPC_EXCP_TRAP:
a47dddd7 1450 cpu_abort(cs, "Tried to call a TRAP\n");
e1833e1f 1451 break;
61190b14
FB
1452 default:
1453 /* Should not happen ! */
a47dddd7 1454 cpu_abort(cs, "Unknown program exception (%02x)\n",
e1833e1f
JM
1455 env->error_code);
1456 break;
61190b14 1457 }
bd6fefe7 1458 info._sifields._sigfault._addr = env->nip;
9d2803f7 1459 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
67867308 1460 break;
e1833e1f 1461 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
61190b14 1462 info.si_signo = TARGET_SIGILL;
67867308 1463 info.si_errno = 0;
61190b14 1464 info.si_code = TARGET_ILL_COPROC;
bd6fefe7 1465 info._sifields._sigfault._addr = env->nip;
9d2803f7 1466 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
67867308 1467 break;
e1833e1f 1468 case POWERPC_EXCP_SYSCALL: /* System call exception */
a47dddd7 1469 cpu_abort(cs, "Syscall exception while in user mode. "
e1833e1f 1470 "Aborting\n");
61190b14 1471 break;
e1833e1f 1472 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
e1833e1f
JM
1473 info.si_signo = TARGET_SIGILL;
1474 info.si_errno = 0;
1475 info.si_code = TARGET_ILL_COPROC;
bd6fefe7 1476 info._sifields._sigfault._addr = env->nip;
9d2803f7 1477 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
61190b14 1478 break;
e1833e1f 1479 case POWERPC_EXCP_DECR: /* Decrementer exception */
a47dddd7 1480 cpu_abort(cs, "Decrementer interrupt while in user mode. "
e1833e1f 1481 "Aborting\n");
61190b14 1482 break;
e1833e1f 1483 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
a47dddd7 1484 cpu_abort(cs, "Fix interval timer interrupt while in user mode. "
e1833e1f
JM
1485 "Aborting\n");
1486 break;
1487 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
a47dddd7 1488 cpu_abort(cs, "Watchdog timer interrupt while in user mode. "
e1833e1f
JM
1489 "Aborting\n");
1490 break;
1491 case POWERPC_EXCP_DTLB: /* Data TLB error */
a47dddd7 1492 cpu_abort(cs, "Data TLB exception while in user mode. "
e1833e1f
JM
1493 "Aborting\n");
1494 break;
1495 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
a47dddd7 1496 cpu_abort(cs, "Instruction TLB exception while in user mode. "
e1833e1f
JM
1497 "Aborting\n");
1498 break;
e1833e1f 1499 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
e1833e1f
JM
1500 info.si_signo = TARGET_SIGILL;
1501 info.si_errno = 0;
1502 info.si_code = TARGET_ILL_COPROC;
bd6fefe7 1503 info._sifields._sigfault._addr = env->nip;
9d2803f7 1504 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
e1833e1f
JM
1505 break;
1506 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
a47dddd7 1507 cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
e1833e1f
JM
1508 break;
1509 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
a47dddd7 1510 cpu_abort(cs, "Embedded floating-point round IRQ not handled\n");
e1833e1f
JM
1511 break;
1512 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
a47dddd7 1513 cpu_abort(cs, "Performance monitor exception not handled\n");
e1833e1f
JM
1514 break;
1515 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
a47dddd7 1516 cpu_abort(cs, "Doorbell interrupt while in user mode. "
e1833e1f
JM
1517 "Aborting\n");
1518 break;
1519 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
a47dddd7 1520 cpu_abort(cs, "Doorbell critical interrupt while in user mode. "
e1833e1f
JM
1521 "Aborting\n");
1522 break;
1523 case POWERPC_EXCP_RESET: /* System reset exception */
a47dddd7 1524 cpu_abort(cs, "Reset interrupt while in user mode. "
e1833e1f
JM
1525 "Aborting\n");
1526 break;
e1833e1f 1527 case POWERPC_EXCP_DSEG: /* Data segment exception */
a47dddd7 1528 cpu_abort(cs, "Data segment exception while in user mode. "
e1833e1f
JM
1529 "Aborting\n");
1530 break;
1531 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
a47dddd7 1532 cpu_abort(cs, "Instruction segment exception "
e1833e1f
JM
1533 "while in user mode. Aborting\n");
1534 break;
e85e7c6e 1535 /* PowerPC 64 with hypervisor mode support */
e1833e1f 1536 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
a47dddd7 1537 cpu_abort(cs, "Hypervisor decrementer interrupt "
e1833e1f
JM
1538 "while in user mode. Aborting\n");
1539 break;
e1833e1f
JM
1540 case POWERPC_EXCP_TRACE: /* Trace exception */
1541 /* Nothing to do:
1542 * we use this exception to emulate step-by-step execution mode.
1543 */
1544 break;
e85e7c6e 1545 /* PowerPC 64 with hypervisor mode support */
e1833e1f 1546 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
a47dddd7 1547 cpu_abort(cs, "Hypervisor data storage exception "
e1833e1f
JM
1548 "while in user mode. Aborting\n");
1549 break;
1550 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
a47dddd7 1551 cpu_abort(cs, "Hypervisor instruction storage exception "
e1833e1f
JM
1552 "while in user mode. Aborting\n");
1553 break;
1554 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
a47dddd7 1555 cpu_abort(cs, "Hypervisor data segment exception "
e1833e1f
JM
1556 "while in user mode. Aborting\n");
1557 break;
1558 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
a47dddd7 1559 cpu_abort(cs, "Hypervisor instruction segment exception "
e1833e1f
JM
1560 "while in user mode. Aborting\n");
1561 break;
e1833e1f 1562 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
e1833e1f
JM
1563 info.si_signo = TARGET_SIGILL;
1564 info.si_errno = 0;
1565 info.si_code = TARGET_ILL_COPROC;
bd6fefe7 1566 info._sifields._sigfault._addr = env->nip;
9d2803f7 1567 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
e1833e1f
JM
1568 break;
1569 case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
a47dddd7 1570 cpu_abort(cs, "Programmable interval timer interrupt "
e1833e1f
JM
1571 "while in user mode. Aborting\n");
1572 break;
1573 case POWERPC_EXCP_IO: /* IO error exception */
a47dddd7 1574 cpu_abort(cs, "IO error exception while in user mode. "
e1833e1f
JM
1575 "Aborting\n");
1576 break;
1577 case POWERPC_EXCP_RUNM: /* Run mode exception */
a47dddd7 1578 cpu_abort(cs, "Run mode exception while in user mode. "
e1833e1f
JM
1579 "Aborting\n");
1580 break;
1581 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
a47dddd7 1582 cpu_abort(cs, "Emulation trap exception not handled\n");
e1833e1f
JM
1583 break;
1584 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
a47dddd7 1585 cpu_abort(cs, "Instruction fetch TLB exception "
e1833e1f
JM
1586 "while in user-mode. Aborting");
1587 break;
1588 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
a47dddd7 1589 cpu_abort(cs, "Data load TLB exception while in user-mode. "
e1833e1f
JM
1590 "Aborting");
1591 break;
1592 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
a47dddd7 1593 cpu_abort(cs, "Data store TLB exception while in user-mode. "
e1833e1f
JM
1594 "Aborting");
1595 break;
1596 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
a47dddd7 1597 cpu_abort(cs, "Floating-point assist exception not handled\n");
e1833e1f
JM
1598 break;
1599 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
a47dddd7 1600 cpu_abort(cs, "Instruction address breakpoint exception "
e1833e1f
JM
1601 "not handled\n");
1602 break;
1603 case POWERPC_EXCP_SMI: /* System management interrupt */
a47dddd7 1604 cpu_abort(cs, "System management interrupt while in user mode. "
e1833e1f
JM
1605 "Aborting\n");
1606 break;
1607 case POWERPC_EXCP_THERM: /* Thermal interrupt */
a47dddd7 1608 cpu_abort(cs, "Thermal interrupt interrupt while in user mode. "
e1833e1f
JM
1609 "Aborting\n");
1610 break;
1611 case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
a47dddd7 1612 cpu_abort(cs, "Performance monitor exception not handled\n");
e1833e1f
JM
1613 break;
1614 case POWERPC_EXCP_VPUA: /* Vector assist exception */
a47dddd7 1615 cpu_abort(cs, "Vector assist exception not handled\n");
e1833e1f
JM
1616 break;
1617 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
a47dddd7 1618 cpu_abort(cs, "Soft patch exception not handled\n");
e1833e1f
JM
1619 break;
1620 case POWERPC_EXCP_MAINT: /* Maintenance exception */
a47dddd7 1621 cpu_abort(cs, "Maintenance exception while in user mode. "
e1833e1f
JM
1622 "Aborting\n");
1623 break;
1624 case POWERPC_EXCP_STOP: /* stop translation */
1625 /* We did invalidate the instruction cache. Go on */
1626 break;
1627 case POWERPC_EXCP_BRANCH: /* branch instruction: */
1628 /* We just stopped because of a branch. Go on */
1629 break;
1630 case POWERPC_EXCP_SYSCALL_USER:
1631 /* system call in user-mode emulation */
1632 /* WARNING:
1633 * PPC ABI uses overflow flag in cr0 to signal an error
1634 * in syscalls.
1635 */
e1833e1f 1636 env->crf[0] &= ~0x1;
2635531f 1637 env->nip += 4;
e1833e1f
JM
1638 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
1639 env->gpr[5], env->gpr[6], env->gpr[7],
5945cfcb 1640 env->gpr[8], 0, 0);
6db9d00e 1641 if (ret == -TARGET_ERESTARTSYS) {
2635531f 1642 env->nip -= 4;
6db9d00e
TB
1643 break;
1644 }
9e0e2f96 1645 if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
bcd4933a
NF
1646 /* Returning from a successful sigreturn syscall.
1647 Avoid corrupting register state. */
1648 break;
1649 }
9e0e2f96 1650 if (ret > (target_ulong)(-515)) {
e1833e1f
JM
1651 env->crf[0] |= 0x1;
1652 ret = -ret;
61190b14 1653 }
e1833e1f 1654 env->gpr[3] = ret;
e1833e1f 1655 break;
56f066bb
NF
1656 case POWERPC_EXCP_STCX:
1657 if (do_store_exclusive(env)) {
1658 info.si_signo = TARGET_SIGSEGV;
1659 info.si_errno = 0;
1660 info.si_code = TARGET_SEGV_MAPERR;
1661 info._sifields._sigfault._addr = env->nip;
9d2803f7 1662 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
56f066bb
NF
1663 }
1664 break;
71f75756
AJ
1665 case EXCP_DEBUG:
1666 {
1667 int sig;
1668
db6b81d4 1669 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
71f75756
AJ
1670 if (sig) {
1671 info.si_signo = sig;
1672 info.si_errno = 0;
1673 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 1674 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
71f75756
AJ
1675 }
1676 }
1677 break;
56ba31ff
JM
1678 case EXCP_INTERRUPT:
1679 /* just indicate that signals should be handled asap */
1680 break;
fdbc2b57
RH
1681 case EXCP_ATOMIC:
1682 cpu_exec_step_atomic(cs);
1683 break;
e1833e1f 1684 default:
8223f345 1685 cpu_abort(cs, "Unknown exception 0x%x. Aborting\n", trapnr);
e1833e1f 1686 break;
67867308
FB
1687 }
1688 process_pending_signals(env);
1689 }
1690}
1691#endif
1692
048f6b4d
FB
1693#ifdef TARGET_MIPS
1694
ff4f7382
RH
1695# ifdef TARGET_ABI_MIPSO32
1696# define MIPS_SYS(name, args) args,
048f6b4d 1697static const uint8_t mips_syscall_args[] = {
29fb0f25 1698 MIPS_SYS(sys_syscall , 8) /* 4000 */
048f6b4d
FB
1699 MIPS_SYS(sys_exit , 1)
1700 MIPS_SYS(sys_fork , 0)
1701 MIPS_SYS(sys_read , 3)
1702 MIPS_SYS(sys_write , 3)
1703 MIPS_SYS(sys_open , 3) /* 4005 */
1704 MIPS_SYS(sys_close , 1)
1705 MIPS_SYS(sys_waitpid , 3)
1706 MIPS_SYS(sys_creat , 2)
1707 MIPS_SYS(sys_link , 2)
1708 MIPS_SYS(sys_unlink , 1) /* 4010 */
1709 MIPS_SYS(sys_execve , 0)
1710 MIPS_SYS(sys_chdir , 1)
1711 MIPS_SYS(sys_time , 1)
1712 MIPS_SYS(sys_mknod , 3)
1713 MIPS_SYS(sys_chmod , 2) /* 4015 */
1714 MIPS_SYS(sys_lchown , 3)
1715 MIPS_SYS(sys_ni_syscall , 0)
1716 MIPS_SYS(sys_ni_syscall , 0) /* was sys_stat */
1717 MIPS_SYS(sys_lseek , 3)
1718 MIPS_SYS(sys_getpid , 0) /* 4020 */
1719 MIPS_SYS(sys_mount , 5)
868e34d7 1720 MIPS_SYS(sys_umount , 1)
048f6b4d
FB
1721 MIPS_SYS(sys_setuid , 1)
1722 MIPS_SYS(sys_getuid , 0)
1723 MIPS_SYS(sys_stime , 1) /* 4025 */
1724 MIPS_SYS(sys_ptrace , 4)
1725 MIPS_SYS(sys_alarm , 1)
1726 MIPS_SYS(sys_ni_syscall , 0) /* was sys_fstat */
1727 MIPS_SYS(sys_pause , 0)
1728 MIPS_SYS(sys_utime , 2) /* 4030 */
1729 MIPS_SYS(sys_ni_syscall , 0)
1730 MIPS_SYS(sys_ni_syscall , 0)
1731 MIPS_SYS(sys_access , 2)
1732 MIPS_SYS(sys_nice , 1)
1733 MIPS_SYS(sys_ni_syscall , 0) /* 4035 */
1734 MIPS_SYS(sys_sync , 0)
1735 MIPS_SYS(sys_kill , 2)
1736 MIPS_SYS(sys_rename , 2)
1737 MIPS_SYS(sys_mkdir , 2)
1738 MIPS_SYS(sys_rmdir , 1) /* 4040 */
1739 MIPS_SYS(sys_dup , 1)
1740 MIPS_SYS(sys_pipe , 0)
1741 MIPS_SYS(sys_times , 1)
1742 MIPS_SYS(sys_ni_syscall , 0)
1743 MIPS_SYS(sys_brk , 1) /* 4045 */
1744 MIPS_SYS(sys_setgid , 1)
1745 MIPS_SYS(sys_getgid , 0)
1746 MIPS_SYS(sys_ni_syscall , 0) /* was signal(2) */
1747 MIPS_SYS(sys_geteuid , 0)
1748 MIPS_SYS(sys_getegid , 0) /* 4050 */
1749 MIPS_SYS(sys_acct , 0)
868e34d7 1750 MIPS_SYS(sys_umount2 , 2)
048f6b4d
FB
1751 MIPS_SYS(sys_ni_syscall , 0)
1752 MIPS_SYS(sys_ioctl , 3)
1753 MIPS_SYS(sys_fcntl , 3) /* 4055 */
1754 MIPS_SYS(sys_ni_syscall , 2)
1755 MIPS_SYS(sys_setpgid , 2)
1756 MIPS_SYS(sys_ni_syscall , 0)
1757 MIPS_SYS(sys_olduname , 1)
1758 MIPS_SYS(sys_umask , 1) /* 4060 */
1759 MIPS_SYS(sys_chroot , 1)
1760 MIPS_SYS(sys_ustat , 2)
1761 MIPS_SYS(sys_dup2 , 2)
1762 MIPS_SYS(sys_getppid , 0)
1763 MIPS_SYS(sys_getpgrp , 0) /* 4065 */
1764 MIPS_SYS(sys_setsid , 0)
1765 MIPS_SYS(sys_sigaction , 3)
1766 MIPS_SYS(sys_sgetmask , 0)
1767 MIPS_SYS(sys_ssetmask , 1)
1768 MIPS_SYS(sys_setreuid , 2) /* 4070 */
1769 MIPS_SYS(sys_setregid , 2)
1770 MIPS_SYS(sys_sigsuspend , 0)
1771 MIPS_SYS(sys_sigpending , 1)
1772 MIPS_SYS(sys_sethostname , 2)
1773 MIPS_SYS(sys_setrlimit , 2) /* 4075 */
1774 MIPS_SYS(sys_getrlimit , 2)
1775 MIPS_SYS(sys_getrusage , 2)
1776 MIPS_SYS(sys_gettimeofday, 2)
1777 MIPS_SYS(sys_settimeofday, 2)
1778 MIPS_SYS(sys_getgroups , 2) /* 4080 */
1779 MIPS_SYS(sys_setgroups , 2)
1780 MIPS_SYS(sys_ni_syscall , 0) /* old_select */
1781 MIPS_SYS(sys_symlink , 2)
1782 MIPS_SYS(sys_ni_syscall , 0) /* was sys_lstat */
1783 MIPS_SYS(sys_readlink , 3) /* 4085 */
1784 MIPS_SYS(sys_uselib , 1)
1785 MIPS_SYS(sys_swapon , 2)
1786 MIPS_SYS(sys_reboot , 3)
1787 MIPS_SYS(old_readdir , 3)
1788 MIPS_SYS(old_mmap , 6) /* 4090 */
1789 MIPS_SYS(sys_munmap , 2)
1790 MIPS_SYS(sys_truncate , 2)
1791 MIPS_SYS(sys_ftruncate , 2)
1792 MIPS_SYS(sys_fchmod , 2)
1793 MIPS_SYS(sys_fchown , 3) /* 4095 */
1794 MIPS_SYS(sys_getpriority , 2)
1795 MIPS_SYS(sys_setpriority , 3)
1796 MIPS_SYS(sys_ni_syscall , 0)
1797 MIPS_SYS(sys_statfs , 2)
1798 MIPS_SYS(sys_fstatfs , 2) /* 4100 */
1799 MIPS_SYS(sys_ni_syscall , 0) /* was ioperm(2) */
1800 MIPS_SYS(sys_socketcall , 2)
1801 MIPS_SYS(sys_syslog , 3)
1802 MIPS_SYS(sys_setitimer , 3)
1803 MIPS_SYS(sys_getitimer , 2) /* 4105 */
1804 MIPS_SYS(sys_newstat , 2)
1805 MIPS_SYS(sys_newlstat , 2)
1806 MIPS_SYS(sys_newfstat , 2)
1807 MIPS_SYS(sys_uname , 1)
1808 MIPS_SYS(sys_ni_syscall , 0) /* 4110 was iopl(2) */
1809 MIPS_SYS(sys_vhangup , 0)
1810 MIPS_SYS(sys_ni_syscall , 0) /* was sys_idle() */
1811 MIPS_SYS(sys_ni_syscall , 0) /* was sys_vm86 */
1812 MIPS_SYS(sys_wait4 , 4)
1813 MIPS_SYS(sys_swapoff , 1) /* 4115 */
1814 MIPS_SYS(sys_sysinfo , 1)
1815 MIPS_SYS(sys_ipc , 6)
1816 MIPS_SYS(sys_fsync , 1)
1817 MIPS_SYS(sys_sigreturn , 0)
18113962 1818 MIPS_SYS(sys_clone , 6) /* 4120 */
048f6b4d
FB
1819 MIPS_SYS(sys_setdomainname, 2)
1820 MIPS_SYS(sys_newuname , 1)
1821 MIPS_SYS(sys_ni_syscall , 0) /* sys_modify_ldt */
1822 MIPS_SYS(sys_adjtimex , 1)
1823 MIPS_SYS(sys_mprotect , 3) /* 4125 */
1824 MIPS_SYS(sys_sigprocmask , 3)
1825 MIPS_SYS(sys_ni_syscall , 0) /* was create_module */
1826 MIPS_SYS(sys_init_module , 5)
1827 MIPS_SYS(sys_delete_module, 1)
1828 MIPS_SYS(sys_ni_syscall , 0) /* 4130 was get_kernel_syms */
1829 MIPS_SYS(sys_quotactl , 0)
1830 MIPS_SYS(sys_getpgid , 1)
1831 MIPS_SYS(sys_fchdir , 1)
1832 MIPS_SYS(sys_bdflush , 2)
1833 MIPS_SYS(sys_sysfs , 3) /* 4135 */
1834 MIPS_SYS(sys_personality , 1)
1835 MIPS_SYS(sys_ni_syscall , 0) /* for afs_syscall */
1836 MIPS_SYS(sys_setfsuid , 1)
1837 MIPS_SYS(sys_setfsgid , 1)
1838 MIPS_SYS(sys_llseek , 5) /* 4140 */
1839 MIPS_SYS(sys_getdents , 3)
1840 MIPS_SYS(sys_select , 5)
1841 MIPS_SYS(sys_flock , 2)
1842 MIPS_SYS(sys_msync , 3)
1843 MIPS_SYS(sys_readv , 3) /* 4145 */
1844 MIPS_SYS(sys_writev , 3)
1845 MIPS_SYS(sys_cacheflush , 3)
1846 MIPS_SYS(sys_cachectl , 3)
1847 MIPS_SYS(sys_sysmips , 4)
1848 MIPS_SYS(sys_ni_syscall , 0) /* 4150 */
1849 MIPS_SYS(sys_getsid , 1)
1850 MIPS_SYS(sys_fdatasync , 0)
1851 MIPS_SYS(sys_sysctl , 1)
1852 MIPS_SYS(sys_mlock , 2)
1853 MIPS_SYS(sys_munlock , 2) /* 4155 */
1854 MIPS_SYS(sys_mlockall , 1)
1855 MIPS_SYS(sys_munlockall , 0)
1856 MIPS_SYS(sys_sched_setparam, 2)
1857 MIPS_SYS(sys_sched_getparam, 2)
1858 MIPS_SYS(sys_sched_setscheduler, 3) /* 4160 */
1859 MIPS_SYS(sys_sched_getscheduler, 1)
1860 MIPS_SYS(sys_sched_yield , 0)
1861 MIPS_SYS(sys_sched_get_priority_max, 1)
1862 MIPS_SYS(sys_sched_get_priority_min, 1)
1863 MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */
1864 MIPS_SYS(sys_nanosleep, 2)
b0932e06 1865 MIPS_SYS(sys_mremap , 5)
048f6b4d
FB
1866 MIPS_SYS(sys_accept , 3)
1867 MIPS_SYS(sys_bind , 3)
1868 MIPS_SYS(sys_connect , 3) /* 4170 */
1869 MIPS_SYS(sys_getpeername , 3)
1870 MIPS_SYS(sys_getsockname , 3)
1871 MIPS_SYS(sys_getsockopt , 5)
1872 MIPS_SYS(sys_listen , 2)
1873 MIPS_SYS(sys_recv , 4) /* 4175 */
1874 MIPS_SYS(sys_recvfrom , 6)
1875 MIPS_SYS(sys_recvmsg , 3)
1876 MIPS_SYS(sys_send , 4)
1877 MIPS_SYS(sys_sendmsg , 3)
1878 MIPS_SYS(sys_sendto , 6) /* 4180 */
1879 MIPS_SYS(sys_setsockopt , 5)
1880 MIPS_SYS(sys_shutdown , 2)
1881 MIPS_SYS(sys_socket , 3)
1882 MIPS_SYS(sys_socketpair , 4)
1883 MIPS_SYS(sys_setresuid , 3) /* 4185 */
1884 MIPS_SYS(sys_getresuid , 3)
1885 MIPS_SYS(sys_ni_syscall , 0) /* was sys_query_module */
1886 MIPS_SYS(sys_poll , 3)
1887 MIPS_SYS(sys_nfsservctl , 3)
1888 MIPS_SYS(sys_setresgid , 3) /* 4190 */
1889 MIPS_SYS(sys_getresgid , 3)
1890 MIPS_SYS(sys_prctl , 5)
1891 MIPS_SYS(sys_rt_sigreturn, 0)
1892 MIPS_SYS(sys_rt_sigaction, 4)
1893 MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
1894 MIPS_SYS(sys_rt_sigpending, 2)
1895 MIPS_SYS(sys_rt_sigtimedwait, 4)
1896 MIPS_SYS(sys_rt_sigqueueinfo, 3)
1897 MIPS_SYS(sys_rt_sigsuspend, 0)
1898 MIPS_SYS(sys_pread64 , 6) /* 4200 */
1899 MIPS_SYS(sys_pwrite64 , 6)
1900 MIPS_SYS(sys_chown , 3)
1901 MIPS_SYS(sys_getcwd , 2)
1902 MIPS_SYS(sys_capget , 2)
1903 MIPS_SYS(sys_capset , 2) /* 4205 */
053ebb27 1904 MIPS_SYS(sys_sigaltstack , 2)
048f6b4d
FB
1905 MIPS_SYS(sys_sendfile , 4)
1906 MIPS_SYS(sys_ni_syscall , 0)
1907 MIPS_SYS(sys_ni_syscall , 0)
1908 MIPS_SYS(sys_mmap2 , 6) /* 4210 */
1909 MIPS_SYS(sys_truncate64 , 4)
1910 MIPS_SYS(sys_ftruncate64 , 4)
1911 MIPS_SYS(sys_stat64 , 2)
1912 MIPS_SYS(sys_lstat64 , 2)
1913 MIPS_SYS(sys_fstat64 , 2) /* 4215 */
1914 MIPS_SYS(sys_pivot_root , 2)
1915 MIPS_SYS(sys_mincore , 3)
1916 MIPS_SYS(sys_madvise , 3)
1917 MIPS_SYS(sys_getdents64 , 3)
1918 MIPS_SYS(sys_fcntl64 , 3) /* 4220 */
1919 MIPS_SYS(sys_ni_syscall , 0)
1920 MIPS_SYS(sys_gettid , 0)
1921 MIPS_SYS(sys_readahead , 5)
1922 MIPS_SYS(sys_setxattr , 5)
1923 MIPS_SYS(sys_lsetxattr , 5) /* 4225 */
1924 MIPS_SYS(sys_fsetxattr , 5)
1925 MIPS_SYS(sys_getxattr , 4)
1926 MIPS_SYS(sys_lgetxattr , 4)
1927 MIPS_SYS(sys_fgetxattr , 4)
1928 MIPS_SYS(sys_listxattr , 3) /* 4230 */
1929 MIPS_SYS(sys_llistxattr , 3)
1930 MIPS_SYS(sys_flistxattr , 3)
1931 MIPS_SYS(sys_removexattr , 2)
1932 MIPS_SYS(sys_lremovexattr, 2)
1933 MIPS_SYS(sys_fremovexattr, 2) /* 4235 */
1934 MIPS_SYS(sys_tkill , 2)
1935 MIPS_SYS(sys_sendfile64 , 5)
43be1343 1936 MIPS_SYS(sys_futex , 6)
048f6b4d
FB
1937 MIPS_SYS(sys_sched_setaffinity, 3)
1938 MIPS_SYS(sys_sched_getaffinity, 3) /* 4240 */
1939 MIPS_SYS(sys_io_setup , 2)
1940 MIPS_SYS(sys_io_destroy , 1)
1941 MIPS_SYS(sys_io_getevents, 5)
1942 MIPS_SYS(sys_io_submit , 3)
1943 MIPS_SYS(sys_io_cancel , 3) /* 4245 */
1944 MIPS_SYS(sys_exit_group , 1)
1945 MIPS_SYS(sys_lookup_dcookie, 3)
1946 MIPS_SYS(sys_epoll_create, 1)
1947 MIPS_SYS(sys_epoll_ctl , 4)
1948 MIPS_SYS(sys_epoll_wait , 3) /* 4250 */
1949 MIPS_SYS(sys_remap_file_pages, 5)
1950 MIPS_SYS(sys_set_tid_address, 1)
1951 MIPS_SYS(sys_restart_syscall, 0)
1952 MIPS_SYS(sys_fadvise64_64, 7)
1953 MIPS_SYS(sys_statfs64 , 3) /* 4255 */
1954 MIPS_SYS(sys_fstatfs64 , 2)
1955 MIPS_SYS(sys_timer_create, 3)
1956 MIPS_SYS(sys_timer_settime, 4)
1957 MIPS_SYS(sys_timer_gettime, 2)
1958 MIPS_SYS(sys_timer_getoverrun, 1) /* 4260 */
1959 MIPS_SYS(sys_timer_delete, 1)
1960 MIPS_SYS(sys_clock_settime, 2)
1961 MIPS_SYS(sys_clock_gettime, 2)
1962 MIPS_SYS(sys_clock_getres, 2)
1963 MIPS_SYS(sys_clock_nanosleep, 4) /* 4265 */
1964 MIPS_SYS(sys_tgkill , 3)
1965 MIPS_SYS(sys_utimes , 2)
1966 MIPS_SYS(sys_mbind , 4)
1967 MIPS_SYS(sys_ni_syscall , 0) /* sys_get_mempolicy */
1968 MIPS_SYS(sys_ni_syscall , 0) /* 4270 sys_set_mempolicy */
1969 MIPS_SYS(sys_mq_open , 4)
1970 MIPS_SYS(sys_mq_unlink , 1)
1971 MIPS_SYS(sys_mq_timedsend, 5)
1972 MIPS_SYS(sys_mq_timedreceive, 5)
1973 MIPS_SYS(sys_mq_notify , 2) /* 4275 */
1974 MIPS_SYS(sys_mq_getsetattr, 3)
1975 MIPS_SYS(sys_ni_syscall , 0) /* sys_vserver */
1976 MIPS_SYS(sys_waitid , 4)
1977 MIPS_SYS(sys_ni_syscall , 0) /* available, was setaltroot */
1978 MIPS_SYS(sys_add_key , 5)
388bb21a 1979 MIPS_SYS(sys_request_key, 4)
048f6b4d 1980 MIPS_SYS(sys_keyctl , 5)
6f5b89a0 1981 MIPS_SYS(sys_set_thread_area, 1)
388bb21a
TS
1982 MIPS_SYS(sys_inotify_init, 0)
1983 MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
1984 MIPS_SYS(sys_inotify_rm_watch, 2)
1985 MIPS_SYS(sys_migrate_pages, 4)
1986 MIPS_SYS(sys_openat, 4)
1987 MIPS_SYS(sys_mkdirat, 3)
1988 MIPS_SYS(sys_mknodat, 4) /* 4290 */
1989 MIPS_SYS(sys_fchownat, 5)
1990 MIPS_SYS(sys_futimesat, 3)
1991 MIPS_SYS(sys_fstatat64, 4)
1992 MIPS_SYS(sys_unlinkat, 3)
1993 MIPS_SYS(sys_renameat, 4) /* 4295 */
1994 MIPS_SYS(sys_linkat, 5)
1995 MIPS_SYS(sys_symlinkat, 3)
1996 MIPS_SYS(sys_readlinkat, 4)
1997 MIPS_SYS(sys_fchmodat, 3)
1998 MIPS_SYS(sys_faccessat, 3) /* 4300 */
1999 MIPS_SYS(sys_pselect6, 6)
2000 MIPS_SYS(sys_ppoll, 5)
2001 MIPS_SYS(sys_unshare, 1)
b0932e06 2002 MIPS_SYS(sys_splice, 6)
388bb21a
TS
2003 MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
2004 MIPS_SYS(sys_tee, 4)
2005 MIPS_SYS(sys_vmsplice, 4)
2006 MIPS_SYS(sys_move_pages, 6)
2007 MIPS_SYS(sys_set_robust_list, 2)
2008 MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
2009 MIPS_SYS(sys_kexec_load, 4)
2010 MIPS_SYS(sys_getcpu, 3)
2011 MIPS_SYS(sys_epoll_pwait, 6)
2012 MIPS_SYS(sys_ioprio_set, 3)
2013 MIPS_SYS(sys_ioprio_get, 2)
d979e8eb
PM
2014 MIPS_SYS(sys_utimensat, 4)
2015 MIPS_SYS(sys_signalfd, 3)
2016 MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
2017 MIPS_SYS(sys_eventfd, 1)
2018 MIPS_SYS(sys_fallocate, 6) /* 4320 */
2019 MIPS_SYS(sys_timerfd_create, 2)
2020 MIPS_SYS(sys_timerfd_gettime, 2)
2021 MIPS_SYS(sys_timerfd_settime, 4)
2022 MIPS_SYS(sys_signalfd4, 4)
2023 MIPS_SYS(sys_eventfd2, 2) /* 4325 */
2024 MIPS_SYS(sys_epoll_create1, 1)
2025 MIPS_SYS(sys_dup3, 3)
2026 MIPS_SYS(sys_pipe2, 2)
2027 MIPS_SYS(sys_inotify_init1, 1)
2e6eeb67
AM
2028 MIPS_SYS(sys_preadv, 5) /* 4330 */
2029 MIPS_SYS(sys_pwritev, 5)
d979e8eb
PM
2030 MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
2031 MIPS_SYS(sys_perf_event_open, 5)
2032 MIPS_SYS(sys_accept4, 4)
2033 MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
2034 MIPS_SYS(sys_fanotify_init, 2)
2035 MIPS_SYS(sys_fanotify_mark, 6)
2036 MIPS_SYS(sys_prlimit64, 4)
2037 MIPS_SYS(sys_name_to_handle_at, 5)
2038 MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
2039 MIPS_SYS(sys_clock_adjtime, 2)
2040 MIPS_SYS(sys_syncfs, 1)
2e6eeb67
AM
2041 MIPS_SYS(sys_sendmmsg, 4)
2042 MIPS_SYS(sys_setns, 2)
2043 MIPS_SYS(sys_process_vm_readv, 6) /* 345 */
2044 MIPS_SYS(sys_process_vm_writev, 6)
2045 MIPS_SYS(sys_kcmp, 5)
2046 MIPS_SYS(sys_finit_module, 3)
2047 MIPS_SYS(sys_sched_setattr, 2)
2048 MIPS_SYS(sys_sched_getattr, 3) /* 350 */
2049 MIPS_SYS(sys_renameat2, 5)
2050 MIPS_SYS(sys_seccomp, 3)
2051 MIPS_SYS(sys_getrandom, 3)
2052 MIPS_SYS(sys_memfd_create, 2)
2053 MIPS_SYS(sys_bpf, 3) /* 355 */
2054 MIPS_SYS(sys_execveat, 5)
2055 MIPS_SYS(sys_userfaultfd, 1)
2056 MIPS_SYS(sys_membarrier, 2)
2057 MIPS_SYS(sys_mlock2, 3)
2058 MIPS_SYS(sys_copy_file_range, 6) /* 360 */
2059 MIPS_SYS(sys_preadv2, 6)
2060 MIPS_SYS(sys_pwritev2, 6)
048f6b4d 2061};
ff4f7382
RH
2062# undef MIPS_SYS
2063# endif /* O32 */
048f6b4d 2064
590bc601
PB
2065static int do_store_exclusive(CPUMIPSState *env)
2066{
2067 target_ulong addr;
2068 target_ulong page_addr;
2069 target_ulong val;
2070 int flags;
2071 int segv = 0;
2072 int reg;
2073 int d;
2074
5499b6ff 2075 addr = env->lladdr;
590bc601
PB
2076 page_addr = addr & TARGET_PAGE_MASK;
2077 start_exclusive();
2078 mmap_lock();
2079 flags = page_get_flags(page_addr);
2080 if ((flags & PAGE_READ) == 0) {
2081 segv = 1;
2082 } else {
2083 reg = env->llreg & 0x1f;
2084 d = (env->llreg & 0x20) != 0;
2085 if (d) {
2086 segv = get_user_s64(val, addr);
2087 } else {
2088 segv = get_user_s32(val, addr);
2089 }
2090 if (!segv) {
2091 if (val != env->llval) {
2092 env->active_tc.gpr[reg] = 0;
2093 } else {
2094 if (d) {
2095 segv = put_user_u64(env->llnewval, addr);
2096 } else {
2097 segv = put_user_u32(env->llnewval, addr);
2098 }
2099 if (!segv) {
2100 env->active_tc.gpr[reg] = 1;
2101 }
2102 }
2103 }
2104 }
5499b6ff 2105 env->lladdr = -1;
590bc601
PB
2106 if (!segv) {
2107 env->active_tc.PC += 4;
2108 }
2109 mmap_unlock();
2110 end_exclusive();
2111 return segv;
2112}
2113
54b2f42c
MI
2114/* Break codes */
2115enum {
2116 BRK_OVERFLOW = 6,
2117 BRK_DIVZERO = 7
2118};
2119
2120static int do_break(CPUMIPSState *env, target_siginfo_t *info,
2121 unsigned int code)
2122{
2123 int ret = -1;
2124
2125 switch (code) {
2126 case BRK_OVERFLOW:
2127 case BRK_DIVZERO:
2128 info->si_signo = TARGET_SIGFPE;
2129 info->si_errno = 0;
2130 info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
9d2803f7 2131 queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
54b2f42c
MI
2132 ret = 0;
2133 break;
2134 default:
b51910ba
PJ
2135 info->si_signo = TARGET_SIGTRAP;
2136 info->si_errno = 0;
9d2803f7 2137 queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
b51910ba 2138 ret = 0;
54b2f42c
MI
2139 break;
2140 }
2141
2142 return ret;
2143}
2144
048f6b4d
FB
2145void cpu_loop(CPUMIPSState *env)
2146{
0315c31c 2147 CPUState *cs = CPU(mips_env_get_cpu(env));
c227f099 2148 target_siginfo_t info;
ff4f7382
RH
2149 int trapnr;
2150 abi_long ret;
2151# ifdef TARGET_ABI_MIPSO32
048f6b4d 2152 unsigned int syscall_num;
ff4f7382 2153# endif
048f6b4d
FB
2154
2155 for(;;) {
0315c31c 2156 cpu_exec_start(cs);
8642c1b8 2157 trapnr = cpu_exec(cs);
0315c31c 2158 cpu_exec_end(cs);
d148d90e
SF
2159 process_queued_cpu_work(cs);
2160
048f6b4d
FB
2161 switch(trapnr) {
2162 case EXCP_SYSCALL:
b5dc7732 2163 env->active_tc.PC += 4;
ff4f7382
RH
2164# ifdef TARGET_ABI_MIPSO32
2165 syscall_num = env->active_tc.gpr[2] - 4000;
388bb21a 2166 if (syscall_num >= sizeof(mips_syscall_args)) {
7c2f6157 2167 ret = -TARGET_ENOSYS;
388bb21a
TS
2168 } else {
2169 int nb_args;
992f48a0
BS
2170 abi_ulong sp_reg;
2171 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
388bb21a
TS
2172
2173 nb_args = mips_syscall_args[syscall_num];
b5dc7732 2174 sp_reg = env->active_tc.gpr[29];
388bb21a
TS
2175 switch (nb_args) {
2176 /* these arguments are taken from the stack */
94c19610
ACH
2177 case 8:
2178 if ((ret = get_user_ual(arg8, sp_reg + 28)) != 0) {
2179 goto done_syscall;
2180 }
2181 case 7:
2182 if ((ret = get_user_ual(arg7, sp_reg + 24)) != 0) {
2183 goto done_syscall;
2184 }
2185 case 6:
2186 if ((ret = get_user_ual(arg6, sp_reg + 20)) != 0) {
2187 goto done_syscall;
2188 }
2189 case 5:
2190 if ((ret = get_user_ual(arg5, sp_reg + 16)) != 0) {
2191 goto done_syscall;
2192 }
388bb21a
TS
2193 default:
2194 break;
048f6b4d 2195 }
b5dc7732
TS
2196 ret = do_syscall(env, env->active_tc.gpr[2],
2197 env->active_tc.gpr[4],
2198 env->active_tc.gpr[5],
2199 env->active_tc.gpr[6],
2200 env->active_tc.gpr[7],
5945cfcb 2201 arg5, arg6, arg7, arg8);
388bb21a 2202 }
94c19610 2203done_syscall:
ff4f7382
RH
2204# else
2205 ret = do_syscall(env, env->active_tc.gpr[2],
2206 env->active_tc.gpr[4], env->active_tc.gpr[5],
2207 env->active_tc.gpr[6], env->active_tc.gpr[7],
2208 env->active_tc.gpr[8], env->active_tc.gpr[9],
2209 env->active_tc.gpr[10], env->active_tc.gpr[11]);
2210# endif /* O32 */
2eb3ae27
TB
2211 if (ret == -TARGET_ERESTARTSYS) {
2212 env->active_tc.PC -= 4;
2213 break;
2214 }
0b1bcb00
PB
2215 if (ret == -TARGET_QEMU_ESIGRETURN) {
2216 /* Returning from a successful sigreturn syscall.
2217 Avoid clobbering register state. */
2218 break;
2219 }
ff4f7382 2220 if ((abi_ulong)ret >= (abi_ulong)-1133) {
b5dc7732 2221 env->active_tc.gpr[7] = 1; /* error flag */
388bb21a
TS
2222 ret = -ret;
2223 } else {
b5dc7732 2224 env->active_tc.gpr[7] = 0; /* error flag */
048f6b4d 2225 }
b5dc7732 2226 env->active_tc.gpr[2] = ret;
048f6b4d 2227 break;
ca7c2b1b
TS
2228 case EXCP_TLBL:
2229 case EXCP_TLBS:
e6e5bd2d
WT
2230 case EXCP_AdEL:
2231 case EXCP_AdES:
e4474235
PB
2232 info.si_signo = TARGET_SIGSEGV;
2233 info.si_errno = 0;
2234 /* XXX: check env->error_code */
2235 info.si_code = TARGET_SEGV_MAPERR;
2236 info._sifields._sigfault._addr = env->CP0_BadVAddr;
9d2803f7 2237 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
e4474235 2238 break;
6900e84b 2239 case EXCP_CpU:
048f6b4d 2240 case EXCP_RI:
bc1ad2de
FB
2241 info.si_signo = TARGET_SIGILL;
2242 info.si_errno = 0;
2243 info.si_code = 0;
9d2803f7 2244 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
048f6b4d 2245 break;
106ec879
FB
2246 case EXCP_INTERRUPT:
2247 /* just indicate that signals should be handled asap */
2248 break;
d08b2a28
PB
2249 case EXCP_DEBUG:
2250 {
2251 int sig;
2252
db6b81d4 2253 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
d08b2a28
PB
2254 if (sig)
2255 {
2256 info.si_signo = sig;
2257 info.si_errno = 0;
2258 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 2259 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
d08b2a28
PB
2260 }
2261 }
2262 break;
590bc601
PB
2263 case EXCP_SC:
2264 if (do_store_exclusive(env)) {
2265 info.si_signo = TARGET_SIGSEGV;
2266 info.si_errno = 0;
2267 info.si_code = TARGET_SEGV_MAPERR;
2268 info._sifields._sigfault._addr = env->active_tc.PC;
9d2803f7 2269 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
590bc601
PB
2270 }
2271 break;
853c3240
JL
2272 case EXCP_DSPDIS:
2273 info.si_signo = TARGET_SIGILL;
2274 info.si_errno = 0;
2275 info.si_code = TARGET_ILL_ILLOPC;
9d2803f7 2276 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
853c3240 2277 break;
54b2f42c
MI
2278 /* The code below was inspired by the MIPS Linux kernel trap
2279 * handling code in arch/mips/kernel/traps.c.
2280 */
2281 case EXCP_BREAK:
2282 {
2283 abi_ulong trap_instr;
2284 unsigned int code;
2285
a0333817
KCY
2286 if (env->hflags & MIPS_HFLAG_M16) {
2287 if (env->insn_flags & ASE_MICROMIPS) {
2288 /* microMIPS mode */
1308c464
KCY
2289 ret = get_user_u16(trap_instr, env->active_tc.PC);
2290 if (ret != 0) {
2291 goto error;
2292 }
a0333817 2293
1308c464
KCY
2294 if ((trap_instr >> 10) == 0x11) {
2295 /* 16-bit instruction */
2296 code = trap_instr & 0xf;
2297 } else {
2298 /* 32-bit instruction */
2299 abi_ulong instr_lo;
2300
2301 ret = get_user_u16(instr_lo,
2302 env->active_tc.PC + 2);
2303 if (ret != 0) {
2304 goto error;
2305 }
2306 trap_instr = (trap_instr << 16) | instr_lo;
2307 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2308 /* Unfortunately, microMIPS also suffers from
2309 the old assembler bug... */
2310 if (code >= (1 << 10)) {
2311 code >>= 10;
2312 }
2313 }
a0333817
KCY
2314 } else {
2315 /* MIPS16e mode */
2316 ret = get_user_u16(trap_instr, env->active_tc.PC);
2317 if (ret != 0) {
2318 goto error;
2319 }
2320 code = (trap_instr >> 6) & 0x3f;
a0333817
KCY
2321 }
2322 } else {
f01a361b 2323 ret = get_user_u32(trap_instr, env->active_tc.PC);
1308c464
KCY
2324 if (ret != 0) {
2325 goto error;
2326 }
54b2f42c 2327
1308c464
KCY
2328 /* As described in the original Linux kernel code, the
2329 * below checks on 'code' are to work around an old
2330 * assembly bug.
2331 */
2332 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2333 if (code >= (1 << 10)) {
2334 code >>= 10;
2335 }
54b2f42c
MI
2336 }
2337
2338 if (do_break(env, &info, code) != 0) {
2339 goto error;
2340 }
2341 }
2342 break;
2343 case EXCP_TRAP:
2344 {
2345 abi_ulong trap_instr;
2346 unsigned int code = 0;
2347
a0333817
KCY
2348 if (env->hflags & MIPS_HFLAG_M16) {
2349 /* microMIPS mode */
2350 abi_ulong instr[2];
2351
2352 ret = get_user_u16(instr[0], env->active_tc.PC) ||
2353 get_user_u16(instr[1], env->active_tc.PC + 2);
2354
2355 trap_instr = (instr[0] << 16) | instr[1];
2356 } else {
f01a361b 2357 ret = get_user_u32(trap_instr, env->active_tc.PC);
a0333817
KCY
2358 }
2359
54b2f42c
MI
2360 if (ret != 0) {
2361 goto error;
2362 }
2363
2364 /* The immediate versions don't provide a code. */
2365 if (!(trap_instr & 0xFC000000)) {
a0333817
KCY
2366 if (env->hflags & MIPS_HFLAG_M16) {
2367 /* microMIPS mode */
2368 code = ((trap_instr >> 12) & ((1 << 4) - 1));
2369 } else {
2370 code = ((trap_instr >> 6) & ((1 << 10) - 1));
2371 }
54b2f42c
MI
2372 }
2373
2374 if (do_break(env, &info, code) != 0) {
2375 goto error;
2376 }
2377 }
2378 break;
fdbc2b57
RH
2379 case EXCP_ATOMIC:
2380 cpu_exec_step_atomic(cs);
2381 break;
048f6b4d 2382 default:
54b2f42c 2383error:
120a9848 2384 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
048f6b4d
FB
2385 abort();
2386 }
2387 process_pending_signals(env);
2388 }
2389}
2390#endif
2391
a0a839b6
MV
2392#ifdef TARGET_NIOS2
2393
2394void cpu_loop(CPUNios2State *env)
2395{
2396 CPUState *cs = ENV_GET_CPU(env);
2397 Nios2CPU *cpu = NIOS2_CPU(cs);
2398 target_siginfo_t info;
2399 int trapnr, gdbsig, ret;
2400
2401 for (;;) {
2402 cpu_exec_start(cs);
2403 trapnr = cpu_exec(cs);
2404 cpu_exec_end(cs);
2405 gdbsig = 0;
2406
2407 switch (trapnr) {
2408 case EXCP_INTERRUPT:
2409 /* just indicate that signals should be handled asap */
2410 break;
2411 case EXCP_TRAP:
2412 if (env->regs[R_AT] == 0) {
2413 abi_long ret;
2414 qemu_log_mask(CPU_LOG_INT, "\nSyscall\n");
2415
2416 ret = do_syscall(env, env->regs[2],
2417 env->regs[4], env->regs[5], env->regs[6],
2418 env->regs[7], env->regs[8], env->regs[9],
2419 0, 0);
2420
2421 if (env->regs[2] == 0) { /* FIXME: syscall 0 workaround */
2422 ret = 0;
2423 }
2424
2425 env->regs[2] = abs(ret);
2426 /* Return value is 0..4096 */
2427 env->regs[7] = (ret > 0xfffffffffffff000ULL);
2428 env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
2429 env->regs[CR_STATUS] &= ~0x3;
2430 env->regs[R_EA] = env->regs[R_PC] + 4;
2431 env->regs[R_PC] += 4;
2432 break;
2433 } else {
2434 qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
2435
2436 env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
2437 env->regs[CR_STATUS] &= ~0x3;
2438 env->regs[R_EA] = env->regs[R_PC] + 4;
2439 env->regs[R_PC] = cpu->exception_addr;
2440
2441 gdbsig = TARGET_SIGTRAP;
2442 break;
2443 }
2444 case 0xaa:
2445 switch (env->regs[R_PC]) {
2446 /*case 0x1000:*/ /* TODO:__kuser_helper_version */
2447 case 0x1004: /* __kuser_cmpxchg */
2448 start_exclusive();
2449 if (env->regs[4] & 0x3) {
2450 goto kuser_fail;
2451 }
2452 ret = get_user_u32(env->regs[2], env->regs[4]);
2453 if (ret) {
2454 end_exclusive();
2455 goto kuser_fail;
2456 }
2457 env->regs[2] -= env->regs[5];
2458 if (env->regs[2] == 0) {
2459 put_user_u32(env->regs[6], env->regs[4]);
2460 }
2461 end_exclusive();
2462 env->regs[R_PC] = env->regs[R_RA];
2463 break;
2464 /*case 0x1040:*/ /* TODO:__kuser_sigtramp */
2465 default:
2466 ;
2467kuser_fail:
2468 info.si_signo = TARGET_SIGSEGV;
2469 info.si_errno = 0;
2470 /* TODO: check env->error_code */
2471 info.si_code = TARGET_SEGV_MAPERR;
2472 info._sifields._sigfault._addr = env->regs[R_PC];
2473 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2474 }
2475 break;
2476 default:
2477 EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
2478 trapnr);
2479 gdbsig = TARGET_SIGILL;
2480 break;
2481 }
2482 if (gdbsig) {
2483 gdb_handlesig(cs, gdbsig);
2484 if (gdbsig != TARGET_SIGTRAP) {
2485 exit(EXIT_FAILURE);
2486 }
2487 }
2488
2489 process_pending_signals(env);
2490 }
2491}
2492
2493#endif /* TARGET_NIOS2 */
2494
d962783e
JL
2495#ifdef TARGET_OPENRISC
2496
2497void cpu_loop(CPUOpenRISCState *env)
2498{
878096ee 2499 CPUState *cs = CPU(openrisc_env_get_cpu(env));
a0adc417 2500 int trapnr;
7fe7231a 2501 abi_long ret;
a0adc417 2502 target_siginfo_t info;
d962783e
JL
2503
2504 for (;;) {
b040bc9c 2505 cpu_exec_start(cs);
8642c1b8 2506 trapnr = cpu_exec(cs);
b040bc9c 2507 cpu_exec_end(cs);
d148d90e 2508 process_queued_cpu_work(cs);
d962783e
JL
2509
2510 switch (trapnr) {
d962783e
JL
2511 case EXCP_SYSCALL:
2512 env->pc += 4; /* 0xc00; */
7fe7231a 2513 ret = do_syscall(env,
d89e71e8
SH
2514 cpu_get_gpr(env, 11), /* return value */
2515 cpu_get_gpr(env, 3), /* r3 - r7 are params */
2516 cpu_get_gpr(env, 4),
2517 cpu_get_gpr(env, 5),
2518 cpu_get_gpr(env, 6),
2519 cpu_get_gpr(env, 7),
2520 cpu_get_gpr(env, 8), 0, 0);
7fe7231a
TB
2521 if (ret == -TARGET_ERESTARTSYS) {
2522 env->pc -= 4;
2523 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
d89e71e8 2524 cpu_set_gpr(env, 11, ret);
7fe7231a 2525 }
d962783e 2526 break;
a0adc417
RH
2527 case EXCP_DPF:
2528 case EXCP_IPF:
2529 case EXCP_RANGE:
2530 info.si_signo = TARGET_SIGSEGV;
2531 info.si_errno = 0;
2532 info.si_code = TARGET_SEGV_MAPERR;
2533 info._sifields._sigfault._addr = env->pc;
2534 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2535 break;
2536 case EXCP_ALIGN:
2537 info.si_signo = TARGET_SIGBUS;
2538 info.si_errno = 0;
2539 info.si_code = TARGET_BUS_ADRALN;
2540 info._sifields._sigfault._addr = env->pc;
2541 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2542 break;
2543 case EXCP_ILLEGAL:
2544 info.si_signo = TARGET_SIGILL;
2545 info.si_errno = 0;
2546 info.si_code = TARGET_ILL_ILLOPC;
2547 info._sifields._sigfault._addr = env->pc;
2548 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2549 break;
d962783e 2550 case EXCP_FPE:
a0adc417
RH
2551 info.si_signo = TARGET_SIGFPE;
2552 info.si_errno = 0;
2553 info.si_code = 0;
2554 info._sifields._sigfault._addr = env->pc;
2555 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
d962783e 2556 break;
a0adc417
RH
2557 case EXCP_INTERRUPT:
2558 /* We processed the pending cpu work above. */
d962783e 2559 break;
a0adc417
RH
2560 case EXCP_DEBUG:
2561 trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
2562 if (trapnr) {
2563 info.si_signo = trapnr;
2564 info.si_errno = 0;
2565 info.si_code = TARGET_TRAP_BRKPT;
2566 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2567 }
d962783e 2568 break;
fdbc2b57
RH
2569 case EXCP_ATOMIC:
2570 cpu_exec_step_atomic(cs);
2571 break;
d962783e 2572 default:
a0adc417 2573 g_assert_not_reached();
d962783e 2574 }
d962783e
JL
2575 process_pending_signals(env);
2576 }
2577}
2578
2579#endif /* TARGET_OPENRISC */
2580
fdf9b3e8 2581#ifdef TARGET_SH4
05390248 2582void cpu_loop(CPUSH4State *env)
fdf9b3e8 2583{
878096ee 2584 CPUState *cs = CPU(sh_env_get_cpu(env));
fdf9b3e8 2585 int trapnr, ret;
c227f099 2586 target_siginfo_t info;
3b46e624 2587
fdf9b3e8 2588 while (1) {
f85da308
RH
2589 bool arch_interrupt = true;
2590
b040bc9c 2591 cpu_exec_start(cs);
8642c1b8 2592 trapnr = cpu_exec(cs);
b040bc9c 2593 cpu_exec_end(cs);
d148d90e 2594 process_queued_cpu_work(cs);
3b46e624 2595
fdf9b3e8
FB
2596 switch (trapnr) {
2597 case 0x160:
0b6d3ae0 2598 env->pc += 2;
5fafdf24
TS
2599 ret = do_syscall(env,
2600 env->gregs[3],
2601 env->gregs[4],
2602 env->gregs[5],
2603 env->gregs[6],
2604 env->gregs[7],
2605 env->gregs[0],
5945cfcb
PM
2606 env->gregs[1],
2607 0, 0);
ba412496
TB
2608 if (ret == -TARGET_ERESTARTSYS) {
2609 env->pc -= 2;
2610 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2611 env->gregs[0] = ret;
2612 }
fdf9b3e8 2613 break;
c3b5bc8a
TS
2614 case EXCP_INTERRUPT:
2615 /* just indicate that signals should be handled asap */
2616 break;
355fb23d
PB
2617 case EXCP_DEBUG:
2618 {
2619 int sig;
2620
db6b81d4 2621 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
f85da308 2622 if (sig) {
355fb23d
PB
2623 info.si_signo = sig;
2624 info.si_errno = 0;
2625 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 2626 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
f85da308
RH
2627 } else {
2628 arch_interrupt = false;
2629 }
355fb23d
PB
2630 }
2631 break;
c3b5bc8a
TS
2632 case 0xa0:
2633 case 0xc0:
a86b3c64 2634 info.si_signo = TARGET_SIGSEGV;
c3b5bc8a
TS
2635 info.si_errno = 0;
2636 info.si_code = TARGET_SEGV_MAPERR;
2637 info._sifields._sigfault._addr = env->tea;
9d2803f7 2638 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
c3b5bc8a 2639 break;
fdbc2b57
RH
2640 case EXCP_ATOMIC:
2641 cpu_exec_step_atomic(cs);
f85da308 2642 arch_interrupt = false;
fdbc2b57 2643 break;
fdf9b3e8
FB
2644 default:
2645 printf ("Unhandled trap: 0x%x\n", trapnr);
878096ee 2646 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 2647 exit(EXIT_FAILURE);
fdf9b3e8
FB
2648 }
2649 process_pending_signals (env);
f85da308
RH
2650
2651 /* Most of the traps imply an exception or interrupt, which
2652 implies an REI instruction has been executed. Which means
2653 that LDST (aka LOK_ADDR) should be cleared. But there are
2654 a few exceptions for traps internal to QEMU. */
2655 if (arch_interrupt) {
2656 env->lock_addr = -1;
2657 }
fdf9b3e8
FB
2658 }
2659}
2660#endif
2661
48733d19 2662#ifdef TARGET_CRIS
05390248 2663void cpu_loop(CPUCRISState *env)
48733d19 2664{
878096ee 2665 CPUState *cs = CPU(cris_env_get_cpu(env));
48733d19 2666 int trapnr, ret;
c227f099 2667 target_siginfo_t info;
48733d19
TS
2668
2669 while (1) {
b040bc9c 2670 cpu_exec_start(cs);
8642c1b8 2671 trapnr = cpu_exec(cs);
b040bc9c 2672 cpu_exec_end(cs);
d148d90e
SF
2673 process_queued_cpu_work(cs);
2674
48733d19
TS
2675 switch (trapnr) {
2676 case 0xaa:
2677 {
a86b3c64 2678 info.si_signo = TARGET_SIGSEGV;
48733d19
TS
2679 info.si_errno = 0;
2680 /* XXX: check env->error_code */
2681 info.si_code = TARGET_SEGV_MAPERR;
e00c1e71 2682 info._sifields._sigfault._addr = env->pregs[PR_EDA];
9d2803f7 2683 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
48733d19
TS
2684 }
2685 break;
b6d3abda
EI
2686 case EXCP_INTERRUPT:
2687 /* just indicate that signals should be handled asap */
2688 break;
48733d19
TS
2689 case EXCP_BREAK:
2690 ret = do_syscall(env,
2691 env->regs[9],
2692 env->regs[10],
2693 env->regs[11],
2694 env->regs[12],
2695 env->regs[13],
2696 env->pregs[7],
5945cfcb
PM
2697 env->pregs[11],
2698 0, 0);
62050865
TB
2699 if (ret == -TARGET_ERESTARTSYS) {
2700 env->pc -= 2;
2701 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2702 env->regs[10] = ret;
2703 }
48733d19
TS
2704 break;
2705 case EXCP_DEBUG:
2706 {
2707 int sig;
2708
db6b81d4 2709 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
48733d19
TS
2710 if (sig)
2711 {
2712 info.si_signo = sig;
2713 info.si_errno = 0;
2714 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 2715 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
48733d19
TS
2716 }
2717 }
2718 break;
fdbc2b57
RH
2719 case EXCP_ATOMIC:
2720 cpu_exec_step_atomic(cs);
2721 break;
48733d19
TS
2722 default:
2723 printf ("Unhandled trap: 0x%x\n", trapnr);
878096ee 2724 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 2725 exit(EXIT_FAILURE);
48733d19
TS
2726 }
2727 process_pending_signals (env);
2728 }
2729}
2730#endif
2731
b779e29e 2732#ifdef TARGET_MICROBLAZE
05390248 2733void cpu_loop(CPUMBState *env)
b779e29e 2734{
878096ee 2735 CPUState *cs = CPU(mb_env_get_cpu(env));
b779e29e 2736 int trapnr, ret;
c227f099 2737 target_siginfo_t info;
b779e29e
EI
2738
2739 while (1) {
b040bc9c 2740 cpu_exec_start(cs);
8642c1b8 2741 trapnr = cpu_exec(cs);
b040bc9c 2742 cpu_exec_end(cs);
d148d90e
SF
2743 process_queued_cpu_work(cs);
2744
b779e29e
EI
2745 switch (trapnr) {
2746 case 0xaa:
2747 {
a86b3c64 2748 info.si_signo = TARGET_SIGSEGV;
b779e29e
EI
2749 info.si_errno = 0;
2750 /* XXX: check env->error_code */
2751 info.si_code = TARGET_SEGV_MAPERR;
2752 info._sifields._sigfault._addr = 0;
9d2803f7 2753 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
b779e29e
EI
2754 }
2755 break;
2756 case EXCP_INTERRUPT:
2757 /* just indicate that signals should be handled asap */
2758 break;
2759 case EXCP_BREAK:
2760 /* Return address is 4 bytes after the call. */
2761 env->regs[14] += 4;
d7dce494 2762 env->sregs[SR_PC] = env->regs[14];
b779e29e
EI
2763 ret = do_syscall(env,
2764 env->regs[12],
2765 env->regs[5],
2766 env->regs[6],
2767 env->regs[7],
2768 env->regs[8],
2769 env->regs[9],
5945cfcb
PM
2770 env->regs[10],
2771 0, 0);
4134ecfe
TB
2772 if (ret == -TARGET_ERESTARTSYS) {
2773 /* Wind back to before the syscall. */
2774 env->sregs[SR_PC] -= 4;
2775 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2776 env->regs[3] = ret;
2777 }
d7749ab7
PM
2778 /* All syscall exits result in guest r14 being equal to the
2779 * PC we return to, because the kernel syscall exit "rtbd" does
2780 * this. (This is true even for sigreturn(); note that r14 is
2781 * not a userspace-usable register, as the kernel may clobber it
2782 * at any point.)
2783 */
2784 env->regs[14] = env->sregs[SR_PC];
b779e29e 2785 break;
b76da7e3
EI
2786 case EXCP_HW_EXCP:
2787 env->regs[17] = env->sregs[SR_PC] + 4;
2788 if (env->iflags & D_FLAG) {
2789 env->sregs[SR_ESR] |= 1 << 12;
2790 env->sregs[SR_PC] -= 4;
b4916d7b 2791 /* FIXME: if branch was immed, replay the imm as well. */
b76da7e3
EI
2792 }
2793
2794 env->iflags &= ~(IMM_FLAG | D_FLAG);
2795
2796 switch (env->sregs[SR_ESR] & 31) {
22a78d64 2797 case ESR_EC_DIVZERO:
a86b3c64 2798 info.si_signo = TARGET_SIGFPE;
22a78d64
EI
2799 info.si_errno = 0;
2800 info.si_code = TARGET_FPE_FLTDIV;
2801 info._sifields._sigfault._addr = 0;
9d2803f7 2802 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
22a78d64 2803 break;
b76da7e3 2804 case ESR_EC_FPU:
a86b3c64 2805 info.si_signo = TARGET_SIGFPE;
b76da7e3
EI
2806 info.si_errno = 0;
2807 if (env->sregs[SR_FSR] & FSR_IO) {
2808 info.si_code = TARGET_FPE_FLTINV;
2809 }
2810 if (env->sregs[SR_FSR] & FSR_DZ) {
2811 info.si_code = TARGET_FPE_FLTDIV;
2812 }
2813 info._sifields._sigfault._addr = 0;
9d2803f7 2814 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
b76da7e3
EI
2815 break;
2816 default:
2817 printf ("Unhandled hw-exception: 0x%x\n",
2e42d52d 2818 env->sregs[SR_ESR] & ESR_EC_MASK);
878096ee 2819 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 2820 exit(EXIT_FAILURE);
b76da7e3
EI
2821 break;
2822 }
2823 break;
b779e29e
EI
2824 case EXCP_DEBUG:
2825 {
2826 int sig;
2827
db6b81d4 2828 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
b779e29e
EI
2829 if (sig)
2830 {
2831 info.si_signo = sig;
2832 info.si_errno = 0;
2833 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 2834 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
b779e29e
EI
2835 }
2836 }
2837 break;
fdbc2b57
RH
2838 case EXCP_ATOMIC:
2839 cpu_exec_step_atomic(cs);
2840 break;
b779e29e
EI
2841 default:
2842 printf ("Unhandled trap: 0x%x\n", trapnr);
878096ee 2843 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 2844 exit(EXIT_FAILURE);
b779e29e
EI
2845 }
2846 process_pending_signals (env);
2847 }
2848}
2849#endif
2850
e6e5906b
PB
2851#ifdef TARGET_M68K
2852
2853void cpu_loop(CPUM68KState *env)
2854{
878096ee 2855 CPUState *cs = CPU(m68k_env_get_cpu(env));
e6e5906b
PB
2856 int trapnr;
2857 unsigned int n;
c227f099 2858 target_siginfo_t info;
0429a971 2859 TaskState *ts = cs->opaque;
3b46e624 2860
e6e5906b 2861 for(;;) {
b040bc9c 2862 cpu_exec_start(cs);
8642c1b8 2863 trapnr = cpu_exec(cs);
b040bc9c 2864 cpu_exec_end(cs);
d148d90e
SF
2865 process_queued_cpu_work(cs);
2866
e6e5906b
PB
2867 switch(trapnr) {
2868 case EXCP_ILLEGAL:
2869 {
2870 if (ts->sim_syscalls) {
2871 uint16_t nr;
d8d5119c 2872 get_user_u16(nr, env->pc + 2);
e6e5906b
PB
2873 env->pc += 4;
2874 do_m68k_simcall(env, nr);
2875 } else {
2876 goto do_sigill;
2877 }
2878 }
2879 break;
a87295e8 2880 case EXCP_HALT_INSN:
e6e5906b 2881 /* Semihosing syscall. */
a87295e8 2882 env->pc += 4;
e6e5906b
PB
2883 do_m68k_semihosting(env, env->dregs[0]);
2884 break;
2885 case EXCP_LINEA:
2886 case EXCP_LINEF:
2887 case EXCP_UNSUPPORTED:
2888 do_sigill:
a86b3c64 2889 info.si_signo = TARGET_SIGILL;
e6e5906b
PB
2890 info.si_errno = 0;
2891 info.si_code = TARGET_ILL_ILLOPN;
2892 info._sifields._sigfault._addr = env->pc;
0ccb9c1d
LV
2893 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2894 break;
8bf6cbaf
LV
2895 case EXCP_CHK:
2896 info.si_signo = TARGET_SIGFPE;
2897 info.si_errno = 0;
2898 info.si_code = TARGET_FPE_INTOVF;
2899 info._sifields._sigfault._addr = env->pc;
2900 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2901 break;
0ccb9c1d
LV
2902 case EXCP_DIV0:
2903 info.si_signo = TARGET_SIGFPE;
2904 info.si_errno = 0;
2905 info.si_code = TARGET_FPE_INTDIV;
2906 info._sifields._sigfault._addr = env->pc;
9d2803f7 2907 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
e6e5906b
PB
2908 break;
2909 case EXCP_TRAP0:
2910 {
7ccb84a9 2911 abi_long ret;
e6e5906b
PB
2912 ts->sim_syscalls = 0;
2913 n = env->dregs[0];
2914 env->pc += 2;
7ccb84a9
TB
2915 ret = do_syscall(env,
2916 n,
2917 env->dregs[1],
2918 env->dregs[2],
2919 env->dregs[3],
2920 env->dregs[4],
2921 env->dregs[5],
2922 env->aregs[0],
2923 0, 0);
2924 if (ret == -TARGET_ERESTARTSYS) {
2925 env->pc -= 2;
2926 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2927 env->dregs[0] = ret;
2928 }
e6e5906b
PB
2929 }
2930 break;
2931 case EXCP_INTERRUPT:
2932 /* just indicate that signals should be handled asap */
2933 break;
2934 case EXCP_ACCESS:
2935 {
a86b3c64 2936 info.si_signo = TARGET_SIGSEGV;
e6e5906b
PB
2937 info.si_errno = 0;
2938 /* XXX: check env->error_code */
2939 info.si_code = TARGET_SEGV_MAPERR;
2940 info._sifields._sigfault._addr = env->mmu.ar;
9d2803f7 2941 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
e6e5906b
PB
2942 }
2943 break;
2944 case EXCP_DEBUG:
2945 {
2946 int sig;
2947
db6b81d4 2948 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
e6e5906b
PB
2949 if (sig)
2950 {
2951 info.si_signo = sig;
2952 info.si_errno = 0;
2953 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 2954 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
e6e5906b
PB
2955 }
2956 }
2957 break;
fdbc2b57
RH
2958 case EXCP_ATOMIC:
2959 cpu_exec_step_atomic(cs);
2960 break;
e6e5906b 2961 default:
120a9848 2962 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
e6e5906b
PB
2963 abort();
2964 }
2965 process_pending_signals(env);
2966 }
2967}
2968#endif /* TARGET_M68K */
2969
7a3148a9 2970#ifdef TARGET_ALPHA
05390248 2971void cpu_loop(CPUAlphaState *env)
7a3148a9 2972{
878096ee 2973 CPUState *cs = CPU(alpha_env_get_cpu(env));
e96efcfc 2974 int trapnr;
c227f099 2975 target_siginfo_t info;
6049f4f8 2976 abi_long sysret;
3b46e624 2977
7a3148a9 2978 while (1) {
bcd2625d
RH
2979 bool arch_interrupt = true;
2980
b040bc9c 2981 cpu_exec_start(cs);
8642c1b8 2982 trapnr = cpu_exec(cs);
b040bc9c 2983 cpu_exec_end(cs);
d148d90e 2984 process_queued_cpu_work(cs);
3b46e624 2985
7a3148a9
JM
2986 switch (trapnr) {
2987 case EXCP_RESET:
2988 fprintf(stderr, "Reset requested. Exit\n");
4d1275c2 2989 exit(EXIT_FAILURE);
7a3148a9
JM
2990 break;
2991 case EXCP_MCHK:
2992 fprintf(stderr, "Machine check exception. Exit\n");
4d1275c2 2993 exit(EXIT_FAILURE);
7a3148a9 2994 break;
07b6c13b
RH
2995 case EXCP_SMP_INTERRUPT:
2996 case EXCP_CLK_INTERRUPT:
2997 case EXCP_DEV_INTERRUPT:
5fafdf24 2998 fprintf(stderr, "External interrupt. Exit\n");
4d1275c2 2999 exit(EXIT_FAILURE);
7a3148a9 3000 break;
07b6c13b 3001 case EXCP_MMFAULT:
6049f4f8
RH
3002 info.si_signo = TARGET_SIGSEGV;
3003 info.si_errno = 0;
129d8aa5 3004 info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
0be1d07c 3005 ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
129d8aa5 3006 info._sifields._sigfault._addr = env->trap_arg0;
9d2803f7 3007 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
7a3148a9 3008 break;
7a3148a9 3009 case EXCP_UNALIGN:
6049f4f8
RH
3010 info.si_signo = TARGET_SIGBUS;
3011 info.si_errno = 0;
3012 info.si_code = TARGET_BUS_ADRALN;
129d8aa5 3013 info._sifields._sigfault._addr = env->trap_arg0;
9d2803f7 3014 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
7a3148a9
JM
3015 break;
3016 case EXCP_OPCDEC:
6049f4f8
RH
3017 do_sigill:
3018 info.si_signo = TARGET_SIGILL;
3019 info.si_errno = 0;
3020 info.si_code = TARGET_ILL_ILLOPC;
3021 info._sifields._sigfault._addr = env->pc;
9d2803f7 3022 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
7a3148a9 3023 break;
07b6c13b 3024 case EXCP_ARITH:
07b6c13b
RH
3025 info.si_signo = TARGET_SIGFPE;
3026 info.si_errno = 0;
3027 info.si_code = TARGET_FPE_FLTINV;
3028 info._sifields._sigfault._addr = env->pc;
9d2803f7 3029 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
07b6c13b 3030 break;
7a3148a9 3031 case EXCP_FEN:
6049f4f8 3032 /* No-op. Linux simply re-enables the FPU. */
7a3148a9 3033 break;
07b6c13b 3034 case EXCP_CALL_PAL:
07b6c13b 3035 switch (env->error_code) {
6049f4f8
RH
3036 case 0x80:
3037 /* BPT */
3038 info.si_signo = TARGET_SIGTRAP;
3039 info.si_errno = 0;
3040 info.si_code = TARGET_TRAP_BRKPT;
3041 info._sifields._sigfault._addr = env->pc;
9d2803f7 3042 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
6049f4f8
RH
3043 break;
3044 case 0x81:
3045 /* BUGCHK */
3046 info.si_signo = TARGET_SIGTRAP;
3047 info.si_errno = 0;
3048 info.si_code = 0;
3049 info._sifields._sigfault._addr = env->pc;
9d2803f7 3050 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
6049f4f8
RH
3051 break;
3052 case 0x83:
3053 /* CALLSYS */
3054 trapnr = env->ir[IR_V0];
3055 sysret = do_syscall(env, trapnr,
3056 env->ir[IR_A0], env->ir[IR_A1],
3057 env->ir[IR_A2], env->ir[IR_A3],
5945cfcb
PM
3058 env->ir[IR_A4], env->ir[IR_A5],
3059 0, 0);
338c858c
TB
3060 if (sysret == -TARGET_ERESTARTSYS) {
3061 env->pc -= 4;
3062 break;
3063 }
3064 if (sysret == -TARGET_QEMU_ESIGRETURN) {
a5b3b13b
RH
3065 break;
3066 }
3067 /* Syscall writes 0 to V0 to bypass error check, similar
0e141977
RH
3068 to how this is handled internal to Linux kernel.
3069 (Ab)use trapnr temporarily as boolean indicating error. */
3070 trapnr = (env->ir[IR_V0] != 0 && sysret < 0);
3071 env->ir[IR_V0] = (trapnr ? -sysret : sysret);
3072 env->ir[IR_A3] = trapnr;
6049f4f8
RH
3073 break;
3074 case 0x86:
3075 /* IMB */
3076 /* ??? We can probably elide the code using page_unprotect
3077 that is checking for self-modifying code. Instead we
3078 could simply call tb_flush here. Until we work out the
3079 changes required to turn off the extra write protection,
3080 this can be a no-op. */
3081 break;
3082 case 0x9E:
3083 /* RDUNIQUE */
3084 /* Handled in the translator for usermode. */
3085 abort();
3086 case 0x9F:
3087 /* WRUNIQUE */
3088 /* Handled in the translator for usermode. */
3089 abort();
3090 case 0xAA:
3091 /* GENTRAP */
3092 info.si_signo = TARGET_SIGFPE;
3093 switch (env->ir[IR_A0]) {
3094 case TARGET_GEN_INTOVF:
3095 info.si_code = TARGET_FPE_INTOVF;
3096 break;
3097 case TARGET_GEN_INTDIV:
3098 info.si_code = TARGET_FPE_INTDIV;
3099 break;
3100 case TARGET_GEN_FLTOVF:
3101 info.si_code = TARGET_FPE_FLTOVF;
3102 break;
3103 case TARGET_GEN_FLTUND:
3104 info.si_code = TARGET_FPE_FLTUND;
3105 break;
3106 case TARGET_GEN_FLTINV:
3107 info.si_code = TARGET_FPE_FLTINV;
3108 break;
3109 case TARGET_GEN_FLTINE:
3110 info.si_code = TARGET_FPE_FLTRES;
3111 break;
3112 case TARGET_GEN_ROPRAND:
3113 info.si_code = 0;
3114 break;
3115 default:
3116 info.si_signo = TARGET_SIGTRAP;
3117 info.si_code = 0;
3118 break;
3119 }
3120 info.si_errno = 0;
3121 info._sifields._sigfault._addr = env->pc;
9d2803f7 3122 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
6049f4f8
RH
3123 break;
3124 default:
3125 goto do_sigill;
3126 }
7a3148a9 3127 break;
7a3148a9 3128 case EXCP_DEBUG:
db6b81d4 3129 info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
6049f4f8
RH
3130 if (info.si_signo) {
3131 info.si_errno = 0;
3132 info.si_code = TARGET_TRAP_BRKPT;
9d2803f7 3133 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
bcd2625d
RH
3134 } else {
3135 arch_interrupt = false;
7a3148a9
JM
3136 }
3137 break;
d0f20495
RH
3138 case EXCP_INTERRUPT:
3139 /* Just indicate that signals should be handled asap. */
3140 break;
fdbc2b57
RH
3141 case EXCP_ATOMIC:
3142 cpu_exec_step_atomic(cs);
bcd2625d 3143 arch_interrupt = false;
fdbc2b57 3144 break;
7a3148a9
JM
3145 default:
3146 printf ("Unhandled trap: 0x%x\n", trapnr);
878096ee 3147 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 3148 exit(EXIT_FAILURE);
7a3148a9
JM
3149 }
3150 process_pending_signals (env);
bcd2625d
RH
3151
3152 /* Most of the traps imply a transition through PALcode, which
3153 implies an REI instruction has been executed. Which means
3154 that RX and LOCK_ADDR should be cleared. But there are a
3155 few exceptions for traps internal to QEMU. */
3156 if (arch_interrupt) {
3157 env->flags &= ~ENV_FLAG_RX_FLAG;
3158 env->lock_addr = -1;
3159 }
7a3148a9
JM
3160 }
3161}
3162#endif /* TARGET_ALPHA */
3163
a4c075f1 3164#ifdef TARGET_S390X
f2d34df3
PM
3165
3166/* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS */
3167#define S390X_FAIL_ADDR_MASK -4096LL
3168
a4c075f1
UH
3169void cpu_loop(CPUS390XState *env)
3170{
878096ee 3171 CPUState *cs = CPU(s390_env_get_cpu(env));
d5a103cd 3172 int trapnr, n, sig;
a4c075f1 3173 target_siginfo_t info;
d5a103cd 3174 target_ulong addr;
47405ab6 3175 abi_long ret;
a4c075f1
UH
3176
3177 while (1) {
b040bc9c 3178 cpu_exec_start(cs);
8642c1b8 3179 trapnr = cpu_exec(cs);
b040bc9c 3180 cpu_exec_end(cs);
d148d90e
SF
3181 process_queued_cpu_work(cs);
3182
a4c075f1
UH
3183 switch (trapnr) {
3184 case EXCP_INTERRUPT:
d5a103cd 3185 /* Just indicate that signals should be handled asap. */
a4c075f1 3186 break;
a4c075f1 3187
d5a103cd
RH
3188 case EXCP_SVC:
3189 n = env->int_svc_code;
3190 if (!n) {
3191 /* syscalls > 255 */
3192 n = env->regs[1];
a4c075f1 3193 }
d5a103cd 3194 env->psw.addr += env->int_svc_ilen;
47405ab6
TB
3195 ret = do_syscall(env, n, env->regs[2], env->regs[3],
3196 env->regs[4], env->regs[5],
3197 env->regs[6], env->regs[7], 0, 0);
3198 if (ret == -TARGET_ERESTARTSYS) {
3199 env->psw.addr -= env->int_svc_ilen;
3200 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
3201 env->regs[2] = ret;
3202 }
a4c075f1 3203 break;
d5a103cd
RH
3204
3205 case EXCP_DEBUG:
db6b81d4 3206 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
d5a103cd
RH
3207 if (sig) {
3208 n = TARGET_TRAP_BRKPT;
3209 goto do_signal_pc;
a4c075f1
UH
3210 }
3211 break;
d5a103cd
RH
3212 case EXCP_PGM:
3213 n = env->int_pgm_code;
3214 switch (n) {
3215 case PGM_OPERATION:
3216 case PGM_PRIVILEGED:
a86b3c64 3217 sig = TARGET_SIGILL;
d5a103cd
RH
3218 n = TARGET_ILL_ILLOPC;
3219 goto do_signal_pc;
3220 case PGM_PROTECTION:
3221 case PGM_ADDRESSING:
a86b3c64 3222 sig = TARGET_SIGSEGV;
a4c075f1 3223 /* XXX: check env->error_code */
d5a103cd 3224 n = TARGET_SEGV_MAPERR;
f2d34df3 3225 addr = env->__excp_addr & S390X_FAIL_ADDR_MASK;
d5a103cd
RH
3226 goto do_signal;
3227 case PGM_EXECUTE:
3228 case PGM_SPECIFICATION:
3229 case PGM_SPECIAL_OP:
3230 case PGM_OPERAND:
3231 do_sigill_opn:
a86b3c64 3232 sig = TARGET_SIGILL;
d5a103cd
RH
3233 n = TARGET_ILL_ILLOPN;
3234 goto do_signal_pc;
3235
3236 case PGM_FIXPT_OVERFLOW:
a86b3c64 3237 sig = TARGET_SIGFPE;
d5a103cd
RH
3238 n = TARGET_FPE_INTOVF;
3239 goto do_signal_pc;
3240 case PGM_FIXPT_DIVIDE:
a86b3c64 3241 sig = TARGET_SIGFPE;
d5a103cd
RH
3242 n = TARGET_FPE_INTDIV;
3243 goto do_signal_pc;
3244
3245 case PGM_DATA:
3246 n = (env->fpc >> 8) & 0xff;
3247 if (n == 0xff) {
3248 /* compare-and-trap */
3249 goto do_sigill_opn;
3250 } else {
3251 /* An IEEE exception, simulated or otherwise. */
3252 if (n & 0x80) {
3253 n = TARGET_FPE_FLTINV;
3254 } else if (n & 0x40) {
3255 n = TARGET_FPE_FLTDIV;
3256 } else if (n & 0x20) {
3257 n = TARGET_FPE_FLTOVF;
3258 } else if (n & 0x10) {
3259 n = TARGET_FPE_FLTUND;
3260 } else if (n & 0x08) {
3261 n = TARGET_FPE_FLTRES;
3262 } else {
3263 /* ??? Quantum exception; BFP, DFP error. */
3264 goto do_sigill_opn;
3265 }
a86b3c64 3266 sig = TARGET_SIGFPE;
d5a103cd
RH
3267 goto do_signal_pc;
3268 }
3269
3270 default:
3271 fprintf(stderr, "Unhandled program exception: %#x\n", n);
878096ee 3272 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 3273 exit(EXIT_FAILURE);
a4c075f1
UH
3274 }
3275 break;
d5a103cd
RH
3276
3277 do_signal_pc:
3278 addr = env->psw.addr;
3279 do_signal:
3280 info.si_signo = sig;
3281 info.si_errno = 0;
3282 info.si_code = n;
3283 info._sifields._sigfault._addr = addr;
9d2803f7 3284 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
a4c075f1 3285 break;
d5a103cd 3286
fdbc2b57
RH
3287 case EXCP_ATOMIC:
3288 cpu_exec_step_atomic(cs);
3289 break;
a4c075f1 3290 default:
d5a103cd 3291 fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
878096ee 3292 cpu_dump_state(cs, stderr, fprintf, 0);
4d1275c2 3293 exit(EXIT_FAILURE);
a4c075f1
UH
3294 }
3295 process_pending_signals (env);
3296 }
3297}
3298
3299#endif /* TARGET_S390X */
3300
b16189b2
CG
3301#ifdef TARGET_TILEGX
3302
b16189b2
CG
3303static void gen_sigill_reg(CPUTLGState *env)
3304{
3305 target_siginfo_t info;
3306
3307 info.si_signo = TARGET_SIGILL;
3308 info.si_errno = 0;
3309 info.si_code = TARGET_ILL_PRVREG;
3310 info._sifields._sigfault._addr = env->pc;
9d2803f7 3311 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
b16189b2
CG
3312}
3313
a0577d2a 3314static void do_signal(CPUTLGState *env, int signo, int sigcode)
dd8070d8
CG
3315{
3316 target_siginfo_t info;
3317
a0577d2a 3318 info.si_signo = signo;
dd8070d8 3319 info.si_errno = 0;
dd8070d8 3320 info._sifields._sigfault._addr = env->pc;
a0577d2a
RH
3321
3322 if (signo == TARGET_SIGSEGV) {
3323 /* The passed in sigcode is a dummy; check for a page mapping
3324 and pass either MAPERR or ACCERR. */
3325 target_ulong addr = env->excaddr;
3326 info._sifields._sigfault._addr = addr;
3327 if (page_check_range(addr, 1, PAGE_VALID) < 0) {
3328 sigcode = TARGET_SEGV_MAPERR;
3329 } else {
3330 sigcode = TARGET_SEGV_ACCERR;
3331 }
3332 }
3333 info.si_code = sigcode;
3334
9d2803f7 3335 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
dd8070d8
CG
3336}
3337
a0577d2a
RH
3338static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
3339{
3340 env->excaddr = addr;
3341 do_signal(env, TARGET_SIGSEGV, 0);
3342}
3343
0583b233
RH
3344static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val)
3345{
3346 if (unlikely(reg >= TILEGX_R_COUNT)) {
3347 switch (reg) {
3348 case TILEGX_R_SN:
3349 case TILEGX_R_ZERO:
3350 return;
3351 case TILEGX_R_IDN0:
3352 case TILEGX_R_IDN1:
3353 case TILEGX_R_UDN0:
3354 case TILEGX_R_UDN1:
3355 case TILEGX_R_UDN2:
3356 case TILEGX_R_UDN3:
3357 gen_sigill_reg(env);
3358 return;
3359 default:
3360 g_assert_not_reached();
3361 }
3362 }
3363 env->regs[reg] = val;
3364}
3365
3366/*
3367 * Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
3368 * memory at the address held in the first source register. If the values are
3369 * not equal, then no memory operation is performed. If the values are equal,
3370 * the 8-byte quantity from the second source register is written into memory
3371 * at the address held in the first source register. In either case, the result
3372 * of the instruction is the value read from memory. The compare and write to
3373 * memory are atomic and thus can be used for synchronization purposes. This
3374 * instruction only operates for addresses aligned to a 8-byte boundary.
3375 * Unaligned memory access causes an Unaligned Data Reference interrupt.
3376 *
3377 * Functional Description (64-bit)
3378 * uint64_t memVal = memoryReadDoubleWord (rf[SrcA]);
3379 * rf[Dest] = memVal;
3380 * if (memVal == SPR[CmpValueSPR])
3381 * memoryWriteDoubleWord (rf[SrcA], rf[SrcB]);
3382 *
3383 * Functional Description (32-bit)
3384 * uint64_t memVal = signExtend32 (memoryReadWord (rf[SrcA]));
3385 * rf[Dest] = memVal;
3386 * if (memVal == signExtend32 (SPR[CmpValueSPR]))
3387 * memoryWriteWord (rf[SrcA], rf[SrcB]);
3388 *
3389 *
3390 * This function also processes exch and exch4 which need not process SPR.
3391 */
3392static void do_exch(CPUTLGState *env, bool quad, bool cmp)
3393{
3394 target_ulong addr;
3395 target_long val, sprval;
3396
3397 start_exclusive();
3398
3399 addr = env->atomic_srca;
3400 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
3401 goto sigsegv_maperr;
3402 }
3403
3404 if (cmp) {
3405 if (quad) {
3406 sprval = env->spregs[TILEGX_SPR_CMPEXCH];
3407 } else {
3408 sprval = sextract64(env->spregs[TILEGX_SPR_CMPEXCH], 0, 32);
3409 }
3410 }
3411
3412 if (!cmp || val == sprval) {
3413 target_long valb = env->atomic_srcb;
3414 if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
3415 goto sigsegv_maperr;
3416 }
3417 }
3418
3419 set_regval(env, env->atomic_dstr, val);
3420 end_exclusive();
3421 return;
3422
3423 sigsegv_maperr:
3424 end_exclusive();
3425 gen_sigsegv_maperr(env, addr);
3426}
3427
3428static void do_fetch(CPUTLGState *env, int trapnr, bool quad)
3429{
3430 int8_t write = 1;
3431 target_ulong addr;
3432 target_long val, valb;
3433
3434 start_exclusive();
3435
3436 addr = env->atomic_srca;
3437 valb = env->atomic_srcb;
3438 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
3439 goto sigsegv_maperr;
3440 }
3441
3442 switch (trapnr) {
3443 case TILEGX_EXCP_OPCODE_FETCHADD:
3444 case TILEGX_EXCP_OPCODE_FETCHADD4:
3445 valb += val;
3446 break;
3447 case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
3448 valb += val;
3449 if (valb < 0) {
3450 write = 0;
3451 }
3452 break;
3453 case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
3454 valb += val;
3455 if ((int32_t)valb < 0) {
3456 write = 0;
3457 }
3458 break;
3459 case TILEGX_EXCP_OPCODE_FETCHAND:
3460 case TILEGX_EXCP_OPCODE_FETCHAND4:
3461 valb &= val;
3462 break;
3463 case TILEGX_EXCP_OPCODE_FETCHOR:
3464 case TILEGX_EXCP_OPCODE_FETCHOR4:
3465 valb |= val;
3466 break;
3467 default:
3468 g_assert_not_reached();
3469 }
3470
3471 if (write) {
3472 if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
3473 goto sigsegv_maperr;
3474 }
3475 }
3476
3477 set_regval(env, env->atomic_dstr, val);
3478 end_exclusive();
3479 return;
3480
3481 sigsegv_maperr:
3482 end_exclusive();
3483 gen_sigsegv_maperr(env, addr);
3484}
3485
b16189b2
CG
3486void cpu_loop(CPUTLGState *env)
3487{
3488 CPUState *cs = CPU(tilegx_env_get_cpu(env));
3489 int trapnr;
3490
3491 while (1) {
3492 cpu_exec_start(cs);
8642c1b8 3493 trapnr = cpu_exec(cs);
b16189b2 3494 cpu_exec_end(cs);
d148d90e
SF
3495 process_queued_cpu_work(cs);
3496
b16189b2
CG
3497 switch (trapnr) {
3498 case TILEGX_EXCP_SYSCALL:
a9175169
PM
3499 {
3500 abi_ulong ret = do_syscall(env, env->regs[TILEGX_R_NR],
3501 env->regs[0], env->regs[1],
3502 env->regs[2], env->regs[3],
3503 env->regs[4], env->regs[5],
3504 env->regs[6], env->regs[7]);
3505 if (ret == -TARGET_ERESTARTSYS) {
3506 env->pc -= 8;
3507 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
3508 env->regs[TILEGX_R_RE] = ret;
3509 env->regs[TILEGX_R_ERR] = TILEGX_IS_ERRNO(ret) ? -ret : 0;
3510 }
b16189b2 3511 break;
a9175169 3512 }
0583b233
RH
3513 case TILEGX_EXCP_OPCODE_EXCH:
3514 do_exch(env, true, false);
3515 break;
3516 case TILEGX_EXCP_OPCODE_EXCH4:
3517 do_exch(env, false, false);
3518 break;
3519 case TILEGX_EXCP_OPCODE_CMPEXCH:
3520 do_exch(env, true, true);
3521 break;
3522 case TILEGX_EXCP_OPCODE_CMPEXCH4:
3523 do_exch(env, false, true);
3524 break;
3525 case TILEGX_EXCP_OPCODE_FETCHADD:
3526 case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
3527 case TILEGX_EXCP_OPCODE_FETCHAND:
3528 case TILEGX_EXCP_OPCODE_FETCHOR:
3529 do_fetch(env, trapnr, true);
3530 break;
3531 case TILEGX_EXCP_OPCODE_FETCHADD4:
3532 case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
3533 case TILEGX_EXCP_OPCODE_FETCHAND4:
3534 case TILEGX_EXCP_OPCODE_FETCHOR4:
3535 do_fetch(env, trapnr, false);
3536 break;
dd8070d8 3537 case TILEGX_EXCP_SIGNAL:
a0577d2a 3538 do_signal(env, env->signo, env->sigcode);
dd8070d8 3539 break;
b16189b2
CG
3540 case TILEGX_EXCP_REG_IDN_ACCESS:
3541 case TILEGX_EXCP_REG_UDN_ACCESS:
3542 gen_sigill_reg(env);
3543 break;
fdbc2b57
RH
3544 case EXCP_ATOMIC:
3545 cpu_exec_step_atomic(cs);
3546 break;
b16189b2
CG
3547 default:
3548 fprintf(stderr, "trapnr is %d[0x%x].\n", trapnr, trapnr);
3549 g_assert_not_reached();
3550 }
3551 process_pending_signals(env);
3552 }
3553}
3554
3555#endif
3556
47ae93cd
MC
3557#ifdef TARGET_RISCV
3558
3559void cpu_loop(CPURISCVState *env)
3560{
3561 CPUState *cs = CPU(riscv_env_get_cpu(env));
3562 int trapnr, signum, sigcode;
3563 target_ulong sigaddr;
3564 target_ulong ret;
3565
3566 for (;;) {
3567 cpu_exec_start(cs);
3568 trapnr = cpu_exec(cs);
3569 cpu_exec_end(cs);
3570 process_queued_cpu_work(cs);
3571
3572 signum = 0;
3573 sigcode = 0;
3574 sigaddr = 0;
3575
3576 switch (trapnr) {
3577 case EXCP_INTERRUPT:
3578 /* just indicate that signals should be handled asap */
3579 break;
3580 case EXCP_ATOMIC:
3581 cpu_exec_step_atomic(cs);
3582 break;
3583 case RISCV_EXCP_U_ECALL:
3584 env->pc += 4;
3585 if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
3586 /* riscv_flush_icache_syscall is a no-op in QEMU as
3587 self-modifying code is automatically detected */
3588 ret = 0;
3589 } else {
3590 ret = do_syscall(env,
3591 env->gpr[xA7],
3592 env->gpr[xA0],
3593 env->gpr[xA1],
3594 env->gpr[xA2],
3595 env->gpr[xA3],
3596 env->gpr[xA4],
3597 env->gpr[xA5],
3598 0, 0);
3599 }
3600 if (ret == -TARGET_ERESTARTSYS) {
3601 env->pc -= 4;
3602 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
3603 env->gpr[xA0] = ret;
3604 }
3605 if (cs->singlestep_enabled) {
3606 goto gdbstep;
3607 }
3608 break;
3609 case RISCV_EXCP_ILLEGAL_INST:
3610 signum = TARGET_SIGILL;
3611 sigcode = TARGET_ILL_ILLOPC;
3612 break;
3613 case RISCV_EXCP_BREAKPOINT:
3614 signum = TARGET_SIGTRAP;
3615 sigcode = TARGET_TRAP_BRKPT;
3616 sigaddr = env->pc;
3617 break;
3618 case RISCV_EXCP_INST_PAGE_FAULT:
3619 case RISCV_EXCP_LOAD_PAGE_FAULT:
3620 case RISCV_EXCP_STORE_PAGE_FAULT:
3621 signum = TARGET_SIGSEGV;
3622 sigcode = TARGET_SEGV_MAPERR;
3623 break;
3624 case EXCP_DEBUG:
3625 gdbstep:
3626 signum = gdb_handlesig(cs, TARGET_SIGTRAP);
3627 sigcode = TARGET_TRAP_BRKPT;
3628 break;
3629 default:
3630 EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
3631 trapnr);
3632 exit(EXIT_FAILURE);
3633 }
3634
3635 if (signum) {
3636 target_siginfo_t info = {
3637 .si_signo = signum,
3638 .si_errno = 0,
3639 .si_code = sigcode,
3640 ._sifields._sigfault._addr = sigaddr
3641 };
3642 queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
3643 }
3644
3645 process_pending_signals(env);
3646 }
3647}
3648
3649#endif /* TARGET_RISCV */
3650
7c248bcd
RH
3651#ifdef TARGET_HPPA
3652
3653static abi_ulong hppa_lws(CPUHPPAState *env)
3654{
3655 uint32_t which = env->gr[20];
3656 abi_ulong addr = env->gr[26];
3657 abi_ulong old = env->gr[25];
3658 abi_ulong new = env->gr[24];
3659 abi_ulong size, ret;
3660
3661 switch (which) {
3662 default:
3663 return -TARGET_ENOSYS;
3664
3665 case 0: /* elf32 atomic 32bit cmpxchg */
3666 if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) {
3667 return -TARGET_EFAULT;
3668 }
3669 old = tswap32(old);
3670 new = tswap32(new);
3671 ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
3672 ret = tswap32(ret);
3673 break;
3674
3675 case 2: /* elf32 atomic "new" cmpxchg */
3676 size = env->gr[23];
3677 if (size >= 4) {
3678 return -TARGET_ENOSYS;
3679 }
3680 if (((addr | old | new) & ((1 << size) - 1))
3681 || !access_ok(VERIFY_WRITE, addr, 1 << size)
3682 || !access_ok(VERIFY_READ, old, 1 << size)
3683 || !access_ok(VERIFY_READ, new, 1 << size)) {
3684 return -TARGET_EFAULT;
3685 }
3686 /* Note that below we use host-endian loads so that the cmpxchg
3687 can be host-endian as well. */
3688 switch (size) {
3689 case 0:
3690 old = *(uint8_t *)g2h(old);
3691 new = *(uint8_t *)g2h(new);
3692 ret = atomic_cmpxchg((uint8_t *)g2h(addr), old, new);
3693 ret = ret != old;
3694 break;
3695 case 1:
3696 old = *(uint16_t *)g2h(old);
3697 new = *(uint16_t *)g2h(new);
3698 ret = atomic_cmpxchg((uint16_t *)g2h(addr), old, new);
3699 ret = ret != old;
3700 break;
3701 case 2:
3702 old = *(uint32_t *)g2h(old);
3703 new = *(uint32_t *)g2h(new);
3704 ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
3705 ret = ret != old;
3706 break;
3707 case 3:
3708 {
3709 uint64_t o64, n64, r64;
3710 o64 = *(uint64_t *)g2h(old);
3711 n64 = *(uint64_t *)g2h(new);
3712#ifdef CONFIG_ATOMIC64
3713 r64 = atomic_cmpxchg__nocheck((uint64_t *)g2h(addr), o64, n64);
3714 ret = r64 != o64;
3715#else
3716 start_exclusive();
3717 r64 = *(uint64_t *)g2h(addr);
3718 ret = 1;
3719 if (r64 == o64) {
3720 *(uint64_t *)g2h(addr) = n64;
3721 ret = 0;
3722 }
3723 end_exclusive();
3724#endif
3725 }
3726 break;
3727 }
3728 break;
3729 }
3730
3731 env->gr[28] = ret;
3732 return 0;
3733}
3734
3735void cpu_loop(CPUHPPAState *env)
3736{
3737 CPUState *cs = CPU(hppa_env_get_cpu(env));
3738 target_siginfo_t info;
3739 abi_ulong ret;
3740 int trapnr;
3741
3742 while (1) {
3743 cpu_exec_start(cs);
3744 trapnr = cpu_exec(cs);
3745 cpu_exec_end(cs);
3746 process_queued_cpu_work(cs);
3747
3748 switch (trapnr) {
3749 case EXCP_SYSCALL:
3750 ret = do_syscall(env, env->gr[20],
3751 env->gr[26], env->gr[25],
3752 env->gr[24], env->gr[23],
3753 env->gr[22], env->gr[21], 0, 0);
3754 switch (ret) {
3755 default:
3756 env->gr[28] = ret;
3757 /* We arrived here by faking the gateway page. Return. */
3758 env->iaoq_f = env->gr[31];
3759 env->iaoq_b = env->gr[31] + 4;
3760 break;
3761 case -TARGET_ERESTARTSYS:
3762 case -TARGET_QEMU_ESIGRETURN:
3763 break;
3764 }
3765 break;
3766 case EXCP_SYSCALL_LWS:
3767 env->gr[21] = hppa_lws(env);
3768 /* We arrived here by faking the gateway page. Return. */
3769 env->iaoq_f = env->gr[31];
3770 env->iaoq_b = env->gr[31] + 4;
3771 break;
2986721d
RH
3772 case EXCP_ITLB_MISS:
3773 case EXCP_DTLB_MISS:
3774 case EXCP_NA_ITLB_MISS:
3775 case EXCP_NA_DTLB_MISS:
3776 case EXCP_IMP:
3777 case EXCP_DMP:
3778 case EXCP_DMB:
3779 case EXCP_PAGE_REF:
3780 case EXCP_DMAR:
3781 case EXCP_DMPI:
7c248bcd
RH
3782 info.si_signo = TARGET_SIGSEGV;
3783 info.si_errno = 0;
3784 info.si_code = TARGET_SEGV_ACCERR;
35136a77 3785 info._sifields._sigfault._addr = env->cr[CR_IOR];
7c248bcd
RH
3786 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3787 break;
2986721d
RH
3788 case EXCP_UNALIGN:
3789 info.si_signo = TARGET_SIGBUS;
3790 info.si_errno = 0;
3791 info.si_code = 0;
35136a77 3792 info._sifields._sigfault._addr = env->cr[CR_IOR];
2986721d
RH
3793 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3794 break;
3795 case EXCP_ILL:
3796 case EXCP_PRIV_OPR:
3797 case EXCP_PRIV_REG:
7c248bcd
RH
3798 info.si_signo = TARGET_SIGILL;
3799 info.si_errno = 0;
3800 info.si_code = TARGET_ILL_ILLOPN;
3801 info._sifields._sigfault._addr = env->iaoq_f;
3802 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3803 break;
2986721d
RH
3804 case EXCP_OVERFLOW:
3805 case EXCP_COND:
3806 case EXCP_ASSIST:
7c248bcd
RH
3807 info.si_signo = TARGET_SIGFPE;
3808 info.si_errno = 0;
3809 info.si_code = 0;
3810 info._sifields._sigfault._addr = env->iaoq_f;
3811 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3812 break;
3813 case EXCP_DEBUG:
3814 trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
3815 if (trapnr) {
3816 info.si_signo = trapnr;
3817 info.si_errno = 0;
3818 info.si_code = TARGET_TRAP_BRKPT;
3819 queue_signal(env, trapnr, QEMU_SI_FAULT, &info);
3820 }
3821 break;
3822 case EXCP_INTERRUPT:
3823 /* just indicate that signals should be handled asap */
3824 break;
3825 default:
3826 g_assert_not_reached();
3827 }
3828 process_pending_signals(env);
3829 }
3830}
3831
3832#endif /* TARGET_HPPA */
3833
ba7651fb
MF
3834#ifdef TARGET_XTENSA
3835
3836static void xtensa_rfw(CPUXtensaState *env)
3837{
3838 xtensa_restore_owb(env);
3839 env->pc = env->sregs[EPC1];
3840}
3841
3842static void xtensa_rfwu(CPUXtensaState *env)
3843{
3844 env->sregs[WINDOW_START] |= (1 << env->sregs[WINDOW_BASE]);
3845 xtensa_rfw(env);
3846}
3847
3848static void xtensa_rfwo(CPUXtensaState *env)
3849{
3850 env->sregs[WINDOW_START] &= ~(1 << env->sregs[WINDOW_BASE]);
3851 xtensa_rfw(env);
3852}
3853
3854static void xtensa_overflow4(CPUXtensaState *env)
3855{
3856 put_user_ual(env->regs[0], env->regs[5] - 16);
3857 put_user_ual(env->regs[1], env->regs[5] - 12);
3858 put_user_ual(env->regs[2], env->regs[5] - 8);
3859 put_user_ual(env->regs[3], env->regs[5] - 4);
3860 xtensa_rfwo(env);
3861}
3862
3863static void xtensa_underflow4(CPUXtensaState *env)
3864{
3865 get_user_ual(env->regs[0], env->regs[5] - 16);
3866 get_user_ual(env->regs[1], env->regs[5] - 12);
3867 get_user_ual(env->regs[2], env->regs[5] - 8);
3868 get_user_ual(env->regs[3], env->regs[5] - 4);
3869 xtensa_rfwu(env);
3870}
3871
3872static void xtensa_overflow8(CPUXtensaState *env)
3873{
3874 put_user_ual(env->regs[0], env->regs[9] - 16);
3875 get_user_ual(env->regs[0], env->regs[1] - 12);
3876 put_user_ual(env->regs[1], env->regs[9] - 12);
3877 put_user_ual(env->regs[2], env->regs[9] - 8);
3878 put_user_ual(env->regs[3], env->regs[9] - 4);
3879 put_user_ual(env->regs[4], env->regs[0] - 32);
3880 put_user_ual(env->regs[5], env->regs[0] - 28);
3881 put_user_ual(env->regs[6], env->regs[0] - 24);
3882 put_user_ual(env->regs[7], env->regs[0] - 20);
3883 xtensa_rfwo(env);
3884}
3885
3886static void xtensa_underflow8(CPUXtensaState *env)
3887{
3888 get_user_ual(env->regs[0], env->regs[9] - 16);
3889 get_user_ual(env->regs[1], env->regs[9] - 12);
3890 get_user_ual(env->regs[2], env->regs[9] - 8);
3891 get_user_ual(env->regs[7], env->regs[1] - 12);
3892 get_user_ual(env->regs[3], env->regs[9] - 4);
3893 get_user_ual(env->regs[4], env->regs[7] - 32);
3894 get_user_ual(env->regs[5], env->regs[7] - 28);
3895 get_user_ual(env->regs[6], env->regs[7] - 24);
3896 get_user_ual(env->regs[7], env->regs[7] - 20);
3897 xtensa_rfwu(env);
3898}
3899
3900static void xtensa_overflow12(CPUXtensaState *env)
3901{
3902 put_user_ual(env->regs[0], env->regs[13] - 16);
3903 get_user_ual(env->regs[0], env->regs[1] - 12);
3904 put_user_ual(env->regs[1], env->regs[13] - 12);
3905 put_user_ual(env->regs[2], env->regs[13] - 8);
3906 put_user_ual(env->regs[3], env->regs[13] - 4);
3907 put_user_ual(env->regs[4], env->regs[0] - 48);
3908 put_user_ual(env->regs[5], env->regs[0] - 44);
3909 put_user_ual(env->regs[6], env->regs[0] - 40);
3910 put_user_ual(env->regs[7], env->regs[0] - 36);
3911 put_user_ual(env->regs[8], env->regs[0] - 32);
3912 put_user_ual(env->regs[9], env->regs[0] - 28);
3913 put_user_ual(env->regs[10], env->regs[0] - 24);
3914 put_user_ual(env->regs[11], env->regs[0] - 20);
3915 xtensa_rfwo(env);
3916}
3917
3918static void xtensa_underflow12(CPUXtensaState *env)
3919{
3920 get_user_ual(env->regs[0], env->regs[13] - 16);
3921 get_user_ual(env->regs[1], env->regs[13] - 12);
3922 get_user_ual(env->regs[2], env->regs[13] - 8);
3923 get_user_ual(env->regs[11], env->regs[1] - 12);
3924 get_user_ual(env->regs[3], env->regs[13] - 4);
3925 get_user_ual(env->regs[4], env->regs[11] - 48);
3926 get_user_ual(env->regs[5], env->regs[11] - 44);
3927 get_user_ual(env->regs[6], env->regs[11] - 40);
3928 get_user_ual(env->regs[7], env->regs[11] - 36);
3929 get_user_ual(env->regs[8], env->regs[11] - 32);
3930 get_user_ual(env->regs[9], env->regs[11] - 28);
3931 get_user_ual(env->regs[10], env->regs[11] - 24);
3932 get_user_ual(env->regs[11], env->regs[11] - 20);
3933 xtensa_rfwu(env);
3934}
3935
3936void cpu_loop(CPUXtensaState *env)
3937{
3938 CPUState *cs = CPU(xtensa_env_get_cpu(env));
3939 target_siginfo_t info;
3940 abi_ulong ret;
3941 int trapnr;
3942
3943 while (1) {
3944 cpu_exec_start(cs);
3945 trapnr = cpu_exec(cs);
3946 cpu_exec_end(cs);
3947 process_queued_cpu_work(cs);
3948
3949 env->sregs[PS] &= ~PS_EXCM;
3950 switch (trapnr) {
3951 case EXCP_INTERRUPT:
3952 break;
3953
3954 case EXC_WINDOW_OVERFLOW4:
3955 xtensa_overflow4(env);
3956 break;
3957 case EXC_WINDOW_UNDERFLOW4:
3958 xtensa_underflow4(env);
3959 break;
3960 case EXC_WINDOW_OVERFLOW8:
3961 xtensa_overflow8(env);
3962 break;
3963 case EXC_WINDOW_UNDERFLOW8:
3964 xtensa_underflow8(env);
3965 break;
3966 case EXC_WINDOW_OVERFLOW12:
3967 xtensa_overflow12(env);
3968 break;
3969 case EXC_WINDOW_UNDERFLOW12:
3970 xtensa_underflow12(env);
3971 break;
3972
3973 case EXC_USER:
3974 switch (env->sregs[EXCCAUSE]) {
3975 case ILLEGAL_INSTRUCTION_CAUSE:
3976 case PRIVILEGED_CAUSE:
3977 info.si_signo = TARGET_SIGILL;
3978 info.si_errno = 0;
3979 info.si_code =
3980 env->sregs[EXCCAUSE] == ILLEGAL_INSTRUCTION_CAUSE ?
3981 TARGET_ILL_ILLOPC : TARGET_ILL_PRVOPC;
3982 info._sifields._sigfault._addr = env->sregs[EPC1];
3983 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3984 break;
3985
3986 case SYSCALL_CAUSE:
3987 env->pc += 3;
3988 ret = do_syscall(env, env->regs[2],
3989 env->regs[6], env->regs[3],
3990 env->regs[4], env->regs[5],
3991 env->regs[8], env->regs[9], 0, 0);
3992 switch (ret) {
3993 default:
3994 env->regs[2] = ret;
3995 break;
3996
3997 case -TARGET_ERESTARTSYS:
4a6bf7ad
MF
3998 env->pc -= 3;
3999 break;
4000
ba7651fb
MF
4001 case -TARGET_QEMU_ESIGRETURN:
4002 break;
4003 }
4004 break;
4005
4006 case ALLOCA_CAUSE:
4007 env->sregs[PS] = deposit32(env->sregs[PS],
4008 PS_OWB_SHIFT,
4009 PS_OWB_LEN,
4010 env->sregs[WINDOW_BASE]);
4011
4012 switch (env->regs[0] & 0xc0000000) {
4013 case 0x00000000:
4014 case 0x40000000:
4015 xtensa_rotate_window(env, -1);
4016 xtensa_underflow4(env);
4017 break;
4018
4019 case 0x80000000:
4020 xtensa_rotate_window(env, -2);
4021 xtensa_underflow8(env);
4022 break;
4023
4024 case 0xc0000000:
4025 xtensa_rotate_window(env, -3);
4026 xtensa_underflow12(env);
4027 break;
4028 }
4029 break;
4030
4031 case INTEGER_DIVIDE_BY_ZERO_CAUSE:
4032 info.si_signo = TARGET_SIGFPE;
4033 info.si_errno = 0;
4034 info.si_code = TARGET_FPE_INTDIV;
4035 info._sifields._sigfault._addr = env->sregs[EPC1];
4036 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
4037 break;
4038
4039 case LOAD_PROHIBITED_CAUSE:
4040 case STORE_PROHIBITED_CAUSE:
4041 info.si_signo = TARGET_SIGSEGV;
4042 info.si_errno = 0;
4043 info.si_code = TARGET_SEGV_ACCERR;
4044 info._sifields._sigfault._addr = env->sregs[EXCVADDR];
4045 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
4046 break;
4047
4048 default:
4049 fprintf(stderr, "exccause = %d\n", env->sregs[EXCCAUSE]);
4050 g_assert_not_reached();
4051 }
4052 break;
4053 case EXCP_DEBUG:
4054 trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
4055 if (trapnr) {
4056 info.si_signo = trapnr;
4057 info.si_errno = 0;
4058 info.si_code = TARGET_TRAP_BRKPT;
4059 queue_signal(env, trapnr, QEMU_SI_FAULT, &info);
4060 }
4061 break;
4062 case EXC_DEBUG:
4063 default:
4064 fprintf(stderr, "trapnr = %d\n", trapnr);
4065 g_assert_not_reached();
4066 }
4067 process_pending_signals(env);
4068 }
4069}
4070
4071#endif /* TARGET_XTENSA */
4072
b44316fb 4073__thread CPUState *thread_cpu;
59faf6d6 4074
178f9429
SF
4075bool qemu_cpu_is_self(CPUState *cpu)
4076{
4077 return thread_cpu == cpu;
4078}
4079
4080void qemu_cpu_kick(CPUState *cpu)
4081{
4082 cpu_exit(cpu);
4083}
4084
edf8e2af
MW
4085void task_settid(TaskState *ts)
4086{
4087 if (ts->ts_tid == 0) {
edf8e2af 4088 ts->ts_tid = (pid_t)syscall(SYS_gettid);
edf8e2af
MW
4089 }
4090}
4091
4092void stop_all_tasks(void)
4093{
4094 /*
4095 * We trust that when using NPTL, start_exclusive()
4096 * handles thread stopping correctly.
4097 */
4098 start_exclusive();
4099}
4100
c3a92833 4101/* Assumes contents are already zeroed. */
624f7979
PB
4102void init_task_state(TaskState *ts)
4103{
624f7979 4104 ts->used = 1;
624f7979 4105}
fc9c5412 4106
30ba0ee5
AF
4107CPUArchState *cpu_copy(CPUArchState *env)
4108{
ff4700b0 4109 CPUState *cpu = ENV_GET_CPU(env);
2278b939 4110 CPUState *new_cpu = cpu_create(cpu_type);
61c7480f 4111 CPUArchState *new_env = new_cpu->env_ptr;
30ba0ee5
AF
4112 CPUBreakpoint *bp;
4113 CPUWatchpoint *wp;
30ba0ee5
AF
4114
4115 /* Reset non arch specific state */
75a34036 4116 cpu_reset(new_cpu);
30ba0ee5
AF
4117
4118 memcpy(new_env, env, sizeof(CPUArchState));
4119
4120 /* Clone all break/watchpoints.
4121 Note: Once we support ptrace with hw-debug register access, make sure
4122 BP_CPU break/watchpoints are handled correctly on clone. */
1d085f6c
TB
4123 QTAILQ_INIT(&new_cpu->breakpoints);
4124 QTAILQ_INIT(&new_cpu->watchpoints);
f0c3c505 4125 QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
b3310ab3 4126 cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
30ba0ee5 4127 }
ff4700b0 4128 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
05068c0d 4129 cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
30ba0ee5 4130 }
30ba0ee5
AF
4131
4132 return new_env;
4133}
4134
fc9c5412
JS
4135static void handle_arg_help(const char *arg)
4136{
4d1275c2 4137 usage(EXIT_SUCCESS);
fc9c5412
JS
4138}
4139
4140static void handle_arg_log(const char *arg)
4141{
4142 int mask;
fc9c5412 4143
4fde1eba 4144 mask = qemu_str_to_log_mask(arg);
fc9c5412 4145 if (!mask) {
59a6fa6e 4146 qemu_print_log_usage(stdout);
4d1275c2 4147 exit(EXIT_FAILURE);
fc9c5412 4148 }
f2937a33 4149 qemu_log_needs_buffers();
24537a01 4150 qemu_set_log(mask);
fc9c5412
JS
4151}
4152
8423fa90
AB
4153static void handle_arg_dfilter(const char *arg)
4154{
4155 qemu_set_dfilter_ranges(arg, NULL);
4156}
4157
50171d42
CWR
4158static void handle_arg_log_filename(const char *arg)
4159{
daa76aa4 4160 qemu_set_log_filename(arg, &error_fatal);
50171d42
CWR
4161}
4162
fc9c5412
JS
4163static void handle_arg_set_env(const char *arg)
4164{
4165 char *r, *p, *token;
4166 r = p = strdup(arg);
4167 while ((token = strsep(&p, ",")) != NULL) {
4168 if (envlist_setenv(envlist, token) != 0) {
4d1275c2 4169 usage(EXIT_FAILURE);
fc9c5412
JS
4170 }
4171 }
4172 free(r);
4173}
4174
4175static void handle_arg_unset_env(const char *arg)
4176{
4177 char *r, *p, *token;
4178 r = p = strdup(arg);
4179 while ((token = strsep(&p, ",")) != NULL) {
4180 if (envlist_unsetenv(envlist, token) != 0) {
4d1275c2 4181 usage(EXIT_FAILURE);
fc9c5412
JS
4182 }
4183 }
4184 free(r);
4185}
4186
4187static void handle_arg_argv0(const char *arg)
4188{
4189 argv0 = strdup(arg);
4190}
4191
4192static void handle_arg_stack_size(const char *arg)
4193{
4194 char *p;
4195 guest_stack_size = strtoul(arg, &p, 0);
4196 if (guest_stack_size == 0) {
4d1275c2 4197 usage(EXIT_FAILURE);
fc9c5412
JS
4198 }
4199
4200 if (*p == 'M') {
4201 guest_stack_size *= 1024 * 1024;
4202 } else if (*p == 'k' || *p == 'K') {
4203 guest_stack_size *= 1024;
4204 }
4205}
4206
4207static void handle_arg_ld_prefix(const char *arg)
4208{
4209 interp_prefix = strdup(arg);
4210}
4211
4212static void handle_arg_pagesize(const char *arg)
4213{
4214 qemu_host_page_size = atoi(arg);
4215 if (qemu_host_page_size == 0 ||
4216 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
4217 fprintf(stderr, "page size must be a power of two\n");
4d1275c2 4218 exit(EXIT_FAILURE);
fc9c5412
JS
4219 }
4220}
4221
c5e4a5a9
MR
4222static void handle_arg_randseed(const char *arg)
4223{
4224 unsigned long long seed;
4225
4226 if (parse_uint_full(arg, &seed, 0) != 0 || seed > UINT_MAX) {
4227 fprintf(stderr, "Invalid seed number: %s\n", arg);
4d1275c2 4228 exit(EXIT_FAILURE);
c5e4a5a9
MR
4229 }
4230 srand(seed);
4231}
4232
fc9c5412
JS
4233static void handle_arg_gdb(const char *arg)
4234{
4235 gdbstub_port = atoi(arg);
4236}
4237
4238static void handle_arg_uname(const char *arg)
4239{
4240 qemu_uname_release = strdup(arg);
4241}
4242
4243static void handle_arg_cpu(const char *arg)
4244{
4245 cpu_model = strdup(arg);
c8057f95 4246 if (cpu_model == NULL || is_help_option(cpu_model)) {
fc9c5412 4247 /* XXX: implement xxx_cpu_list for targets that still miss it */
e916cbf8
PM
4248#if defined(cpu_list)
4249 cpu_list(stdout, &fprintf);
fc9c5412 4250#endif
4d1275c2 4251 exit(EXIT_FAILURE);
fc9c5412
JS
4252 }
4253}
4254
fc9c5412
JS
4255static void handle_arg_guest_base(const char *arg)
4256{
4257 guest_base = strtol(arg, NULL, 0);
4258 have_guest_base = 1;
4259}
4260
4261static void handle_arg_reserved_va(const char *arg)
4262{
4263 char *p;
4264 int shift = 0;
4265 reserved_va = strtoul(arg, &p, 0);
4266 switch (*p) {
4267 case 'k':
4268 case 'K':
4269 shift = 10;
4270 break;
4271 case 'M':
4272 shift = 20;
4273 break;
4274 case 'G':
4275 shift = 30;
4276 break;
4277 }
4278 if (shift) {
4279 unsigned long unshifted = reserved_va;
4280 p++;
4281 reserved_va <<= shift;
18e80c55
RH
4282 if (reserved_va >> shift != unshifted
4283 || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
fc9c5412 4284 fprintf(stderr, "Reserved virtual address too big\n");
4d1275c2 4285 exit(EXIT_FAILURE);
fc9c5412
JS
4286 }
4287 }
4288 if (*p) {
4289 fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
4d1275c2 4290 exit(EXIT_FAILURE);
fc9c5412
JS
4291 }
4292}
fc9c5412
JS
4293
4294static void handle_arg_singlestep(const char *arg)
4295{
4296 singlestep = 1;
4297}
4298
4299static void handle_arg_strace(const char *arg)
4300{
4301 do_strace = 1;
4302}
4303
4304static void handle_arg_version(const char *arg)
4305{
7e563bfb 4306 printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
0781dd6e 4307 "\n" QEMU_COPYRIGHT "\n");
4d1275c2 4308 exit(EXIT_SUCCESS);
fc9c5412
JS
4309}
4310
6533dd6e
LV
4311static char *trace_file;
4312static void handle_arg_trace(const char *arg)
4313{
4314 g_free(trace_file);
4315 trace_file = trace_opt_parse(arg);
4316}
4317
fc9c5412
JS
4318struct qemu_argument {
4319 const char *argv;
4320 const char *env;
4321 bool has_arg;
4322 void (*handle_opt)(const char *arg);
4323 const char *example;
4324 const char *help;
4325};
4326
42644cee 4327static const struct qemu_argument arg_table[] = {
fc9c5412
JS
4328 {"h", "", false, handle_arg_help,
4329 "", "print this help"},
daaf8c8e
MI
4330 {"help", "", false, handle_arg_help,
4331 "", ""},
fc9c5412
JS
4332 {"g", "QEMU_GDB", true, handle_arg_gdb,
4333 "port", "wait gdb connection to 'port'"},
4334 {"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix,
4335 "path", "set the elf interpreter prefix to 'path'"},
4336 {"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
4337 "size", "set the stack size to 'size' bytes"},
4338 {"cpu", "QEMU_CPU", true, handle_arg_cpu,
c8057f95 4339 "model", "select CPU (-cpu help for list)"},
fc9c5412
JS
4340 {"E", "QEMU_SET_ENV", true, handle_arg_set_env,
4341 "var=value", "sets targets environment variable (see below)"},
4342 {"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
4343 "var", "unsets targets environment variable (see below)"},
4344 {"0", "QEMU_ARGV0", true, handle_arg_argv0,
4345 "argv0", "forces target process argv[0] to be 'argv0'"},
4346 {"r", "QEMU_UNAME", true, handle_arg_uname,
4347 "uname", "set qemu uname release string to 'uname'"},
fc9c5412
JS
4348 {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base,
4349 "address", "set guest_base address to 'address'"},
4350 {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
4351 "size", "reserve 'size' bytes for guest virtual address space"},
fc9c5412 4352 {"d", "QEMU_LOG", true, handle_arg_log,
989b697d
PM
4353 "item[,...]", "enable logging of specified items "
4354 "(use '-d help' for a list of items)"},
8423fa90
AB
4355 {"dfilter", "QEMU_DFILTER", true, handle_arg_dfilter,
4356 "range[,...]","filter logging based on address range"},
50171d42 4357 {"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
989b697d 4358 "logfile", "write logs to 'logfile' (default stderr)"},
fc9c5412
JS
4359 {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
4360 "pagesize", "set the host page size to 'pagesize'"},
4361 {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
4362 "", "run in singlestep mode"},
4363 {"strace", "QEMU_STRACE", false, handle_arg_strace,
4364 "", "log system calls"},
c5e4a5a9
MR
4365 {"seed", "QEMU_RAND_SEED", true, handle_arg_randseed,
4366 "", "Seed for pseudo-random number generator"},
6533dd6e
LV
4367 {"trace", "QEMU_TRACE", true, handle_arg_trace,
4368 "", "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
fc9c5412 4369 {"version", "QEMU_VERSION", false, handle_arg_version,
1386d4c0 4370 "", "display version information and exit"},
fc9c5412
JS
4371 {NULL, NULL, false, NULL, NULL, NULL}
4372};
4373
d03f9c32 4374static void usage(int exitcode)
fc9c5412 4375{
42644cee 4376 const struct qemu_argument *arginfo;
fc9c5412
JS
4377 int maxarglen;
4378 int maxenvlen;
4379
2e59915d
PB
4380 printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
4381 "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
fc9c5412
JS
4382 "\n"
4383 "Options and associated environment variables:\n"
4384 "\n");
4385
63ec54d7
PM
4386 /* Calculate column widths. We must always have at least enough space
4387 * for the column header.
4388 */
4389 maxarglen = strlen("Argument");
4390 maxenvlen = strlen("Env-variable");
fc9c5412
JS
4391
4392 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
63ec54d7
PM
4393 int arglen = strlen(arginfo->argv);
4394 if (arginfo->has_arg) {
4395 arglen += strlen(arginfo->example) + 1;
4396 }
fc9c5412
JS
4397 if (strlen(arginfo->env) > maxenvlen) {
4398 maxenvlen = strlen(arginfo->env);
4399 }
63ec54d7
PM
4400 if (arglen > maxarglen) {
4401 maxarglen = arglen;
fc9c5412
JS
4402 }
4403 }
4404
63ec54d7
PM
4405 printf("%-*s %-*s Description\n", maxarglen+1, "Argument",
4406 maxenvlen, "Env-variable");
fc9c5412
JS
4407
4408 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
4409 if (arginfo->has_arg) {
4410 printf("-%s %-*s %-*s %s\n", arginfo->argv,
63ec54d7
PM
4411 (int)(maxarglen - strlen(arginfo->argv) - 1),
4412 arginfo->example, maxenvlen, arginfo->env, arginfo->help);
fc9c5412 4413 } else {
63ec54d7 4414 printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv,
fc9c5412
JS
4415 maxenvlen, arginfo->env,
4416 arginfo->help);
4417 }
4418 }
4419
4420 printf("\n"
4421 "Defaults:\n"
4422 "QEMU_LD_PREFIX = %s\n"
989b697d 4423 "QEMU_STACK_SIZE = %ld byte\n",
fc9c5412 4424 interp_prefix,
989b697d 4425 guest_stack_size);
fc9c5412
JS
4426
4427 printf("\n"
4428 "You can use -E and -U options or the QEMU_SET_ENV and\n"
4429 "QEMU_UNSET_ENV environment variables to set and unset\n"
4430 "environment variables for the target process.\n"
4431 "It is possible to provide several variables by separating them\n"
4432 "by commas in getsubopt(3) style. Additionally it is possible to\n"
4433 "provide the -E and -U options multiple times.\n"
4434 "The following lines are equivalent:\n"
4435 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
4436 " -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
4437 " QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
4438 "Note that if you provide several changes to a single variable\n"
f5048cb7
EB
4439 "the last change will stay in effect.\n"
4440 "\n"
4441 QEMU_HELP_BOTTOM "\n");
fc9c5412 4442
d03f9c32 4443 exit(exitcode);
fc9c5412
JS
4444}
4445
4446static int parse_args(int argc, char **argv)
4447{
4448 const char *r;
4449 int optind;
42644cee 4450 const struct qemu_argument *arginfo;
fc9c5412
JS
4451
4452 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
4453 if (arginfo->env == NULL) {
4454 continue;
4455 }
4456
4457 r = getenv(arginfo->env);
4458 if (r != NULL) {
4459 arginfo->handle_opt(r);
4460 }
4461 }
4462
4463 optind = 1;
4464 for (;;) {
4465 if (optind >= argc) {
4466 break;
4467 }
4468 r = argv[optind];
4469 if (r[0] != '-') {
4470 break;
4471 }
4472 optind++;
4473 r++;
4474 if (!strcmp(r, "-")) {
4475 break;
4476 }
ba02577c
MI
4477 /* Treat --foo the same as -foo. */
4478 if (r[0] == '-') {
4479 r++;
4480 }
fc9c5412
JS
4481
4482 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
4483 if (!strcmp(r, arginfo->argv)) {
fc9c5412 4484 if (arginfo->has_arg) {
1386d4c0 4485 if (optind >= argc) {
138940bf
MI
4486 (void) fprintf(stderr,
4487 "qemu: missing argument for option '%s'\n", r);
4d1275c2 4488 exit(EXIT_FAILURE);
1386d4c0
PM
4489 }
4490 arginfo->handle_opt(argv[optind]);
fc9c5412 4491 optind++;
1386d4c0
PM
4492 } else {
4493 arginfo->handle_opt(NULL);
fc9c5412 4494 }
fc9c5412
JS
4495 break;
4496 }
4497 }
4498
4499 /* no option matched the current argv */
4500 if (arginfo->handle_opt == NULL) {
138940bf 4501 (void) fprintf(stderr, "qemu: unknown option '%s'\n", r);
4d1275c2 4502 exit(EXIT_FAILURE);
fc9c5412
JS
4503 }
4504 }
4505
4506 if (optind >= argc) {
138940bf 4507 (void) fprintf(stderr, "qemu: no user program specified\n");
4d1275c2 4508 exit(EXIT_FAILURE);
fc9c5412
JS
4509 }
4510
4511 filename = argv[optind];
4512 exec_path = argv[optind];
4513
4514 return optind;
4515}
4516
902b3d5c 4517int main(int argc, char **argv, char **envp)
31e31b8a 4518{
01ffc75b 4519 struct target_pt_regs regs1, *regs = &regs1;
31e31b8a 4520 struct image_info info1, *info = &info1;
edf8e2af 4521 struct linux_binprm bprm;
48e15fc2 4522 TaskState *ts;
9349b4f9 4523 CPUArchState *env;
db6b81d4 4524 CPUState *cpu;
586314f2 4525 int optind;
04a6dfeb 4526 char **target_environ, **wrk;
7d8cec95
AJ
4527 char **target_argv;
4528 int target_argc;
7d8cec95 4529 int i;
fd4d81dd 4530 int ret;
03cfd8fa 4531 int execfd;
b12b6a18 4532
fe4db84d 4533 module_call_init(MODULE_INIT_TRACE);
267f685b 4534 qemu_init_cpu_list();
ce008c1f
AF
4535 module_call_init(MODULE_INIT_QOM);
4536
ec45bbe5 4537 envlist = envlist_create();
04a6dfeb
AJ
4538
4539 /* add current environment into the list */
4540 for (wrk = environ; *wrk != NULL; wrk++) {
4541 (void) envlist_setenv(envlist, *wrk);
4542 }
4543
703e0e89
RH
4544 /* Read the stack limit from the kernel. If it's "unlimited",
4545 then we can do little else besides use the default. */
4546 {
4547 struct rlimit lim;
4548 if (getrlimit(RLIMIT_STACK, &lim) == 0
81bbe906
TY
4549 && lim.rlim_cur != RLIM_INFINITY
4550 && lim.rlim_cur == (target_long)lim.rlim_cur) {
703e0e89
RH
4551 guest_stack_size = lim.rlim_cur;
4552 }
4553 }
4554
b1f9be31 4555 cpu_model = NULL;
b5ec5ce0 4556
c5e4a5a9
MR
4557 srand(time(NULL));
4558
6533dd6e
LV
4559 qemu_add_opts(&qemu_trace_opts);
4560
fc9c5412 4561 optind = parse_args(argc, argv);
586314f2 4562
6533dd6e
LV
4563 if (!trace_init_backends()) {
4564 exit(1);
4565 }
4566 trace_init_file(trace_file);
4567
31e31b8a 4568 /* Zero out regs */
01ffc75b 4569 memset(regs, 0, sizeof(struct target_pt_regs));
31e31b8a
FB
4570
4571 /* Zero out image_info */
4572 memset(info, 0, sizeof(struct image_info));
4573
edf8e2af
MW
4574 memset(&bprm, 0, sizeof (bprm));
4575
74cd30b8
FB
4576 /* Scan interp_prefix dir for replacement files. */
4577 init_paths(interp_prefix);
4578
4a24a758
PM
4579 init_qemu_uname_release();
4580
768fe76e
YS
4581 execfd = qemu_getauxval(AT_EXECFD);
4582 if (execfd == 0) {
4583 execfd = open(filename, O_RDONLY);
4584 if (execfd < 0) {
4585 printf("Error while loading %s: %s\n", filename, strerror(errno));
4586 _exit(EXIT_FAILURE);
4587 }
4588 }
4589
46027c07 4590 if (cpu_model == NULL) {
768fe76e 4591 cpu_model = cpu_get_model(get_elf_eflags(execfd));
aaed909a 4592 }
2278b939
IM
4593 cpu_type = parse_cpu_model(cpu_model);
4594
d5ab9713 4595 tcg_exec_init(0);
83fb7adf
FB
4596 /* NOTE: we need to init the CPU at this stage to get
4597 qemu_host_page_size */
2278b939
IM
4598
4599 cpu = cpu_create(cpu_type);
2994fd96 4600 env = cpu->env_ptr;
0ac46af3 4601 cpu_reset(cpu);
b55a37c9 4602
db6b81d4 4603 thread_cpu = cpu;
3b46e624 4604
b6741956
FB
4605 if (getenv("QEMU_STRACE")) {
4606 do_strace = 1;
b92c47c1
TS
4607 }
4608
c5e4a5a9
MR
4609 if (getenv("QEMU_RAND_SEED")) {
4610 handle_arg_randseed(getenv("QEMU_RAND_SEED"));
4611 }
4612
04a6dfeb
AJ
4613 target_environ = envlist_to_environ(envlist, NULL);
4614 envlist_free(envlist);
b12b6a18 4615
379f6698
PB
4616 /*
4617 * Now that page sizes are configured in cpu_init() we can do
4618 * proper page alignment for guest_base.
4619 */
4620 guest_base = HOST_PAGE_ALIGN(guest_base);
68a1c816 4621
806d1021
MI
4622 if (reserved_va || have_guest_base) {
4623 guest_base = init_guest_space(guest_base, reserved_va, 0,
4624 have_guest_base);
4625 if (guest_base == (unsigned long)-1) {
097b8cb8
PM
4626 fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
4627 "space for use as guest address space (check your virtual "
4628 "memory ulimit setting or reserve less using -R option)\n",
4629 reserved_va);
4d1275c2 4630 exit(EXIT_FAILURE);
68a1c816 4631 }
97cc7560 4632
806d1021
MI
4633 if (reserved_va) {
4634 mmap_next_start = reserved_va;
97cc7560
DDAG
4635 }
4636 }
379f6698
PB
4637
4638 /*
4639 * Read in mmap_min_addr kernel parameter. This value is used
4640 * When loading the ELF image to determine whether guest_base
14f24e14 4641 * is needed. It is also used in mmap_find_vma.
379f6698 4642 */
14f24e14 4643 {
379f6698
PB
4644 FILE *fp;
4645
4646 if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
4647 unsigned long tmp;
4648 if (fscanf(fp, "%lu", &tmp) == 1) {
4649 mmap_min_addr = tmp;
13829020 4650 qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
379f6698
PB
4651 }
4652 fclose(fp);
4653 }
4654 }
379f6698 4655
7d8cec95
AJ
4656 /*
4657 * Prepare copy of argv vector for target.
4658 */
4659 target_argc = argc - optind;
4660 target_argv = calloc(target_argc + 1, sizeof (char *));
4661 if (target_argv == NULL) {
4662 (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
4d1275c2 4663 exit(EXIT_FAILURE);
7d8cec95
AJ
4664 }
4665
4666 /*
4667 * If argv0 is specified (using '-0' switch) we replace
4668 * argv[0] pointer with the given one.
4669 */
4670 i = 0;
4671 if (argv0 != NULL) {
4672 target_argv[i++] = strdup(argv0);
4673 }
4674 for (; i < target_argc; i++) {
4675 target_argv[i] = strdup(argv[optind + i]);
4676 }
4677 target_argv[target_argc] = NULL;
4678
c78d65e8 4679 ts = g_new0(TaskState, 1);
edf8e2af
MW
4680 init_task_state(ts);
4681 /* build Task State */
4682 ts->info = info;
4683 ts->bprm = &bprm;
0429a971 4684 cpu->opaque = ts;
edf8e2af
MW
4685 task_settid(ts);
4686
03cfd8fa 4687 ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
fd4d81dd
AP
4688 info, &bprm);
4689 if (ret != 0) {
885c1d10 4690 printf("Error while loading %s: %s\n", filename, strerror(-ret));
4d1275c2 4691 _exit(EXIT_FAILURE);
b12b6a18
TS
4692 }
4693
4694 for (wrk = target_environ; *wrk; wrk++) {
ec45bbe5 4695 g_free(*wrk);
31e31b8a 4696 }
3b46e624 4697
ec45bbe5 4698 g_free(target_environ);
b12b6a18 4699
13829020 4700 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
379f6698 4701 qemu_log("guest_base 0x%lx\n", guest_base);
2e77eac6
BS
4702 log_page_dump();
4703
4704 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
4705 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
7c4ee5bc
RH
4706 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n", info->start_code);
4707 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n", info->start_data);
2e77eac6 4708 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
7c4ee5bc 4709 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", info->start_stack);
2e77eac6
BS
4710 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
4711 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
7c4ee5bc
RH
4712 qemu_log("argv_start 0x" TARGET_ABI_FMT_lx "\n", info->arg_start);
4713 qemu_log("env_start 0x" TARGET_ABI_FMT_lx "\n",
4714 info->arg_end + (abi_ulong)sizeof(abi_ulong));
4715 qemu_log("auxv_start 0x" TARGET_ABI_FMT_lx "\n", info->saved_auxv);
2e77eac6 4716 }
31e31b8a 4717
53a5960a 4718 target_set_brk(info->brk);
31e31b8a 4719 syscall_init();
66fb9763 4720 signal_init();
31e31b8a 4721
9002ec79
RH
4722 /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
4723 generating the prologue until now so that the prologue can take
4724 the real value of GUEST_BASE into account. */
b1311c4a 4725 tcg_prologue_init(tcg_ctx);
e8feb96f 4726 tcg_region_init();
9002ec79 4727
cd71c089
LV
4728 target_cpu_copy_regs(env, regs);
4729
b346ff46 4730#if defined(TARGET_I386)
3802ce26 4731 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
b98dbc90 4732 env->hflags |= HF_PE_MASK | HF_CPL_MASK;
0514ef2f 4733 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
1bde465e
FB
4734 env->cr[4] |= CR4_OSFXSR_MASK;
4735 env->hflags |= HF_OSFXSR_MASK;
4736 }
d2fd1af7 4737#ifndef TARGET_ABI32
4dbc422b 4738 /* enable 64 bit mode if possible */
0514ef2f 4739 if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
4dbc422b 4740 fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
4d1275c2 4741 exit(EXIT_FAILURE);
4dbc422b 4742 }
d2fd1af7 4743 env->cr[4] |= CR4_PAE_MASK;
4dbc422b 4744 env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
d2fd1af7
FB
4745 env->hflags |= HF_LMA_MASK;
4746#endif
1bde465e 4747
415e561f
FB
4748 /* flags setup : we activate the IRQs by default as in user mode */
4749 env->eflags |= IF_MASK;
3b46e624 4750
6dbad63e 4751 /* linux register setup */
d2fd1af7 4752#ifndef TARGET_ABI32
84409ddb
JM
4753 env->regs[R_EAX] = regs->rax;
4754 env->regs[R_EBX] = regs->rbx;
4755 env->regs[R_ECX] = regs->rcx;
4756 env->regs[R_EDX] = regs->rdx;
4757 env->regs[R_ESI] = regs->rsi;
4758 env->regs[R_EDI] = regs->rdi;
4759 env->regs[R_EBP] = regs->rbp;
4760 env->regs[R_ESP] = regs->rsp;
4761 env->eip = regs->rip;
4762#else
0ecfa993
FB
4763 env->regs[R_EAX] = regs->eax;
4764 env->regs[R_EBX] = regs->ebx;
4765 env->regs[R_ECX] = regs->ecx;
4766 env->regs[R_EDX] = regs->edx;
4767 env->regs[R_ESI] = regs->esi;
4768 env->regs[R_EDI] = regs->edi;
4769 env->regs[R_EBP] = regs->ebp;
4770 env->regs[R_ESP] = regs->esp;
dab2ed99 4771 env->eip = regs->eip;
84409ddb 4772#endif
31e31b8a 4773
f4beb510 4774 /* linux interrupt setup */
e441570f
AZ
4775#ifndef TARGET_ABI32
4776 env->idt.limit = 511;
4777#else
4778 env->idt.limit = 255;
4779#endif
4780 env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
4781 PROT_READ|PROT_WRITE,
4782 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4783 idt_table = g2h(env->idt.base);
f4beb510
FB
4784 set_idt(0, 0);
4785 set_idt(1, 0);
4786 set_idt(2, 0);
4787 set_idt(3, 3);
4788 set_idt(4, 3);
ec95da6c 4789 set_idt(5, 0);
f4beb510
FB
4790 set_idt(6, 0);
4791 set_idt(7, 0);
4792 set_idt(8, 0);
4793 set_idt(9, 0);
4794 set_idt(10, 0);
4795 set_idt(11, 0);
4796 set_idt(12, 0);
4797 set_idt(13, 0);
4798 set_idt(14, 0);
4799 set_idt(15, 0);
4800 set_idt(16, 0);
4801 set_idt(17, 0);
4802 set_idt(18, 0);
4803 set_idt(19, 0);
4804 set_idt(0x80, 3);
4805
6dbad63e 4806 /* linux segment setup */
8d18e893
FB
4807 {
4808 uint64_t *gdt_table;
e441570f
AZ
4809 env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
4810 PROT_READ|PROT_WRITE,
4811 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
8d18e893 4812 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
e441570f 4813 gdt_table = g2h(env->gdt.base);
d2fd1af7 4814#ifdef TARGET_ABI32
8d18e893
FB
4815 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
4816 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4817 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
d2fd1af7
FB
4818#else
4819 /* 64 bit code segment */
4820 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
4821 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4822 DESC_L_MASK |
4823 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
4824#endif
8d18e893
FB
4825 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
4826 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4827 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
4828 }
6dbad63e 4829 cpu_x86_load_seg(env, R_CS, __USER_CS);
d2fd1af7
FB
4830 cpu_x86_load_seg(env, R_SS, __USER_DS);
4831#ifdef TARGET_ABI32
6dbad63e
FB
4832 cpu_x86_load_seg(env, R_DS, __USER_DS);
4833 cpu_x86_load_seg(env, R_ES, __USER_DS);
6dbad63e
FB
4834 cpu_x86_load_seg(env, R_FS, __USER_DS);
4835 cpu_x86_load_seg(env, R_GS, __USER_DS);
d6eb40f6
TS
4836 /* This hack makes Wine work... */
4837 env->segs[R_FS].selector = 0;
d2fd1af7
FB
4838#else
4839 cpu_x86_load_seg(env, R_DS, 0);
4840 cpu_x86_load_seg(env, R_ES, 0);
4841 cpu_x86_load_seg(env, R_FS, 0);
4842 cpu_x86_load_seg(env, R_GS, 0);
4843#endif
99033cae
AG
4844#elif defined(TARGET_AARCH64)
4845 {
4846 int i;
4847
4848 if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
4849 fprintf(stderr,
4850 "The selected ARM CPU does not support 64 bit mode\n");
4d1275c2 4851 exit(EXIT_FAILURE);
99033cae
AG
4852 }
4853
4854 for (i = 0; i < 31; i++) {
4855 env->xregs[i] = regs->regs[i];
4856 }
4857 env->pc = regs->pc;
4858 env->xregs[31] = regs->sp;
dfdcf340
MW
4859#ifdef TARGET_WORDS_BIGENDIAN
4860 env->cp15.sctlr_el[1] |= SCTLR_E0E;
4861 for (i = 1; i < 4; ++i) {
4862 env->cp15.sctlr_el[i] |= SCTLR_EE;
4863 }
4864#endif
99033cae 4865 }
b346ff46
FB
4866#elif defined(TARGET_ARM)
4867 {
4868 int i;
ae087923
PM
4869 cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
4870 CPSRWriteByInstr);
b346ff46
FB
4871 for(i = 0; i < 16; i++) {
4872 env->regs[i] = regs->uregs[i];
4873 }
f9fd40eb 4874#ifdef TARGET_WORDS_BIGENDIAN
d8fd2954
PB
4875 /* Enable BE8. */
4876 if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
4877 && (info->elf_flags & EF_ARM_BE8)) {
9c5a7460
PC
4878 env->uncached_cpsr |= CPSR_E;
4879 env->cp15.sctlr_el[1] |= SCTLR_E0E;
f9fd40eb
PB
4880 } else {
4881 env->cp15.sctlr_el[1] |= SCTLR_B;
d8fd2954 4882 }
f9fd40eb 4883#endif
b346ff46 4884 }
93ac68bc 4885#elif defined(TARGET_SPARC)
060366c5
FB
4886 {
4887 int i;
4888 env->pc = regs->pc;
4889 env->npc = regs->npc;
4890 env->y = regs->y;
4891 for(i = 0; i < 8; i++)
4892 env->gregs[i] = regs->u_regs[i];
4893 for(i = 0; i < 8; i++)
4894 env->regwptr[i] = regs->u_regs[i + 8];
4895 }
67867308
FB
4896#elif defined(TARGET_PPC)
4897 {
4898 int i;
3fc6c082 4899
0411a972 4900#if defined(TARGET_PPC64)
c8361129 4901 int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF;
0411a972 4902#if defined(TARGET_ABI32)
c8361129 4903 env->msr &= ~((target_ulong)1 << flag);
e85e7c6e 4904#else
c8361129 4905 env->msr |= (target_ulong)1 << flag;
0411a972 4906#endif
84409ddb 4907#endif
67867308
FB
4908 env->nip = regs->nip;
4909 for(i = 0; i < 32; i++) {
4910 env->gpr[i] = regs->gpr[i];
4911 }
4912 }
e6e5906b
PB
4913#elif defined(TARGET_M68K)
4914 {
e6e5906b
PB
4915 env->pc = regs->pc;
4916 env->dregs[0] = regs->d0;
4917 env->dregs[1] = regs->d1;
4918 env->dregs[2] = regs->d2;
4919 env->dregs[3] = regs->d3;
4920 env->dregs[4] = regs->d4;
4921 env->dregs[5] = regs->d5;
4922 env->dregs[6] = regs->d6;
4923 env->dregs[7] = regs->d7;
4924 env->aregs[0] = regs->a0;
4925 env->aregs[1] = regs->a1;
4926 env->aregs[2] = regs->a2;
4927 env->aregs[3] = regs->a3;
4928 env->aregs[4] = regs->a4;
4929 env->aregs[5] = regs->a5;
4930 env->aregs[6] = regs->a6;
4931 env->aregs[7] = regs->usp;
4932 env->sr = regs->sr;
4933 ts->sim_syscalls = 1;
4934 }
b779e29e
EI
4935#elif defined(TARGET_MICROBLAZE)
4936 {
4937 env->regs[0] = regs->r0;
4938 env->regs[1] = regs->r1;
4939 env->regs[2] = regs->r2;
4940 env->regs[3] = regs->r3;
4941 env->regs[4] = regs->r4;
4942 env->regs[5] = regs->r5;
4943 env->regs[6] = regs->r6;
4944 env->regs[7] = regs->r7;
4945 env->regs[8] = regs->r8;
4946 env->regs[9] = regs->r9;
4947 env->regs[10] = regs->r10;
4948 env->regs[11] = regs->r11;
4949 env->regs[12] = regs->r12;
4950 env->regs[13] = regs->r13;
4951 env->regs[14] = regs->r14;
4952 env->regs[15] = regs->r15;
4953 env->regs[16] = regs->r16;
4954 env->regs[17] = regs->r17;
4955 env->regs[18] = regs->r18;
4956 env->regs[19] = regs->r19;
4957 env->regs[20] = regs->r20;
4958 env->regs[21] = regs->r21;
4959 env->regs[22] = regs->r22;
4960 env->regs[23] = regs->r23;
4961 env->regs[24] = regs->r24;
4962 env->regs[25] = regs->r25;
4963 env->regs[26] = regs->r26;
4964 env->regs[27] = regs->r27;
4965 env->regs[28] = regs->r28;
4966 env->regs[29] = regs->r29;
4967 env->regs[30] = regs->r30;
4968 env->regs[31] = regs->r31;
4969 env->sregs[SR_PC] = regs->pc;
4970 }
048f6b4d
FB
4971#elif defined(TARGET_MIPS)
4972 {
4973 int i;
4974
4975 for(i = 0; i < 32; i++) {
b5dc7732 4976 env->active_tc.gpr[i] = regs->regs[i];
048f6b4d 4977 }
0fddbbf2
NF
4978 env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1;
4979 if (regs->cp0_epc & 1) {
4980 env->hflags |= MIPS_HFLAG_M16;
4981 }
599bc5e8
AM
4982 if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
4983 ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
4984 if ((env->active_fpu.fcr31_rw_bitmask &
4985 (1 << FCR31_NAN2008)) == 0) {
4986 fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
4987 exit(1);
4988 }
4989 if ((info->elf_flags & EF_MIPS_NAN2008) != 0) {
4990 env->active_fpu.fcr31 |= (1 << FCR31_NAN2008);
4991 } else {
4992 env->active_fpu.fcr31 &= ~(1 << FCR31_NAN2008);
4993 }
4994 restore_snan_bit_mode(env);
4995 }
048f6b4d 4996 }
a0a839b6
MV
4997#elif defined(TARGET_NIOS2)
4998 {
4999 env->regs[0] = 0;
5000 env->regs[1] = regs->r1;
5001 env->regs[2] = regs->r2;
5002 env->regs[3] = regs->r3;
5003 env->regs[4] = regs->r4;
5004 env->regs[5] = regs->r5;
5005 env->regs[6] = regs->r6;
5006 env->regs[7] = regs->r7;
5007 env->regs[8] = regs->r8;
5008 env->regs[9] = regs->r9;
5009 env->regs[10] = regs->r10;
5010 env->regs[11] = regs->r11;
5011 env->regs[12] = regs->r12;
5012 env->regs[13] = regs->r13;
5013 env->regs[14] = regs->r14;
5014 env->regs[15] = regs->r15;
5015 /* TODO: unsigned long orig_r2; */
5016 env->regs[R_RA] = regs->ra;
5017 env->regs[R_FP] = regs->fp;
5018 env->regs[R_SP] = regs->sp;
5019 env->regs[R_GP] = regs->gp;
5020 env->regs[CR_ESTATUS] = regs->estatus;
5021 env->regs[R_EA] = regs->ea;
5022 /* TODO: unsigned long orig_r7; */
5023
5024 /* Emulate eret when starting thread. */
5025 env->regs[R_PC] = regs->ea;
5026 }
d962783e
JL
5027#elif defined(TARGET_OPENRISC)
5028 {
5029 int i;
5030
5031 for (i = 0; i < 32; i++) {
d89e71e8 5032 cpu_set_gpr(env, i, regs->gpr[i]);
d962783e 5033 }
d962783e 5034 env->pc = regs->pc;
84775c43 5035 cpu_set_sr(env, regs->sr);
d962783e 5036 }
47ae93cd
MC
5037#elif defined(TARGET_RISCV)
5038 {
5039 env->pc = regs->sepc;
5040 env->gpr[xSP] = regs->sp;
5041 }
fdf9b3e8
FB
5042#elif defined(TARGET_SH4)
5043 {
5044 int i;
5045
5046 for(i = 0; i < 16; i++) {
5047 env->gregs[i] = regs->regs[i];
5048 }
5049 env->pc = regs->pc;
5050 }
7a3148a9
JM
5051#elif defined(TARGET_ALPHA)
5052 {
5053 int i;
5054
5055 for(i = 0; i < 28; i++) {
992f48a0 5056 env->ir[i] = ((abi_ulong *)regs)[i];
7a3148a9 5057 }
dad081ee 5058 env->ir[IR_SP] = regs->usp;
7a3148a9 5059 env->pc = regs->pc;
7a3148a9 5060 }
48733d19
TS
5061#elif defined(TARGET_CRIS)
5062 {
5063 env->regs[0] = regs->r0;
5064 env->regs[1] = regs->r1;
5065 env->regs[2] = regs->r2;
5066 env->regs[3] = regs->r3;
5067 env->regs[4] = regs->r4;
5068 env->regs[5] = regs->r5;
5069 env->regs[6] = regs->r6;
5070 env->regs[7] = regs->r7;
5071 env->regs[8] = regs->r8;
5072 env->regs[9] = regs->r9;
5073 env->regs[10] = regs->r10;
5074 env->regs[11] = regs->r11;
5075 env->regs[12] = regs->r12;
5076 env->regs[13] = regs->r13;
5077 env->regs[14] = info->start_stack;
5078 env->regs[15] = regs->acr;
5079 env->pc = regs->erp;
5080 }
a4c075f1
UH
5081#elif defined(TARGET_S390X)
5082 {
5083 int i;
5084 for (i = 0; i < 16; i++) {
5085 env->regs[i] = regs->gprs[i];
5086 }
5087 env->psw.mask = regs->psw.mask;
5088 env->psw.addr = regs->psw.addr;
5089 }
b16189b2
CG
5090#elif defined(TARGET_TILEGX)
5091 {
5092 int i;
5093 for (i = 0; i < TILEGX_R_COUNT; i++) {
5094 env->regs[i] = regs->regs[i];
5095 }
5096 for (i = 0; i < TILEGX_SPR_COUNT; i++) {
5097 env->spregs[i] = 0;
5098 }
5099 env->pc = regs->pc;
5100 }
7c248bcd
RH
5101#elif defined(TARGET_HPPA)
5102 {
5103 int i;
5104 for (i = 1; i < 32; i++) {
5105 env->gr[i] = regs->gr[i];
5106 }
5107 env->iaoq_f = regs->iaoq[0];
5108 env->iaoq_b = regs->iaoq[1];
5109 }
ba7651fb
MF
5110#elif defined(TARGET_XTENSA)
5111 {
5112 int i;
5113 for (i = 0; i < 16; ++i) {
5114 env->regs[i] = regs->areg[i];
5115 }
5116 env->sregs[WINDOW_START] = regs->windowstart;
5117 env->pc = regs->pc;
5118 }
b346ff46 5119#endif
31e31b8a 5120
daa4374a 5121#if defined(TARGET_ARM) || defined(TARGET_M68K)
a87295e8
PB
5122 ts->stack_base = info->start_stack;
5123 ts->heap_base = info->brk;
5124 /* This will be filled in on the first SYS_HEAPINFO call. */
5125 ts->heap_limit = 0;
5126#endif
5127
74c33bed 5128 if (gdbstub_port) {
ff7a981a
PM
5129 if (gdbserver_start(gdbstub_port) < 0) {
5130 fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
5131 gdbstub_port);
4d1275c2 5132 exit(EXIT_FAILURE);
ff7a981a 5133 }
db6b81d4 5134 gdb_handlesig(cpu, 0);
1fddef4b 5135 }
1b6b029e
FB
5136 cpu_loop(env);
5137 /* never exits */
31e31b8a
FB
5138 return 0;
5139}
This page took 1.775255 seconds and 4 git commands to generate.