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