tcg-ppc: Merge cache-utils into the backend
[qemu.git] / linux-user / main.c
blobdf1bb0e758a3dccf15e7062628e552f07cc7e5aa
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 <stdlib.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <sys/mman.h>
26 #include <sys/syscall.h>
27 #include <sys/resource.h>
29 #include "qemu.h"
30 #include "qemu-common.h"
31 #include "cpu.h"
32 #include "tcg.h"
33 #include "qemu/timer.h"
34 #include "qemu/envlist.h"
35 #include "elf.h"
37 char *exec_path;
39 int singlestep;
40 const char *filename;
41 const char *argv0;
42 int gdbstub_port;
43 envlist_t *envlist;
44 static const char *cpu_model;
45 unsigned long mmap_min_addr;
46 #if defined(CONFIG_USE_GUEST_BASE)
47 unsigned long guest_base;
48 int have_guest_base;
49 #if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
51 * When running 32-on-64 we should make sure we can fit all of the possible
52 * guest address space into a contiguous chunk of virtual host memory.
54 * This way we will never overlap with our own libraries or binaries or stack
55 * or anything else that QEMU maps.
57 # ifdef TARGET_MIPS
58 /* MIPS only supports 31 bits of virtual address space for user space */
59 unsigned long reserved_va = 0x77000000;
60 # else
61 unsigned long reserved_va = 0xf7000000;
62 # endif
63 #else
64 unsigned long reserved_va;
65 #endif
66 #endif
68 static void usage(void);
70 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
71 const char *qemu_uname_release;
73 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
74 we allocate a bigger stack. Need a better solution, for example
75 by remapping the process stack directly at the right place */
76 unsigned long guest_stack_size = 8 * 1024 * 1024UL;
78 void gemu_log(const char *fmt, ...)
80 va_list ap;
82 va_start(ap, fmt);
83 vfprintf(stderr, fmt, ap);
84 va_end(ap);
87 #if defined(TARGET_I386)
88 int cpu_get_pic_interrupt(CPUX86State *env)
90 return -1;
92 #endif
94 /***********************************************************/
95 /* Helper routines for implementing atomic operations. */
97 /* To implement exclusive operations we force all cpus to syncronise.
98 We don't require a full sync, only that no cpus are executing guest code.
99 The alternative is to map target atomic ops onto host equivalents,
100 which requires quite a lot of per host/target work. */
101 static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
102 static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
103 static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
104 static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
105 static int pending_cpus;
107 /* Make sure everything is in a consistent state for calling fork(). */
108 void fork_start(void)
110 pthread_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
111 pthread_mutex_lock(&exclusive_lock);
112 mmap_fork_start();
115 void fork_end(int child)
117 mmap_fork_end(child);
118 if (child) {
119 CPUState *cpu, *next_cpu;
120 /* Child processes created by fork() only have a single thread.
121 Discard information about the parent threads. */
122 CPU_FOREACH_SAFE(cpu, next_cpu) {
123 if (cpu != thread_cpu) {
124 QTAILQ_REMOVE(&cpus, thread_cpu, node);
127 pending_cpus = 0;
128 pthread_mutex_init(&exclusive_lock, NULL);
129 pthread_mutex_init(&cpu_list_mutex, NULL);
130 pthread_cond_init(&exclusive_cond, NULL);
131 pthread_cond_init(&exclusive_resume, NULL);
132 pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL);
133 gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
134 } else {
135 pthread_mutex_unlock(&exclusive_lock);
136 pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
140 /* Wait for pending exclusive operations to complete. The exclusive lock
141 must be held. */
142 static inline void exclusive_idle(void)
144 while (pending_cpus) {
145 pthread_cond_wait(&exclusive_resume, &exclusive_lock);
149 /* Start an exclusive operation.
150 Must only be called from outside cpu_arm_exec. */
151 static inline void start_exclusive(void)
153 CPUState *other_cpu;
155 pthread_mutex_lock(&exclusive_lock);
156 exclusive_idle();
158 pending_cpus = 1;
159 /* Make all other cpus stop executing. */
160 CPU_FOREACH(other_cpu) {
161 if (other_cpu->running) {
162 pending_cpus++;
163 cpu_exit(other_cpu);
166 if (pending_cpus > 1) {
167 pthread_cond_wait(&exclusive_cond, &exclusive_lock);
171 /* Finish an exclusive operation. */
172 static inline void end_exclusive(void)
174 pending_cpus = 0;
175 pthread_cond_broadcast(&exclusive_resume);
176 pthread_mutex_unlock(&exclusive_lock);
179 /* Wait for exclusive ops to finish, and begin cpu execution. */
180 static inline void cpu_exec_start(CPUState *cpu)
182 pthread_mutex_lock(&exclusive_lock);
183 exclusive_idle();
184 cpu->running = true;
185 pthread_mutex_unlock(&exclusive_lock);
188 /* Mark cpu as not executing, and release pending exclusive ops. */
189 static inline void cpu_exec_end(CPUState *cpu)
191 pthread_mutex_lock(&exclusive_lock);
192 cpu->running = false;
193 if (pending_cpus > 1) {
194 pending_cpus--;
195 if (pending_cpus == 1) {
196 pthread_cond_signal(&exclusive_cond);
199 exclusive_idle();
200 pthread_mutex_unlock(&exclusive_lock);
203 void cpu_list_lock(void)
205 pthread_mutex_lock(&cpu_list_mutex);
208 void cpu_list_unlock(void)
210 pthread_mutex_unlock(&cpu_list_mutex);
214 #ifdef TARGET_I386
215 /***********************************************************/
216 /* CPUX86 core interface */
218 void cpu_smm_update(CPUX86State *env)
222 uint64_t cpu_get_tsc(CPUX86State *env)
224 return cpu_get_real_ticks();
227 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
228 int flags)
230 unsigned int e1, e2;
231 uint32_t *p;
232 e1 = (addr << 16) | (limit & 0xffff);
233 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
234 e2 |= flags;
235 p = ptr;
236 p[0] = tswap32(e1);
237 p[1] = tswap32(e2);
240 static uint64_t *idt_table;
241 #ifdef TARGET_X86_64
242 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
243 uint64_t addr, unsigned int sel)
245 uint32_t *p, e1, e2;
246 e1 = (addr & 0xffff) | (sel << 16);
247 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
248 p = ptr;
249 p[0] = tswap32(e1);
250 p[1] = tswap32(e2);
251 p[2] = tswap32(addr >> 32);
252 p[3] = 0;
254 /* only dpl matters as we do only user space emulation */
255 static void set_idt(int n, unsigned int dpl)
257 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
259 #else
260 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
261 uint32_t addr, unsigned int sel)
263 uint32_t *p, e1, e2;
264 e1 = (addr & 0xffff) | (sel << 16);
265 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
266 p = ptr;
267 p[0] = tswap32(e1);
268 p[1] = tswap32(e2);
271 /* only dpl matters as we do only user space emulation */
272 static void set_idt(int n, unsigned int dpl)
274 set_gate(idt_table + n, 0, dpl, 0, 0);
276 #endif
278 void cpu_loop(CPUX86State *env)
280 CPUState *cs = CPU(x86_env_get_cpu(env));
281 int trapnr;
282 abi_ulong pc;
283 target_siginfo_t info;
285 for(;;) {
286 trapnr = cpu_x86_exec(env);
287 switch(trapnr) {
288 case 0x80:
289 /* linux syscall from int $0x80 */
290 env->regs[R_EAX] = do_syscall(env,
291 env->regs[R_EAX],
292 env->regs[R_EBX],
293 env->regs[R_ECX],
294 env->regs[R_EDX],
295 env->regs[R_ESI],
296 env->regs[R_EDI],
297 env->regs[R_EBP],
298 0, 0);
299 break;
300 #ifndef TARGET_ABI32
301 case EXCP_SYSCALL:
302 /* linux syscall from syscall instruction */
303 env->regs[R_EAX] = do_syscall(env,
304 env->regs[R_EAX],
305 env->regs[R_EDI],
306 env->regs[R_ESI],
307 env->regs[R_EDX],
308 env->regs[10],
309 env->regs[8],
310 env->regs[9],
311 0, 0);
312 env->eip = env->exception_next_eip;
313 break;
314 #endif
315 case EXCP0B_NOSEG:
316 case EXCP0C_STACK:
317 info.si_signo = SIGBUS;
318 info.si_errno = 0;
319 info.si_code = TARGET_SI_KERNEL;
320 info._sifields._sigfault._addr = 0;
321 queue_signal(env, info.si_signo, &info);
322 break;
323 case EXCP0D_GPF:
324 /* XXX: potential problem if ABI32 */
325 #ifndef TARGET_X86_64
326 if (env->eflags & VM_MASK) {
327 handle_vm86_fault(env);
328 } else
329 #endif
331 info.si_signo = SIGSEGV;
332 info.si_errno = 0;
333 info.si_code = TARGET_SI_KERNEL;
334 info._sifields._sigfault._addr = 0;
335 queue_signal(env, info.si_signo, &info);
337 break;
338 case EXCP0E_PAGE:
339 info.si_signo = SIGSEGV;
340 info.si_errno = 0;
341 if (!(env->error_code & 1))
342 info.si_code = TARGET_SEGV_MAPERR;
343 else
344 info.si_code = TARGET_SEGV_ACCERR;
345 info._sifields._sigfault._addr = env->cr[2];
346 queue_signal(env, info.si_signo, &info);
347 break;
348 case EXCP00_DIVZ:
349 #ifndef TARGET_X86_64
350 if (env->eflags & VM_MASK) {
351 handle_vm86_trap(env, trapnr);
352 } else
353 #endif
355 /* division by zero */
356 info.si_signo = SIGFPE;
357 info.si_errno = 0;
358 info.si_code = TARGET_FPE_INTDIV;
359 info._sifields._sigfault._addr = env->eip;
360 queue_signal(env, info.si_signo, &info);
362 break;
363 case EXCP01_DB:
364 case EXCP03_INT3:
365 #ifndef TARGET_X86_64
366 if (env->eflags & VM_MASK) {
367 handle_vm86_trap(env, trapnr);
368 } else
369 #endif
371 info.si_signo = SIGTRAP;
372 info.si_errno = 0;
373 if (trapnr == EXCP01_DB) {
374 info.si_code = TARGET_TRAP_BRKPT;
375 info._sifields._sigfault._addr = env->eip;
376 } else {
377 info.si_code = TARGET_SI_KERNEL;
378 info._sifields._sigfault._addr = 0;
380 queue_signal(env, info.si_signo, &info);
382 break;
383 case EXCP04_INTO:
384 case EXCP05_BOUND:
385 #ifndef TARGET_X86_64
386 if (env->eflags & VM_MASK) {
387 handle_vm86_trap(env, trapnr);
388 } else
389 #endif
391 info.si_signo = SIGSEGV;
392 info.si_errno = 0;
393 info.si_code = TARGET_SI_KERNEL;
394 info._sifields._sigfault._addr = 0;
395 queue_signal(env, info.si_signo, &info);
397 break;
398 case EXCP06_ILLOP:
399 info.si_signo = SIGILL;
400 info.si_errno = 0;
401 info.si_code = TARGET_ILL_ILLOPN;
402 info._sifields._sigfault._addr = env->eip;
403 queue_signal(env, info.si_signo, &info);
404 break;
405 case EXCP_INTERRUPT:
406 /* just indicate that signals should be handled asap */
407 break;
408 case EXCP_DEBUG:
410 int sig;
412 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
413 if (sig)
415 info.si_signo = sig;
416 info.si_errno = 0;
417 info.si_code = TARGET_TRAP_BRKPT;
418 queue_signal(env, info.si_signo, &info);
421 break;
422 default:
423 pc = env->segs[R_CS].base + env->eip;
424 fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
425 (long)pc, trapnr);
426 abort();
428 process_pending_signals(env);
431 #endif
433 #ifdef TARGET_ARM
435 #define get_user_code_u32(x, gaddr, doswap) \
436 ({ abi_long __r = get_user_u32((x), (gaddr)); \
437 if (!__r && (doswap)) { \
438 (x) = bswap32(x); \
440 __r; \
443 #define get_user_code_u16(x, gaddr, doswap) \
444 ({ abi_long __r = get_user_u16((x), (gaddr)); \
445 if (!__r && (doswap)) { \
446 (x) = bswap16(x); \
448 __r; \
451 #ifdef TARGET_ABI32
452 /* Commpage handling -- there is no commpage for AArch64 */
455 * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
456 * Input:
457 * r0 = pointer to oldval
458 * r1 = pointer to newval
459 * r2 = pointer to target value
461 * Output:
462 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
463 * C set if *ptr was changed, clear if no exchange happened
465 * Note segv's in kernel helpers are a bit tricky, we can set the
466 * data address sensibly but the PC address is just the entry point.
468 static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
470 uint64_t oldval, newval, val;
471 uint32_t addr, cpsr;
472 target_siginfo_t info;
474 /* Based on the 32 bit code in do_kernel_trap */
476 /* XXX: This only works between threads, not between processes.
477 It's probably possible to implement this with native host
478 operations. However things like ldrex/strex are much harder so
479 there's not much point trying. */
480 start_exclusive();
481 cpsr = cpsr_read(env);
482 addr = env->regs[2];
484 if (get_user_u64(oldval, env->regs[0])) {
485 env->exception.vaddress = env->regs[0];
486 goto segv;
489 if (get_user_u64(newval, env->regs[1])) {
490 env->exception.vaddress = env->regs[1];
491 goto segv;
494 if (get_user_u64(val, addr)) {
495 env->exception.vaddress = addr;
496 goto segv;
499 if (val == oldval) {
500 val = newval;
502 if (put_user_u64(val, addr)) {
503 env->exception.vaddress = addr;
504 goto segv;
507 env->regs[0] = 0;
508 cpsr |= CPSR_C;
509 } else {
510 env->regs[0] = -1;
511 cpsr &= ~CPSR_C;
513 cpsr_write(env, cpsr, CPSR_C);
514 end_exclusive();
515 return;
517 segv:
518 end_exclusive();
519 /* We get the PC of the entry address - which is as good as anything,
520 on a real kernel what you get depends on which mode it uses. */
521 info.si_signo = SIGSEGV;
522 info.si_errno = 0;
523 /* XXX: check env->error_code */
524 info.si_code = TARGET_SEGV_MAPERR;
525 info._sifields._sigfault._addr = env->exception.vaddress;
526 queue_signal(env, info.si_signo, &info);
528 end_exclusive();
531 /* Handle a jump to the kernel code page. */
532 static int
533 do_kernel_trap(CPUARMState *env)
535 uint32_t addr;
536 uint32_t cpsr;
537 uint32_t val;
539 switch (env->regs[15]) {
540 case 0xffff0fa0: /* __kernel_memory_barrier */
541 /* ??? No-op. Will need to do better for SMP. */
542 break;
543 case 0xffff0fc0: /* __kernel_cmpxchg */
544 /* XXX: This only works between threads, not between processes.
545 It's probably possible to implement this with native host
546 operations. However things like ldrex/strex are much harder so
547 there's not much point trying. */
548 start_exclusive();
549 cpsr = cpsr_read(env);
550 addr = env->regs[2];
551 /* FIXME: This should SEGV if the access fails. */
552 if (get_user_u32(val, addr))
553 val = ~env->regs[0];
554 if (val == env->regs[0]) {
555 val = env->regs[1];
556 /* FIXME: Check for segfaults. */
557 put_user_u32(val, addr);
558 env->regs[0] = 0;
559 cpsr |= CPSR_C;
560 } else {
561 env->regs[0] = -1;
562 cpsr &= ~CPSR_C;
564 cpsr_write(env, cpsr, CPSR_C);
565 end_exclusive();
566 break;
567 case 0xffff0fe0: /* __kernel_get_tls */
568 env->regs[0] = env->cp15.tpidrro_el0;
569 break;
570 case 0xffff0f60: /* __kernel_cmpxchg64 */
571 arm_kernel_cmpxchg64_helper(env);
572 break;
574 default:
575 return 1;
577 /* Jump back to the caller. */
578 addr = env->regs[14];
579 if (addr & 1) {
580 env->thumb = 1;
581 addr &= ~1;
583 env->regs[15] = addr;
585 return 0;
588 /* Store exclusive handling for AArch32 */
589 static int do_strex(CPUARMState *env)
591 uint64_t val;
592 int size;
593 int rc = 1;
594 int segv = 0;
595 uint32_t addr;
596 start_exclusive();
597 if (env->exclusive_addr != env->exclusive_test) {
598 goto fail;
600 /* We know we're always AArch32 so the address is in uint32_t range
601 * unless it was the -1 exclusive-monitor-lost value (which won't
602 * match exclusive_test above).
604 assert(extract64(env->exclusive_addr, 32, 32) == 0);
605 addr = env->exclusive_addr;
606 size = env->exclusive_info & 0xf;
607 switch (size) {
608 case 0:
609 segv = get_user_u8(val, addr);
610 break;
611 case 1:
612 segv = get_user_u16(val, addr);
613 break;
614 case 2:
615 case 3:
616 segv = get_user_u32(val, addr);
617 break;
618 default:
619 abort();
621 if (segv) {
622 env->exception.vaddress = addr;
623 goto done;
625 if (size == 3) {
626 uint32_t valhi;
627 segv = get_user_u32(valhi, addr + 4);
628 if (segv) {
629 env->exception.vaddress = addr + 4;
630 goto done;
632 val = deposit64(val, 32, 32, valhi);
634 if (val != env->exclusive_val) {
635 goto fail;
638 val = env->regs[(env->exclusive_info >> 8) & 0xf];
639 switch (size) {
640 case 0:
641 segv = put_user_u8(val, addr);
642 break;
643 case 1:
644 segv = put_user_u16(val, addr);
645 break;
646 case 2:
647 case 3:
648 segv = put_user_u32(val, addr);
649 break;
651 if (segv) {
652 env->exception.vaddress = addr;
653 goto done;
655 if (size == 3) {
656 val = env->regs[(env->exclusive_info >> 12) & 0xf];
657 segv = put_user_u32(val, addr + 4);
658 if (segv) {
659 env->exception.vaddress = addr + 4;
660 goto done;
663 rc = 0;
664 fail:
665 env->regs[15] += 4;
666 env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
667 done:
668 end_exclusive();
669 return segv;
672 void cpu_loop(CPUARMState *env)
674 CPUState *cs = CPU(arm_env_get_cpu(env));
675 int trapnr;
676 unsigned int n, insn;
677 target_siginfo_t info;
678 uint32_t addr;
680 for(;;) {
681 cpu_exec_start(cs);
682 trapnr = cpu_arm_exec(env);
683 cpu_exec_end(cs);
684 switch(trapnr) {
685 case EXCP_UDEF:
687 TaskState *ts = cs->opaque;
688 uint32_t opcode;
689 int rc;
691 /* we handle the FPU emulation here, as Linux */
692 /* we get the opcode */
693 /* FIXME - what to do if get_user() fails? */
694 get_user_code_u32(opcode, env->regs[15], env->bswap_code);
696 rc = EmulateAll(opcode, &ts->fpa, env);
697 if (rc == 0) { /* illegal instruction */
698 info.si_signo = SIGILL;
699 info.si_errno = 0;
700 info.si_code = TARGET_ILL_ILLOPN;
701 info._sifields._sigfault._addr = env->regs[15];
702 queue_signal(env, info.si_signo, &info);
703 } else if (rc < 0) { /* FP exception */
704 int arm_fpe=0;
706 /* translate softfloat flags to FPSR flags */
707 if (-rc & float_flag_invalid)
708 arm_fpe |= BIT_IOC;
709 if (-rc & float_flag_divbyzero)
710 arm_fpe |= BIT_DZC;
711 if (-rc & float_flag_overflow)
712 arm_fpe |= BIT_OFC;
713 if (-rc & float_flag_underflow)
714 arm_fpe |= BIT_UFC;
715 if (-rc & float_flag_inexact)
716 arm_fpe |= BIT_IXC;
718 FPSR fpsr = ts->fpa.fpsr;
719 //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
721 if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
722 info.si_signo = SIGFPE;
723 info.si_errno = 0;
725 /* ordered by priority, least first */
726 if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
727 if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
728 if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
729 if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
730 if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
732 info._sifields._sigfault._addr = env->regs[15];
733 queue_signal(env, info.si_signo, &info);
734 } else {
735 env->regs[15] += 4;
738 /* accumulate unenabled exceptions */
739 if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
740 fpsr |= BIT_IXC;
741 if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
742 fpsr |= BIT_UFC;
743 if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
744 fpsr |= BIT_OFC;
745 if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
746 fpsr |= BIT_DZC;
747 if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
748 fpsr |= BIT_IOC;
749 ts->fpa.fpsr=fpsr;
750 } else { /* everything OK */
751 /* increment PC */
752 env->regs[15] += 4;
755 break;
756 case EXCP_SWI:
757 case EXCP_BKPT:
759 env->eabi = 1;
760 /* system call */
761 if (trapnr == EXCP_BKPT) {
762 if (env->thumb) {
763 /* FIXME - what to do if get_user() fails? */
764 get_user_code_u16(insn, env->regs[15], env->bswap_code);
765 n = insn & 0xff;
766 env->regs[15] += 2;
767 } else {
768 /* FIXME - what to do if get_user() fails? */
769 get_user_code_u32(insn, env->regs[15], env->bswap_code);
770 n = (insn & 0xf) | ((insn >> 4) & 0xff0);
771 env->regs[15] += 4;
773 } else {
774 if (env->thumb) {
775 /* FIXME - what to do if get_user() fails? */
776 get_user_code_u16(insn, env->regs[15] - 2,
777 env->bswap_code);
778 n = insn & 0xff;
779 } else {
780 /* FIXME - what to do if get_user() fails? */
781 get_user_code_u32(insn, env->regs[15] - 4,
782 env->bswap_code);
783 n = insn & 0xffffff;
787 if (n == ARM_NR_cacheflush) {
788 /* nop */
789 } else if (n == ARM_NR_semihosting
790 || n == ARM_NR_thumb_semihosting) {
791 env->regs[0] = do_arm_semihosting (env);
792 } else if (n == 0 || n >= ARM_SYSCALL_BASE || env->thumb) {
793 /* linux syscall */
794 if (env->thumb || n == 0) {
795 n = env->regs[7];
796 } else {
797 n -= ARM_SYSCALL_BASE;
798 env->eabi = 0;
800 if ( n > ARM_NR_BASE) {
801 switch (n) {
802 case ARM_NR_cacheflush:
803 /* nop */
804 break;
805 case ARM_NR_set_tls:
806 cpu_set_tls(env, env->regs[0]);
807 env->regs[0] = 0;
808 break;
809 default:
810 gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
812 env->regs[0] = -TARGET_ENOSYS;
813 break;
815 } else {
816 env->regs[0] = do_syscall(env,
818 env->regs[0],
819 env->regs[1],
820 env->regs[2],
821 env->regs[3],
822 env->regs[4],
823 env->regs[5],
824 0, 0);
826 } else {
827 goto error;
830 break;
831 case EXCP_INTERRUPT:
832 /* just indicate that signals should be handled asap */
833 break;
834 case EXCP_STREX:
835 if (!do_strex(env)) {
836 break;
838 /* fall through for segv */
839 case EXCP_PREFETCH_ABORT:
840 case EXCP_DATA_ABORT:
841 addr = env->exception.vaddress;
843 info.si_signo = SIGSEGV;
844 info.si_errno = 0;
845 /* XXX: check env->error_code */
846 info.si_code = TARGET_SEGV_MAPERR;
847 info._sifields._sigfault._addr = addr;
848 queue_signal(env, info.si_signo, &info);
850 break;
851 case EXCP_DEBUG:
853 int sig;
855 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
856 if (sig)
858 info.si_signo = sig;
859 info.si_errno = 0;
860 info.si_code = TARGET_TRAP_BRKPT;
861 queue_signal(env, info.si_signo, &info);
864 break;
865 case EXCP_KERNEL_TRAP:
866 if (do_kernel_trap(env))
867 goto error;
868 break;
869 default:
870 error:
871 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
872 trapnr);
873 cpu_dump_state(cs, stderr, fprintf, 0);
874 abort();
876 process_pending_signals(env);
880 #else
883 * Handle AArch64 store-release exclusive
885 * rs = gets the status result of store exclusive
886 * rt = is the register that is stored
887 * rt2 = is the second register store (in STP)
890 static int do_strex_a64(CPUARMState *env)
892 uint64_t val;
893 int size;
894 bool is_pair;
895 int rc = 1;
896 int segv = 0;
897 uint64_t addr;
898 int rs, rt, rt2;
900 start_exclusive();
901 /* size | is_pair << 2 | (rs << 4) | (rt << 9) | (rt2 << 14)); */
902 size = extract32(env->exclusive_info, 0, 2);
903 is_pair = extract32(env->exclusive_info, 2, 1);
904 rs = extract32(env->exclusive_info, 4, 5);
905 rt = extract32(env->exclusive_info, 9, 5);
906 rt2 = extract32(env->exclusive_info, 14, 5);
908 addr = env->exclusive_addr;
910 if (addr != env->exclusive_test) {
911 goto finish;
914 switch (size) {
915 case 0:
916 segv = get_user_u8(val, addr);
917 break;
918 case 1:
919 segv = get_user_u16(val, addr);
920 break;
921 case 2:
922 segv = get_user_u32(val, addr);
923 break;
924 case 3:
925 segv = get_user_u64(val, addr);
926 break;
927 default:
928 abort();
930 if (segv) {
931 env->exception.vaddress = addr;
932 goto error;
934 if (val != env->exclusive_val) {
935 goto finish;
937 if (is_pair) {
938 if (size == 2) {
939 segv = get_user_u32(val, addr + 4);
940 } else {
941 segv = get_user_u64(val, addr + 8);
943 if (segv) {
944 env->exception.vaddress = addr + (size == 2 ? 4 : 8);
945 goto error;
947 if (val != env->exclusive_high) {
948 goto finish;
951 /* handle the zero register */
952 val = rt == 31 ? 0 : env->xregs[rt];
953 switch (size) {
954 case 0:
955 segv = put_user_u8(val, addr);
956 break;
957 case 1:
958 segv = put_user_u16(val, addr);
959 break;
960 case 2:
961 segv = put_user_u32(val, addr);
962 break;
963 case 3:
964 segv = put_user_u64(val, addr);
965 break;
967 if (segv) {
968 goto error;
970 if (is_pair) {
971 /* handle the zero register */
972 val = rt2 == 31 ? 0 : env->xregs[rt2];
973 if (size == 2) {
974 segv = put_user_u32(val, addr + 4);
975 } else {
976 segv = put_user_u64(val, addr + 8);
978 if (segv) {
979 env->exception.vaddress = addr + (size == 2 ? 4 : 8);
980 goto error;
983 rc = 0;
984 finish:
985 env->pc += 4;
986 /* rs == 31 encodes a write to the ZR, thus throwing away
987 * the status return. This is rather silly but valid.
989 if (rs < 31) {
990 env->xregs[rs] = rc;
992 error:
993 /* instruction faulted, PC does not advance */
994 /* either way a strex releases any exclusive lock we have */
995 env->exclusive_addr = -1;
996 end_exclusive();
997 return segv;
1000 /* AArch64 main loop */
1001 void cpu_loop(CPUARMState *env)
1003 CPUState *cs = CPU(arm_env_get_cpu(env));
1004 int trapnr, sig;
1005 target_siginfo_t info;
1006 uint32_t addr;
1008 for (;;) {
1009 cpu_exec_start(cs);
1010 trapnr = cpu_arm_exec(env);
1011 cpu_exec_end(cs);
1013 switch (trapnr) {
1014 case EXCP_SWI:
1015 env->xregs[0] = do_syscall(env,
1016 env->xregs[8],
1017 env->xregs[0],
1018 env->xregs[1],
1019 env->xregs[2],
1020 env->xregs[3],
1021 env->xregs[4],
1022 env->xregs[5],
1023 0, 0);
1024 break;
1025 case EXCP_INTERRUPT:
1026 /* just indicate that signals should be handled asap */
1027 break;
1028 case EXCP_UDEF:
1029 info.si_signo = SIGILL;
1030 info.si_errno = 0;
1031 info.si_code = TARGET_ILL_ILLOPN;
1032 info._sifields._sigfault._addr = env->pc;
1033 queue_signal(env, info.si_signo, &info);
1034 break;
1035 case EXCP_STREX:
1036 if (!do_strex_a64(env)) {
1037 break;
1039 /* fall through for segv */
1040 case EXCP_PREFETCH_ABORT:
1041 case EXCP_DATA_ABORT:
1042 addr = env->exception.vaddress;
1043 info.si_signo = SIGSEGV;
1044 info.si_errno = 0;
1045 /* XXX: check env->error_code */
1046 info.si_code = TARGET_SEGV_MAPERR;
1047 info._sifields._sigfault._addr = addr;
1048 queue_signal(env, info.si_signo, &info);
1049 break;
1050 case EXCP_DEBUG:
1051 case EXCP_BKPT:
1052 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1053 if (sig) {
1054 info.si_signo = sig;
1055 info.si_errno = 0;
1056 info.si_code = TARGET_TRAP_BRKPT;
1057 queue_signal(env, info.si_signo, &info);
1059 break;
1060 default:
1061 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1062 trapnr);
1063 cpu_dump_state(cs, stderr, fprintf, 0);
1064 abort();
1066 process_pending_signals(env);
1067 /* Exception return on AArch64 always clears the exclusive monitor,
1068 * so any return to running guest code implies this.
1069 * A strex (successful or otherwise) also clears the monitor, so
1070 * we don't need to specialcase EXCP_STREX.
1072 env->exclusive_addr = -1;
1075 #endif /* ndef TARGET_ABI32 */
1077 #endif
1079 #ifdef TARGET_UNICORE32
1081 void cpu_loop(CPUUniCore32State *env)
1083 CPUState *cs = CPU(uc32_env_get_cpu(env));
1084 int trapnr;
1085 unsigned int n, insn;
1086 target_siginfo_t info;
1088 for (;;) {
1089 cpu_exec_start(cs);
1090 trapnr = uc32_cpu_exec(env);
1091 cpu_exec_end(cs);
1092 switch (trapnr) {
1093 case UC32_EXCP_PRIV:
1095 /* system call */
1096 get_user_u32(insn, env->regs[31] - 4);
1097 n = insn & 0xffffff;
1099 if (n >= UC32_SYSCALL_BASE) {
1100 /* linux syscall */
1101 n -= UC32_SYSCALL_BASE;
1102 if (n == UC32_SYSCALL_NR_set_tls) {
1103 cpu_set_tls(env, env->regs[0]);
1104 env->regs[0] = 0;
1105 } else {
1106 env->regs[0] = do_syscall(env,
1108 env->regs[0],
1109 env->regs[1],
1110 env->regs[2],
1111 env->regs[3],
1112 env->regs[4],
1113 env->regs[5],
1114 0, 0);
1116 } else {
1117 goto error;
1120 break;
1121 case UC32_EXCP_DTRAP:
1122 case UC32_EXCP_ITRAP:
1123 info.si_signo = SIGSEGV;
1124 info.si_errno = 0;
1125 /* XXX: check env->error_code */
1126 info.si_code = TARGET_SEGV_MAPERR;
1127 info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
1128 queue_signal(env, info.si_signo, &info);
1129 break;
1130 case EXCP_INTERRUPT:
1131 /* just indicate that signals should be handled asap */
1132 break;
1133 case EXCP_DEBUG:
1135 int sig;
1137 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1138 if (sig) {
1139 info.si_signo = sig;
1140 info.si_errno = 0;
1141 info.si_code = TARGET_TRAP_BRKPT;
1142 queue_signal(env, info.si_signo, &info);
1145 break;
1146 default:
1147 goto error;
1149 process_pending_signals(env);
1152 error:
1153 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
1154 cpu_dump_state(cs, stderr, fprintf, 0);
1155 abort();
1157 #endif
1159 #ifdef TARGET_SPARC
1160 #define SPARC64_STACK_BIAS 2047
1162 //#define DEBUG_WIN
1164 /* WARNING: dealing with register windows _is_ complicated. More info
1165 can be found at http://www.sics.se/~psm/sparcstack.html */
1166 static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
1168 index = (index + cwp * 16) % (16 * env->nwindows);
1169 /* wrap handling : if cwp is on the last window, then we use the
1170 registers 'after' the end */
1171 if (index < 8 && env->cwp == env->nwindows - 1)
1172 index += 16 * env->nwindows;
1173 return index;
1176 /* save the register window 'cwp1' */
1177 static inline void save_window_offset(CPUSPARCState *env, int cwp1)
1179 unsigned int i;
1180 abi_ulong sp_ptr;
1182 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1183 #ifdef TARGET_SPARC64
1184 if (sp_ptr & 3)
1185 sp_ptr += SPARC64_STACK_BIAS;
1186 #endif
1187 #if defined(DEBUG_WIN)
1188 printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
1189 sp_ptr, cwp1);
1190 #endif
1191 for(i = 0; i < 16; i++) {
1192 /* FIXME - what to do if put_user() fails? */
1193 put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
1194 sp_ptr += sizeof(abi_ulong);
1198 static void save_window(CPUSPARCState *env)
1200 #ifndef TARGET_SPARC64
1201 unsigned int new_wim;
1202 new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
1203 ((1LL << env->nwindows) - 1);
1204 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1205 env->wim = new_wim;
1206 #else
1207 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1208 env->cansave++;
1209 env->canrestore--;
1210 #endif
1213 static void restore_window(CPUSPARCState *env)
1215 #ifndef TARGET_SPARC64
1216 unsigned int new_wim;
1217 #endif
1218 unsigned int i, cwp1;
1219 abi_ulong sp_ptr;
1221 #ifndef TARGET_SPARC64
1222 new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
1223 ((1LL << env->nwindows) - 1);
1224 #endif
1226 /* restore the invalid window */
1227 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1228 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1229 #ifdef TARGET_SPARC64
1230 if (sp_ptr & 3)
1231 sp_ptr += SPARC64_STACK_BIAS;
1232 #endif
1233 #if defined(DEBUG_WIN)
1234 printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
1235 sp_ptr, cwp1);
1236 #endif
1237 for(i = 0; i < 16; i++) {
1238 /* FIXME - what to do if get_user() fails? */
1239 get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
1240 sp_ptr += sizeof(abi_ulong);
1242 #ifdef TARGET_SPARC64
1243 env->canrestore++;
1244 if (env->cleanwin < env->nwindows - 1)
1245 env->cleanwin++;
1246 env->cansave--;
1247 #else
1248 env->wim = new_wim;
1249 #endif
1252 static void flush_windows(CPUSPARCState *env)
1254 int offset, cwp1;
1256 offset = 1;
1257 for(;;) {
1258 /* if restore would invoke restore_window(), then we can stop */
1259 cwp1 = cpu_cwp_inc(env, env->cwp + offset);
1260 #ifndef TARGET_SPARC64
1261 if (env->wim & (1 << cwp1))
1262 break;
1263 #else
1264 if (env->canrestore == 0)
1265 break;
1266 env->cansave++;
1267 env->canrestore--;
1268 #endif
1269 save_window_offset(env, cwp1);
1270 offset++;
1272 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1273 #ifndef TARGET_SPARC64
1274 /* set wim so that restore will reload the registers */
1275 env->wim = 1 << cwp1;
1276 #endif
1277 #if defined(DEBUG_WIN)
1278 printf("flush_windows: nb=%d\n", offset - 1);
1279 #endif
1282 void cpu_loop (CPUSPARCState *env)
1284 CPUState *cs = CPU(sparc_env_get_cpu(env));
1285 int trapnr;
1286 abi_long ret;
1287 target_siginfo_t info;
1289 while (1) {
1290 trapnr = cpu_sparc_exec (env);
1292 /* Compute PSR before exposing state. */
1293 if (env->cc_op != CC_OP_FLAGS) {
1294 cpu_get_psr(env);
1297 switch (trapnr) {
1298 #ifndef TARGET_SPARC64
1299 case 0x88:
1300 case 0x90:
1301 #else
1302 case 0x110:
1303 case 0x16d:
1304 #endif
1305 ret = do_syscall (env, env->gregs[1],
1306 env->regwptr[0], env->regwptr[1],
1307 env->regwptr[2], env->regwptr[3],
1308 env->regwptr[4], env->regwptr[5],
1309 0, 0);
1310 if ((abi_ulong)ret >= (abi_ulong)(-515)) {
1311 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1312 env->xcc |= PSR_CARRY;
1313 #else
1314 env->psr |= PSR_CARRY;
1315 #endif
1316 ret = -ret;
1317 } else {
1318 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1319 env->xcc &= ~PSR_CARRY;
1320 #else
1321 env->psr &= ~PSR_CARRY;
1322 #endif
1324 env->regwptr[0] = ret;
1325 /* next instruction */
1326 env->pc = env->npc;
1327 env->npc = env->npc + 4;
1328 break;
1329 case 0x83: /* flush windows */
1330 #ifdef TARGET_ABI32
1331 case 0x103:
1332 #endif
1333 flush_windows(env);
1334 /* next instruction */
1335 env->pc = env->npc;
1336 env->npc = env->npc + 4;
1337 break;
1338 #ifndef TARGET_SPARC64
1339 case TT_WIN_OVF: /* window overflow */
1340 save_window(env);
1341 break;
1342 case TT_WIN_UNF: /* window underflow */
1343 restore_window(env);
1344 break;
1345 case TT_TFAULT:
1346 case TT_DFAULT:
1348 info.si_signo = TARGET_SIGSEGV;
1349 info.si_errno = 0;
1350 /* XXX: check env->error_code */
1351 info.si_code = TARGET_SEGV_MAPERR;
1352 info._sifields._sigfault._addr = env->mmuregs[4];
1353 queue_signal(env, info.si_signo, &info);
1355 break;
1356 #else
1357 case TT_SPILL: /* window overflow */
1358 save_window(env);
1359 break;
1360 case TT_FILL: /* window underflow */
1361 restore_window(env);
1362 break;
1363 case TT_TFAULT:
1364 case TT_DFAULT:
1366 info.si_signo = TARGET_SIGSEGV;
1367 info.si_errno = 0;
1368 /* XXX: check env->error_code */
1369 info.si_code = TARGET_SEGV_MAPERR;
1370 if (trapnr == TT_DFAULT)
1371 info._sifields._sigfault._addr = env->dmmuregs[4];
1372 else
1373 info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
1374 queue_signal(env, info.si_signo, &info);
1376 break;
1377 #ifndef TARGET_ABI32
1378 case 0x16e:
1379 flush_windows(env);
1380 sparc64_get_context(env);
1381 break;
1382 case 0x16f:
1383 flush_windows(env);
1384 sparc64_set_context(env);
1385 break;
1386 #endif
1387 #endif
1388 case EXCP_INTERRUPT:
1389 /* just indicate that signals should be handled asap */
1390 break;
1391 case TT_ILL_INSN:
1393 info.si_signo = TARGET_SIGILL;
1394 info.si_errno = 0;
1395 info.si_code = TARGET_ILL_ILLOPC;
1396 info._sifields._sigfault._addr = env->pc;
1397 queue_signal(env, info.si_signo, &info);
1399 break;
1400 case EXCP_DEBUG:
1402 int sig;
1404 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1405 if (sig)
1407 info.si_signo = sig;
1408 info.si_errno = 0;
1409 info.si_code = TARGET_TRAP_BRKPT;
1410 queue_signal(env, info.si_signo, &info);
1413 break;
1414 default:
1415 printf ("Unhandled trap: 0x%x\n", trapnr);
1416 cpu_dump_state(cs, stderr, fprintf, 0);
1417 exit (1);
1419 process_pending_signals (env);
1423 #endif
1425 #ifdef TARGET_PPC
1426 static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
1428 /* TO FIX */
1429 return 0;
1432 uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
1434 return cpu_ppc_get_tb(env);
1437 uint32_t cpu_ppc_load_tbu(CPUPPCState *env)
1439 return cpu_ppc_get_tb(env) >> 32;
1442 uint64_t cpu_ppc_load_atbl(CPUPPCState *env)
1444 return cpu_ppc_get_tb(env);
1447 uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
1449 return cpu_ppc_get_tb(env) >> 32;
1452 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
1453 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
1455 uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
1457 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
1460 /* XXX: to be fixed */
1461 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
1463 return -1;
1466 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
1468 return -1;
1471 #define EXCP_DUMP(env, fmt, ...) \
1472 do { \
1473 CPUState *cs = ENV_GET_CPU(env); \
1474 fprintf(stderr, fmt , ## __VA_ARGS__); \
1475 cpu_dump_state(cs, stderr, fprintf, 0); \
1476 qemu_log(fmt, ## __VA_ARGS__); \
1477 if (qemu_log_enabled()) { \
1478 log_cpu_state(cs, 0); \
1480 } while (0)
1482 static int do_store_exclusive(CPUPPCState *env)
1484 target_ulong addr;
1485 target_ulong page_addr;
1486 target_ulong val, val2 __attribute__((unused)) = 0;
1487 int flags;
1488 int segv = 0;
1490 addr = env->reserve_ea;
1491 page_addr = addr & TARGET_PAGE_MASK;
1492 start_exclusive();
1493 mmap_lock();
1494 flags = page_get_flags(page_addr);
1495 if ((flags & PAGE_READ) == 0) {
1496 segv = 1;
1497 } else {
1498 int reg = env->reserve_info & 0x1f;
1499 int size = env->reserve_info >> 5;
1500 int stored = 0;
1502 if (addr == env->reserve_addr) {
1503 switch (size) {
1504 case 1: segv = get_user_u8(val, addr); break;
1505 case 2: segv = get_user_u16(val, addr); break;
1506 case 4: segv = get_user_u32(val, addr); break;
1507 #if defined(TARGET_PPC64)
1508 case 8: segv = get_user_u64(val, addr); break;
1509 case 16: {
1510 segv = get_user_u64(val, addr);
1511 if (!segv) {
1512 segv = get_user_u64(val2, addr + 8);
1514 break;
1516 #endif
1517 default: abort();
1519 if (!segv && val == env->reserve_val) {
1520 val = env->gpr[reg];
1521 switch (size) {
1522 case 1: segv = put_user_u8(val, addr); break;
1523 case 2: segv = put_user_u16(val, addr); break;
1524 case 4: segv = put_user_u32(val, addr); break;
1525 #if defined(TARGET_PPC64)
1526 case 8: segv = put_user_u64(val, addr); break;
1527 case 16: {
1528 if (val2 == env->reserve_val2) {
1529 if (msr_le) {
1530 val2 = val;
1531 val = env->gpr[reg+1];
1532 } else {
1533 val2 = env->gpr[reg+1];
1535 segv = put_user_u64(val, addr);
1536 if (!segv) {
1537 segv = put_user_u64(val2, addr + 8);
1540 break;
1542 #endif
1543 default: abort();
1545 if (!segv) {
1546 stored = 1;
1550 env->crf[0] = (stored << 1) | xer_so;
1551 env->reserve_addr = (target_ulong)-1;
1553 if (!segv) {
1554 env->nip += 4;
1556 mmap_unlock();
1557 end_exclusive();
1558 return segv;
1561 void cpu_loop(CPUPPCState *env)
1563 CPUState *cs = CPU(ppc_env_get_cpu(env));
1564 target_siginfo_t info;
1565 int trapnr;
1566 target_ulong ret;
1568 for(;;) {
1569 cpu_exec_start(cs);
1570 trapnr = cpu_ppc_exec(env);
1571 cpu_exec_end(cs);
1572 switch(trapnr) {
1573 case POWERPC_EXCP_NONE:
1574 /* Just go on */
1575 break;
1576 case POWERPC_EXCP_CRITICAL: /* Critical input */
1577 cpu_abort(cs, "Critical interrupt while in user mode. "
1578 "Aborting\n");
1579 break;
1580 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1581 cpu_abort(cs, "Machine check exception while in user mode. "
1582 "Aborting\n");
1583 break;
1584 case POWERPC_EXCP_DSI: /* Data storage exception */
1585 EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",
1586 env->spr[SPR_DAR]);
1587 /* XXX: check this. Seems bugged */
1588 switch (env->error_code & 0xFF000000) {
1589 case 0x40000000:
1590 info.si_signo = TARGET_SIGSEGV;
1591 info.si_errno = 0;
1592 info.si_code = TARGET_SEGV_MAPERR;
1593 break;
1594 case 0x04000000:
1595 info.si_signo = TARGET_SIGILL;
1596 info.si_errno = 0;
1597 info.si_code = TARGET_ILL_ILLADR;
1598 break;
1599 case 0x08000000:
1600 info.si_signo = TARGET_SIGSEGV;
1601 info.si_errno = 0;
1602 info.si_code = TARGET_SEGV_ACCERR;
1603 break;
1604 default:
1605 /* Let's send a regular segfault... */
1606 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1607 env->error_code);
1608 info.si_signo = TARGET_SIGSEGV;
1609 info.si_errno = 0;
1610 info.si_code = TARGET_SEGV_MAPERR;
1611 break;
1613 info._sifields._sigfault._addr = env->nip;
1614 queue_signal(env, info.si_signo, &info);
1615 break;
1616 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1617 EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx
1618 "\n", env->spr[SPR_SRR0]);
1619 /* XXX: check this */
1620 switch (env->error_code & 0xFF000000) {
1621 case 0x40000000:
1622 info.si_signo = TARGET_SIGSEGV;
1623 info.si_errno = 0;
1624 info.si_code = TARGET_SEGV_MAPERR;
1625 break;
1626 case 0x10000000:
1627 case 0x08000000:
1628 info.si_signo = TARGET_SIGSEGV;
1629 info.si_errno = 0;
1630 info.si_code = TARGET_SEGV_ACCERR;
1631 break;
1632 default:
1633 /* Let's send a regular segfault... */
1634 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1635 env->error_code);
1636 info.si_signo = TARGET_SIGSEGV;
1637 info.si_errno = 0;
1638 info.si_code = TARGET_SEGV_MAPERR;
1639 break;
1641 info._sifields._sigfault._addr = env->nip - 4;
1642 queue_signal(env, info.si_signo, &info);
1643 break;
1644 case POWERPC_EXCP_EXTERNAL: /* External input */
1645 cpu_abort(cs, "External interrupt while in user mode. "
1646 "Aborting\n");
1647 break;
1648 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1649 EXCP_DUMP(env, "Unaligned memory access\n");
1650 /* XXX: check this */
1651 info.si_signo = TARGET_SIGBUS;
1652 info.si_errno = 0;
1653 info.si_code = TARGET_BUS_ADRALN;
1654 info._sifields._sigfault._addr = env->nip - 4;
1655 queue_signal(env, info.si_signo, &info);
1656 break;
1657 case POWERPC_EXCP_PROGRAM: /* Program exception */
1658 /* XXX: check this */
1659 switch (env->error_code & ~0xF) {
1660 case POWERPC_EXCP_FP:
1661 EXCP_DUMP(env, "Floating point program exception\n");
1662 info.si_signo = TARGET_SIGFPE;
1663 info.si_errno = 0;
1664 switch (env->error_code & 0xF) {
1665 case POWERPC_EXCP_FP_OX:
1666 info.si_code = TARGET_FPE_FLTOVF;
1667 break;
1668 case POWERPC_EXCP_FP_UX:
1669 info.si_code = TARGET_FPE_FLTUND;
1670 break;
1671 case POWERPC_EXCP_FP_ZX:
1672 case POWERPC_EXCP_FP_VXZDZ:
1673 info.si_code = TARGET_FPE_FLTDIV;
1674 break;
1675 case POWERPC_EXCP_FP_XX:
1676 info.si_code = TARGET_FPE_FLTRES;
1677 break;
1678 case POWERPC_EXCP_FP_VXSOFT:
1679 info.si_code = TARGET_FPE_FLTINV;
1680 break;
1681 case POWERPC_EXCP_FP_VXSNAN:
1682 case POWERPC_EXCP_FP_VXISI:
1683 case POWERPC_EXCP_FP_VXIDI:
1684 case POWERPC_EXCP_FP_VXIMZ:
1685 case POWERPC_EXCP_FP_VXVC:
1686 case POWERPC_EXCP_FP_VXSQRT:
1687 case POWERPC_EXCP_FP_VXCVI:
1688 info.si_code = TARGET_FPE_FLTSUB;
1689 break;
1690 default:
1691 EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
1692 env->error_code);
1693 break;
1695 break;
1696 case POWERPC_EXCP_INVAL:
1697 EXCP_DUMP(env, "Invalid instruction\n");
1698 info.si_signo = TARGET_SIGILL;
1699 info.si_errno = 0;
1700 switch (env->error_code & 0xF) {
1701 case POWERPC_EXCP_INVAL_INVAL:
1702 info.si_code = TARGET_ILL_ILLOPC;
1703 break;
1704 case POWERPC_EXCP_INVAL_LSWX:
1705 info.si_code = TARGET_ILL_ILLOPN;
1706 break;
1707 case POWERPC_EXCP_INVAL_SPR:
1708 info.si_code = TARGET_ILL_PRVREG;
1709 break;
1710 case POWERPC_EXCP_INVAL_FP:
1711 info.si_code = TARGET_ILL_COPROC;
1712 break;
1713 default:
1714 EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
1715 env->error_code & 0xF);
1716 info.si_code = TARGET_ILL_ILLADR;
1717 break;
1719 break;
1720 case POWERPC_EXCP_PRIV:
1721 EXCP_DUMP(env, "Privilege violation\n");
1722 info.si_signo = TARGET_SIGILL;
1723 info.si_errno = 0;
1724 switch (env->error_code & 0xF) {
1725 case POWERPC_EXCP_PRIV_OPC:
1726 info.si_code = TARGET_ILL_PRVOPC;
1727 break;
1728 case POWERPC_EXCP_PRIV_REG:
1729 info.si_code = TARGET_ILL_PRVREG;
1730 break;
1731 default:
1732 EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
1733 env->error_code & 0xF);
1734 info.si_code = TARGET_ILL_PRVOPC;
1735 break;
1737 break;
1738 case POWERPC_EXCP_TRAP:
1739 cpu_abort(cs, "Tried to call a TRAP\n");
1740 break;
1741 default:
1742 /* Should not happen ! */
1743 cpu_abort(cs, "Unknown program exception (%02x)\n",
1744 env->error_code);
1745 break;
1747 info._sifields._sigfault._addr = env->nip - 4;
1748 queue_signal(env, info.si_signo, &info);
1749 break;
1750 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1751 EXCP_DUMP(env, "No floating point allowed\n");
1752 info.si_signo = TARGET_SIGILL;
1753 info.si_errno = 0;
1754 info.si_code = TARGET_ILL_COPROC;
1755 info._sifields._sigfault._addr = env->nip - 4;
1756 queue_signal(env, info.si_signo, &info);
1757 break;
1758 case POWERPC_EXCP_SYSCALL: /* System call exception */
1759 cpu_abort(cs, "Syscall exception while in user mode. "
1760 "Aborting\n");
1761 break;
1762 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1763 EXCP_DUMP(env, "No APU instruction allowed\n");
1764 info.si_signo = TARGET_SIGILL;
1765 info.si_errno = 0;
1766 info.si_code = TARGET_ILL_COPROC;
1767 info._sifields._sigfault._addr = env->nip - 4;
1768 queue_signal(env, info.si_signo, &info);
1769 break;
1770 case POWERPC_EXCP_DECR: /* Decrementer exception */
1771 cpu_abort(cs, "Decrementer interrupt while in user mode. "
1772 "Aborting\n");
1773 break;
1774 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1775 cpu_abort(cs, "Fix interval timer interrupt while in user mode. "
1776 "Aborting\n");
1777 break;
1778 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1779 cpu_abort(cs, "Watchdog timer interrupt while in user mode. "
1780 "Aborting\n");
1781 break;
1782 case POWERPC_EXCP_DTLB: /* Data TLB error */
1783 cpu_abort(cs, "Data TLB exception while in user mode. "
1784 "Aborting\n");
1785 break;
1786 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1787 cpu_abort(cs, "Instruction TLB exception while in user mode. "
1788 "Aborting\n");
1789 break;
1790 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
1791 EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
1792 info.si_signo = TARGET_SIGILL;
1793 info.si_errno = 0;
1794 info.si_code = TARGET_ILL_COPROC;
1795 info._sifields._sigfault._addr = env->nip - 4;
1796 queue_signal(env, info.si_signo, &info);
1797 break;
1798 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
1799 cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
1800 break;
1801 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
1802 cpu_abort(cs, "Embedded floating-point round IRQ not handled\n");
1803 break;
1804 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
1805 cpu_abort(cs, "Performance monitor exception not handled\n");
1806 break;
1807 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1808 cpu_abort(cs, "Doorbell interrupt while in user mode. "
1809 "Aborting\n");
1810 break;
1811 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1812 cpu_abort(cs, "Doorbell critical interrupt while in user mode. "
1813 "Aborting\n");
1814 break;
1815 case POWERPC_EXCP_RESET: /* System reset exception */
1816 cpu_abort(cs, "Reset interrupt while in user mode. "
1817 "Aborting\n");
1818 break;
1819 case POWERPC_EXCP_DSEG: /* Data segment exception */
1820 cpu_abort(cs, "Data segment exception while in user mode. "
1821 "Aborting\n");
1822 break;
1823 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1824 cpu_abort(cs, "Instruction segment exception "
1825 "while in user mode. Aborting\n");
1826 break;
1827 /* PowerPC 64 with hypervisor mode support */
1828 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1829 cpu_abort(cs, "Hypervisor decrementer interrupt "
1830 "while in user mode. Aborting\n");
1831 break;
1832 case POWERPC_EXCP_TRACE: /* Trace exception */
1833 /* Nothing to do:
1834 * we use this exception to emulate step-by-step execution mode.
1836 break;
1837 /* PowerPC 64 with hypervisor mode support */
1838 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1839 cpu_abort(cs, "Hypervisor data storage exception "
1840 "while in user mode. Aborting\n");
1841 break;
1842 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
1843 cpu_abort(cs, "Hypervisor instruction storage exception "
1844 "while in user mode. Aborting\n");
1845 break;
1846 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
1847 cpu_abort(cs, "Hypervisor data segment exception "
1848 "while in user mode. Aborting\n");
1849 break;
1850 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
1851 cpu_abort(cs, "Hypervisor instruction segment exception "
1852 "while in user mode. Aborting\n");
1853 break;
1854 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1855 EXCP_DUMP(env, "No Altivec instructions allowed\n");
1856 info.si_signo = TARGET_SIGILL;
1857 info.si_errno = 0;
1858 info.si_code = TARGET_ILL_COPROC;
1859 info._sifields._sigfault._addr = env->nip - 4;
1860 queue_signal(env, info.si_signo, &info);
1861 break;
1862 case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
1863 cpu_abort(cs, "Programmable interval timer interrupt "
1864 "while in user mode. Aborting\n");
1865 break;
1866 case POWERPC_EXCP_IO: /* IO error exception */
1867 cpu_abort(cs, "IO error exception while in user mode. "
1868 "Aborting\n");
1869 break;
1870 case POWERPC_EXCP_RUNM: /* Run mode exception */
1871 cpu_abort(cs, "Run mode exception while in user mode. "
1872 "Aborting\n");
1873 break;
1874 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
1875 cpu_abort(cs, "Emulation trap exception not handled\n");
1876 break;
1877 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
1878 cpu_abort(cs, "Instruction fetch TLB exception "
1879 "while in user-mode. Aborting");
1880 break;
1881 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
1882 cpu_abort(cs, "Data load TLB exception while in user-mode. "
1883 "Aborting");
1884 break;
1885 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
1886 cpu_abort(cs, "Data store TLB exception while in user-mode. "
1887 "Aborting");
1888 break;
1889 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
1890 cpu_abort(cs, "Floating-point assist exception not handled\n");
1891 break;
1892 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
1893 cpu_abort(cs, "Instruction address breakpoint exception "
1894 "not handled\n");
1895 break;
1896 case POWERPC_EXCP_SMI: /* System management interrupt */
1897 cpu_abort(cs, "System management interrupt while in user mode. "
1898 "Aborting\n");
1899 break;
1900 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1901 cpu_abort(cs, "Thermal interrupt interrupt while in user mode. "
1902 "Aborting\n");
1903 break;
1904 case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
1905 cpu_abort(cs, "Performance monitor exception not handled\n");
1906 break;
1907 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1908 cpu_abort(cs, "Vector assist exception not handled\n");
1909 break;
1910 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
1911 cpu_abort(cs, "Soft patch exception not handled\n");
1912 break;
1913 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1914 cpu_abort(cs, "Maintenance exception while in user mode. "
1915 "Aborting\n");
1916 break;
1917 case POWERPC_EXCP_STOP: /* stop translation */
1918 /* We did invalidate the instruction cache. Go on */
1919 break;
1920 case POWERPC_EXCP_BRANCH: /* branch instruction: */
1921 /* We just stopped because of a branch. Go on */
1922 break;
1923 case POWERPC_EXCP_SYSCALL_USER:
1924 /* system call in user-mode emulation */
1925 /* WARNING:
1926 * PPC ABI uses overflow flag in cr0 to signal an error
1927 * in syscalls.
1929 env->crf[0] &= ~0x1;
1930 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
1931 env->gpr[5], env->gpr[6], env->gpr[7],
1932 env->gpr[8], 0, 0);
1933 if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
1934 /* Returning from a successful sigreturn syscall.
1935 Avoid corrupting register state. */
1936 break;
1938 if (ret > (target_ulong)(-515)) {
1939 env->crf[0] |= 0x1;
1940 ret = -ret;
1942 env->gpr[3] = ret;
1943 break;
1944 case POWERPC_EXCP_STCX:
1945 if (do_store_exclusive(env)) {
1946 info.si_signo = TARGET_SIGSEGV;
1947 info.si_errno = 0;
1948 info.si_code = TARGET_SEGV_MAPERR;
1949 info._sifields._sigfault._addr = env->nip;
1950 queue_signal(env, info.si_signo, &info);
1952 break;
1953 case EXCP_DEBUG:
1955 int sig;
1957 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1958 if (sig) {
1959 info.si_signo = sig;
1960 info.si_errno = 0;
1961 info.si_code = TARGET_TRAP_BRKPT;
1962 queue_signal(env, info.si_signo, &info);
1965 break;
1966 case EXCP_INTERRUPT:
1967 /* just indicate that signals should be handled asap */
1968 break;
1969 default:
1970 cpu_abort(cs, "Unknown exception 0x%d. Aborting\n", trapnr);
1971 break;
1973 process_pending_signals(env);
1976 #endif
1978 #ifdef TARGET_MIPS
1980 # ifdef TARGET_ABI_MIPSO32
1981 # define MIPS_SYS(name, args) args,
1982 static const uint8_t mips_syscall_args[] = {
1983 MIPS_SYS(sys_syscall , 8) /* 4000 */
1984 MIPS_SYS(sys_exit , 1)
1985 MIPS_SYS(sys_fork , 0)
1986 MIPS_SYS(sys_read , 3)
1987 MIPS_SYS(sys_write , 3)
1988 MIPS_SYS(sys_open , 3) /* 4005 */
1989 MIPS_SYS(sys_close , 1)
1990 MIPS_SYS(sys_waitpid , 3)
1991 MIPS_SYS(sys_creat , 2)
1992 MIPS_SYS(sys_link , 2)
1993 MIPS_SYS(sys_unlink , 1) /* 4010 */
1994 MIPS_SYS(sys_execve , 0)
1995 MIPS_SYS(sys_chdir , 1)
1996 MIPS_SYS(sys_time , 1)
1997 MIPS_SYS(sys_mknod , 3)
1998 MIPS_SYS(sys_chmod , 2) /* 4015 */
1999 MIPS_SYS(sys_lchown , 3)
2000 MIPS_SYS(sys_ni_syscall , 0)
2001 MIPS_SYS(sys_ni_syscall , 0) /* was sys_stat */
2002 MIPS_SYS(sys_lseek , 3)
2003 MIPS_SYS(sys_getpid , 0) /* 4020 */
2004 MIPS_SYS(sys_mount , 5)
2005 MIPS_SYS(sys_umount , 1)
2006 MIPS_SYS(sys_setuid , 1)
2007 MIPS_SYS(sys_getuid , 0)
2008 MIPS_SYS(sys_stime , 1) /* 4025 */
2009 MIPS_SYS(sys_ptrace , 4)
2010 MIPS_SYS(sys_alarm , 1)
2011 MIPS_SYS(sys_ni_syscall , 0) /* was sys_fstat */
2012 MIPS_SYS(sys_pause , 0)
2013 MIPS_SYS(sys_utime , 2) /* 4030 */
2014 MIPS_SYS(sys_ni_syscall , 0)
2015 MIPS_SYS(sys_ni_syscall , 0)
2016 MIPS_SYS(sys_access , 2)
2017 MIPS_SYS(sys_nice , 1)
2018 MIPS_SYS(sys_ni_syscall , 0) /* 4035 */
2019 MIPS_SYS(sys_sync , 0)
2020 MIPS_SYS(sys_kill , 2)
2021 MIPS_SYS(sys_rename , 2)
2022 MIPS_SYS(sys_mkdir , 2)
2023 MIPS_SYS(sys_rmdir , 1) /* 4040 */
2024 MIPS_SYS(sys_dup , 1)
2025 MIPS_SYS(sys_pipe , 0)
2026 MIPS_SYS(sys_times , 1)
2027 MIPS_SYS(sys_ni_syscall , 0)
2028 MIPS_SYS(sys_brk , 1) /* 4045 */
2029 MIPS_SYS(sys_setgid , 1)
2030 MIPS_SYS(sys_getgid , 0)
2031 MIPS_SYS(sys_ni_syscall , 0) /* was signal(2) */
2032 MIPS_SYS(sys_geteuid , 0)
2033 MIPS_SYS(sys_getegid , 0) /* 4050 */
2034 MIPS_SYS(sys_acct , 0)
2035 MIPS_SYS(sys_umount2 , 2)
2036 MIPS_SYS(sys_ni_syscall , 0)
2037 MIPS_SYS(sys_ioctl , 3)
2038 MIPS_SYS(sys_fcntl , 3) /* 4055 */
2039 MIPS_SYS(sys_ni_syscall , 2)
2040 MIPS_SYS(sys_setpgid , 2)
2041 MIPS_SYS(sys_ni_syscall , 0)
2042 MIPS_SYS(sys_olduname , 1)
2043 MIPS_SYS(sys_umask , 1) /* 4060 */
2044 MIPS_SYS(sys_chroot , 1)
2045 MIPS_SYS(sys_ustat , 2)
2046 MIPS_SYS(sys_dup2 , 2)
2047 MIPS_SYS(sys_getppid , 0)
2048 MIPS_SYS(sys_getpgrp , 0) /* 4065 */
2049 MIPS_SYS(sys_setsid , 0)
2050 MIPS_SYS(sys_sigaction , 3)
2051 MIPS_SYS(sys_sgetmask , 0)
2052 MIPS_SYS(sys_ssetmask , 1)
2053 MIPS_SYS(sys_setreuid , 2) /* 4070 */
2054 MIPS_SYS(sys_setregid , 2)
2055 MIPS_SYS(sys_sigsuspend , 0)
2056 MIPS_SYS(sys_sigpending , 1)
2057 MIPS_SYS(sys_sethostname , 2)
2058 MIPS_SYS(sys_setrlimit , 2) /* 4075 */
2059 MIPS_SYS(sys_getrlimit , 2)
2060 MIPS_SYS(sys_getrusage , 2)
2061 MIPS_SYS(sys_gettimeofday, 2)
2062 MIPS_SYS(sys_settimeofday, 2)
2063 MIPS_SYS(sys_getgroups , 2) /* 4080 */
2064 MIPS_SYS(sys_setgroups , 2)
2065 MIPS_SYS(sys_ni_syscall , 0) /* old_select */
2066 MIPS_SYS(sys_symlink , 2)
2067 MIPS_SYS(sys_ni_syscall , 0) /* was sys_lstat */
2068 MIPS_SYS(sys_readlink , 3) /* 4085 */
2069 MIPS_SYS(sys_uselib , 1)
2070 MIPS_SYS(sys_swapon , 2)
2071 MIPS_SYS(sys_reboot , 3)
2072 MIPS_SYS(old_readdir , 3)
2073 MIPS_SYS(old_mmap , 6) /* 4090 */
2074 MIPS_SYS(sys_munmap , 2)
2075 MIPS_SYS(sys_truncate , 2)
2076 MIPS_SYS(sys_ftruncate , 2)
2077 MIPS_SYS(sys_fchmod , 2)
2078 MIPS_SYS(sys_fchown , 3) /* 4095 */
2079 MIPS_SYS(sys_getpriority , 2)
2080 MIPS_SYS(sys_setpriority , 3)
2081 MIPS_SYS(sys_ni_syscall , 0)
2082 MIPS_SYS(sys_statfs , 2)
2083 MIPS_SYS(sys_fstatfs , 2) /* 4100 */
2084 MIPS_SYS(sys_ni_syscall , 0) /* was ioperm(2) */
2085 MIPS_SYS(sys_socketcall , 2)
2086 MIPS_SYS(sys_syslog , 3)
2087 MIPS_SYS(sys_setitimer , 3)
2088 MIPS_SYS(sys_getitimer , 2) /* 4105 */
2089 MIPS_SYS(sys_newstat , 2)
2090 MIPS_SYS(sys_newlstat , 2)
2091 MIPS_SYS(sys_newfstat , 2)
2092 MIPS_SYS(sys_uname , 1)
2093 MIPS_SYS(sys_ni_syscall , 0) /* 4110 was iopl(2) */
2094 MIPS_SYS(sys_vhangup , 0)
2095 MIPS_SYS(sys_ni_syscall , 0) /* was sys_idle() */
2096 MIPS_SYS(sys_ni_syscall , 0) /* was sys_vm86 */
2097 MIPS_SYS(sys_wait4 , 4)
2098 MIPS_SYS(sys_swapoff , 1) /* 4115 */
2099 MIPS_SYS(sys_sysinfo , 1)
2100 MIPS_SYS(sys_ipc , 6)
2101 MIPS_SYS(sys_fsync , 1)
2102 MIPS_SYS(sys_sigreturn , 0)
2103 MIPS_SYS(sys_clone , 6) /* 4120 */
2104 MIPS_SYS(sys_setdomainname, 2)
2105 MIPS_SYS(sys_newuname , 1)
2106 MIPS_SYS(sys_ni_syscall , 0) /* sys_modify_ldt */
2107 MIPS_SYS(sys_adjtimex , 1)
2108 MIPS_SYS(sys_mprotect , 3) /* 4125 */
2109 MIPS_SYS(sys_sigprocmask , 3)
2110 MIPS_SYS(sys_ni_syscall , 0) /* was create_module */
2111 MIPS_SYS(sys_init_module , 5)
2112 MIPS_SYS(sys_delete_module, 1)
2113 MIPS_SYS(sys_ni_syscall , 0) /* 4130 was get_kernel_syms */
2114 MIPS_SYS(sys_quotactl , 0)
2115 MIPS_SYS(sys_getpgid , 1)
2116 MIPS_SYS(sys_fchdir , 1)
2117 MIPS_SYS(sys_bdflush , 2)
2118 MIPS_SYS(sys_sysfs , 3) /* 4135 */
2119 MIPS_SYS(sys_personality , 1)
2120 MIPS_SYS(sys_ni_syscall , 0) /* for afs_syscall */
2121 MIPS_SYS(sys_setfsuid , 1)
2122 MIPS_SYS(sys_setfsgid , 1)
2123 MIPS_SYS(sys_llseek , 5) /* 4140 */
2124 MIPS_SYS(sys_getdents , 3)
2125 MIPS_SYS(sys_select , 5)
2126 MIPS_SYS(sys_flock , 2)
2127 MIPS_SYS(sys_msync , 3)
2128 MIPS_SYS(sys_readv , 3) /* 4145 */
2129 MIPS_SYS(sys_writev , 3)
2130 MIPS_SYS(sys_cacheflush , 3)
2131 MIPS_SYS(sys_cachectl , 3)
2132 MIPS_SYS(sys_sysmips , 4)
2133 MIPS_SYS(sys_ni_syscall , 0) /* 4150 */
2134 MIPS_SYS(sys_getsid , 1)
2135 MIPS_SYS(sys_fdatasync , 0)
2136 MIPS_SYS(sys_sysctl , 1)
2137 MIPS_SYS(sys_mlock , 2)
2138 MIPS_SYS(sys_munlock , 2) /* 4155 */
2139 MIPS_SYS(sys_mlockall , 1)
2140 MIPS_SYS(sys_munlockall , 0)
2141 MIPS_SYS(sys_sched_setparam, 2)
2142 MIPS_SYS(sys_sched_getparam, 2)
2143 MIPS_SYS(sys_sched_setscheduler, 3) /* 4160 */
2144 MIPS_SYS(sys_sched_getscheduler, 1)
2145 MIPS_SYS(sys_sched_yield , 0)
2146 MIPS_SYS(sys_sched_get_priority_max, 1)
2147 MIPS_SYS(sys_sched_get_priority_min, 1)
2148 MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */
2149 MIPS_SYS(sys_nanosleep, 2)
2150 MIPS_SYS(sys_mremap , 5)
2151 MIPS_SYS(sys_accept , 3)
2152 MIPS_SYS(sys_bind , 3)
2153 MIPS_SYS(sys_connect , 3) /* 4170 */
2154 MIPS_SYS(sys_getpeername , 3)
2155 MIPS_SYS(sys_getsockname , 3)
2156 MIPS_SYS(sys_getsockopt , 5)
2157 MIPS_SYS(sys_listen , 2)
2158 MIPS_SYS(sys_recv , 4) /* 4175 */
2159 MIPS_SYS(sys_recvfrom , 6)
2160 MIPS_SYS(sys_recvmsg , 3)
2161 MIPS_SYS(sys_send , 4)
2162 MIPS_SYS(sys_sendmsg , 3)
2163 MIPS_SYS(sys_sendto , 6) /* 4180 */
2164 MIPS_SYS(sys_setsockopt , 5)
2165 MIPS_SYS(sys_shutdown , 2)
2166 MIPS_SYS(sys_socket , 3)
2167 MIPS_SYS(sys_socketpair , 4)
2168 MIPS_SYS(sys_setresuid , 3) /* 4185 */
2169 MIPS_SYS(sys_getresuid , 3)
2170 MIPS_SYS(sys_ni_syscall , 0) /* was sys_query_module */
2171 MIPS_SYS(sys_poll , 3)
2172 MIPS_SYS(sys_nfsservctl , 3)
2173 MIPS_SYS(sys_setresgid , 3) /* 4190 */
2174 MIPS_SYS(sys_getresgid , 3)
2175 MIPS_SYS(sys_prctl , 5)
2176 MIPS_SYS(sys_rt_sigreturn, 0)
2177 MIPS_SYS(sys_rt_sigaction, 4)
2178 MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
2179 MIPS_SYS(sys_rt_sigpending, 2)
2180 MIPS_SYS(sys_rt_sigtimedwait, 4)
2181 MIPS_SYS(sys_rt_sigqueueinfo, 3)
2182 MIPS_SYS(sys_rt_sigsuspend, 0)
2183 MIPS_SYS(sys_pread64 , 6) /* 4200 */
2184 MIPS_SYS(sys_pwrite64 , 6)
2185 MIPS_SYS(sys_chown , 3)
2186 MIPS_SYS(sys_getcwd , 2)
2187 MIPS_SYS(sys_capget , 2)
2188 MIPS_SYS(sys_capset , 2) /* 4205 */
2189 MIPS_SYS(sys_sigaltstack , 2)
2190 MIPS_SYS(sys_sendfile , 4)
2191 MIPS_SYS(sys_ni_syscall , 0)
2192 MIPS_SYS(sys_ni_syscall , 0)
2193 MIPS_SYS(sys_mmap2 , 6) /* 4210 */
2194 MIPS_SYS(sys_truncate64 , 4)
2195 MIPS_SYS(sys_ftruncate64 , 4)
2196 MIPS_SYS(sys_stat64 , 2)
2197 MIPS_SYS(sys_lstat64 , 2)
2198 MIPS_SYS(sys_fstat64 , 2) /* 4215 */
2199 MIPS_SYS(sys_pivot_root , 2)
2200 MIPS_SYS(sys_mincore , 3)
2201 MIPS_SYS(sys_madvise , 3)
2202 MIPS_SYS(sys_getdents64 , 3)
2203 MIPS_SYS(sys_fcntl64 , 3) /* 4220 */
2204 MIPS_SYS(sys_ni_syscall , 0)
2205 MIPS_SYS(sys_gettid , 0)
2206 MIPS_SYS(sys_readahead , 5)
2207 MIPS_SYS(sys_setxattr , 5)
2208 MIPS_SYS(sys_lsetxattr , 5) /* 4225 */
2209 MIPS_SYS(sys_fsetxattr , 5)
2210 MIPS_SYS(sys_getxattr , 4)
2211 MIPS_SYS(sys_lgetxattr , 4)
2212 MIPS_SYS(sys_fgetxattr , 4)
2213 MIPS_SYS(sys_listxattr , 3) /* 4230 */
2214 MIPS_SYS(sys_llistxattr , 3)
2215 MIPS_SYS(sys_flistxattr , 3)
2216 MIPS_SYS(sys_removexattr , 2)
2217 MIPS_SYS(sys_lremovexattr, 2)
2218 MIPS_SYS(sys_fremovexattr, 2) /* 4235 */
2219 MIPS_SYS(sys_tkill , 2)
2220 MIPS_SYS(sys_sendfile64 , 5)
2221 MIPS_SYS(sys_futex , 6)
2222 MIPS_SYS(sys_sched_setaffinity, 3)
2223 MIPS_SYS(sys_sched_getaffinity, 3) /* 4240 */
2224 MIPS_SYS(sys_io_setup , 2)
2225 MIPS_SYS(sys_io_destroy , 1)
2226 MIPS_SYS(sys_io_getevents, 5)
2227 MIPS_SYS(sys_io_submit , 3)
2228 MIPS_SYS(sys_io_cancel , 3) /* 4245 */
2229 MIPS_SYS(sys_exit_group , 1)
2230 MIPS_SYS(sys_lookup_dcookie, 3)
2231 MIPS_SYS(sys_epoll_create, 1)
2232 MIPS_SYS(sys_epoll_ctl , 4)
2233 MIPS_SYS(sys_epoll_wait , 3) /* 4250 */
2234 MIPS_SYS(sys_remap_file_pages, 5)
2235 MIPS_SYS(sys_set_tid_address, 1)
2236 MIPS_SYS(sys_restart_syscall, 0)
2237 MIPS_SYS(sys_fadvise64_64, 7)
2238 MIPS_SYS(sys_statfs64 , 3) /* 4255 */
2239 MIPS_SYS(sys_fstatfs64 , 2)
2240 MIPS_SYS(sys_timer_create, 3)
2241 MIPS_SYS(sys_timer_settime, 4)
2242 MIPS_SYS(sys_timer_gettime, 2)
2243 MIPS_SYS(sys_timer_getoverrun, 1) /* 4260 */
2244 MIPS_SYS(sys_timer_delete, 1)
2245 MIPS_SYS(sys_clock_settime, 2)
2246 MIPS_SYS(sys_clock_gettime, 2)
2247 MIPS_SYS(sys_clock_getres, 2)
2248 MIPS_SYS(sys_clock_nanosleep, 4) /* 4265 */
2249 MIPS_SYS(sys_tgkill , 3)
2250 MIPS_SYS(sys_utimes , 2)
2251 MIPS_SYS(sys_mbind , 4)
2252 MIPS_SYS(sys_ni_syscall , 0) /* sys_get_mempolicy */
2253 MIPS_SYS(sys_ni_syscall , 0) /* 4270 sys_set_mempolicy */
2254 MIPS_SYS(sys_mq_open , 4)
2255 MIPS_SYS(sys_mq_unlink , 1)
2256 MIPS_SYS(sys_mq_timedsend, 5)
2257 MIPS_SYS(sys_mq_timedreceive, 5)
2258 MIPS_SYS(sys_mq_notify , 2) /* 4275 */
2259 MIPS_SYS(sys_mq_getsetattr, 3)
2260 MIPS_SYS(sys_ni_syscall , 0) /* sys_vserver */
2261 MIPS_SYS(sys_waitid , 4)
2262 MIPS_SYS(sys_ni_syscall , 0) /* available, was setaltroot */
2263 MIPS_SYS(sys_add_key , 5)
2264 MIPS_SYS(sys_request_key, 4)
2265 MIPS_SYS(sys_keyctl , 5)
2266 MIPS_SYS(sys_set_thread_area, 1)
2267 MIPS_SYS(sys_inotify_init, 0)
2268 MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
2269 MIPS_SYS(sys_inotify_rm_watch, 2)
2270 MIPS_SYS(sys_migrate_pages, 4)
2271 MIPS_SYS(sys_openat, 4)
2272 MIPS_SYS(sys_mkdirat, 3)
2273 MIPS_SYS(sys_mknodat, 4) /* 4290 */
2274 MIPS_SYS(sys_fchownat, 5)
2275 MIPS_SYS(sys_futimesat, 3)
2276 MIPS_SYS(sys_fstatat64, 4)
2277 MIPS_SYS(sys_unlinkat, 3)
2278 MIPS_SYS(sys_renameat, 4) /* 4295 */
2279 MIPS_SYS(sys_linkat, 5)
2280 MIPS_SYS(sys_symlinkat, 3)
2281 MIPS_SYS(sys_readlinkat, 4)
2282 MIPS_SYS(sys_fchmodat, 3)
2283 MIPS_SYS(sys_faccessat, 3) /* 4300 */
2284 MIPS_SYS(sys_pselect6, 6)
2285 MIPS_SYS(sys_ppoll, 5)
2286 MIPS_SYS(sys_unshare, 1)
2287 MIPS_SYS(sys_splice, 6)
2288 MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
2289 MIPS_SYS(sys_tee, 4)
2290 MIPS_SYS(sys_vmsplice, 4)
2291 MIPS_SYS(sys_move_pages, 6)
2292 MIPS_SYS(sys_set_robust_list, 2)
2293 MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
2294 MIPS_SYS(sys_kexec_load, 4)
2295 MIPS_SYS(sys_getcpu, 3)
2296 MIPS_SYS(sys_epoll_pwait, 6)
2297 MIPS_SYS(sys_ioprio_set, 3)
2298 MIPS_SYS(sys_ioprio_get, 2)
2299 MIPS_SYS(sys_utimensat, 4)
2300 MIPS_SYS(sys_signalfd, 3)
2301 MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
2302 MIPS_SYS(sys_eventfd, 1)
2303 MIPS_SYS(sys_fallocate, 6) /* 4320 */
2304 MIPS_SYS(sys_timerfd_create, 2)
2305 MIPS_SYS(sys_timerfd_gettime, 2)
2306 MIPS_SYS(sys_timerfd_settime, 4)
2307 MIPS_SYS(sys_signalfd4, 4)
2308 MIPS_SYS(sys_eventfd2, 2) /* 4325 */
2309 MIPS_SYS(sys_epoll_create1, 1)
2310 MIPS_SYS(sys_dup3, 3)
2311 MIPS_SYS(sys_pipe2, 2)
2312 MIPS_SYS(sys_inotify_init1, 1)
2313 MIPS_SYS(sys_preadv, 6) /* 4330 */
2314 MIPS_SYS(sys_pwritev, 6)
2315 MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
2316 MIPS_SYS(sys_perf_event_open, 5)
2317 MIPS_SYS(sys_accept4, 4)
2318 MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
2319 MIPS_SYS(sys_fanotify_init, 2)
2320 MIPS_SYS(sys_fanotify_mark, 6)
2321 MIPS_SYS(sys_prlimit64, 4)
2322 MIPS_SYS(sys_name_to_handle_at, 5)
2323 MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
2324 MIPS_SYS(sys_clock_adjtime, 2)
2325 MIPS_SYS(sys_syncfs, 1)
2327 # undef MIPS_SYS
2328 # endif /* O32 */
2330 static int do_store_exclusive(CPUMIPSState *env)
2332 target_ulong addr;
2333 target_ulong page_addr;
2334 target_ulong val;
2335 int flags;
2336 int segv = 0;
2337 int reg;
2338 int d;
2340 addr = env->lladdr;
2341 page_addr = addr & TARGET_PAGE_MASK;
2342 start_exclusive();
2343 mmap_lock();
2344 flags = page_get_flags(page_addr);
2345 if ((flags & PAGE_READ) == 0) {
2346 segv = 1;
2347 } else {
2348 reg = env->llreg & 0x1f;
2349 d = (env->llreg & 0x20) != 0;
2350 if (d) {
2351 segv = get_user_s64(val, addr);
2352 } else {
2353 segv = get_user_s32(val, addr);
2355 if (!segv) {
2356 if (val != env->llval) {
2357 env->active_tc.gpr[reg] = 0;
2358 } else {
2359 if (d) {
2360 segv = put_user_u64(env->llnewval, addr);
2361 } else {
2362 segv = put_user_u32(env->llnewval, addr);
2364 if (!segv) {
2365 env->active_tc.gpr[reg] = 1;
2370 env->lladdr = -1;
2371 if (!segv) {
2372 env->active_tc.PC += 4;
2374 mmap_unlock();
2375 end_exclusive();
2376 return segv;
2379 /* Break codes */
2380 enum {
2381 BRK_OVERFLOW = 6,
2382 BRK_DIVZERO = 7
2385 static int do_break(CPUMIPSState *env, target_siginfo_t *info,
2386 unsigned int code)
2388 int ret = -1;
2390 switch (code) {
2391 case BRK_OVERFLOW:
2392 case BRK_DIVZERO:
2393 info->si_signo = TARGET_SIGFPE;
2394 info->si_errno = 0;
2395 info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
2396 queue_signal(env, info->si_signo, &*info);
2397 ret = 0;
2398 break;
2399 default:
2400 info->si_signo = TARGET_SIGTRAP;
2401 info->si_errno = 0;
2402 queue_signal(env, info->si_signo, &*info);
2403 ret = 0;
2404 break;
2407 return ret;
2410 void cpu_loop(CPUMIPSState *env)
2412 CPUState *cs = CPU(mips_env_get_cpu(env));
2413 target_siginfo_t info;
2414 int trapnr;
2415 abi_long ret;
2416 # ifdef TARGET_ABI_MIPSO32
2417 unsigned int syscall_num;
2418 # endif
2420 for(;;) {
2421 cpu_exec_start(cs);
2422 trapnr = cpu_mips_exec(env);
2423 cpu_exec_end(cs);
2424 switch(trapnr) {
2425 case EXCP_SYSCALL:
2426 env->active_tc.PC += 4;
2427 # ifdef TARGET_ABI_MIPSO32
2428 syscall_num = env->active_tc.gpr[2] - 4000;
2429 if (syscall_num >= sizeof(mips_syscall_args)) {
2430 ret = -TARGET_ENOSYS;
2431 } else {
2432 int nb_args;
2433 abi_ulong sp_reg;
2434 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
2436 nb_args = mips_syscall_args[syscall_num];
2437 sp_reg = env->active_tc.gpr[29];
2438 switch (nb_args) {
2439 /* these arguments are taken from the stack */
2440 case 8:
2441 if ((ret = get_user_ual(arg8, sp_reg + 28)) != 0) {
2442 goto done_syscall;
2444 case 7:
2445 if ((ret = get_user_ual(arg7, sp_reg + 24)) != 0) {
2446 goto done_syscall;
2448 case 6:
2449 if ((ret = get_user_ual(arg6, sp_reg + 20)) != 0) {
2450 goto done_syscall;
2452 case 5:
2453 if ((ret = get_user_ual(arg5, sp_reg + 16)) != 0) {
2454 goto done_syscall;
2456 default:
2457 break;
2459 ret = do_syscall(env, env->active_tc.gpr[2],
2460 env->active_tc.gpr[4],
2461 env->active_tc.gpr[5],
2462 env->active_tc.gpr[6],
2463 env->active_tc.gpr[7],
2464 arg5, arg6, arg7, arg8);
2466 done_syscall:
2467 # else
2468 ret = do_syscall(env, env->active_tc.gpr[2],
2469 env->active_tc.gpr[4], env->active_tc.gpr[5],
2470 env->active_tc.gpr[6], env->active_tc.gpr[7],
2471 env->active_tc.gpr[8], env->active_tc.gpr[9],
2472 env->active_tc.gpr[10], env->active_tc.gpr[11]);
2473 # endif /* O32 */
2474 if (ret == -TARGET_QEMU_ESIGRETURN) {
2475 /* Returning from a successful sigreturn syscall.
2476 Avoid clobbering register state. */
2477 break;
2479 if ((abi_ulong)ret >= (abi_ulong)-1133) {
2480 env->active_tc.gpr[7] = 1; /* error flag */
2481 ret = -ret;
2482 } else {
2483 env->active_tc.gpr[7] = 0; /* error flag */
2485 env->active_tc.gpr[2] = ret;
2486 break;
2487 case EXCP_TLBL:
2488 case EXCP_TLBS:
2489 case EXCP_AdEL:
2490 case EXCP_AdES:
2491 info.si_signo = TARGET_SIGSEGV;
2492 info.si_errno = 0;
2493 /* XXX: check env->error_code */
2494 info.si_code = TARGET_SEGV_MAPERR;
2495 info._sifields._sigfault._addr = env->CP0_BadVAddr;
2496 queue_signal(env, info.si_signo, &info);
2497 break;
2498 case EXCP_CpU:
2499 case EXCP_RI:
2500 info.si_signo = TARGET_SIGILL;
2501 info.si_errno = 0;
2502 info.si_code = 0;
2503 queue_signal(env, info.si_signo, &info);
2504 break;
2505 case EXCP_INTERRUPT:
2506 /* just indicate that signals should be handled asap */
2507 break;
2508 case EXCP_DEBUG:
2510 int sig;
2512 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2513 if (sig)
2515 info.si_signo = sig;
2516 info.si_errno = 0;
2517 info.si_code = TARGET_TRAP_BRKPT;
2518 queue_signal(env, info.si_signo, &info);
2521 break;
2522 case EXCP_SC:
2523 if (do_store_exclusive(env)) {
2524 info.si_signo = TARGET_SIGSEGV;
2525 info.si_errno = 0;
2526 info.si_code = TARGET_SEGV_MAPERR;
2527 info._sifields._sigfault._addr = env->active_tc.PC;
2528 queue_signal(env, info.si_signo, &info);
2530 break;
2531 case EXCP_DSPDIS:
2532 info.si_signo = TARGET_SIGILL;
2533 info.si_errno = 0;
2534 info.si_code = TARGET_ILL_ILLOPC;
2535 queue_signal(env, info.si_signo, &info);
2536 break;
2537 /* The code below was inspired by the MIPS Linux kernel trap
2538 * handling code in arch/mips/kernel/traps.c.
2540 case EXCP_BREAK:
2542 abi_ulong trap_instr;
2543 unsigned int code;
2545 if (env->hflags & MIPS_HFLAG_M16) {
2546 if (env->insn_flags & ASE_MICROMIPS) {
2547 /* microMIPS mode */
2548 ret = get_user_u16(trap_instr, env->active_tc.PC);
2549 if (ret != 0) {
2550 goto error;
2553 if ((trap_instr >> 10) == 0x11) {
2554 /* 16-bit instruction */
2555 code = trap_instr & 0xf;
2556 } else {
2557 /* 32-bit instruction */
2558 abi_ulong instr_lo;
2560 ret = get_user_u16(instr_lo,
2561 env->active_tc.PC + 2);
2562 if (ret != 0) {
2563 goto error;
2565 trap_instr = (trap_instr << 16) | instr_lo;
2566 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2567 /* Unfortunately, microMIPS also suffers from
2568 the old assembler bug... */
2569 if (code >= (1 << 10)) {
2570 code >>= 10;
2573 } else {
2574 /* MIPS16e mode */
2575 ret = get_user_u16(trap_instr, env->active_tc.PC);
2576 if (ret != 0) {
2577 goto error;
2579 code = (trap_instr >> 6) & 0x3f;
2581 } else {
2582 ret = get_user_ual(trap_instr, env->active_tc.PC);
2583 if (ret != 0) {
2584 goto error;
2587 /* As described in the original Linux kernel code, the
2588 * below checks on 'code' are to work around an old
2589 * assembly bug.
2591 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2592 if (code >= (1 << 10)) {
2593 code >>= 10;
2597 if (do_break(env, &info, code) != 0) {
2598 goto error;
2601 break;
2602 case EXCP_TRAP:
2604 abi_ulong trap_instr;
2605 unsigned int code = 0;
2607 if (env->hflags & MIPS_HFLAG_M16) {
2608 /* microMIPS mode */
2609 abi_ulong instr[2];
2611 ret = get_user_u16(instr[0], env->active_tc.PC) ||
2612 get_user_u16(instr[1], env->active_tc.PC + 2);
2614 trap_instr = (instr[0] << 16) | instr[1];
2615 } else {
2616 ret = get_user_ual(trap_instr, env->active_tc.PC);
2619 if (ret != 0) {
2620 goto error;
2623 /* The immediate versions don't provide a code. */
2624 if (!(trap_instr & 0xFC000000)) {
2625 if (env->hflags & MIPS_HFLAG_M16) {
2626 /* microMIPS mode */
2627 code = ((trap_instr >> 12) & ((1 << 4) - 1));
2628 } else {
2629 code = ((trap_instr >> 6) & ((1 << 10) - 1));
2633 if (do_break(env, &info, code) != 0) {
2634 goto error;
2637 break;
2638 default:
2639 error:
2640 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
2641 trapnr);
2642 cpu_dump_state(cs, stderr, fprintf, 0);
2643 abort();
2645 process_pending_signals(env);
2648 #endif
2650 #ifdef TARGET_OPENRISC
2652 void cpu_loop(CPUOpenRISCState *env)
2654 CPUState *cs = CPU(openrisc_env_get_cpu(env));
2655 int trapnr, gdbsig;
2657 for (;;) {
2658 trapnr = cpu_exec(env);
2659 gdbsig = 0;
2661 switch (trapnr) {
2662 case EXCP_RESET:
2663 qemu_log("\nReset request, exit, pc is %#x\n", env->pc);
2664 exit(1);
2665 break;
2666 case EXCP_BUSERR:
2667 qemu_log("\nBus error, exit, pc is %#x\n", env->pc);
2668 gdbsig = SIGBUS;
2669 break;
2670 case EXCP_DPF:
2671 case EXCP_IPF:
2672 cpu_dump_state(cs, stderr, fprintf, 0);
2673 gdbsig = TARGET_SIGSEGV;
2674 break;
2675 case EXCP_TICK:
2676 qemu_log("\nTick time interrupt pc is %#x\n", env->pc);
2677 break;
2678 case EXCP_ALIGN:
2679 qemu_log("\nAlignment pc is %#x\n", env->pc);
2680 gdbsig = SIGBUS;
2681 break;
2682 case EXCP_ILLEGAL:
2683 qemu_log("\nIllegal instructionpc is %#x\n", env->pc);
2684 gdbsig = SIGILL;
2685 break;
2686 case EXCP_INT:
2687 qemu_log("\nExternal interruptpc is %#x\n", env->pc);
2688 break;
2689 case EXCP_DTLBMISS:
2690 case EXCP_ITLBMISS:
2691 qemu_log("\nTLB miss\n");
2692 break;
2693 case EXCP_RANGE:
2694 qemu_log("\nRange\n");
2695 gdbsig = SIGSEGV;
2696 break;
2697 case EXCP_SYSCALL:
2698 env->pc += 4; /* 0xc00; */
2699 env->gpr[11] = do_syscall(env,
2700 env->gpr[11], /* return value */
2701 env->gpr[3], /* r3 - r7 are params */
2702 env->gpr[4],
2703 env->gpr[5],
2704 env->gpr[6],
2705 env->gpr[7],
2706 env->gpr[8], 0, 0);
2707 break;
2708 case EXCP_FPE:
2709 qemu_log("\nFloating point error\n");
2710 break;
2711 case EXCP_TRAP:
2712 qemu_log("\nTrap\n");
2713 gdbsig = SIGTRAP;
2714 break;
2715 case EXCP_NR:
2716 qemu_log("\nNR\n");
2717 break;
2718 default:
2719 qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
2720 trapnr);
2721 cpu_dump_state(cs, stderr, fprintf, 0);
2722 gdbsig = TARGET_SIGILL;
2723 break;
2725 if (gdbsig) {
2726 gdb_handlesig(cs, gdbsig);
2727 if (gdbsig != TARGET_SIGTRAP) {
2728 exit(1);
2732 process_pending_signals(env);
2736 #endif /* TARGET_OPENRISC */
2738 #ifdef TARGET_SH4
2739 void cpu_loop(CPUSH4State *env)
2741 CPUState *cs = CPU(sh_env_get_cpu(env));
2742 int trapnr, ret;
2743 target_siginfo_t info;
2745 while (1) {
2746 trapnr = cpu_sh4_exec (env);
2748 switch (trapnr) {
2749 case 0x160:
2750 env->pc += 2;
2751 ret = do_syscall(env,
2752 env->gregs[3],
2753 env->gregs[4],
2754 env->gregs[5],
2755 env->gregs[6],
2756 env->gregs[7],
2757 env->gregs[0],
2758 env->gregs[1],
2759 0, 0);
2760 env->gregs[0] = ret;
2761 break;
2762 case EXCP_INTERRUPT:
2763 /* just indicate that signals should be handled asap */
2764 break;
2765 case EXCP_DEBUG:
2767 int sig;
2769 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2770 if (sig)
2772 info.si_signo = sig;
2773 info.si_errno = 0;
2774 info.si_code = TARGET_TRAP_BRKPT;
2775 queue_signal(env, info.si_signo, &info);
2778 break;
2779 case 0xa0:
2780 case 0xc0:
2781 info.si_signo = SIGSEGV;
2782 info.si_errno = 0;
2783 info.si_code = TARGET_SEGV_MAPERR;
2784 info._sifields._sigfault._addr = env->tea;
2785 queue_signal(env, info.si_signo, &info);
2786 break;
2788 default:
2789 printf ("Unhandled trap: 0x%x\n", trapnr);
2790 cpu_dump_state(cs, stderr, fprintf, 0);
2791 exit (1);
2793 process_pending_signals (env);
2796 #endif
2798 #ifdef TARGET_CRIS
2799 void cpu_loop(CPUCRISState *env)
2801 CPUState *cs = CPU(cris_env_get_cpu(env));
2802 int trapnr, ret;
2803 target_siginfo_t info;
2805 while (1) {
2806 trapnr = cpu_cris_exec (env);
2807 switch (trapnr) {
2808 case 0xaa:
2810 info.si_signo = SIGSEGV;
2811 info.si_errno = 0;
2812 /* XXX: check env->error_code */
2813 info.si_code = TARGET_SEGV_MAPERR;
2814 info._sifields._sigfault._addr = env->pregs[PR_EDA];
2815 queue_signal(env, info.si_signo, &info);
2817 break;
2818 case EXCP_INTERRUPT:
2819 /* just indicate that signals should be handled asap */
2820 break;
2821 case EXCP_BREAK:
2822 ret = do_syscall(env,
2823 env->regs[9],
2824 env->regs[10],
2825 env->regs[11],
2826 env->regs[12],
2827 env->regs[13],
2828 env->pregs[7],
2829 env->pregs[11],
2830 0, 0);
2831 env->regs[10] = ret;
2832 break;
2833 case EXCP_DEBUG:
2835 int sig;
2837 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2838 if (sig)
2840 info.si_signo = sig;
2841 info.si_errno = 0;
2842 info.si_code = TARGET_TRAP_BRKPT;
2843 queue_signal(env, info.si_signo, &info);
2846 break;
2847 default:
2848 printf ("Unhandled trap: 0x%x\n", trapnr);
2849 cpu_dump_state(cs, stderr, fprintf, 0);
2850 exit (1);
2852 process_pending_signals (env);
2855 #endif
2857 #ifdef TARGET_MICROBLAZE
2858 void cpu_loop(CPUMBState *env)
2860 CPUState *cs = CPU(mb_env_get_cpu(env));
2861 int trapnr, ret;
2862 target_siginfo_t info;
2864 while (1) {
2865 trapnr = cpu_mb_exec (env);
2866 switch (trapnr) {
2867 case 0xaa:
2869 info.si_signo = SIGSEGV;
2870 info.si_errno = 0;
2871 /* XXX: check env->error_code */
2872 info.si_code = TARGET_SEGV_MAPERR;
2873 info._sifields._sigfault._addr = 0;
2874 queue_signal(env, info.si_signo, &info);
2876 break;
2877 case EXCP_INTERRUPT:
2878 /* just indicate that signals should be handled asap */
2879 break;
2880 case EXCP_BREAK:
2881 /* Return address is 4 bytes after the call. */
2882 env->regs[14] += 4;
2883 env->sregs[SR_PC] = env->regs[14];
2884 ret = do_syscall(env,
2885 env->regs[12],
2886 env->regs[5],
2887 env->regs[6],
2888 env->regs[7],
2889 env->regs[8],
2890 env->regs[9],
2891 env->regs[10],
2892 0, 0);
2893 env->regs[3] = ret;
2894 break;
2895 case EXCP_HW_EXCP:
2896 env->regs[17] = env->sregs[SR_PC] + 4;
2897 if (env->iflags & D_FLAG) {
2898 env->sregs[SR_ESR] |= 1 << 12;
2899 env->sregs[SR_PC] -= 4;
2900 /* FIXME: if branch was immed, replay the imm as well. */
2903 env->iflags &= ~(IMM_FLAG | D_FLAG);
2905 switch (env->sregs[SR_ESR] & 31) {
2906 case ESR_EC_DIVZERO:
2907 info.si_signo = SIGFPE;
2908 info.si_errno = 0;
2909 info.si_code = TARGET_FPE_FLTDIV;
2910 info._sifields._sigfault._addr = 0;
2911 queue_signal(env, info.si_signo, &info);
2912 break;
2913 case ESR_EC_FPU:
2914 info.si_signo = SIGFPE;
2915 info.si_errno = 0;
2916 if (env->sregs[SR_FSR] & FSR_IO) {
2917 info.si_code = TARGET_FPE_FLTINV;
2919 if (env->sregs[SR_FSR] & FSR_DZ) {
2920 info.si_code = TARGET_FPE_FLTDIV;
2922 info._sifields._sigfault._addr = 0;
2923 queue_signal(env, info.si_signo, &info);
2924 break;
2925 default:
2926 printf ("Unhandled hw-exception: 0x%x\n",
2927 env->sregs[SR_ESR] & ESR_EC_MASK);
2928 cpu_dump_state(cs, stderr, fprintf, 0);
2929 exit (1);
2930 break;
2932 break;
2933 case EXCP_DEBUG:
2935 int sig;
2937 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2938 if (sig)
2940 info.si_signo = sig;
2941 info.si_errno = 0;
2942 info.si_code = TARGET_TRAP_BRKPT;
2943 queue_signal(env, info.si_signo, &info);
2946 break;
2947 default:
2948 printf ("Unhandled trap: 0x%x\n", trapnr);
2949 cpu_dump_state(cs, stderr, fprintf, 0);
2950 exit (1);
2952 process_pending_signals (env);
2955 #endif
2957 #ifdef TARGET_M68K
2959 void cpu_loop(CPUM68KState *env)
2961 CPUState *cs = CPU(m68k_env_get_cpu(env));
2962 int trapnr;
2963 unsigned int n;
2964 target_siginfo_t info;
2965 TaskState *ts = cs->opaque;
2967 for(;;) {
2968 trapnr = cpu_m68k_exec(env);
2969 switch(trapnr) {
2970 case EXCP_ILLEGAL:
2972 if (ts->sim_syscalls) {
2973 uint16_t nr;
2974 nr = lduw(env->pc + 2);
2975 env->pc += 4;
2976 do_m68k_simcall(env, nr);
2977 } else {
2978 goto do_sigill;
2981 break;
2982 case EXCP_HALT_INSN:
2983 /* Semihosing syscall. */
2984 env->pc += 4;
2985 do_m68k_semihosting(env, env->dregs[0]);
2986 break;
2987 case EXCP_LINEA:
2988 case EXCP_LINEF:
2989 case EXCP_UNSUPPORTED:
2990 do_sigill:
2991 info.si_signo = SIGILL;
2992 info.si_errno = 0;
2993 info.si_code = TARGET_ILL_ILLOPN;
2994 info._sifields._sigfault._addr = env->pc;
2995 queue_signal(env, info.si_signo, &info);
2996 break;
2997 case EXCP_TRAP0:
2999 ts->sim_syscalls = 0;
3000 n = env->dregs[0];
3001 env->pc += 2;
3002 env->dregs[0] = do_syscall(env,
3004 env->dregs[1],
3005 env->dregs[2],
3006 env->dregs[3],
3007 env->dregs[4],
3008 env->dregs[5],
3009 env->aregs[0],
3010 0, 0);
3012 break;
3013 case EXCP_INTERRUPT:
3014 /* just indicate that signals should be handled asap */
3015 break;
3016 case EXCP_ACCESS:
3018 info.si_signo = SIGSEGV;
3019 info.si_errno = 0;
3020 /* XXX: check env->error_code */
3021 info.si_code = TARGET_SEGV_MAPERR;
3022 info._sifields._sigfault._addr = env->mmu.ar;
3023 queue_signal(env, info.si_signo, &info);
3025 break;
3026 case EXCP_DEBUG:
3028 int sig;
3030 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
3031 if (sig)
3033 info.si_signo = sig;
3034 info.si_errno = 0;
3035 info.si_code = TARGET_TRAP_BRKPT;
3036 queue_signal(env, info.si_signo, &info);
3039 break;
3040 default:
3041 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
3042 trapnr);
3043 cpu_dump_state(cs, stderr, fprintf, 0);
3044 abort();
3046 process_pending_signals(env);
3049 #endif /* TARGET_M68K */
3051 #ifdef TARGET_ALPHA
3052 static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
3054 target_ulong addr, val, tmp;
3055 target_siginfo_t info;
3056 int ret = 0;
3058 addr = env->lock_addr;
3059 tmp = env->lock_st_addr;
3060 env->lock_addr = -1;
3061 env->lock_st_addr = 0;
3063 start_exclusive();
3064 mmap_lock();
3066 if (addr == tmp) {
3067 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
3068 goto do_sigsegv;
3071 if (val == env->lock_value) {
3072 tmp = env->ir[reg];
3073 if (quad ? put_user_u64(tmp, addr) : put_user_u32(tmp, addr)) {
3074 goto do_sigsegv;
3076 ret = 1;
3079 env->ir[reg] = ret;
3080 env->pc += 4;
3082 mmap_unlock();
3083 end_exclusive();
3084 return;
3086 do_sigsegv:
3087 mmap_unlock();
3088 end_exclusive();
3090 info.si_signo = TARGET_SIGSEGV;
3091 info.si_errno = 0;
3092 info.si_code = TARGET_SEGV_MAPERR;
3093 info._sifields._sigfault._addr = addr;
3094 queue_signal(env, TARGET_SIGSEGV, &info);
3097 void cpu_loop(CPUAlphaState *env)
3099 CPUState *cs = CPU(alpha_env_get_cpu(env));
3100 int trapnr;
3101 target_siginfo_t info;
3102 abi_long sysret;
3104 while (1) {
3105 trapnr = cpu_alpha_exec (env);
3107 /* All of the traps imply a transition through PALcode, which
3108 implies an REI instruction has been executed. Which means
3109 that the intr_flag should be cleared. */
3110 env->intr_flag = 0;
3112 switch (trapnr) {
3113 case EXCP_RESET:
3114 fprintf(stderr, "Reset requested. Exit\n");
3115 exit(1);
3116 break;
3117 case EXCP_MCHK:
3118 fprintf(stderr, "Machine check exception. Exit\n");
3119 exit(1);
3120 break;
3121 case EXCP_SMP_INTERRUPT:
3122 case EXCP_CLK_INTERRUPT:
3123 case EXCP_DEV_INTERRUPT:
3124 fprintf(stderr, "External interrupt. Exit\n");
3125 exit(1);
3126 break;
3127 case EXCP_MMFAULT:
3128 env->lock_addr = -1;
3129 info.si_signo = TARGET_SIGSEGV;
3130 info.si_errno = 0;
3131 info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
3132 ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
3133 info._sifields._sigfault._addr = env->trap_arg0;
3134 queue_signal(env, info.si_signo, &info);
3135 break;
3136 case EXCP_UNALIGN:
3137 env->lock_addr = -1;
3138 info.si_signo = TARGET_SIGBUS;
3139 info.si_errno = 0;
3140 info.si_code = TARGET_BUS_ADRALN;
3141 info._sifields._sigfault._addr = env->trap_arg0;
3142 queue_signal(env, info.si_signo, &info);
3143 break;
3144 case EXCP_OPCDEC:
3145 do_sigill:
3146 env->lock_addr = -1;
3147 info.si_signo = TARGET_SIGILL;
3148 info.si_errno = 0;
3149 info.si_code = TARGET_ILL_ILLOPC;
3150 info._sifields._sigfault._addr = env->pc;
3151 queue_signal(env, info.si_signo, &info);
3152 break;
3153 case EXCP_ARITH:
3154 env->lock_addr = -1;
3155 info.si_signo = TARGET_SIGFPE;
3156 info.si_errno = 0;
3157 info.si_code = TARGET_FPE_FLTINV;
3158 info._sifields._sigfault._addr = env->pc;
3159 queue_signal(env, info.si_signo, &info);
3160 break;
3161 case EXCP_FEN:
3162 /* No-op. Linux simply re-enables the FPU. */
3163 break;
3164 case EXCP_CALL_PAL:
3165 env->lock_addr = -1;
3166 switch (env->error_code) {
3167 case 0x80:
3168 /* BPT */
3169 info.si_signo = TARGET_SIGTRAP;
3170 info.si_errno = 0;
3171 info.si_code = TARGET_TRAP_BRKPT;
3172 info._sifields._sigfault._addr = env->pc;
3173 queue_signal(env, info.si_signo, &info);
3174 break;
3175 case 0x81:
3176 /* BUGCHK */
3177 info.si_signo = TARGET_SIGTRAP;
3178 info.si_errno = 0;
3179 info.si_code = 0;
3180 info._sifields._sigfault._addr = env->pc;
3181 queue_signal(env, info.si_signo, &info);
3182 break;
3183 case 0x83:
3184 /* CALLSYS */
3185 trapnr = env->ir[IR_V0];
3186 sysret = do_syscall(env, trapnr,
3187 env->ir[IR_A0], env->ir[IR_A1],
3188 env->ir[IR_A2], env->ir[IR_A3],
3189 env->ir[IR_A4], env->ir[IR_A5],
3190 0, 0);
3191 if (trapnr == TARGET_NR_sigreturn
3192 || trapnr == TARGET_NR_rt_sigreturn) {
3193 break;
3195 /* Syscall writes 0 to V0 to bypass error check, similar
3196 to how this is handled internal to Linux kernel.
3197 (Ab)use trapnr temporarily as boolean indicating error. */
3198 trapnr = (env->ir[IR_V0] != 0 && sysret < 0);
3199 env->ir[IR_V0] = (trapnr ? -sysret : sysret);
3200 env->ir[IR_A3] = trapnr;
3201 break;
3202 case 0x86:
3203 /* IMB */
3204 /* ??? We can probably elide the code using page_unprotect
3205 that is checking for self-modifying code. Instead we
3206 could simply call tb_flush here. Until we work out the
3207 changes required to turn off the extra write protection,
3208 this can be a no-op. */
3209 break;
3210 case 0x9E:
3211 /* RDUNIQUE */
3212 /* Handled in the translator for usermode. */
3213 abort();
3214 case 0x9F:
3215 /* WRUNIQUE */
3216 /* Handled in the translator for usermode. */
3217 abort();
3218 case 0xAA:
3219 /* GENTRAP */
3220 info.si_signo = TARGET_SIGFPE;
3221 switch (env->ir[IR_A0]) {
3222 case TARGET_GEN_INTOVF:
3223 info.si_code = TARGET_FPE_INTOVF;
3224 break;
3225 case TARGET_GEN_INTDIV:
3226 info.si_code = TARGET_FPE_INTDIV;
3227 break;
3228 case TARGET_GEN_FLTOVF:
3229 info.si_code = TARGET_FPE_FLTOVF;
3230 break;
3231 case TARGET_GEN_FLTUND:
3232 info.si_code = TARGET_FPE_FLTUND;
3233 break;
3234 case TARGET_GEN_FLTINV:
3235 info.si_code = TARGET_FPE_FLTINV;
3236 break;
3237 case TARGET_GEN_FLTINE:
3238 info.si_code = TARGET_FPE_FLTRES;
3239 break;
3240 case TARGET_GEN_ROPRAND:
3241 info.si_code = 0;
3242 break;
3243 default:
3244 info.si_signo = TARGET_SIGTRAP;
3245 info.si_code = 0;
3246 break;
3248 info.si_errno = 0;
3249 info._sifields._sigfault._addr = env->pc;
3250 queue_signal(env, info.si_signo, &info);
3251 break;
3252 default:
3253 goto do_sigill;
3255 break;
3256 case EXCP_DEBUG:
3257 info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
3258 if (info.si_signo) {
3259 env->lock_addr = -1;
3260 info.si_errno = 0;
3261 info.si_code = TARGET_TRAP_BRKPT;
3262 queue_signal(env, info.si_signo, &info);
3264 break;
3265 case EXCP_STL_C:
3266 case EXCP_STQ_C:
3267 do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C);
3268 break;
3269 case EXCP_INTERRUPT:
3270 /* Just indicate that signals should be handled asap. */
3271 break;
3272 default:
3273 printf ("Unhandled trap: 0x%x\n", trapnr);
3274 cpu_dump_state(cs, stderr, fprintf, 0);
3275 exit (1);
3277 process_pending_signals (env);
3280 #endif /* TARGET_ALPHA */
3282 #ifdef TARGET_S390X
3283 void cpu_loop(CPUS390XState *env)
3285 CPUState *cs = CPU(s390_env_get_cpu(env));
3286 int trapnr, n, sig;
3287 target_siginfo_t info;
3288 target_ulong addr;
3290 while (1) {
3291 trapnr = cpu_s390x_exec(env);
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 = SIGILL;
3322 n = TARGET_ILL_ILLOPC;
3323 goto do_signal_pc;
3324 case PGM_PROTECTION:
3325 case PGM_ADDRESSING:
3326 sig = 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 = SIGILL;
3337 n = TARGET_ILL_ILLOPN;
3338 goto do_signal_pc;
3340 case PGM_FIXPT_OVERFLOW:
3341 sig = SIGFPE;
3342 n = TARGET_FPE_INTOVF;
3343 goto do_signal_pc;
3344 case PGM_FIXPT_DIVIDE:
3345 sig = 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 = 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(1);
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(1);
3396 process_pending_signals (env);
3400 #endif /* TARGET_S390X */
3402 THREAD CPUState *thread_cpu;
3404 void task_settid(TaskState *ts)
3406 if (ts->ts_tid == 0) {
3407 ts->ts_tid = (pid_t)syscall(SYS_gettid);
3411 void stop_all_tasks(void)
3414 * We trust that when using NPTL, start_exclusive()
3415 * handles thread stopping correctly.
3417 start_exclusive();
3420 /* Assumes contents are already zeroed. */
3421 void init_task_state(TaskState *ts)
3423 int i;
3425 ts->used = 1;
3426 ts->first_free = ts->sigqueue_table;
3427 for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
3428 ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
3430 ts->sigqueue_table[i].next = NULL;
3433 CPUArchState *cpu_copy(CPUArchState *env)
3435 CPUState *cpu = ENV_GET_CPU(env);
3436 CPUArchState *new_env = cpu_init(cpu_model);
3437 CPUState *new_cpu = ENV_GET_CPU(new_env);
3438 #if defined(TARGET_HAS_ICE)
3439 CPUBreakpoint *bp;
3440 CPUWatchpoint *wp;
3441 #endif
3443 /* Reset non arch specific state */
3444 cpu_reset(new_cpu);
3446 memcpy(new_env, env, sizeof(CPUArchState));
3448 /* Clone all break/watchpoints.
3449 Note: Once we support ptrace with hw-debug register access, make sure
3450 BP_CPU break/watchpoints are handled correctly on clone. */
3451 QTAILQ_INIT(&cpu->breakpoints);
3452 QTAILQ_INIT(&cpu->watchpoints);
3453 #if defined(TARGET_HAS_ICE)
3454 QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
3455 cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
3457 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
3458 cpu_watchpoint_insert(new_cpu, wp->vaddr, (~wp->len_mask) + 1,
3459 wp->flags, NULL);
3461 #endif
3463 return new_env;
3466 static void handle_arg_help(const char *arg)
3468 usage();
3471 static void handle_arg_log(const char *arg)
3473 int mask;
3475 mask = qemu_str_to_log_mask(arg);
3476 if (!mask) {
3477 qemu_print_log_usage(stdout);
3478 exit(1);
3480 qemu_set_log(mask);
3483 static void handle_arg_log_filename(const char *arg)
3485 qemu_set_log_filename(arg);
3488 static void handle_arg_set_env(const char *arg)
3490 char *r, *p, *token;
3491 r = p = strdup(arg);
3492 while ((token = strsep(&p, ",")) != NULL) {
3493 if (envlist_setenv(envlist, token) != 0) {
3494 usage();
3497 free(r);
3500 static void handle_arg_unset_env(const char *arg)
3502 char *r, *p, *token;
3503 r = p = strdup(arg);
3504 while ((token = strsep(&p, ",")) != NULL) {
3505 if (envlist_unsetenv(envlist, token) != 0) {
3506 usage();
3509 free(r);
3512 static void handle_arg_argv0(const char *arg)
3514 argv0 = strdup(arg);
3517 static void handle_arg_stack_size(const char *arg)
3519 char *p;
3520 guest_stack_size = strtoul(arg, &p, 0);
3521 if (guest_stack_size == 0) {
3522 usage();
3525 if (*p == 'M') {
3526 guest_stack_size *= 1024 * 1024;
3527 } else if (*p == 'k' || *p == 'K') {
3528 guest_stack_size *= 1024;
3532 static void handle_arg_ld_prefix(const char *arg)
3534 interp_prefix = strdup(arg);
3537 static void handle_arg_pagesize(const char *arg)
3539 qemu_host_page_size = atoi(arg);
3540 if (qemu_host_page_size == 0 ||
3541 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
3542 fprintf(stderr, "page size must be a power of two\n");
3543 exit(1);
3547 static void handle_arg_gdb(const char *arg)
3549 gdbstub_port = atoi(arg);
3552 static void handle_arg_uname(const char *arg)
3554 qemu_uname_release = strdup(arg);
3557 static void handle_arg_cpu(const char *arg)
3559 cpu_model = strdup(arg);
3560 if (cpu_model == NULL || is_help_option(cpu_model)) {
3561 /* XXX: implement xxx_cpu_list for targets that still miss it */
3562 #if defined(cpu_list)
3563 cpu_list(stdout, &fprintf);
3564 #endif
3565 exit(1);
3569 #if defined(CONFIG_USE_GUEST_BASE)
3570 static void handle_arg_guest_base(const char *arg)
3572 guest_base = strtol(arg, NULL, 0);
3573 have_guest_base = 1;
3576 static void handle_arg_reserved_va(const char *arg)
3578 char *p;
3579 int shift = 0;
3580 reserved_va = strtoul(arg, &p, 0);
3581 switch (*p) {
3582 case 'k':
3583 case 'K':
3584 shift = 10;
3585 break;
3586 case 'M':
3587 shift = 20;
3588 break;
3589 case 'G':
3590 shift = 30;
3591 break;
3593 if (shift) {
3594 unsigned long unshifted = reserved_va;
3595 p++;
3596 reserved_va <<= shift;
3597 if (((reserved_va >> shift) != unshifted)
3598 #if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
3599 || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
3600 #endif
3602 fprintf(stderr, "Reserved virtual address too big\n");
3603 exit(1);
3606 if (*p) {
3607 fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
3608 exit(1);
3611 #endif
3613 static void handle_arg_singlestep(const char *arg)
3615 singlestep = 1;
3618 static void handle_arg_strace(const char *arg)
3620 do_strace = 1;
3623 static void handle_arg_version(const char *arg)
3625 printf("qemu-" TARGET_NAME " version " QEMU_VERSION QEMU_PKGVERSION
3626 ", Copyright (c) 2003-2008 Fabrice Bellard\n");
3627 exit(0);
3630 struct qemu_argument {
3631 const char *argv;
3632 const char *env;
3633 bool has_arg;
3634 void (*handle_opt)(const char *arg);
3635 const char *example;
3636 const char *help;
3639 static const struct qemu_argument arg_table[] = {
3640 {"h", "", false, handle_arg_help,
3641 "", "print this help"},
3642 {"g", "QEMU_GDB", true, handle_arg_gdb,
3643 "port", "wait gdb connection to 'port'"},
3644 {"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix,
3645 "path", "set the elf interpreter prefix to 'path'"},
3646 {"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
3647 "size", "set the stack size to 'size' bytes"},
3648 {"cpu", "QEMU_CPU", true, handle_arg_cpu,
3649 "model", "select CPU (-cpu help for list)"},
3650 {"E", "QEMU_SET_ENV", true, handle_arg_set_env,
3651 "var=value", "sets targets environment variable (see below)"},
3652 {"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
3653 "var", "unsets targets environment variable (see below)"},
3654 {"0", "QEMU_ARGV0", true, handle_arg_argv0,
3655 "argv0", "forces target process argv[0] to be 'argv0'"},
3656 {"r", "QEMU_UNAME", true, handle_arg_uname,
3657 "uname", "set qemu uname release string to 'uname'"},
3658 #if defined(CONFIG_USE_GUEST_BASE)
3659 {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base,
3660 "address", "set guest_base address to 'address'"},
3661 {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
3662 "size", "reserve 'size' bytes for guest virtual address space"},
3663 #endif
3664 {"d", "QEMU_LOG", true, handle_arg_log,
3665 "item[,...]", "enable logging of specified items "
3666 "(use '-d help' for a list of items)"},
3667 {"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
3668 "logfile", "write logs to 'logfile' (default stderr)"},
3669 {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
3670 "pagesize", "set the host page size to 'pagesize'"},
3671 {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
3672 "", "run in singlestep mode"},
3673 {"strace", "QEMU_STRACE", false, handle_arg_strace,
3674 "", "log system calls"},
3675 {"version", "QEMU_VERSION", false, handle_arg_version,
3676 "", "display version information and exit"},
3677 {NULL, NULL, false, NULL, NULL, NULL}
3680 static void usage(void)
3682 const struct qemu_argument *arginfo;
3683 int maxarglen;
3684 int maxenvlen;
3686 printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
3687 "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
3688 "\n"
3689 "Options and associated environment variables:\n"
3690 "\n");
3692 /* Calculate column widths. We must always have at least enough space
3693 * for the column header.
3695 maxarglen = strlen("Argument");
3696 maxenvlen = strlen("Env-variable");
3698 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3699 int arglen = strlen(arginfo->argv);
3700 if (arginfo->has_arg) {
3701 arglen += strlen(arginfo->example) + 1;
3703 if (strlen(arginfo->env) > maxenvlen) {
3704 maxenvlen = strlen(arginfo->env);
3706 if (arglen > maxarglen) {
3707 maxarglen = arglen;
3711 printf("%-*s %-*s Description\n", maxarglen+1, "Argument",
3712 maxenvlen, "Env-variable");
3714 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3715 if (arginfo->has_arg) {
3716 printf("-%s %-*s %-*s %s\n", arginfo->argv,
3717 (int)(maxarglen - strlen(arginfo->argv) - 1),
3718 arginfo->example, maxenvlen, arginfo->env, arginfo->help);
3719 } else {
3720 printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv,
3721 maxenvlen, arginfo->env,
3722 arginfo->help);
3726 printf("\n"
3727 "Defaults:\n"
3728 "QEMU_LD_PREFIX = %s\n"
3729 "QEMU_STACK_SIZE = %ld byte\n",
3730 interp_prefix,
3731 guest_stack_size);
3733 printf("\n"
3734 "You can use -E and -U options or the QEMU_SET_ENV and\n"
3735 "QEMU_UNSET_ENV environment variables to set and unset\n"
3736 "environment variables for the target process.\n"
3737 "It is possible to provide several variables by separating them\n"
3738 "by commas in getsubopt(3) style. Additionally it is possible to\n"
3739 "provide the -E and -U options multiple times.\n"
3740 "The following lines are equivalent:\n"
3741 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
3742 " -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
3743 " QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
3744 "Note that if you provide several changes to a single variable\n"
3745 "the last change will stay in effect.\n");
3747 exit(1);
3750 static int parse_args(int argc, char **argv)
3752 const char *r;
3753 int optind;
3754 const struct qemu_argument *arginfo;
3756 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3757 if (arginfo->env == NULL) {
3758 continue;
3761 r = getenv(arginfo->env);
3762 if (r != NULL) {
3763 arginfo->handle_opt(r);
3767 optind = 1;
3768 for (;;) {
3769 if (optind >= argc) {
3770 break;
3772 r = argv[optind];
3773 if (r[0] != '-') {
3774 break;
3776 optind++;
3777 r++;
3778 if (!strcmp(r, "-")) {
3779 break;
3782 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3783 if (!strcmp(r, arginfo->argv)) {
3784 if (arginfo->has_arg) {
3785 if (optind >= argc) {
3786 usage();
3788 arginfo->handle_opt(argv[optind]);
3789 optind++;
3790 } else {
3791 arginfo->handle_opt(NULL);
3793 break;
3797 /* no option matched the current argv */
3798 if (arginfo->handle_opt == NULL) {
3799 usage();
3803 if (optind >= argc) {
3804 usage();
3807 filename = argv[optind];
3808 exec_path = argv[optind];
3810 return optind;
3813 int main(int argc, char **argv, char **envp)
3815 struct target_pt_regs regs1, *regs = &regs1;
3816 struct image_info info1, *info = &info1;
3817 struct linux_binprm bprm;
3818 TaskState *ts;
3819 CPUArchState *env;
3820 CPUState *cpu;
3821 int optind;
3822 char **target_environ, **wrk;
3823 char **target_argv;
3824 int target_argc;
3825 int i;
3826 int ret;
3827 int execfd;
3829 module_call_init(MODULE_INIT_QOM);
3831 if ((envlist = envlist_create()) == NULL) {
3832 (void) fprintf(stderr, "Unable to allocate envlist\n");
3833 exit(1);
3836 /* add current environment into the list */
3837 for (wrk = environ; *wrk != NULL; wrk++) {
3838 (void) envlist_setenv(envlist, *wrk);
3841 /* Read the stack limit from the kernel. If it's "unlimited",
3842 then we can do little else besides use the default. */
3844 struct rlimit lim;
3845 if (getrlimit(RLIMIT_STACK, &lim) == 0
3846 && lim.rlim_cur != RLIM_INFINITY
3847 && lim.rlim_cur == (target_long)lim.rlim_cur) {
3848 guest_stack_size = lim.rlim_cur;
3852 cpu_model = NULL;
3853 #if defined(cpudef_setup)
3854 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
3855 #endif
3857 optind = parse_args(argc, argv);
3859 /* Zero out regs */
3860 memset(regs, 0, sizeof(struct target_pt_regs));
3862 /* Zero out image_info */
3863 memset(info, 0, sizeof(struct image_info));
3865 memset(&bprm, 0, sizeof (bprm));
3867 /* Scan interp_prefix dir for replacement files. */
3868 init_paths(interp_prefix);
3870 init_qemu_uname_release();
3872 if (cpu_model == NULL) {
3873 #if defined(TARGET_I386)
3874 #ifdef TARGET_X86_64
3875 cpu_model = "qemu64";
3876 #else
3877 cpu_model = "qemu32";
3878 #endif
3879 #elif defined(TARGET_ARM)
3880 cpu_model = "any";
3881 #elif defined(TARGET_UNICORE32)
3882 cpu_model = "any";
3883 #elif defined(TARGET_M68K)
3884 cpu_model = "any";
3885 #elif defined(TARGET_SPARC)
3886 #ifdef TARGET_SPARC64
3887 cpu_model = "TI UltraSparc II";
3888 #else
3889 cpu_model = "Fujitsu MB86904";
3890 #endif
3891 #elif defined(TARGET_MIPS)
3892 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
3893 cpu_model = "20Kc";
3894 #else
3895 cpu_model = "24Kf";
3896 #endif
3897 #elif defined TARGET_OPENRISC
3898 cpu_model = "or1200";
3899 #elif defined(TARGET_PPC)
3900 #ifdef TARGET_PPC64
3901 cpu_model = "970fx";
3902 #else
3903 cpu_model = "750";
3904 #endif
3905 #else
3906 cpu_model = "any";
3907 #endif
3909 tcg_exec_init(0);
3910 cpu_exec_init_all();
3911 /* NOTE: we need to init the CPU at this stage to get
3912 qemu_host_page_size */
3913 env = cpu_init(cpu_model);
3914 if (!env) {
3915 fprintf(stderr, "Unable to find CPU definition\n");
3916 exit(1);
3918 cpu = ENV_GET_CPU(env);
3919 cpu_reset(cpu);
3921 thread_cpu = cpu;
3923 if (getenv("QEMU_STRACE")) {
3924 do_strace = 1;
3927 target_environ = envlist_to_environ(envlist, NULL);
3928 envlist_free(envlist);
3930 #if defined(CONFIG_USE_GUEST_BASE)
3932 * Now that page sizes are configured in cpu_init() we can do
3933 * proper page alignment for guest_base.
3935 guest_base = HOST_PAGE_ALIGN(guest_base);
3937 if (reserved_va || have_guest_base) {
3938 guest_base = init_guest_space(guest_base, reserved_va, 0,
3939 have_guest_base);
3940 if (guest_base == (unsigned long)-1) {
3941 fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
3942 "space for use as guest address space (check your virtual "
3943 "memory ulimit setting or reserve less using -R option)\n",
3944 reserved_va);
3945 exit(1);
3948 if (reserved_va) {
3949 mmap_next_start = reserved_va;
3952 #endif /* CONFIG_USE_GUEST_BASE */
3955 * Read in mmap_min_addr kernel parameter. This value is used
3956 * When loading the ELF image to determine whether guest_base
3957 * is needed. It is also used in mmap_find_vma.
3960 FILE *fp;
3962 if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
3963 unsigned long tmp;
3964 if (fscanf(fp, "%lu", &tmp) == 1) {
3965 mmap_min_addr = tmp;
3966 qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
3968 fclose(fp);
3973 * Prepare copy of argv vector for target.
3975 target_argc = argc - optind;
3976 target_argv = calloc(target_argc + 1, sizeof (char *));
3977 if (target_argv == NULL) {
3978 (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
3979 exit(1);
3983 * If argv0 is specified (using '-0' switch) we replace
3984 * argv[0] pointer with the given one.
3986 i = 0;
3987 if (argv0 != NULL) {
3988 target_argv[i++] = strdup(argv0);
3990 for (; i < target_argc; i++) {
3991 target_argv[i] = strdup(argv[optind + i]);
3993 target_argv[target_argc] = NULL;
3995 ts = g_malloc0 (sizeof(TaskState));
3996 init_task_state(ts);
3997 /* build Task State */
3998 ts->info = info;
3999 ts->bprm = &bprm;
4000 cpu->opaque = ts;
4001 task_settid(ts);
4003 execfd = qemu_getauxval(AT_EXECFD);
4004 if (execfd == 0) {
4005 execfd = open(filename, O_RDONLY);
4006 if (execfd < 0) {
4007 printf("Error while loading %s: %s\n", filename, strerror(errno));
4008 _exit(1);
4012 ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
4013 info, &bprm);
4014 if (ret != 0) {
4015 printf("Error while loading %s: %s\n", filename, strerror(-ret));
4016 _exit(1);
4019 for (wrk = target_environ; *wrk; wrk++) {
4020 free(*wrk);
4023 free(target_environ);
4025 if (qemu_log_enabled()) {
4026 #if defined(CONFIG_USE_GUEST_BASE)
4027 qemu_log("guest_base 0x%lx\n", guest_base);
4028 #endif
4029 log_page_dump();
4031 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
4032 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
4033 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
4034 info->start_code);
4035 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
4036 info->start_data);
4037 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
4038 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
4039 info->start_stack);
4040 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
4041 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
4044 target_set_brk(info->brk);
4045 syscall_init();
4046 signal_init();
4048 #if defined(CONFIG_USE_GUEST_BASE)
4049 /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
4050 generating the prologue until now so that the prologue can take
4051 the real value of GUEST_BASE into account. */
4052 tcg_prologue_init(&tcg_ctx);
4053 #endif
4055 #if defined(TARGET_I386)
4056 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
4057 env->hflags |= HF_PE_MASK | HF_CPL_MASK;
4058 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
4059 env->cr[4] |= CR4_OSFXSR_MASK;
4060 env->hflags |= HF_OSFXSR_MASK;
4062 #ifndef TARGET_ABI32
4063 /* enable 64 bit mode if possible */
4064 if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
4065 fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
4066 exit(1);
4068 env->cr[4] |= CR4_PAE_MASK;
4069 env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
4070 env->hflags |= HF_LMA_MASK;
4071 #endif
4073 /* flags setup : we activate the IRQs by default as in user mode */
4074 env->eflags |= IF_MASK;
4076 /* linux register setup */
4077 #ifndef TARGET_ABI32
4078 env->regs[R_EAX] = regs->rax;
4079 env->regs[R_EBX] = regs->rbx;
4080 env->regs[R_ECX] = regs->rcx;
4081 env->regs[R_EDX] = regs->rdx;
4082 env->regs[R_ESI] = regs->rsi;
4083 env->regs[R_EDI] = regs->rdi;
4084 env->regs[R_EBP] = regs->rbp;
4085 env->regs[R_ESP] = regs->rsp;
4086 env->eip = regs->rip;
4087 #else
4088 env->regs[R_EAX] = regs->eax;
4089 env->regs[R_EBX] = regs->ebx;
4090 env->regs[R_ECX] = regs->ecx;
4091 env->regs[R_EDX] = regs->edx;
4092 env->regs[R_ESI] = regs->esi;
4093 env->regs[R_EDI] = regs->edi;
4094 env->regs[R_EBP] = regs->ebp;
4095 env->regs[R_ESP] = regs->esp;
4096 env->eip = regs->eip;
4097 #endif
4099 /* linux interrupt setup */
4100 #ifndef TARGET_ABI32
4101 env->idt.limit = 511;
4102 #else
4103 env->idt.limit = 255;
4104 #endif
4105 env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
4106 PROT_READ|PROT_WRITE,
4107 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4108 idt_table = g2h(env->idt.base);
4109 set_idt(0, 0);
4110 set_idt(1, 0);
4111 set_idt(2, 0);
4112 set_idt(3, 3);
4113 set_idt(4, 3);
4114 set_idt(5, 0);
4115 set_idt(6, 0);
4116 set_idt(7, 0);
4117 set_idt(8, 0);
4118 set_idt(9, 0);
4119 set_idt(10, 0);
4120 set_idt(11, 0);
4121 set_idt(12, 0);
4122 set_idt(13, 0);
4123 set_idt(14, 0);
4124 set_idt(15, 0);
4125 set_idt(16, 0);
4126 set_idt(17, 0);
4127 set_idt(18, 0);
4128 set_idt(19, 0);
4129 set_idt(0x80, 3);
4131 /* linux segment setup */
4133 uint64_t *gdt_table;
4134 env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
4135 PROT_READ|PROT_WRITE,
4136 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4137 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
4138 gdt_table = g2h(env->gdt.base);
4139 #ifdef TARGET_ABI32
4140 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
4141 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4142 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
4143 #else
4144 /* 64 bit code segment */
4145 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
4146 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4147 DESC_L_MASK |
4148 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
4149 #endif
4150 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
4151 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4152 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
4154 cpu_x86_load_seg(env, R_CS, __USER_CS);
4155 cpu_x86_load_seg(env, R_SS, __USER_DS);
4156 #ifdef TARGET_ABI32
4157 cpu_x86_load_seg(env, R_DS, __USER_DS);
4158 cpu_x86_load_seg(env, R_ES, __USER_DS);
4159 cpu_x86_load_seg(env, R_FS, __USER_DS);
4160 cpu_x86_load_seg(env, R_GS, __USER_DS);
4161 /* This hack makes Wine work... */
4162 env->segs[R_FS].selector = 0;
4163 #else
4164 cpu_x86_load_seg(env, R_DS, 0);
4165 cpu_x86_load_seg(env, R_ES, 0);
4166 cpu_x86_load_seg(env, R_FS, 0);
4167 cpu_x86_load_seg(env, R_GS, 0);
4168 #endif
4169 #elif defined(TARGET_AARCH64)
4171 int i;
4173 if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
4174 fprintf(stderr,
4175 "The selected ARM CPU does not support 64 bit mode\n");
4176 exit(1);
4179 for (i = 0; i < 31; i++) {
4180 env->xregs[i] = regs->regs[i];
4182 env->pc = regs->pc;
4183 env->xregs[31] = regs->sp;
4185 #elif defined(TARGET_ARM)
4187 int i;
4188 cpsr_write(env, regs->uregs[16], 0xffffffff);
4189 for(i = 0; i < 16; i++) {
4190 env->regs[i] = regs->uregs[i];
4192 /* Enable BE8. */
4193 if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
4194 && (info->elf_flags & EF_ARM_BE8)) {
4195 env->bswap_code = 1;
4198 #elif defined(TARGET_UNICORE32)
4200 int i;
4201 cpu_asr_write(env, regs->uregs[32], 0xffffffff);
4202 for (i = 0; i < 32; i++) {
4203 env->regs[i] = regs->uregs[i];
4206 #elif defined(TARGET_SPARC)
4208 int i;
4209 env->pc = regs->pc;
4210 env->npc = regs->npc;
4211 env->y = regs->y;
4212 for(i = 0; i < 8; i++)
4213 env->gregs[i] = regs->u_regs[i];
4214 for(i = 0; i < 8; i++)
4215 env->regwptr[i] = regs->u_regs[i + 8];
4217 #elif defined(TARGET_PPC)
4219 int i;
4221 #if defined(TARGET_PPC64)
4222 #if defined(TARGET_ABI32)
4223 env->msr &= ~((target_ulong)1 << MSR_SF);
4224 #else
4225 env->msr |= (target_ulong)1 << MSR_SF;
4226 #endif
4227 #endif
4228 env->nip = regs->nip;
4229 for(i = 0; i < 32; i++) {
4230 env->gpr[i] = regs->gpr[i];
4233 #elif defined(TARGET_M68K)
4235 env->pc = regs->pc;
4236 env->dregs[0] = regs->d0;
4237 env->dregs[1] = regs->d1;
4238 env->dregs[2] = regs->d2;
4239 env->dregs[3] = regs->d3;
4240 env->dregs[4] = regs->d4;
4241 env->dregs[5] = regs->d5;
4242 env->dregs[6] = regs->d6;
4243 env->dregs[7] = regs->d7;
4244 env->aregs[0] = regs->a0;
4245 env->aregs[1] = regs->a1;
4246 env->aregs[2] = regs->a2;
4247 env->aregs[3] = regs->a3;
4248 env->aregs[4] = regs->a4;
4249 env->aregs[5] = regs->a5;
4250 env->aregs[6] = regs->a6;
4251 env->aregs[7] = regs->usp;
4252 env->sr = regs->sr;
4253 ts->sim_syscalls = 1;
4255 #elif defined(TARGET_MICROBLAZE)
4257 env->regs[0] = regs->r0;
4258 env->regs[1] = regs->r1;
4259 env->regs[2] = regs->r2;
4260 env->regs[3] = regs->r3;
4261 env->regs[4] = regs->r4;
4262 env->regs[5] = regs->r5;
4263 env->regs[6] = regs->r6;
4264 env->regs[7] = regs->r7;
4265 env->regs[8] = regs->r8;
4266 env->regs[9] = regs->r9;
4267 env->regs[10] = regs->r10;
4268 env->regs[11] = regs->r11;
4269 env->regs[12] = regs->r12;
4270 env->regs[13] = regs->r13;
4271 env->regs[14] = regs->r14;
4272 env->regs[15] = regs->r15;
4273 env->regs[16] = regs->r16;
4274 env->regs[17] = regs->r17;
4275 env->regs[18] = regs->r18;
4276 env->regs[19] = regs->r19;
4277 env->regs[20] = regs->r20;
4278 env->regs[21] = regs->r21;
4279 env->regs[22] = regs->r22;
4280 env->regs[23] = regs->r23;
4281 env->regs[24] = regs->r24;
4282 env->regs[25] = regs->r25;
4283 env->regs[26] = regs->r26;
4284 env->regs[27] = regs->r27;
4285 env->regs[28] = regs->r28;
4286 env->regs[29] = regs->r29;
4287 env->regs[30] = regs->r30;
4288 env->regs[31] = regs->r31;
4289 env->sregs[SR_PC] = regs->pc;
4291 #elif defined(TARGET_MIPS)
4293 int i;
4295 for(i = 0; i < 32; i++) {
4296 env->active_tc.gpr[i] = regs->regs[i];
4298 env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1;
4299 if (regs->cp0_epc & 1) {
4300 env->hflags |= MIPS_HFLAG_M16;
4303 #elif defined(TARGET_OPENRISC)
4305 int i;
4307 for (i = 0; i < 32; i++) {
4308 env->gpr[i] = regs->gpr[i];
4311 env->sr = regs->sr;
4312 env->pc = regs->pc;
4314 #elif defined(TARGET_SH4)
4316 int i;
4318 for(i = 0; i < 16; i++) {
4319 env->gregs[i] = regs->regs[i];
4321 env->pc = regs->pc;
4323 #elif defined(TARGET_ALPHA)
4325 int i;
4327 for(i = 0; i < 28; i++) {
4328 env->ir[i] = ((abi_ulong *)regs)[i];
4330 env->ir[IR_SP] = regs->usp;
4331 env->pc = regs->pc;
4333 #elif defined(TARGET_CRIS)
4335 env->regs[0] = regs->r0;
4336 env->regs[1] = regs->r1;
4337 env->regs[2] = regs->r2;
4338 env->regs[3] = regs->r3;
4339 env->regs[4] = regs->r4;
4340 env->regs[5] = regs->r5;
4341 env->regs[6] = regs->r6;
4342 env->regs[7] = regs->r7;
4343 env->regs[8] = regs->r8;
4344 env->regs[9] = regs->r9;
4345 env->regs[10] = regs->r10;
4346 env->regs[11] = regs->r11;
4347 env->regs[12] = regs->r12;
4348 env->regs[13] = regs->r13;
4349 env->regs[14] = info->start_stack;
4350 env->regs[15] = regs->acr;
4351 env->pc = regs->erp;
4353 #elif defined(TARGET_S390X)
4355 int i;
4356 for (i = 0; i < 16; i++) {
4357 env->regs[i] = regs->gprs[i];
4359 env->psw.mask = regs->psw.mask;
4360 env->psw.addr = regs->psw.addr;
4362 #else
4363 #error unsupported target CPU
4364 #endif
4366 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4367 ts->stack_base = info->start_stack;
4368 ts->heap_base = info->brk;
4369 /* This will be filled in on the first SYS_HEAPINFO call. */
4370 ts->heap_limit = 0;
4371 #endif
4373 if (gdbstub_port) {
4374 if (gdbserver_start(gdbstub_port) < 0) {
4375 fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
4376 gdbstub_port);
4377 exit(1);
4379 gdb_handlesig(cpu, 0);
4381 cpu_loop(env);
4382 /* never exits */
4383 return 0;