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