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