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