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