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