blockdev: Use blk_remove_bs() in do_drive_del()
[qemu/ar7.git] / linux-user / main.c
blobf8d45778c873973654f31d4cc2caf48b51d684d1
1 /*
2 * qemu user main
4 * Copyright (c) 2003-2008 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
20 #include <sys/mman.h>
21 #include <sys/syscall.h>
22 #include <sys/resource.h>
24 #include "qemu.h"
25 #include "qemu-common.h"
26 #include "cpu.h"
27 #include "tcg.h"
28 #include "qemu/timer.h"
29 #include "qemu/envlist.h"
30 #include "elf.h"
32 char *exec_path;
34 int singlestep;
35 static const char *filename;
36 static const char *argv0;
37 static int gdbstub_port;
38 static envlist_t *envlist;
39 static const char *cpu_model;
40 unsigned long mmap_min_addr;
41 unsigned long guest_base;
42 int have_guest_base;
44 #define EXCP_DUMP(env, fmt, ...) \
45 do { \
46 CPUState *cs = ENV_GET_CPU(env); \
47 fprintf(stderr, fmt , ## __VA_ARGS__); \
48 cpu_dump_state(cs, stderr, fprintf, 0); \
49 if (qemu_log_separate()) { \
50 qemu_log(fmt, ## __VA_ARGS__); \
51 log_cpu_state(cs, 0); \
52 } \
53 } while (0)
55 #if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
57 * When running 32-on-64 we should make sure we can fit all of the possible
58 * guest address space into a contiguous chunk of virtual host memory.
60 * This way we will never overlap with our own libraries or binaries or stack
61 * or anything else that QEMU maps.
63 # ifdef TARGET_MIPS
64 /* MIPS only supports 31 bits of virtual address space for user space */
65 unsigned long reserved_va = 0x77000000;
66 # else
67 unsigned long reserved_va = 0xf7000000;
68 # endif
69 #else
70 unsigned long reserved_va;
71 #endif
73 static void usage(int exitcode);
75 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
76 const char *qemu_uname_release;
78 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
79 we allocate a bigger stack. Need a better solution, for example
80 by remapping the process stack directly at the right place */
81 unsigned long guest_stack_size = 8 * 1024 * 1024UL;
83 void gemu_log(const char *fmt, ...)
85 va_list ap;
87 va_start(ap, fmt);
88 vfprintf(stderr, fmt, ap);
89 va_end(ap);
92 #if defined(TARGET_I386)
93 int cpu_get_pic_interrupt(CPUX86State *env)
95 return -1;
97 #endif
99 /***********************************************************/
100 /* Helper routines for implementing atomic operations. */
102 /* To implement exclusive operations we force all cpus to syncronise.
103 We don't require a full sync, only that no cpus are executing guest code.
104 The alternative is to map target atomic ops onto host equivalents,
105 which requires quite a lot of per host/target work. */
106 static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
107 static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
108 static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
109 static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
110 static int pending_cpus;
112 /* Make sure everything is in a consistent state for calling fork(). */
113 void fork_start(void)
115 qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
116 pthread_mutex_lock(&exclusive_lock);
117 mmap_fork_start();
120 void fork_end(int child)
122 mmap_fork_end(child);
123 if (child) {
124 CPUState *cpu, *next_cpu;
125 /* Child processes created by fork() only have a single thread.
126 Discard information about the parent threads. */
127 CPU_FOREACH_SAFE(cpu, next_cpu) {
128 if (cpu != thread_cpu) {
129 QTAILQ_REMOVE(&cpus, thread_cpu, node);
132 pending_cpus = 0;
133 pthread_mutex_init(&exclusive_lock, NULL);
134 pthread_mutex_init(&cpu_list_mutex, NULL);
135 pthread_cond_init(&exclusive_cond, NULL);
136 pthread_cond_init(&exclusive_resume, NULL);
137 qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
138 gdbserver_fork(thread_cpu);
139 } else {
140 pthread_mutex_unlock(&exclusive_lock);
141 qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
145 /* Wait for pending exclusive operations to complete. The exclusive lock
146 must be held. */
147 static inline void exclusive_idle(void)
149 while (pending_cpus) {
150 pthread_cond_wait(&exclusive_resume, &exclusive_lock);
154 /* Start an exclusive operation.
155 Must only be called from outside cpu_arm_exec. */
156 static inline void start_exclusive(void)
158 CPUState *other_cpu;
160 pthread_mutex_lock(&exclusive_lock);
161 exclusive_idle();
163 pending_cpus = 1;
164 /* Make all other cpus stop executing. */
165 CPU_FOREACH(other_cpu) {
166 if (other_cpu->running) {
167 pending_cpus++;
168 cpu_exit(other_cpu);
171 if (pending_cpus > 1) {
172 pthread_cond_wait(&exclusive_cond, &exclusive_lock);
176 /* Finish an exclusive operation. */
177 static inline void __attribute__((unused)) end_exclusive(void)
179 pending_cpus = 0;
180 pthread_cond_broadcast(&exclusive_resume);
181 pthread_mutex_unlock(&exclusive_lock);
184 /* Wait for exclusive ops to finish, and begin cpu execution. */
185 static inline void cpu_exec_start(CPUState *cpu)
187 pthread_mutex_lock(&exclusive_lock);
188 exclusive_idle();
189 cpu->running = true;
190 pthread_mutex_unlock(&exclusive_lock);
193 /* Mark cpu as not executing, and release pending exclusive ops. */
194 static inline void cpu_exec_end(CPUState *cpu)
196 pthread_mutex_lock(&exclusive_lock);
197 cpu->running = false;
198 if (pending_cpus > 1) {
199 pending_cpus--;
200 if (pending_cpus == 1) {
201 pthread_cond_signal(&exclusive_cond);
204 exclusive_idle();
205 pthread_mutex_unlock(&exclusive_lock);
208 void cpu_list_lock(void)
210 pthread_mutex_lock(&cpu_list_mutex);
213 void cpu_list_unlock(void)
215 pthread_mutex_unlock(&cpu_list_mutex);
219 #ifdef TARGET_I386
220 /***********************************************************/
221 /* CPUX86 core interface */
223 uint64_t cpu_get_tsc(CPUX86State *env)
225 return cpu_get_host_ticks();
228 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
229 int flags)
231 unsigned int e1, e2;
232 uint32_t *p;
233 e1 = (addr << 16) | (limit & 0xffff);
234 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
235 e2 |= flags;
236 p = ptr;
237 p[0] = tswap32(e1);
238 p[1] = tswap32(e2);
241 static uint64_t *idt_table;
242 #ifdef TARGET_X86_64
243 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
244 uint64_t addr, unsigned int sel)
246 uint32_t *p, e1, e2;
247 e1 = (addr & 0xffff) | (sel << 16);
248 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
249 p = ptr;
250 p[0] = tswap32(e1);
251 p[1] = tswap32(e2);
252 p[2] = tswap32(addr >> 32);
253 p[3] = 0;
255 /* only dpl matters as we do only user space emulation */
256 static void set_idt(int n, unsigned int dpl)
258 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
260 #else
261 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
262 uint32_t addr, unsigned int sel)
264 uint32_t *p, e1, e2;
265 e1 = (addr & 0xffff) | (sel << 16);
266 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
267 p = ptr;
268 p[0] = tswap32(e1);
269 p[1] = tswap32(e2);
272 /* only dpl matters as we do only user space emulation */
273 static void set_idt(int n, unsigned int dpl)
275 set_gate(idt_table + n, 0, dpl, 0, 0);
277 #endif
279 void cpu_loop(CPUX86State *env)
281 CPUState *cs = CPU(x86_env_get_cpu(env));
282 int trapnr;
283 abi_ulong pc;
284 target_siginfo_t info;
286 for(;;) {
287 cpu_exec_start(cs);
288 trapnr = cpu_x86_exec(cs);
289 cpu_exec_end(cs);
290 switch(trapnr) {
291 case 0x80:
292 /* linux syscall from int $0x80 */
293 env->regs[R_EAX] = do_syscall(env,
294 env->regs[R_EAX],
295 env->regs[R_EBX],
296 env->regs[R_ECX],
297 env->regs[R_EDX],
298 env->regs[R_ESI],
299 env->regs[R_EDI],
300 env->regs[R_EBP],
301 0, 0);
302 break;
303 #ifndef TARGET_ABI32
304 case EXCP_SYSCALL:
305 /* linux syscall from syscall instruction */
306 env->regs[R_EAX] = do_syscall(env,
307 env->regs[R_EAX],
308 env->regs[R_EDI],
309 env->regs[R_ESI],
310 env->regs[R_EDX],
311 env->regs[10],
312 env->regs[8],
313 env->regs[9],
314 0, 0);
315 break;
316 #endif
317 case EXCP0B_NOSEG:
318 case EXCP0C_STACK:
319 info.si_signo = TARGET_SIGBUS;
320 info.si_errno = 0;
321 info.si_code = TARGET_SI_KERNEL;
322 info._sifields._sigfault._addr = 0;
323 queue_signal(env, info.si_signo, &info);
324 break;
325 case EXCP0D_GPF:
326 /* XXX: potential problem if ABI32 */
327 #ifndef TARGET_X86_64
328 if (env->eflags & VM_MASK) {
329 handle_vm86_fault(env);
330 } else
331 #endif
333 info.si_signo = TARGET_SIGSEGV;
334 info.si_errno = 0;
335 info.si_code = TARGET_SI_KERNEL;
336 info._sifields._sigfault._addr = 0;
337 queue_signal(env, info.si_signo, &info);
339 break;
340 case EXCP0E_PAGE:
341 info.si_signo = TARGET_SIGSEGV;
342 info.si_errno = 0;
343 if (!(env->error_code & 1))
344 info.si_code = TARGET_SEGV_MAPERR;
345 else
346 info.si_code = TARGET_SEGV_ACCERR;
347 info._sifields._sigfault._addr = env->cr[2];
348 queue_signal(env, info.si_signo, &info);
349 break;
350 case EXCP00_DIVZ:
351 #ifndef TARGET_X86_64
352 if (env->eflags & VM_MASK) {
353 handle_vm86_trap(env, trapnr);
354 } else
355 #endif
357 /* division by zero */
358 info.si_signo = TARGET_SIGFPE;
359 info.si_errno = 0;
360 info.si_code = TARGET_FPE_INTDIV;
361 info._sifields._sigfault._addr = env->eip;
362 queue_signal(env, info.si_signo, &info);
364 break;
365 case EXCP01_DB:
366 case EXCP03_INT3:
367 #ifndef TARGET_X86_64
368 if (env->eflags & VM_MASK) {
369 handle_vm86_trap(env, trapnr);
370 } else
371 #endif
373 info.si_signo = TARGET_SIGTRAP;
374 info.si_errno = 0;
375 if (trapnr == EXCP01_DB) {
376 info.si_code = TARGET_TRAP_BRKPT;
377 info._sifields._sigfault._addr = env->eip;
378 } else {
379 info.si_code = TARGET_SI_KERNEL;
380 info._sifields._sigfault._addr = 0;
382 queue_signal(env, info.si_signo, &info);
384 break;
385 case EXCP04_INTO:
386 case EXCP05_BOUND:
387 #ifndef TARGET_X86_64
388 if (env->eflags & VM_MASK) {
389 handle_vm86_trap(env, trapnr);
390 } else
391 #endif
393 info.si_signo = TARGET_SIGSEGV;
394 info.si_errno = 0;
395 info.si_code = TARGET_SI_KERNEL;
396 info._sifields._sigfault._addr = 0;
397 queue_signal(env, info.si_signo, &info);
399 break;
400 case EXCP06_ILLOP:
401 info.si_signo = TARGET_SIGILL;
402 info.si_errno = 0;
403 info.si_code = TARGET_ILL_ILLOPN;
404 info._sifields._sigfault._addr = env->eip;
405 queue_signal(env, info.si_signo, &info);
406 break;
407 case EXCP_INTERRUPT:
408 /* just indicate that signals should be handled asap */
409 break;
410 case EXCP_DEBUG:
412 int sig;
414 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
415 if (sig)
417 info.si_signo = sig;
418 info.si_errno = 0;
419 info.si_code = TARGET_TRAP_BRKPT;
420 queue_signal(env, info.si_signo, &info);
423 break;
424 default:
425 pc = env->segs[R_CS].base + env->eip;
426 EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
427 (long)pc, trapnr);
428 abort();
430 process_pending_signals(env);
433 #endif
435 #ifdef TARGET_ARM
437 #define get_user_code_u32(x, gaddr, doswap) \
438 ({ abi_long __r = get_user_u32((x), (gaddr)); \
439 if (!__r && (doswap)) { \
440 (x) = bswap32(x); \
442 __r; \
445 #define get_user_code_u16(x, gaddr, doswap) \
446 ({ abi_long __r = get_user_u16((x), (gaddr)); \
447 if (!__r && (doswap)) { \
448 (x) = bswap16(x); \
450 __r; \
453 #ifdef TARGET_ABI32
454 /* Commpage handling -- there is no commpage for AArch64 */
457 * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
458 * Input:
459 * r0 = pointer to oldval
460 * r1 = pointer to newval
461 * r2 = pointer to target value
463 * Output:
464 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
465 * C set if *ptr was changed, clear if no exchange happened
467 * Note segv's in kernel helpers are a bit tricky, we can set the
468 * data address sensibly but the PC address is just the entry point.
470 static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
472 uint64_t oldval, newval, val;
473 uint32_t addr, cpsr;
474 target_siginfo_t info;
476 /* Based on the 32 bit code in do_kernel_trap */
478 /* XXX: This only works between threads, not between processes.
479 It's probably possible to implement this with native host
480 operations. However things like ldrex/strex are much harder so
481 there's not much point trying. */
482 start_exclusive();
483 cpsr = cpsr_read(env);
484 addr = env->regs[2];
486 if (get_user_u64(oldval, env->regs[0])) {
487 env->exception.vaddress = env->regs[0];
488 goto segv;
491 if (get_user_u64(newval, env->regs[1])) {
492 env->exception.vaddress = env->regs[1];
493 goto segv;
496 if (get_user_u64(val, addr)) {
497 env->exception.vaddress = addr;
498 goto segv;
501 if (val == oldval) {
502 val = newval;
504 if (put_user_u64(val, addr)) {
505 env->exception.vaddress = addr;
506 goto segv;
509 env->regs[0] = 0;
510 cpsr |= CPSR_C;
511 } else {
512 env->regs[0] = -1;
513 cpsr &= ~CPSR_C;
515 cpsr_write(env, cpsr, CPSR_C);
516 end_exclusive();
517 return;
519 segv:
520 end_exclusive();
521 /* We get the PC of the entry address - which is as good as anything,
522 on a real kernel what you get depends on which mode it uses. */
523 info.si_signo = TARGET_SIGSEGV;
524 info.si_errno = 0;
525 /* XXX: check env->error_code */
526 info.si_code = TARGET_SEGV_MAPERR;
527 info._sifields._sigfault._addr = env->exception.vaddress;
528 queue_signal(env, info.si_signo, &info);
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] = cpu_get_tls(env);
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(cs);
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 = TARGET_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 = TARGET_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 case ARM_NR_breakpoint:
810 env->regs[15] -= env->thumb ? 2 : 4;
811 goto excp_debug;
812 default:
813 gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
815 env->regs[0] = -TARGET_ENOSYS;
816 break;
818 } else {
819 env->regs[0] = do_syscall(env,
821 env->regs[0],
822 env->regs[1],
823 env->regs[2],
824 env->regs[3],
825 env->regs[4],
826 env->regs[5],
827 0, 0);
829 } else {
830 goto error;
833 break;
834 case EXCP_INTERRUPT:
835 /* just indicate that signals should be handled asap */
836 break;
837 case EXCP_STREX:
838 if (!do_strex(env)) {
839 break;
841 /* fall through for segv */
842 case EXCP_PREFETCH_ABORT:
843 case EXCP_DATA_ABORT:
844 addr = env->exception.vaddress;
846 info.si_signo = TARGET_SIGSEGV;
847 info.si_errno = 0;
848 /* XXX: check env->error_code */
849 info.si_code = TARGET_SEGV_MAPERR;
850 info._sifields._sigfault._addr = addr;
851 queue_signal(env, info.si_signo, &info);
853 break;
854 case EXCP_DEBUG:
855 excp_debug:
857 int sig;
859 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
860 if (sig)
862 info.si_signo = sig;
863 info.si_errno = 0;
864 info.si_code = TARGET_TRAP_BRKPT;
865 queue_signal(env, info.si_signo, &info);
868 break;
869 case EXCP_KERNEL_TRAP:
870 if (do_kernel_trap(env))
871 goto error;
872 break;
873 default:
874 error:
875 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
876 abort();
878 process_pending_signals(env);
882 #else
885 * Handle AArch64 store-release exclusive
887 * rs = gets the status result of store exclusive
888 * rt = is the register that is stored
889 * rt2 = is the second register store (in STP)
892 static int do_strex_a64(CPUARMState *env)
894 uint64_t val;
895 int size;
896 bool is_pair;
897 int rc = 1;
898 int segv = 0;
899 uint64_t addr;
900 int rs, rt, rt2;
902 start_exclusive();
903 /* size | is_pair << 2 | (rs << 4) | (rt << 9) | (rt2 << 14)); */
904 size = extract32(env->exclusive_info, 0, 2);
905 is_pair = extract32(env->exclusive_info, 2, 1);
906 rs = extract32(env->exclusive_info, 4, 5);
907 rt = extract32(env->exclusive_info, 9, 5);
908 rt2 = extract32(env->exclusive_info, 14, 5);
910 addr = env->exclusive_addr;
912 if (addr != env->exclusive_test) {
913 goto finish;
916 switch (size) {
917 case 0:
918 segv = get_user_u8(val, addr);
919 break;
920 case 1:
921 segv = get_user_u16(val, addr);
922 break;
923 case 2:
924 segv = get_user_u32(val, addr);
925 break;
926 case 3:
927 segv = get_user_u64(val, addr);
928 break;
929 default:
930 abort();
932 if (segv) {
933 env->exception.vaddress = addr;
934 goto error;
936 if (val != env->exclusive_val) {
937 goto finish;
939 if (is_pair) {
940 if (size == 2) {
941 segv = get_user_u32(val, addr + 4);
942 } else {
943 segv = get_user_u64(val, addr + 8);
945 if (segv) {
946 env->exception.vaddress = addr + (size == 2 ? 4 : 8);
947 goto error;
949 if (val != env->exclusive_high) {
950 goto finish;
953 /* handle the zero register */
954 val = rt == 31 ? 0 : env->xregs[rt];
955 switch (size) {
956 case 0:
957 segv = put_user_u8(val, addr);
958 break;
959 case 1:
960 segv = put_user_u16(val, addr);
961 break;
962 case 2:
963 segv = put_user_u32(val, addr);
964 break;
965 case 3:
966 segv = put_user_u64(val, addr);
967 break;
969 if (segv) {
970 goto error;
972 if (is_pair) {
973 /* handle the zero register */
974 val = rt2 == 31 ? 0 : env->xregs[rt2];
975 if (size == 2) {
976 segv = put_user_u32(val, addr + 4);
977 } else {
978 segv = put_user_u64(val, addr + 8);
980 if (segv) {
981 env->exception.vaddress = addr + (size == 2 ? 4 : 8);
982 goto error;
985 rc = 0;
986 finish:
987 env->pc += 4;
988 /* rs == 31 encodes a write to the ZR, thus throwing away
989 * the status return. This is rather silly but valid.
991 if (rs < 31) {
992 env->xregs[rs] = rc;
994 error:
995 /* instruction faulted, PC does not advance */
996 /* either way a strex releases any exclusive lock we have */
997 env->exclusive_addr = -1;
998 end_exclusive();
999 return segv;
1002 /* AArch64 main loop */
1003 void cpu_loop(CPUARMState *env)
1005 CPUState *cs = CPU(arm_env_get_cpu(env));
1006 int trapnr, sig;
1007 target_siginfo_t info;
1009 for (;;) {
1010 cpu_exec_start(cs);
1011 trapnr = cpu_arm_exec(cs);
1012 cpu_exec_end(cs);
1014 switch (trapnr) {
1015 case EXCP_SWI:
1016 env->xregs[0] = do_syscall(env,
1017 env->xregs[8],
1018 env->xregs[0],
1019 env->xregs[1],
1020 env->xregs[2],
1021 env->xregs[3],
1022 env->xregs[4],
1023 env->xregs[5],
1024 0, 0);
1025 break;
1026 case EXCP_INTERRUPT:
1027 /* just indicate that signals should be handled asap */
1028 break;
1029 case EXCP_UDEF:
1030 info.si_signo = TARGET_SIGILL;
1031 info.si_errno = 0;
1032 info.si_code = TARGET_ILL_ILLOPN;
1033 info._sifields._sigfault._addr = env->pc;
1034 queue_signal(env, info.si_signo, &info);
1035 break;
1036 case EXCP_STREX:
1037 if (!do_strex_a64(env)) {
1038 break;
1040 /* fall through for segv */
1041 case EXCP_PREFETCH_ABORT:
1042 case EXCP_DATA_ABORT:
1043 info.si_signo = TARGET_SIGSEGV;
1044 info.si_errno = 0;
1045 /* XXX: check env->error_code */
1046 info.si_code = TARGET_SEGV_MAPERR;
1047 info._sifields._sigfault._addr = env->exception.vaddress;
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 case EXCP_SEMIHOST:
1061 env->xregs[0] = do_arm_semihosting(env);
1062 break;
1063 default:
1064 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
1065 abort();
1067 process_pending_signals(env);
1068 /* Exception return on AArch64 always clears the exclusive monitor,
1069 * so any return to running guest code implies this.
1070 * A strex (successful or otherwise) also clears the monitor, so
1071 * we don't need to specialcase EXCP_STREX.
1073 env->exclusive_addr = -1;
1076 #endif /* ndef TARGET_ABI32 */
1078 #endif
1080 #ifdef TARGET_UNICORE32
1082 void cpu_loop(CPUUniCore32State *env)
1084 CPUState *cs = CPU(uc32_env_get_cpu(env));
1085 int trapnr;
1086 unsigned int n, insn;
1087 target_siginfo_t info;
1089 for (;;) {
1090 cpu_exec_start(cs);
1091 trapnr = uc32_cpu_exec(cs);
1092 cpu_exec_end(cs);
1093 switch (trapnr) {
1094 case UC32_EXCP_PRIV:
1096 /* system call */
1097 get_user_u32(insn, env->regs[31] - 4);
1098 n = insn & 0xffffff;
1100 if (n >= UC32_SYSCALL_BASE) {
1101 /* linux syscall */
1102 n -= UC32_SYSCALL_BASE;
1103 if (n == UC32_SYSCALL_NR_set_tls) {
1104 cpu_set_tls(env, env->regs[0]);
1105 env->regs[0] = 0;
1106 } else {
1107 env->regs[0] = do_syscall(env,
1109 env->regs[0],
1110 env->regs[1],
1111 env->regs[2],
1112 env->regs[3],
1113 env->regs[4],
1114 env->regs[5],
1115 0, 0);
1117 } else {
1118 goto error;
1121 break;
1122 case UC32_EXCP_DTRAP:
1123 case UC32_EXCP_ITRAP:
1124 info.si_signo = TARGET_SIGSEGV;
1125 info.si_errno = 0;
1126 /* XXX: check env->error_code */
1127 info.si_code = TARGET_SEGV_MAPERR;
1128 info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
1129 queue_signal(env, info.si_signo, &info);
1130 break;
1131 case EXCP_INTERRUPT:
1132 /* just indicate that signals should be handled asap */
1133 break;
1134 case EXCP_DEBUG:
1136 int sig;
1138 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1139 if (sig) {
1140 info.si_signo = sig;
1141 info.si_errno = 0;
1142 info.si_code = TARGET_TRAP_BRKPT;
1143 queue_signal(env, info.si_signo, &info);
1146 break;
1147 default:
1148 goto error;
1150 process_pending_signals(env);
1153 error:
1154 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
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 cpu_exec_start(cs);
1291 trapnr = cpu_sparc_exec(cs);
1292 cpu_exec_end(cs);
1294 /* Compute PSR before exposing state. */
1295 if (env->cc_op != CC_OP_FLAGS) {
1296 cpu_get_psr(env);
1299 switch (trapnr) {
1300 #ifndef TARGET_SPARC64
1301 case 0x88:
1302 case 0x90:
1303 #else
1304 case 0x110:
1305 case 0x16d:
1306 #endif
1307 ret = do_syscall (env, env->gregs[1],
1308 env->regwptr[0], env->regwptr[1],
1309 env->regwptr[2], env->regwptr[3],
1310 env->regwptr[4], env->regwptr[5],
1311 0, 0);
1312 if ((abi_ulong)ret >= (abi_ulong)(-515)) {
1313 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1314 env->xcc |= PSR_CARRY;
1315 #else
1316 env->psr |= PSR_CARRY;
1317 #endif
1318 ret = -ret;
1319 } else {
1320 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1321 env->xcc &= ~PSR_CARRY;
1322 #else
1323 env->psr &= ~PSR_CARRY;
1324 #endif
1326 env->regwptr[0] = ret;
1327 /* next instruction */
1328 env->pc = env->npc;
1329 env->npc = env->npc + 4;
1330 break;
1331 case 0x83: /* flush windows */
1332 #ifdef TARGET_ABI32
1333 case 0x103:
1334 #endif
1335 flush_windows(env);
1336 /* next instruction */
1337 env->pc = env->npc;
1338 env->npc = env->npc + 4;
1339 break;
1340 #ifndef TARGET_SPARC64
1341 case TT_WIN_OVF: /* window overflow */
1342 save_window(env);
1343 break;
1344 case TT_WIN_UNF: /* window underflow */
1345 restore_window(env);
1346 break;
1347 case TT_TFAULT:
1348 case TT_DFAULT:
1350 info.si_signo = TARGET_SIGSEGV;
1351 info.si_errno = 0;
1352 /* XXX: check env->error_code */
1353 info.si_code = TARGET_SEGV_MAPERR;
1354 info._sifields._sigfault._addr = env->mmuregs[4];
1355 queue_signal(env, info.si_signo, &info);
1357 break;
1358 #else
1359 case TT_SPILL: /* window overflow */
1360 save_window(env);
1361 break;
1362 case TT_FILL: /* window underflow */
1363 restore_window(env);
1364 break;
1365 case TT_TFAULT:
1366 case TT_DFAULT:
1368 info.si_signo = TARGET_SIGSEGV;
1369 info.si_errno = 0;
1370 /* XXX: check env->error_code */
1371 info.si_code = TARGET_SEGV_MAPERR;
1372 if (trapnr == TT_DFAULT)
1373 info._sifields._sigfault._addr = env->dmmuregs[4];
1374 else
1375 info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
1376 queue_signal(env, info.si_signo, &info);
1378 break;
1379 #ifndef TARGET_ABI32
1380 case 0x16e:
1381 flush_windows(env);
1382 sparc64_get_context(env);
1383 break;
1384 case 0x16f:
1385 flush_windows(env);
1386 sparc64_set_context(env);
1387 break;
1388 #endif
1389 #endif
1390 case EXCP_INTERRUPT:
1391 /* just indicate that signals should be handled asap */
1392 break;
1393 case TT_ILL_INSN:
1395 info.si_signo = TARGET_SIGILL;
1396 info.si_errno = 0;
1397 info.si_code = TARGET_ILL_ILLOPC;
1398 info._sifields._sigfault._addr = env->pc;
1399 queue_signal(env, info.si_signo, &info);
1401 break;
1402 case EXCP_DEBUG:
1404 int sig;
1406 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1407 if (sig)
1409 info.si_signo = sig;
1410 info.si_errno = 0;
1411 info.si_code = TARGET_TRAP_BRKPT;
1412 queue_signal(env, info.si_signo, &info);
1415 break;
1416 default:
1417 printf ("Unhandled trap: 0x%x\n", trapnr);
1418 cpu_dump_state(cs, stderr, fprintf, 0);
1419 exit(EXIT_FAILURE);
1421 process_pending_signals (env);
1425 #endif
1427 #ifdef TARGET_PPC
1428 static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
1430 return cpu_get_host_ticks();
1433 uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
1435 return cpu_ppc_get_tb(env);
1438 uint32_t cpu_ppc_load_tbu(CPUPPCState *env)
1440 return cpu_ppc_get_tb(env) >> 32;
1443 uint64_t cpu_ppc_load_atbl(CPUPPCState *env)
1445 return cpu_ppc_get_tb(env);
1448 uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
1450 return cpu_ppc_get_tb(env) >> 32;
1453 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
1454 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
1456 uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
1458 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
1461 /* XXX: to be fixed */
1462 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
1464 return -1;
1467 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
1469 return -1;
1472 static int do_store_exclusive(CPUPPCState *env)
1474 target_ulong addr;
1475 target_ulong page_addr;
1476 target_ulong val, val2 __attribute__((unused)) = 0;
1477 int flags;
1478 int segv = 0;
1480 addr = env->reserve_ea;
1481 page_addr = addr & TARGET_PAGE_MASK;
1482 start_exclusive();
1483 mmap_lock();
1484 flags = page_get_flags(page_addr);
1485 if ((flags & PAGE_READ) == 0) {
1486 segv = 1;
1487 } else {
1488 int reg = env->reserve_info & 0x1f;
1489 int size = env->reserve_info >> 5;
1490 int stored = 0;
1492 if (addr == env->reserve_addr) {
1493 switch (size) {
1494 case 1: segv = get_user_u8(val, addr); break;
1495 case 2: segv = get_user_u16(val, addr); break;
1496 case 4: segv = get_user_u32(val, addr); break;
1497 #if defined(TARGET_PPC64)
1498 case 8: segv = get_user_u64(val, addr); break;
1499 case 16: {
1500 segv = get_user_u64(val, addr);
1501 if (!segv) {
1502 segv = get_user_u64(val2, addr + 8);
1504 break;
1506 #endif
1507 default: abort();
1509 if (!segv && val == env->reserve_val) {
1510 val = env->gpr[reg];
1511 switch (size) {
1512 case 1: segv = put_user_u8(val, addr); break;
1513 case 2: segv = put_user_u16(val, addr); break;
1514 case 4: segv = put_user_u32(val, addr); break;
1515 #if defined(TARGET_PPC64)
1516 case 8: segv = put_user_u64(val, addr); break;
1517 case 16: {
1518 if (val2 == env->reserve_val2) {
1519 if (msr_le) {
1520 val2 = val;
1521 val = env->gpr[reg+1];
1522 } else {
1523 val2 = env->gpr[reg+1];
1525 segv = put_user_u64(val, addr);
1526 if (!segv) {
1527 segv = put_user_u64(val2, addr + 8);
1530 break;
1532 #endif
1533 default: abort();
1535 if (!segv) {
1536 stored = 1;
1540 env->crf[0] = (stored << 1) | xer_so;
1541 env->reserve_addr = (target_ulong)-1;
1543 if (!segv) {
1544 env->nip += 4;
1546 mmap_unlock();
1547 end_exclusive();
1548 return segv;
1551 void cpu_loop(CPUPPCState *env)
1553 CPUState *cs = CPU(ppc_env_get_cpu(env));
1554 target_siginfo_t info;
1555 int trapnr;
1556 target_ulong ret;
1558 for(;;) {
1559 cpu_exec_start(cs);
1560 trapnr = cpu_ppc_exec(cs);
1561 cpu_exec_end(cs);
1562 switch(trapnr) {
1563 case POWERPC_EXCP_NONE:
1564 /* Just go on */
1565 break;
1566 case POWERPC_EXCP_CRITICAL: /* Critical input */
1567 cpu_abort(cs, "Critical interrupt while in user mode. "
1568 "Aborting\n");
1569 break;
1570 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1571 cpu_abort(cs, "Machine check exception while in user mode. "
1572 "Aborting\n");
1573 break;
1574 case POWERPC_EXCP_DSI: /* Data storage exception */
1575 EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",
1576 env->spr[SPR_DAR]);
1577 /* XXX: check this. Seems bugged */
1578 switch (env->error_code & 0xFF000000) {
1579 case 0x40000000:
1580 info.si_signo = TARGET_SIGSEGV;
1581 info.si_errno = 0;
1582 info.si_code = TARGET_SEGV_MAPERR;
1583 break;
1584 case 0x04000000:
1585 info.si_signo = TARGET_SIGILL;
1586 info.si_errno = 0;
1587 info.si_code = TARGET_ILL_ILLADR;
1588 break;
1589 case 0x08000000:
1590 info.si_signo = TARGET_SIGSEGV;
1591 info.si_errno = 0;
1592 info.si_code = TARGET_SEGV_ACCERR;
1593 break;
1594 default:
1595 /* Let's send a regular segfault... */
1596 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1597 env->error_code);
1598 info.si_signo = TARGET_SIGSEGV;
1599 info.si_errno = 0;
1600 info.si_code = TARGET_SEGV_MAPERR;
1601 break;
1603 info._sifields._sigfault._addr = env->nip;
1604 queue_signal(env, info.si_signo, &info);
1605 break;
1606 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1607 EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx
1608 "\n", env->spr[SPR_SRR0]);
1609 /* XXX: check this */
1610 switch (env->error_code & 0xFF000000) {
1611 case 0x40000000:
1612 info.si_signo = TARGET_SIGSEGV;
1613 info.si_errno = 0;
1614 info.si_code = TARGET_SEGV_MAPERR;
1615 break;
1616 case 0x10000000:
1617 case 0x08000000:
1618 info.si_signo = TARGET_SIGSEGV;
1619 info.si_errno = 0;
1620 info.si_code = TARGET_SEGV_ACCERR;
1621 break;
1622 default:
1623 /* Let's send a regular segfault... */
1624 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1625 env->error_code);
1626 info.si_signo = TARGET_SIGSEGV;
1627 info.si_errno = 0;
1628 info.si_code = TARGET_SEGV_MAPERR;
1629 break;
1631 info._sifields._sigfault._addr = env->nip - 4;
1632 queue_signal(env, info.si_signo, &info);
1633 break;
1634 case POWERPC_EXCP_EXTERNAL: /* External input */
1635 cpu_abort(cs, "External interrupt while in user mode. "
1636 "Aborting\n");
1637 break;
1638 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1639 EXCP_DUMP(env, "Unaligned memory access\n");
1640 /* XXX: check this */
1641 info.si_signo = TARGET_SIGBUS;
1642 info.si_errno = 0;
1643 info.si_code = TARGET_BUS_ADRALN;
1644 info._sifields._sigfault._addr = env->nip;
1645 queue_signal(env, info.si_signo, &info);
1646 break;
1647 case POWERPC_EXCP_PROGRAM: /* Program exception */
1648 /* XXX: check this */
1649 switch (env->error_code & ~0xF) {
1650 case POWERPC_EXCP_FP:
1651 EXCP_DUMP(env, "Floating point program exception\n");
1652 info.si_signo = TARGET_SIGFPE;
1653 info.si_errno = 0;
1654 switch (env->error_code & 0xF) {
1655 case POWERPC_EXCP_FP_OX:
1656 info.si_code = TARGET_FPE_FLTOVF;
1657 break;
1658 case POWERPC_EXCP_FP_UX:
1659 info.si_code = TARGET_FPE_FLTUND;
1660 break;
1661 case POWERPC_EXCP_FP_ZX:
1662 case POWERPC_EXCP_FP_VXZDZ:
1663 info.si_code = TARGET_FPE_FLTDIV;
1664 break;
1665 case POWERPC_EXCP_FP_XX:
1666 info.si_code = TARGET_FPE_FLTRES;
1667 break;
1668 case POWERPC_EXCP_FP_VXSOFT:
1669 info.si_code = TARGET_FPE_FLTINV;
1670 break;
1671 case POWERPC_EXCP_FP_VXSNAN:
1672 case POWERPC_EXCP_FP_VXISI:
1673 case POWERPC_EXCP_FP_VXIDI:
1674 case POWERPC_EXCP_FP_VXIMZ:
1675 case POWERPC_EXCP_FP_VXVC:
1676 case POWERPC_EXCP_FP_VXSQRT:
1677 case POWERPC_EXCP_FP_VXCVI:
1678 info.si_code = TARGET_FPE_FLTSUB;
1679 break;
1680 default:
1681 EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
1682 env->error_code);
1683 break;
1685 break;
1686 case POWERPC_EXCP_INVAL:
1687 EXCP_DUMP(env, "Invalid instruction\n");
1688 info.si_signo = TARGET_SIGILL;
1689 info.si_errno = 0;
1690 switch (env->error_code & 0xF) {
1691 case POWERPC_EXCP_INVAL_INVAL:
1692 info.si_code = TARGET_ILL_ILLOPC;
1693 break;
1694 case POWERPC_EXCP_INVAL_LSWX:
1695 info.si_code = TARGET_ILL_ILLOPN;
1696 break;
1697 case POWERPC_EXCP_INVAL_SPR:
1698 info.si_code = TARGET_ILL_PRVREG;
1699 break;
1700 case POWERPC_EXCP_INVAL_FP:
1701 info.si_code = TARGET_ILL_COPROC;
1702 break;
1703 default:
1704 EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
1705 env->error_code & 0xF);
1706 info.si_code = TARGET_ILL_ILLADR;
1707 break;
1709 break;
1710 case POWERPC_EXCP_PRIV:
1711 EXCP_DUMP(env, "Privilege violation\n");
1712 info.si_signo = TARGET_SIGILL;
1713 info.si_errno = 0;
1714 switch (env->error_code & 0xF) {
1715 case POWERPC_EXCP_PRIV_OPC:
1716 info.si_code = TARGET_ILL_PRVOPC;
1717 break;
1718 case POWERPC_EXCP_PRIV_REG:
1719 info.si_code = TARGET_ILL_PRVREG;
1720 break;
1721 default:
1722 EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
1723 env->error_code & 0xF);
1724 info.si_code = TARGET_ILL_PRVOPC;
1725 break;
1727 break;
1728 case POWERPC_EXCP_TRAP:
1729 cpu_abort(cs, "Tried to call a TRAP\n");
1730 break;
1731 default:
1732 /* Should not happen ! */
1733 cpu_abort(cs, "Unknown program exception (%02x)\n",
1734 env->error_code);
1735 break;
1737 info._sifields._sigfault._addr = env->nip - 4;
1738 queue_signal(env, info.si_signo, &info);
1739 break;
1740 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1741 EXCP_DUMP(env, "No floating point allowed\n");
1742 info.si_signo = TARGET_SIGILL;
1743 info.si_errno = 0;
1744 info.si_code = TARGET_ILL_COPROC;
1745 info._sifields._sigfault._addr = env->nip - 4;
1746 queue_signal(env, info.si_signo, &info);
1747 break;
1748 case POWERPC_EXCP_SYSCALL: /* System call exception */
1749 cpu_abort(cs, "Syscall exception while in user mode. "
1750 "Aborting\n");
1751 break;
1752 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1753 EXCP_DUMP(env, "No APU instruction allowed\n");
1754 info.si_signo = TARGET_SIGILL;
1755 info.si_errno = 0;
1756 info.si_code = TARGET_ILL_COPROC;
1757 info._sifields._sigfault._addr = env->nip - 4;
1758 queue_signal(env, info.si_signo, &info);
1759 break;
1760 case POWERPC_EXCP_DECR: /* Decrementer exception */
1761 cpu_abort(cs, "Decrementer interrupt while in user mode. "
1762 "Aborting\n");
1763 break;
1764 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1765 cpu_abort(cs, "Fix interval timer interrupt while in user mode. "
1766 "Aborting\n");
1767 break;
1768 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1769 cpu_abort(cs, "Watchdog timer interrupt while in user mode. "
1770 "Aborting\n");
1771 break;
1772 case POWERPC_EXCP_DTLB: /* Data TLB error */
1773 cpu_abort(cs, "Data TLB exception while in user mode. "
1774 "Aborting\n");
1775 break;
1776 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1777 cpu_abort(cs, "Instruction TLB exception while in user mode. "
1778 "Aborting\n");
1779 break;
1780 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
1781 EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
1782 info.si_signo = TARGET_SIGILL;
1783 info.si_errno = 0;
1784 info.si_code = TARGET_ILL_COPROC;
1785 info._sifields._sigfault._addr = env->nip - 4;
1786 queue_signal(env, info.si_signo, &info);
1787 break;
1788 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
1789 cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
1790 break;
1791 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
1792 cpu_abort(cs, "Embedded floating-point round IRQ not handled\n");
1793 break;
1794 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
1795 cpu_abort(cs, "Performance monitor exception not handled\n");
1796 break;
1797 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1798 cpu_abort(cs, "Doorbell interrupt while in user mode. "
1799 "Aborting\n");
1800 break;
1801 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1802 cpu_abort(cs, "Doorbell critical interrupt while in user mode. "
1803 "Aborting\n");
1804 break;
1805 case POWERPC_EXCP_RESET: /* System reset exception */
1806 cpu_abort(cs, "Reset interrupt while in user mode. "
1807 "Aborting\n");
1808 break;
1809 case POWERPC_EXCP_DSEG: /* Data segment exception */
1810 cpu_abort(cs, "Data segment exception while in user mode. "
1811 "Aborting\n");
1812 break;
1813 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1814 cpu_abort(cs, "Instruction segment exception "
1815 "while in user mode. Aborting\n");
1816 break;
1817 /* PowerPC 64 with hypervisor mode support */
1818 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1819 cpu_abort(cs, "Hypervisor decrementer interrupt "
1820 "while in user mode. Aborting\n");
1821 break;
1822 case POWERPC_EXCP_TRACE: /* Trace exception */
1823 /* Nothing to do:
1824 * we use this exception to emulate step-by-step execution mode.
1826 break;
1827 /* PowerPC 64 with hypervisor mode support */
1828 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1829 cpu_abort(cs, "Hypervisor data storage exception "
1830 "while in user mode. Aborting\n");
1831 break;
1832 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
1833 cpu_abort(cs, "Hypervisor instruction storage exception "
1834 "while in user mode. Aborting\n");
1835 break;
1836 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
1837 cpu_abort(cs, "Hypervisor data segment exception "
1838 "while in user mode. Aborting\n");
1839 break;
1840 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
1841 cpu_abort(cs, "Hypervisor instruction segment exception "
1842 "while in user mode. Aborting\n");
1843 break;
1844 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1845 EXCP_DUMP(env, "No Altivec instructions allowed\n");
1846 info.si_signo = TARGET_SIGILL;
1847 info.si_errno = 0;
1848 info.si_code = TARGET_ILL_COPROC;
1849 info._sifields._sigfault._addr = env->nip - 4;
1850 queue_signal(env, info.si_signo, &info);
1851 break;
1852 case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
1853 cpu_abort(cs, "Programmable interval timer interrupt "
1854 "while in user mode. Aborting\n");
1855 break;
1856 case POWERPC_EXCP_IO: /* IO error exception */
1857 cpu_abort(cs, "IO error exception while in user mode. "
1858 "Aborting\n");
1859 break;
1860 case POWERPC_EXCP_RUNM: /* Run mode exception */
1861 cpu_abort(cs, "Run mode exception while in user mode. "
1862 "Aborting\n");
1863 break;
1864 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
1865 cpu_abort(cs, "Emulation trap exception not handled\n");
1866 break;
1867 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
1868 cpu_abort(cs, "Instruction fetch TLB exception "
1869 "while in user-mode. Aborting");
1870 break;
1871 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
1872 cpu_abort(cs, "Data load TLB exception while in user-mode. "
1873 "Aborting");
1874 break;
1875 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
1876 cpu_abort(cs, "Data store TLB exception while in user-mode. "
1877 "Aborting");
1878 break;
1879 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
1880 cpu_abort(cs, "Floating-point assist exception not handled\n");
1881 break;
1882 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
1883 cpu_abort(cs, "Instruction address breakpoint exception "
1884 "not handled\n");
1885 break;
1886 case POWERPC_EXCP_SMI: /* System management interrupt */
1887 cpu_abort(cs, "System management interrupt while in user mode. "
1888 "Aborting\n");
1889 break;
1890 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1891 cpu_abort(cs, "Thermal interrupt interrupt while in user mode. "
1892 "Aborting\n");
1893 break;
1894 case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
1895 cpu_abort(cs, "Performance monitor exception not handled\n");
1896 break;
1897 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1898 cpu_abort(cs, "Vector assist exception not handled\n");
1899 break;
1900 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
1901 cpu_abort(cs, "Soft patch exception not handled\n");
1902 break;
1903 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1904 cpu_abort(cs, "Maintenance exception while in user mode. "
1905 "Aborting\n");
1906 break;
1907 case POWERPC_EXCP_STOP: /* stop translation */
1908 /* We did invalidate the instruction cache. Go on */
1909 break;
1910 case POWERPC_EXCP_BRANCH: /* branch instruction: */
1911 /* We just stopped because of a branch. Go on */
1912 break;
1913 case POWERPC_EXCP_SYSCALL_USER:
1914 /* system call in user-mode emulation */
1915 /* WARNING:
1916 * PPC ABI uses overflow flag in cr0 to signal an error
1917 * in syscalls.
1919 env->crf[0] &= ~0x1;
1920 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
1921 env->gpr[5], env->gpr[6], env->gpr[7],
1922 env->gpr[8], 0, 0);
1923 if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
1924 /* Returning from a successful sigreturn syscall.
1925 Avoid corrupting register state. */
1926 break;
1928 if (ret > (target_ulong)(-515)) {
1929 env->crf[0] |= 0x1;
1930 ret = -ret;
1932 env->gpr[3] = ret;
1933 break;
1934 case POWERPC_EXCP_STCX:
1935 if (do_store_exclusive(env)) {
1936 info.si_signo = TARGET_SIGSEGV;
1937 info.si_errno = 0;
1938 info.si_code = TARGET_SEGV_MAPERR;
1939 info._sifields._sigfault._addr = env->nip;
1940 queue_signal(env, info.si_signo, &info);
1942 break;
1943 case EXCP_DEBUG:
1945 int sig;
1947 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1948 if (sig) {
1949 info.si_signo = sig;
1950 info.si_errno = 0;
1951 info.si_code = TARGET_TRAP_BRKPT;
1952 queue_signal(env, info.si_signo, &info);
1955 break;
1956 case EXCP_INTERRUPT:
1957 /* just indicate that signals should be handled asap */
1958 break;
1959 default:
1960 cpu_abort(cs, "Unknown exception 0x%d. Aborting\n", trapnr);
1961 break;
1963 process_pending_signals(env);
1966 #endif
1968 #ifdef TARGET_MIPS
1970 # ifdef TARGET_ABI_MIPSO32
1971 # define MIPS_SYS(name, args) args,
1972 static const uint8_t mips_syscall_args[] = {
1973 MIPS_SYS(sys_syscall , 8) /* 4000 */
1974 MIPS_SYS(sys_exit , 1)
1975 MIPS_SYS(sys_fork , 0)
1976 MIPS_SYS(sys_read , 3)
1977 MIPS_SYS(sys_write , 3)
1978 MIPS_SYS(sys_open , 3) /* 4005 */
1979 MIPS_SYS(sys_close , 1)
1980 MIPS_SYS(sys_waitpid , 3)
1981 MIPS_SYS(sys_creat , 2)
1982 MIPS_SYS(sys_link , 2)
1983 MIPS_SYS(sys_unlink , 1) /* 4010 */
1984 MIPS_SYS(sys_execve , 0)
1985 MIPS_SYS(sys_chdir , 1)
1986 MIPS_SYS(sys_time , 1)
1987 MIPS_SYS(sys_mknod , 3)
1988 MIPS_SYS(sys_chmod , 2) /* 4015 */
1989 MIPS_SYS(sys_lchown , 3)
1990 MIPS_SYS(sys_ni_syscall , 0)
1991 MIPS_SYS(sys_ni_syscall , 0) /* was sys_stat */
1992 MIPS_SYS(sys_lseek , 3)
1993 MIPS_SYS(sys_getpid , 0) /* 4020 */
1994 MIPS_SYS(sys_mount , 5)
1995 MIPS_SYS(sys_umount , 1)
1996 MIPS_SYS(sys_setuid , 1)
1997 MIPS_SYS(sys_getuid , 0)
1998 MIPS_SYS(sys_stime , 1) /* 4025 */
1999 MIPS_SYS(sys_ptrace , 4)
2000 MIPS_SYS(sys_alarm , 1)
2001 MIPS_SYS(sys_ni_syscall , 0) /* was sys_fstat */
2002 MIPS_SYS(sys_pause , 0)
2003 MIPS_SYS(sys_utime , 2) /* 4030 */
2004 MIPS_SYS(sys_ni_syscall , 0)
2005 MIPS_SYS(sys_ni_syscall , 0)
2006 MIPS_SYS(sys_access , 2)
2007 MIPS_SYS(sys_nice , 1)
2008 MIPS_SYS(sys_ni_syscall , 0) /* 4035 */
2009 MIPS_SYS(sys_sync , 0)
2010 MIPS_SYS(sys_kill , 2)
2011 MIPS_SYS(sys_rename , 2)
2012 MIPS_SYS(sys_mkdir , 2)
2013 MIPS_SYS(sys_rmdir , 1) /* 4040 */
2014 MIPS_SYS(sys_dup , 1)
2015 MIPS_SYS(sys_pipe , 0)
2016 MIPS_SYS(sys_times , 1)
2017 MIPS_SYS(sys_ni_syscall , 0)
2018 MIPS_SYS(sys_brk , 1) /* 4045 */
2019 MIPS_SYS(sys_setgid , 1)
2020 MIPS_SYS(sys_getgid , 0)
2021 MIPS_SYS(sys_ni_syscall , 0) /* was signal(2) */
2022 MIPS_SYS(sys_geteuid , 0)
2023 MIPS_SYS(sys_getegid , 0) /* 4050 */
2024 MIPS_SYS(sys_acct , 0)
2025 MIPS_SYS(sys_umount2 , 2)
2026 MIPS_SYS(sys_ni_syscall , 0)
2027 MIPS_SYS(sys_ioctl , 3)
2028 MIPS_SYS(sys_fcntl , 3) /* 4055 */
2029 MIPS_SYS(sys_ni_syscall , 2)
2030 MIPS_SYS(sys_setpgid , 2)
2031 MIPS_SYS(sys_ni_syscall , 0)
2032 MIPS_SYS(sys_olduname , 1)
2033 MIPS_SYS(sys_umask , 1) /* 4060 */
2034 MIPS_SYS(sys_chroot , 1)
2035 MIPS_SYS(sys_ustat , 2)
2036 MIPS_SYS(sys_dup2 , 2)
2037 MIPS_SYS(sys_getppid , 0)
2038 MIPS_SYS(sys_getpgrp , 0) /* 4065 */
2039 MIPS_SYS(sys_setsid , 0)
2040 MIPS_SYS(sys_sigaction , 3)
2041 MIPS_SYS(sys_sgetmask , 0)
2042 MIPS_SYS(sys_ssetmask , 1)
2043 MIPS_SYS(sys_setreuid , 2) /* 4070 */
2044 MIPS_SYS(sys_setregid , 2)
2045 MIPS_SYS(sys_sigsuspend , 0)
2046 MIPS_SYS(sys_sigpending , 1)
2047 MIPS_SYS(sys_sethostname , 2)
2048 MIPS_SYS(sys_setrlimit , 2) /* 4075 */
2049 MIPS_SYS(sys_getrlimit , 2)
2050 MIPS_SYS(sys_getrusage , 2)
2051 MIPS_SYS(sys_gettimeofday, 2)
2052 MIPS_SYS(sys_settimeofday, 2)
2053 MIPS_SYS(sys_getgroups , 2) /* 4080 */
2054 MIPS_SYS(sys_setgroups , 2)
2055 MIPS_SYS(sys_ni_syscall , 0) /* old_select */
2056 MIPS_SYS(sys_symlink , 2)
2057 MIPS_SYS(sys_ni_syscall , 0) /* was sys_lstat */
2058 MIPS_SYS(sys_readlink , 3) /* 4085 */
2059 MIPS_SYS(sys_uselib , 1)
2060 MIPS_SYS(sys_swapon , 2)
2061 MIPS_SYS(sys_reboot , 3)
2062 MIPS_SYS(old_readdir , 3)
2063 MIPS_SYS(old_mmap , 6) /* 4090 */
2064 MIPS_SYS(sys_munmap , 2)
2065 MIPS_SYS(sys_truncate , 2)
2066 MIPS_SYS(sys_ftruncate , 2)
2067 MIPS_SYS(sys_fchmod , 2)
2068 MIPS_SYS(sys_fchown , 3) /* 4095 */
2069 MIPS_SYS(sys_getpriority , 2)
2070 MIPS_SYS(sys_setpriority , 3)
2071 MIPS_SYS(sys_ni_syscall , 0)
2072 MIPS_SYS(sys_statfs , 2)
2073 MIPS_SYS(sys_fstatfs , 2) /* 4100 */
2074 MIPS_SYS(sys_ni_syscall , 0) /* was ioperm(2) */
2075 MIPS_SYS(sys_socketcall , 2)
2076 MIPS_SYS(sys_syslog , 3)
2077 MIPS_SYS(sys_setitimer , 3)
2078 MIPS_SYS(sys_getitimer , 2) /* 4105 */
2079 MIPS_SYS(sys_newstat , 2)
2080 MIPS_SYS(sys_newlstat , 2)
2081 MIPS_SYS(sys_newfstat , 2)
2082 MIPS_SYS(sys_uname , 1)
2083 MIPS_SYS(sys_ni_syscall , 0) /* 4110 was iopl(2) */
2084 MIPS_SYS(sys_vhangup , 0)
2085 MIPS_SYS(sys_ni_syscall , 0) /* was sys_idle() */
2086 MIPS_SYS(sys_ni_syscall , 0) /* was sys_vm86 */
2087 MIPS_SYS(sys_wait4 , 4)
2088 MIPS_SYS(sys_swapoff , 1) /* 4115 */
2089 MIPS_SYS(sys_sysinfo , 1)
2090 MIPS_SYS(sys_ipc , 6)
2091 MIPS_SYS(sys_fsync , 1)
2092 MIPS_SYS(sys_sigreturn , 0)
2093 MIPS_SYS(sys_clone , 6) /* 4120 */
2094 MIPS_SYS(sys_setdomainname, 2)
2095 MIPS_SYS(sys_newuname , 1)
2096 MIPS_SYS(sys_ni_syscall , 0) /* sys_modify_ldt */
2097 MIPS_SYS(sys_adjtimex , 1)
2098 MIPS_SYS(sys_mprotect , 3) /* 4125 */
2099 MIPS_SYS(sys_sigprocmask , 3)
2100 MIPS_SYS(sys_ni_syscall , 0) /* was create_module */
2101 MIPS_SYS(sys_init_module , 5)
2102 MIPS_SYS(sys_delete_module, 1)
2103 MIPS_SYS(sys_ni_syscall , 0) /* 4130 was get_kernel_syms */
2104 MIPS_SYS(sys_quotactl , 0)
2105 MIPS_SYS(sys_getpgid , 1)
2106 MIPS_SYS(sys_fchdir , 1)
2107 MIPS_SYS(sys_bdflush , 2)
2108 MIPS_SYS(sys_sysfs , 3) /* 4135 */
2109 MIPS_SYS(sys_personality , 1)
2110 MIPS_SYS(sys_ni_syscall , 0) /* for afs_syscall */
2111 MIPS_SYS(sys_setfsuid , 1)
2112 MIPS_SYS(sys_setfsgid , 1)
2113 MIPS_SYS(sys_llseek , 5) /* 4140 */
2114 MIPS_SYS(sys_getdents , 3)
2115 MIPS_SYS(sys_select , 5)
2116 MIPS_SYS(sys_flock , 2)
2117 MIPS_SYS(sys_msync , 3)
2118 MIPS_SYS(sys_readv , 3) /* 4145 */
2119 MIPS_SYS(sys_writev , 3)
2120 MIPS_SYS(sys_cacheflush , 3)
2121 MIPS_SYS(sys_cachectl , 3)
2122 MIPS_SYS(sys_sysmips , 4)
2123 MIPS_SYS(sys_ni_syscall , 0) /* 4150 */
2124 MIPS_SYS(sys_getsid , 1)
2125 MIPS_SYS(sys_fdatasync , 0)
2126 MIPS_SYS(sys_sysctl , 1)
2127 MIPS_SYS(sys_mlock , 2)
2128 MIPS_SYS(sys_munlock , 2) /* 4155 */
2129 MIPS_SYS(sys_mlockall , 1)
2130 MIPS_SYS(sys_munlockall , 0)
2131 MIPS_SYS(sys_sched_setparam, 2)
2132 MIPS_SYS(sys_sched_getparam, 2)
2133 MIPS_SYS(sys_sched_setscheduler, 3) /* 4160 */
2134 MIPS_SYS(sys_sched_getscheduler, 1)
2135 MIPS_SYS(sys_sched_yield , 0)
2136 MIPS_SYS(sys_sched_get_priority_max, 1)
2137 MIPS_SYS(sys_sched_get_priority_min, 1)
2138 MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */
2139 MIPS_SYS(sys_nanosleep, 2)
2140 MIPS_SYS(sys_mremap , 5)
2141 MIPS_SYS(sys_accept , 3)
2142 MIPS_SYS(sys_bind , 3)
2143 MIPS_SYS(sys_connect , 3) /* 4170 */
2144 MIPS_SYS(sys_getpeername , 3)
2145 MIPS_SYS(sys_getsockname , 3)
2146 MIPS_SYS(sys_getsockopt , 5)
2147 MIPS_SYS(sys_listen , 2)
2148 MIPS_SYS(sys_recv , 4) /* 4175 */
2149 MIPS_SYS(sys_recvfrom , 6)
2150 MIPS_SYS(sys_recvmsg , 3)
2151 MIPS_SYS(sys_send , 4)
2152 MIPS_SYS(sys_sendmsg , 3)
2153 MIPS_SYS(sys_sendto , 6) /* 4180 */
2154 MIPS_SYS(sys_setsockopt , 5)
2155 MIPS_SYS(sys_shutdown , 2)
2156 MIPS_SYS(sys_socket , 3)
2157 MIPS_SYS(sys_socketpair , 4)
2158 MIPS_SYS(sys_setresuid , 3) /* 4185 */
2159 MIPS_SYS(sys_getresuid , 3)
2160 MIPS_SYS(sys_ni_syscall , 0) /* was sys_query_module */
2161 MIPS_SYS(sys_poll , 3)
2162 MIPS_SYS(sys_nfsservctl , 3)
2163 MIPS_SYS(sys_setresgid , 3) /* 4190 */
2164 MIPS_SYS(sys_getresgid , 3)
2165 MIPS_SYS(sys_prctl , 5)
2166 MIPS_SYS(sys_rt_sigreturn, 0)
2167 MIPS_SYS(sys_rt_sigaction, 4)
2168 MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
2169 MIPS_SYS(sys_rt_sigpending, 2)
2170 MIPS_SYS(sys_rt_sigtimedwait, 4)
2171 MIPS_SYS(sys_rt_sigqueueinfo, 3)
2172 MIPS_SYS(sys_rt_sigsuspend, 0)
2173 MIPS_SYS(sys_pread64 , 6) /* 4200 */
2174 MIPS_SYS(sys_pwrite64 , 6)
2175 MIPS_SYS(sys_chown , 3)
2176 MIPS_SYS(sys_getcwd , 2)
2177 MIPS_SYS(sys_capget , 2)
2178 MIPS_SYS(sys_capset , 2) /* 4205 */
2179 MIPS_SYS(sys_sigaltstack , 2)
2180 MIPS_SYS(sys_sendfile , 4)
2181 MIPS_SYS(sys_ni_syscall , 0)
2182 MIPS_SYS(sys_ni_syscall , 0)
2183 MIPS_SYS(sys_mmap2 , 6) /* 4210 */
2184 MIPS_SYS(sys_truncate64 , 4)
2185 MIPS_SYS(sys_ftruncate64 , 4)
2186 MIPS_SYS(sys_stat64 , 2)
2187 MIPS_SYS(sys_lstat64 , 2)
2188 MIPS_SYS(sys_fstat64 , 2) /* 4215 */
2189 MIPS_SYS(sys_pivot_root , 2)
2190 MIPS_SYS(sys_mincore , 3)
2191 MIPS_SYS(sys_madvise , 3)
2192 MIPS_SYS(sys_getdents64 , 3)
2193 MIPS_SYS(sys_fcntl64 , 3) /* 4220 */
2194 MIPS_SYS(sys_ni_syscall , 0)
2195 MIPS_SYS(sys_gettid , 0)
2196 MIPS_SYS(sys_readahead , 5)
2197 MIPS_SYS(sys_setxattr , 5)
2198 MIPS_SYS(sys_lsetxattr , 5) /* 4225 */
2199 MIPS_SYS(sys_fsetxattr , 5)
2200 MIPS_SYS(sys_getxattr , 4)
2201 MIPS_SYS(sys_lgetxattr , 4)
2202 MIPS_SYS(sys_fgetxattr , 4)
2203 MIPS_SYS(sys_listxattr , 3) /* 4230 */
2204 MIPS_SYS(sys_llistxattr , 3)
2205 MIPS_SYS(sys_flistxattr , 3)
2206 MIPS_SYS(sys_removexattr , 2)
2207 MIPS_SYS(sys_lremovexattr, 2)
2208 MIPS_SYS(sys_fremovexattr, 2) /* 4235 */
2209 MIPS_SYS(sys_tkill , 2)
2210 MIPS_SYS(sys_sendfile64 , 5)
2211 MIPS_SYS(sys_futex , 6)
2212 MIPS_SYS(sys_sched_setaffinity, 3)
2213 MIPS_SYS(sys_sched_getaffinity, 3) /* 4240 */
2214 MIPS_SYS(sys_io_setup , 2)
2215 MIPS_SYS(sys_io_destroy , 1)
2216 MIPS_SYS(sys_io_getevents, 5)
2217 MIPS_SYS(sys_io_submit , 3)
2218 MIPS_SYS(sys_io_cancel , 3) /* 4245 */
2219 MIPS_SYS(sys_exit_group , 1)
2220 MIPS_SYS(sys_lookup_dcookie, 3)
2221 MIPS_SYS(sys_epoll_create, 1)
2222 MIPS_SYS(sys_epoll_ctl , 4)
2223 MIPS_SYS(sys_epoll_wait , 3) /* 4250 */
2224 MIPS_SYS(sys_remap_file_pages, 5)
2225 MIPS_SYS(sys_set_tid_address, 1)
2226 MIPS_SYS(sys_restart_syscall, 0)
2227 MIPS_SYS(sys_fadvise64_64, 7)
2228 MIPS_SYS(sys_statfs64 , 3) /* 4255 */
2229 MIPS_SYS(sys_fstatfs64 , 2)
2230 MIPS_SYS(sys_timer_create, 3)
2231 MIPS_SYS(sys_timer_settime, 4)
2232 MIPS_SYS(sys_timer_gettime, 2)
2233 MIPS_SYS(sys_timer_getoverrun, 1) /* 4260 */
2234 MIPS_SYS(sys_timer_delete, 1)
2235 MIPS_SYS(sys_clock_settime, 2)
2236 MIPS_SYS(sys_clock_gettime, 2)
2237 MIPS_SYS(sys_clock_getres, 2)
2238 MIPS_SYS(sys_clock_nanosleep, 4) /* 4265 */
2239 MIPS_SYS(sys_tgkill , 3)
2240 MIPS_SYS(sys_utimes , 2)
2241 MIPS_SYS(sys_mbind , 4)
2242 MIPS_SYS(sys_ni_syscall , 0) /* sys_get_mempolicy */
2243 MIPS_SYS(sys_ni_syscall , 0) /* 4270 sys_set_mempolicy */
2244 MIPS_SYS(sys_mq_open , 4)
2245 MIPS_SYS(sys_mq_unlink , 1)
2246 MIPS_SYS(sys_mq_timedsend, 5)
2247 MIPS_SYS(sys_mq_timedreceive, 5)
2248 MIPS_SYS(sys_mq_notify , 2) /* 4275 */
2249 MIPS_SYS(sys_mq_getsetattr, 3)
2250 MIPS_SYS(sys_ni_syscall , 0) /* sys_vserver */
2251 MIPS_SYS(sys_waitid , 4)
2252 MIPS_SYS(sys_ni_syscall , 0) /* available, was setaltroot */
2253 MIPS_SYS(sys_add_key , 5)
2254 MIPS_SYS(sys_request_key, 4)
2255 MIPS_SYS(sys_keyctl , 5)
2256 MIPS_SYS(sys_set_thread_area, 1)
2257 MIPS_SYS(sys_inotify_init, 0)
2258 MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
2259 MIPS_SYS(sys_inotify_rm_watch, 2)
2260 MIPS_SYS(sys_migrate_pages, 4)
2261 MIPS_SYS(sys_openat, 4)
2262 MIPS_SYS(sys_mkdirat, 3)
2263 MIPS_SYS(sys_mknodat, 4) /* 4290 */
2264 MIPS_SYS(sys_fchownat, 5)
2265 MIPS_SYS(sys_futimesat, 3)
2266 MIPS_SYS(sys_fstatat64, 4)
2267 MIPS_SYS(sys_unlinkat, 3)
2268 MIPS_SYS(sys_renameat, 4) /* 4295 */
2269 MIPS_SYS(sys_linkat, 5)
2270 MIPS_SYS(sys_symlinkat, 3)
2271 MIPS_SYS(sys_readlinkat, 4)
2272 MIPS_SYS(sys_fchmodat, 3)
2273 MIPS_SYS(sys_faccessat, 3) /* 4300 */
2274 MIPS_SYS(sys_pselect6, 6)
2275 MIPS_SYS(sys_ppoll, 5)
2276 MIPS_SYS(sys_unshare, 1)
2277 MIPS_SYS(sys_splice, 6)
2278 MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
2279 MIPS_SYS(sys_tee, 4)
2280 MIPS_SYS(sys_vmsplice, 4)
2281 MIPS_SYS(sys_move_pages, 6)
2282 MIPS_SYS(sys_set_robust_list, 2)
2283 MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
2284 MIPS_SYS(sys_kexec_load, 4)
2285 MIPS_SYS(sys_getcpu, 3)
2286 MIPS_SYS(sys_epoll_pwait, 6)
2287 MIPS_SYS(sys_ioprio_set, 3)
2288 MIPS_SYS(sys_ioprio_get, 2)
2289 MIPS_SYS(sys_utimensat, 4)
2290 MIPS_SYS(sys_signalfd, 3)
2291 MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
2292 MIPS_SYS(sys_eventfd, 1)
2293 MIPS_SYS(sys_fallocate, 6) /* 4320 */
2294 MIPS_SYS(sys_timerfd_create, 2)
2295 MIPS_SYS(sys_timerfd_gettime, 2)
2296 MIPS_SYS(sys_timerfd_settime, 4)
2297 MIPS_SYS(sys_signalfd4, 4)
2298 MIPS_SYS(sys_eventfd2, 2) /* 4325 */
2299 MIPS_SYS(sys_epoll_create1, 1)
2300 MIPS_SYS(sys_dup3, 3)
2301 MIPS_SYS(sys_pipe2, 2)
2302 MIPS_SYS(sys_inotify_init1, 1)
2303 MIPS_SYS(sys_preadv, 6) /* 4330 */
2304 MIPS_SYS(sys_pwritev, 6)
2305 MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
2306 MIPS_SYS(sys_perf_event_open, 5)
2307 MIPS_SYS(sys_accept4, 4)
2308 MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
2309 MIPS_SYS(sys_fanotify_init, 2)
2310 MIPS_SYS(sys_fanotify_mark, 6)
2311 MIPS_SYS(sys_prlimit64, 4)
2312 MIPS_SYS(sys_name_to_handle_at, 5)
2313 MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
2314 MIPS_SYS(sys_clock_adjtime, 2)
2315 MIPS_SYS(sys_syncfs, 1)
2317 # undef MIPS_SYS
2318 # endif /* O32 */
2320 static int do_store_exclusive(CPUMIPSState *env)
2322 target_ulong addr;
2323 target_ulong page_addr;
2324 target_ulong val;
2325 int flags;
2326 int segv = 0;
2327 int reg;
2328 int d;
2330 addr = env->lladdr;
2331 page_addr = addr & TARGET_PAGE_MASK;
2332 start_exclusive();
2333 mmap_lock();
2334 flags = page_get_flags(page_addr);
2335 if ((flags & PAGE_READ) == 0) {
2336 segv = 1;
2337 } else {
2338 reg = env->llreg & 0x1f;
2339 d = (env->llreg & 0x20) != 0;
2340 if (d) {
2341 segv = get_user_s64(val, addr);
2342 } else {
2343 segv = get_user_s32(val, addr);
2345 if (!segv) {
2346 if (val != env->llval) {
2347 env->active_tc.gpr[reg] = 0;
2348 } else {
2349 if (d) {
2350 segv = put_user_u64(env->llnewval, addr);
2351 } else {
2352 segv = put_user_u32(env->llnewval, addr);
2354 if (!segv) {
2355 env->active_tc.gpr[reg] = 1;
2360 env->lladdr = -1;
2361 if (!segv) {
2362 env->active_tc.PC += 4;
2364 mmap_unlock();
2365 end_exclusive();
2366 return segv;
2369 /* Break codes */
2370 enum {
2371 BRK_OVERFLOW = 6,
2372 BRK_DIVZERO = 7
2375 static int do_break(CPUMIPSState *env, target_siginfo_t *info,
2376 unsigned int code)
2378 int ret = -1;
2380 switch (code) {
2381 case BRK_OVERFLOW:
2382 case BRK_DIVZERO:
2383 info->si_signo = TARGET_SIGFPE;
2384 info->si_errno = 0;
2385 info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
2386 queue_signal(env, info->si_signo, &*info);
2387 ret = 0;
2388 break;
2389 default:
2390 info->si_signo = TARGET_SIGTRAP;
2391 info->si_errno = 0;
2392 queue_signal(env, info->si_signo, &*info);
2393 ret = 0;
2394 break;
2397 return ret;
2400 void cpu_loop(CPUMIPSState *env)
2402 CPUState *cs = CPU(mips_env_get_cpu(env));
2403 target_siginfo_t info;
2404 int trapnr;
2405 abi_long ret;
2406 # ifdef TARGET_ABI_MIPSO32
2407 unsigned int syscall_num;
2408 # endif
2410 for(;;) {
2411 cpu_exec_start(cs);
2412 trapnr = cpu_mips_exec(cs);
2413 cpu_exec_end(cs);
2414 switch(trapnr) {
2415 case EXCP_SYSCALL:
2416 env->active_tc.PC += 4;
2417 # ifdef TARGET_ABI_MIPSO32
2418 syscall_num = env->active_tc.gpr[2] - 4000;
2419 if (syscall_num >= sizeof(mips_syscall_args)) {
2420 ret = -TARGET_ENOSYS;
2421 } else {
2422 int nb_args;
2423 abi_ulong sp_reg;
2424 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
2426 nb_args = mips_syscall_args[syscall_num];
2427 sp_reg = env->active_tc.gpr[29];
2428 switch (nb_args) {
2429 /* these arguments are taken from the stack */
2430 case 8:
2431 if ((ret = get_user_ual(arg8, sp_reg + 28)) != 0) {
2432 goto done_syscall;
2434 case 7:
2435 if ((ret = get_user_ual(arg7, sp_reg + 24)) != 0) {
2436 goto done_syscall;
2438 case 6:
2439 if ((ret = get_user_ual(arg6, sp_reg + 20)) != 0) {
2440 goto done_syscall;
2442 case 5:
2443 if ((ret = get_user_ual(arg5, sp_reg + 16)) != 0) {
2444 goto done_syscall;
2446 default:
2447 break;
2449 ret = do_syscall(env, env->active_tc.gpr[2],
2450 env->active_tc.gpr[4],
2451 env->active_tc.gpr[5],
2452 env->active_tc.gpr[6],
2453 env->active_tc.gpr[7],
2454 arg5, arg6, arg7, arg8);
2456 done_syscall:
2457 # else
2458 ret = do_syscall(env, env->active_tc.gpr[2],
2459 env->active_tc.gpr[4], env->active_tc.gpr[5],
2460 env->active_tc.gpr[6], env->active_tc.gpr[7],
2461 env->active_tc.gpr[8], env->active_tc.gpr[9],
2462 env->active_tc.gpr[10], env->active_tc.gpr[11]);
2463 # endif /* O32 */
2464 if (ret == -TARGET_QEMU_ESIGRETURN) {
2465 /* Returning from a successful sigreturn syscall.
2466 Avoid clobbering register state. */
2467 break;
2469 if ((abi_ulong)ret >= (abi_ulong)-1133) {
2470 env->active_tc.gpr[7] = 1; /* error flag */
2471 ret = -ret;
2472 } else {
2473 env->active_tc.gpr[7] = 0; /* error flag */
2475 env->active_tc.gpr[2] = ret;
2476 break;
2477 case EXCP_TLBL:
2478 case EXCP_TLBS:
2479 case EXCP_AdEL:
2480 case EXCP_AdES:
2481 info.si_signo = TARGET_SIGSEGV;
2482 info.si_errno = 0;
2483 /* XXX: check env->error_code */
2484 info.si_code = TARGET_SEGV_MAPERR;
2485 info._sifields._sigfault._addr = env->CP0_BadVAddr;
2486 queue_signal(env, info.si_signo, &info);
2487 break;
2488 case EXCP_CpU:
2489 case EXCP_RI:
2490 info.si_signo = TARGET_SIGILL;
2491 info.si_errno = 0;
2492 info.si_code = 0;
2493 queue_signal(env, info.si_signo, &info);
2494 break;
2495 case EXCP_INTERRUPT:
2496 /* just indicate that signals should be handled asap */
2497 break;
2498 case EXCP_DEBUG:
2500 int sig;
2502 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2503 if (sig)
2505 info.si_signo = sig;
2506 info.si_errno = 0;
2507 info.si_code = TARGET_TRAP_BRKPT;
2508 queue_signal(env, info.si_signo, &info);
2511 break;
2512 case EXCP_SC:
2513 if (do_store_exclusive(env)) {
2514 info.si_signo = TARGET_SIGSEGV;
2515 info.si_errno = 0;
2516 info.si_code = TARGET_SEGV_MAPERR;
2517 info._sifields._sigfault._addr = env->active_tc.PC;
2518 queue_signal(env, info.si_signo, &info);
2520 break;
2521 case EXCP_DSPDIS:
2522 info.si_signo = TARGET_SIGILL;
2523 info.si_errno = 0;
2524 info.si_code = TARGET_ILL_ILLOPC;
2525 queue_signal(env, info.si_signo, &info);
2526 break;
2527 /* The code below was inspired by the MIPS Linux kernel trap
2528 * handling code in arch/mips/kernel/traps.c.
2530 case EXCP_BREAK:
2532 abi_ulong trap_instr;
2533 unsigned int code;
2535 if (env->hflags & MIPS_HFLAG_M16) {
2536 if (env->insn_flags & ASE_MICROMIPS) {
2537 /* microMIPS mode */
2538 ret = get_user_u16(trap_instr, env->active_tc.PC);
2539 if (ret != 0) {
2540 goto error;
2543 if ((trap_instr >> 10) == 0x11) {
2544 /* 16-bit instruction */
2545 code = trap_instr & 0xf;
2546 } else {
2547 /* 32-bit instruction */
2548 abi_ulong instr_lo;
2550 ret = get_user_u16(instr_lo,
2551 env->active_tc.PC + 2);
2552 if (ret != 0) {
2553 goto error;
2555 trap_instr = (trap_instr << 16) | instr_lo;
2556 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2557 /* Unfortunately, microMIPS also suffers from
2558 the old assembler bug... */
2559 if (code >= (1 << 10)) {
2560 code >>= 10;
2563 } else {
2564 /* MIPS16e mode */
2565 ret = get_user_u16(trap_instr, env->active_tc.PC);
2566 if (ret != 0) {
2567 goto error;
2569 code = (trap_instr >> 6) & 0x3f;
2571 } else {
2572 ret = get_user_u32(trap_instr, env->active_tc.PC);
2573 if (ret != 0) {
2574 goto error;
2577 /* As described in the original Linux kernel code, the
2578 * below checks on 'code' are to work around an old
2579 * assembly bug.
2581 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2582 if (code >= (1 << 10)) {
2583 code >>= 10;
2587 if (do_break(env, &info, code) != 0) {
2588 goto error;
2591 break;
2592 case EXCP_TRAP:
2594 abi_ulong trap_instr;
2595 unsigned int code = 0;
2597 if (env->hflags & MIPS_HFLAG_M16) {
2598 /* microMIPS mode */
2599 abi_ulong instr[2];
2601 ret = get_user_u16(instr[0], env->active_tc.PC) ||
2602 get_user_u16(instr[1], env->active_tc.PC + 2);
2604 trap_instr = (instr[0] << 16) | instr[1];
2605 } else {
2606 ret = get_user_u32(trap_instr, env->active_tc.PC);
2609 if (ret != 0) {
2610 goto error;
2613 /* The immediate versions don't provide a code. */
2614 if (!(trap_instr & 0xFC000000)) {
2615 if (env->hflags & MIPS_HFLAG_M16) {
2616 /* microMIPS mode */
2617 code = ((trap_instr >> 12) & ((1 << 4) - 1));
2618 } else {
2619 code = ((trap_instr >> 6) & ((1 << 10) - 1));
2623 if (do_break(env, &info, code) != 0) {
2624 goto error;
2627 break;
2628 default:
2629 error:
2630 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
2631 abort();
2633 process_pending_signals(env);
2636 #endif
2638 #ifdef TARGET_OPENRISC
2640 void cpu_loop(CPUOpenRISCState *env)
2642 CPUState *cs = CPU(openrisc_env_get_cpu(env));
2643 int trapnr, gdbsig;
2645 for (;;) {
2646 cpu_exec_start(cs);
2647 trapnr = cpu_openrisc_exec(cs);
2648 cpu_exec_end(cs);
2649 gdbsig = 0;
2651 switch (trapnr) {
2652 case EXCP_RESET:
2653 qemu_log_mask(CPU_LOG_INT, "\nReset request, exit, pc is %#x\n", env->pc);
2654 exit(EXIT_FAILURE);
2655 break;
2656 case EXCP_BUSERR:
2657 qemu_log_mask(CPU_LOG_INT, "\nBus error, exit, pc is %#x\n", env->pc);
2658 gdbsig = TARGET_SIGBUS;
2659 break;
2660 case EXCP_DPF:
2661 case EXCP_IPF:
2662 cpu_dump_state(cs, stderr, fprintf, 0);
2663 gdbsig = TARGET_SIGSEGV;
2664 break;
2665 case EXCP_TICK:
2666 qemu_log_mask(CPU_LOG_INT, "\nTick time interrupt pc is %#x\n", env->pc);
2667 break;
2668 case EXCP_ALIGN:
2669 qemu_log_mask(CPU_LOG_INT, "\nAlignment pc is %#x\n", env->pc);
2670 gdbsig = TARGET_SIGBUS;
2671 break;
2672 case EXCP_ILLEGAL:
2673 qemu_log_mask(CPU_LOG_INT, "\nIllegal instructionpc is %#x\n", env->pc);
2674 gdbsig = TARGET_SIGILL;
2675 break;
2676 case EXCP_INT:
2677 qemu_log_mask(CPU_LOG_INT, "\nExternal interruptpc is %#x\n", env->pc);
2678 break;
2679 case EXCP_DTLBMISS:
2680 case EXCP_ITLBMISS:
2681 qemu_log_mask(CPU_LOG_INT, "\nTLB miss\n");
2682 break;
2683 case EXCP_RANGE:
2684 qemu_log_mask(CPU_LOG_INT, "\nRange\n");
2685 gdbsig = TARGET_SIGSEGV;
2686 break;
2687 case EXCP_SYSCALL:
2688 env->pc += 4; /* 0xc00; */
2689 env->gpr[11] = do_syscall(env,
2690 env->gpr[11], /* return value */
2691 env->gpr[3], /* r3 - r7 are params */
2692 env->gpr[4],
2693 env->gpr[5],
2694 env->gpr[6],
2695 env->gpr[7],
2696 env->gpr[8], 0, 0);
2697 break;
2698 case EXCP_FPE:
2699 qemu_log_mask(CPU_LOG_INT, "\nFloating point error\n");
2700 break;
2701 case EXCP_TRAP:
2702 qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
2703 gdbsig = TARGET_SIGTRAP;
2704 break;
2705 case EXCP_NR:
2706 qemu_log_mask(CPU_LOG_INT, "\nNR\n");
2707 break;
2708 default:
2709 EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
2710 trapnr);
2711 gdbsig = TARGET_SIGILL;
2712 break;
2714 if (gdbsig) {
2715 gdb_handlesig(cs, gdbsig);
2716 if (gdbsig != TARGET_SIGTRAP) {
2717 exit(EXIT_FAILURE);
2721 process_pending_signals(env);
2725 #endif /* TARGET_OPENRISC */
2727 #ifdef TARGET_SH4
2728 void cpu_loop(CPUSH4State *env)
2730 CPUState *cs = CPU(sh_env_get_cpu(env));
2731 int trapnr, ret;
2732 target_siginfo_t info;
2734 while (1) {
2735 cpu_exec_start(cs);
2736 trapnr = cpu_sh4_exec(cs);
2737 cpu_exec_end(cs);
2739 switch (trapnr) {
2740 case 0x160:
2741 env->pc += 2;
2742 ret = do_syscall(env,
2743 env->gregs[3],
2744 env->gregs[4],
2745 env->gregs[5],
2746 env->gregs[6],
2747 env->gregs[7],
2748 env->gregs[0],
2749 env->gregs[1],
2750 0, 0);
2751 env->gregs[0] = ret;
2752 break;
2753 case EXCP_INTERRUPT:
2754 /* just indicate that signals should be handled asap */
2755 break;
2756 case EXCP_DEBUG:
2758 int sig;
2760 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2761 if (sig)
2763 info.si_signo = sig;
2764 info.si_errno = 0;
2765 info.si_code = TARGET_TRAP_BRKPT;
2766 queue_signal(env, info.si_signo, &info);
2769 break;
2770 case 0xa0:
2771 case 0xc0:
2772 info.si_signo = TARGET_SIGSEGV;
2773 info.si_errno = 0;
2774 info.si_code = TARGET_SEGV_MAPERR;
2775 info._sifields._sigfault._addr = env->tea;
2776 queue_signal(env, info.si_signo, &info);
2777 break;
2779 default:
2780 printf ("Unhandled trap: 0x%x\n", trapnr);
2781 cpu_dump_state(cs, stderr, fprintf, 0);
2782 exit(EXIT_FAILURE);
2784 process_pending_signals (env);
2787 #endif
2789 #ifdef TARGET_CRIS
2790 void cpu_loop(CPUCRISState *env)
2792 CPUState *cs = CPU(cris_env_get_cpu(env));
2793 int trapnr, ret;
2794 target_siginfo_t info;
2796 while (1) {
2797 cpu_exec_start(cs);
2798 trapnr = cpu_cris_exec(cs);
2799 cpu_exec_end(cs);
2800 switch (trapnr) {
2801 case 0xaa:
2803 info.si_signo = TARGET_SIGSEGV;
2804 info.si_errno = 0;
2805 /* XXX: check env->error_code */
2806 info.si_code = TARGET_SEGV_MAPERR;
2807 info._sifields._sigfault._addr = env->pregs[PR_EDA];
2808 queue_signal(env, info.si_signo, &info);
2810 break;
2811 case EXCP_INTERRUPT:
2812 /* just indicate that signals should be handled asap */
2813 break;
2814 case EXCP_BREAK:
2815 ret = do_syscall(env,
2816 env->regs[9],
2817 env->regs[10],
2818 env->regs[11],
2819 env->regs[12],
2820 env->regs[13],
2821 env->pregs[7],
2822 env->pregs[11],
2823 0, 0);
2824 env->regs[10] = ret;
2825 break;
2826 case EXCP_DEBUG:
2828 int sig;
2830 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2831 if (sig)
2833 info.si_signo = sig;
2834 info.si_errno = 0;
2835 info.si_code = TARGET_TRAP_BRKPT;
2836 queue_signal(env, info.si_signo, &info);
2839 break;
2840 default:
2841 printf ("Unhandled trap: 0x%x\n", trapnr);
2842 cpu_dump_state(cs, stderr, fprintf, 0);
2843 exit(EXIT_FAILURE);
2845 process_pending_signals (env);
2848 #endif
2850 #ifdef TARGET_MICROBLAZE
2851 void cpu_loop(CPUMBState *env)
2853 CPUState *cs = CPU(mb_env_get_cpu(env));
2854 int trapnr, ret;
2855 target_siginfo_t info;
2857 while (1) {
2858 cpu_exec_start(cs);
2859 trapnr = cpu_mb_exec(cs);
2860 cpu_exec_end(cs);
2861 switch (trapnr) {
2862 case 0xaa:
2864 info.si_signo = TARGET_SIGSEGV;
2865 info.si_errno = 0;
2866 /* XXX: check env->error_code */
2867 info.si_code = TARGET_SEGV_MAPERR;
2868 info._sifields._sigfault._addr = 0;
2869 queue_signal(env, info.si_signo, &info);
2871 break;
2872 case EXCP_INTERRUPT:
2873 /* just indicate that signals should be handled asap */
2874 break;
2875 case EXCP_BREAK:
2876 /* Return address is 4 bytes after the call. */
2877 env->regs[14] += 4;
2878 env->sregs[SR_PC] = env->regs[14];
2879 ret = do_syscall(env,
2880 env->regs[12],
2881 env->regs[5],
2882 env->regs[6],
2883 env->regs[7],
2884 env->regs[8],
2885 env->regs[9],
2886 env->regs[10],
2887 0, 0);
2888 env->regs[3] = ret;
2889 break;
2890 case EXCP_HW_EXCP:
2891 env->regs[17] = env->sregs[SR_PC] + 4;
2892 if (env->iflags & D_FLAG) {
2893 env->sregs[SR_ESR] |= 1 << 12;
2894 env->sregs[SR_PC] -= 4;
2895 /* FIXME: if branch was immed, replay the imm as well. */
2898 env->iflags &= ~(IMM_FLAG | D_FLAG);
2900 switch (env->sregs[SR_ESR] & 31) {
2901 case ESR_EC_DIVZERO:
2902 info.si_signo = TARGET_SIGFPE;
2903 info.si_errno = 0;
2904 info.si_code = TARGET_FPE_FLTDIV;
2905 info._sifields._sigfault._addr = 0;
2906 queue_signal(env, info.si_signo, &info);
2907 break;
2908 case ESR_EC_FPU:
2909 info.si_signo = TARGET_SIGFPE;
2910 info.si_errno = 0;
2911 if (env->sregs[SR_FSR] & FSR_IO) {
2912 info.si_code = TARGET_FPE_FLTINV;
2914 if (env->sregs[SR_FSR] & FSR_DZ) {
2915 info.si_code = TARGET_FPE_FLTDIV;
2917 info._sifields._sigfault._addr = 0;
2918 queue_signal(env, info.si_signo, &info);
2919 break;
2920 default:
2921 printf ("Unhandled hw-exception: 0x%x\n",
2922 env->sregs[SR_ESR] & ESR_EC_MASK);
2923 cpu_dump_state(cs, stderr, fprintf, 0);
2924 exit(EXIT_FAILURE);
2925 break;
2927 break;
2928 case EXCP_DEBUG:
2930 int sig;
2932 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2933 if (sig)
2935 info.si_signo = sig;
2936 info.si_errno = 0;
2937 info.si_code = TARGET_TRAP_BRKPT;
2938 queue_signal(env, info.si_signo, &info);
2941 break;
2942 default:
2943 printf ("Unhandled trap: 0x%x\n", trapnr);
2944 cpu_dump_state(cs, stderr, fprintf, 0);
2945 exit(EXIT_FAILURE);
2947 process_pending_signals (env);
2950 #endif
2952 #ifdef TARGET_M68K
2954 void cpu_loop(CPUM68KState *env)
2956 CPUState *cs = CPU(m68k_env_get_cpu(env));
2957 int trapnr;
2958 unsigned int n;
2959 target_siginfo_t info;
2960 TaskState *ts = cs->opaque;
2962 for(;;) {
2963 cpu_exec_start(cs);
2964 trapnr = cpu_m68k_exec(cs);
2965 cpu_exec_end(cs);
2966 switch(trapnr) {
2967 case EXCP_ILLEGAL:
2969 if (ts->sim_syscalls) {
2970 uint16_t nr;
2971 get_user_u16(nr, env->pc + 2);
2972 env->pc += 4;
2973 do_m68k_simcall(env, nr);
2974 } else {
2975 goto do_sigill;
2978 break;
2979 case EXCP_HALT_INSN:
2980 /* Semihosing syscall. */
2981 env->pc += 4;
2982 do_m68k_semihosting(env, env->dregs[0]);
2983 break;
2984 case EXCP_LINEA:
2985 case EXCP_LINEF:
2986 case EXCP_UNSUPPORTED:
2987 do_sigill:
2988 info.si_signo = TARGET_SIGILL;
2989 info.si_errno = 0;
2990 info.si_code = TARGET_ILL_ILLOPN;
2991 info._sifields._sigfault._addr = env->pc;
2992 queue_signal(env, info.si_signo, &info);
2993 break;
2994 case EXCP_TRAP0:
2996 ts->sim_syscalls = 0;
2997 n = env->dregs[0];
2998 env->pc += 2;
2999 env->dregs[0] = do_syscall(env,
3001 env->dregs[1],
3002 env->dregs[2],
3003 env->dregs[3],
3004 env->dregs[4],
3005 env->dregs[5],
3006 env->aregs[0],
3007 0, 0);
3009 break;
3010 case EXCP_INTERRUPT:
3011 /* just indicate that signals should be handled asap */
3012 break;
3013 case EXCP_ACCESS:
3015 info.si_signo = TARGET_SIGSEGV;
3016 info.si_errno = 0;
3017 /* XXX: check env->error_code */
3018 info.si_code = TARGET_SEGV_MAPERR;
3019 info._sifields._sigfault._addr = env->mmu.ar;
3020 queue_signal(env, info.si_signo, &info);
3022 break;
3023 case EXCP_DEBUG:
3025 int sig;
3027 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
3028 if (sig)
3030 info.si_signo = sig;
3031 info.si_errno = 0;
3032 info.si_code = TARGET_TRAP_BRKPT;
3033 queue_signal(env, info.si_signo, &info);
3036 break;
3037 default:
3038 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
3039 abort();
3041 process_pending_signals(env);
3044 #endif /* TARGET_M68K */
3046 #ifdef TARGET_ALPHA
3047 static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
3049 target_ulong addr, val, tmp;
3050 target_siginfo_t info;
3051 int ret = 0;
3053 addr = env->lock_addr;
3054 tmp = env->lock_st_addr;
3055 env->lock_addr = -1;
3056 env->lock_st_addr = 0;
3058 start_exclusive();
3059 mmap_lock();
3061 if (addr == tmp) {
3062 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
3063 goto do_sigsegv;
3066 if (val == env->lock_value) {
3067 tmp = env->ir[reg];
3068 if (quad ? put_user_u64(tmp, addr) : put_user_u32(tmp, addr)) {
3069 goto do_sigsegv;
3071 ret = 1;
3074 env->ir[reg] = ret;
3075 env->pc += 4;
3077 mmap_unlock();
3078 end_exclusive();
3079 return;
3081 do_sigsegv:
3082 mmap_unlock();
3083 end_exclusive();
3085 info.si_signo = TARGET_SIGSEGV;
3086 info.si_errno = 0;
3087 info.si_code = TARGET_SEGV_MAPERR;
3088 info._sifields._sigfault._addr = addr;
3089 queue_signal(env, TARGET_SIGSEGV, &info);
3092 void cpu_loop(CPUAlphaState *env)
3094 CPUState *cs = CPU(alpha_env_get_cpu(env));
3095 int trapnr;
3096 target_siginfo_t info;
3097 abi_long sysret;
3099 while (1) {
3100 cpu_exec_start(cs);
3101 trapnr = cpu_alpha_exec(cs);
3102 cpu_exec_end(cs);
3104 /* All of the traps imply a transition through PALcode, which
3105 implies an REI instruction has been executed. Which means
3106 that the intr_flag should be cleared. */
3107 env->intr_flag = 0;
3109 switch (trapnr) {
3110 case EXCP_RESET:
3111 fprintf(stderr, "Reset requested. Exit\n");
3112 exit(EXIT_FAILURE);
3113 break;
3114 case EXCP_MCHK:
3115 fprintf(stderr, "Machine check exception. Exit\n");
3116 exit(EXIT_FAILURE);
3117 break;
3118 case EXCP_SMP_INTERRUPT:
3119 case EXCP_CLK_INTERRUPT:
3120 case EXCP_DEV_INTERRUPT:
3121 fprintf(stderr, "External interrupt. Exit\n");
3122 exit(EXIT_FAILURE);
3123 break;
3124 case EXCP_MMFAULT:
3125 env->lock_addr = -1;
3126 info.si_signo = TARGET_SIGSEGV;
3127 info.si_errno = 0;
3128 info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
3129 ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
3130 info._sifields._sigfault._addr = env->trap_arg0;
3131 queue_signal(env, info.si_signo, &info);
3132 break;
3133 case EXCP_UNALIGN:
3134 env->lock_addr = -1;
3135 info.si_signo = TARGET_SIGBUS;
3136 info.si_errno = 0;
3137 info.si_code = TARGET_BUS_ADRALN;
3138 info._sifields._sigfault._addr = env->trap_arg0;
3139 queue_signal(env, info.si_signo, &info);
3140 break;
3141 case EXCP_OPCDEC:
3142 do_sigill:
3143 env->lock_addr = -1;
3144 info.si_signo = TARGET_SIGILL;
3145 info.si_errno = 0;
3146 info.si_code = TARGET_ILL_ILLOPC;
3147 info._sifields._sigfault._addr = env->pc;
3148 queue_signal(env, info.si_signo, &info);
3149 break;
3150 case EXCP_ARITH:
3151 env->lock_addr = -1;
3152 info.si_signo = TARGET_SIGFPE;
3153 info.si_errno = 0;
3154 info.si_code = TARGET_FPE_FLTINV;
3155 info._sifields._sigfault._addr = env->pc;
3156 queue_signal(env, info.si_signo, &info);
3157 break;
3158 case EXCP_FEN:
3159 /* No-op. Linux simply re-enables the FPU. */
3160 break;
3161 case EXCP_CALL_PAL:
3162 env->lock_addr = -1;
3163 switch (env->error_code) {
3164 case 0x80:
3165 /* BPT */
3166 info.si_signo = TARGET_SIGTRAP;
3167 info.si_errno = 0;
3168 info.si_code = TARGET_TRAP_BRKPT;
3169 info._sifields._sigfault._addr = env->pc;
3170 queue_signal(env, info.si_signo, &info);
3171 break;
3172 case 0x81:
3173 /* BUGCHK */
3174 info.si_signo = TARGET_SIGTRAP;
3175 info.si_errno = 0;
3176 info.si_code = 0;
3177 info._sifields._sigfault._addr = env->pc;
3178 queue_signal(env, info.si_signo, &info);
3179 break;
3180 case 0x83:
3181 /* CALLSYS */
3182 trapnr = env->ir[IR_V0];
3183 sysret = do_syscall(env, trapnr,
3184 env->ir[IR_A0], env->ir[IR_A1],
3185 env->ir[IR_A2], env->ir[IR_A3],
3186 env->ir[IR_A4], env->ir[IR_A5],
3187 0, 0);
3188 if (trapnr == TARGET_NR_sigreturn
3189 || trapnr == TARGET_NR_rt_sigreturn) {
3190 break;
3192 /* Syscall writes 0 to V0 to bypass error check, similar
3193 to how this is handled internal to Linux kernel.
3194 (Ab)use trapnr temporarily as boolean indicating error. */
3195 trapnr = (env->ir[IR_V0] != 0 && sysret < 0);
3196 env->ir[IR_V0] = (trapnr ? -sysret : sysret);
3197 env->ir[IR_A3] = trapnr;
3198 break;
3199 case 0x86:
3200 /* IMB */
3201 /* ??? We can probably elide the code using page_unprotect
3202 that is checking for self-modifying code. Instead we
3203 could simply call tb_flush here. Until we work out the
3204 changes required to turn off the extra write protection,
3205 this can be a no-op. */
3206 break;
3207 case 0x9E:
3208 /* RDUNIQUE */
3209 /* Handled in the translator for usermode. */
3210 abort();
3211 case 0x9F:
3212 /* WRUNIQUE */
3213 /* Handled in the translator for usermode. */
3214 abort();
3215 case 0xAA:
3216 /* GENTRAP */
3217 info.si_signo = TARGET_SIGFPE;
3218 switch (env->ir[IR_A0]) {
3219 case TARGET_GEN_INTOVF:
3220 info.si_code = TARGET_FPE_INTOVF;
3221 break;
3222 case TARGET_GEN_INTDIV:
3223 info.si_code = TARGET_FPE_INTDIV;
3224 break;
3225 case TARGET_GEN_FLTOVF:
3226 info.si_code = TARGET_FPE_FLTOVF;
3227 break;
3228 case TARGET_GEN_FLTUND:
3229 info.si_code = TARGET_FPE_FLTUND;
3230 break;
3231 case TARGET_GEN_FLTINV:
3232 info.si_code = TARGET_FPE_FLTINV;
3233 break;
3234 case TARGET_GEN_FLTINE:
3235 info.si_code = TARGET_FPE_FLTRES;
3236 break;
3237 case TARGET_GEN_ROPRAND:
3238 info.si_code = 0;
3239 break;
3240 default:
3241 info.si_signo = TARGET_SIGTRAP;
3242 info.si_code = 0;
3243 break;
3245 info.si_errno = 0;
3246 info._sifields._sigfault._addr = env->pc;
3247 queue_signal(env, info.si_signo, &info);
3248 break;
3249 default:
3250 goto do_sigill;
3252 break;
3253 case EXCP_DEBUG:
3254 info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
3255 if (info.si_signo) {
3256 env->lock_addr = -1;
3257 info.si_errno = 0;
3258 info.si_code = TARGET_TRAP_BRKPT;
3259 queue_signal(env, info.si_signo, &info);
3261 break;
3262 case EXCP_STL_C:
3263 case EXCP_STQ_C:
3264 do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C);
3265 break;
3266 case EXCP_INTERRUPT:
3267 /* Just indicate that signals should be handled asap. */
3268 break;
3269 default:
3270 printf ("Unhandled trap: 0x%x\n", trapnr);
3271 cpu_dump_state(cs, stderr, fprintf, 0);
3272 exit(EXIT_FAILURE);
3274 process_pending_signals (env);
3277 #endif /* TARGET_ALPHA */
3279 #ifdef TARGET_S390X
3280 void cpu_loop(CPUS390XState *env)
3282 CPUState *cs = CPU(s390_env_get_cpu(env));
3283 int trapnr, n, sig;
3284 target_siginfo_t info;
3285 target_ulong addr;
3287 while (1) {
3288 cpu_exec_start(cs);
3289 trapnr = cpu_s390x_exec(cs);
3290 cpu_exec_end(cs);
3291 switch (trapnr) {
3292 case EXCP_INTERRUPT:
3293 /* Just indicate that signals should be handled asap. */
3294 break;
3296 case EXCP_SVC:
3297 n = env->int_svc_code;
3298 if (!n) {
3299 /* syscalls > 255 */
3300 n = env->regs[1];
3302 env->psw.addr += env->int_svc_ilen;
3303 env->regs[2] = do_syscall(env, n, env->regs[2], env->regs[3],
3304 env->regs[4], env->regs[5],
3305 env->regs[6], env->regs[7], 0, 0);
3306 break;
3308 case EXCP_DEBUG:
3309 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
3310 if (sig) {
3311 n = TARGET_TRAP_BRKPT;
3312 goto do_signal_pc;
3314 break;
3315 case EXCP_PGM:
3316 n = env->int_pgm_code;
3317 switch (n) {
3318 case PGM_OPERATION:
3319 case PGM_PRIVILEGED:
3320 sig = TARGET_SIGILL;
3321 n = TARGET_ILL_ILLOPC;
3322 goto do_signal_pc;
3323 case PGM_PROTECTION:
3324 case PGM_ADDRESSING:
3325 sig = TARGET_SIGSEGV;
3326 /* XXX: check env->error_code */
3327 n = TARGET_SEGV_MAPERR;
3328 addr = env->__excp_addr;
3329 goto do_signal;
3330 case PGM_EXECUTE:
3331 case PGM_SPECIFICATION:
3332 case PGM_SPECIAL_OP:
3333 case PGM_OPERAND:
3334 do_sigill_opn:
3335 sig = TARGET_SIGILL;
3336 n = TARGET_ILL_ILLOPN;
3337 goto do_signal_pc;
3339 case PGM_FIXPT_OVERFLOW:
3340 sig = TARGET_SIGFPE;
3341 n = TARGET_FPE_INTOVF;
3342 goto do_signal_pc;
3343 case PGM_FIXPT_DIVIDE:
3344 sig = TARGET_SIGFPE;
3345 n = TARGET_FPE_INTDIV;
3346 goto do_signal_pc;
3348 case PGM_DATA:
3349 n = (env->fpc >> 8) & 0xff;
3350 if (n == 0xff) {
3351 /* compare-and-trap */
3352 goto do_sigill_opn;
3353 } else {
3354 /* An IEEE exception, simulated or otherwise. */
3355 if (n & 0x80) {
3356 n = TARGET_FPE_FLTINV;
3357 } else if (n & 0x40) {
3358 n = TARGET_FPE_FLTDIV;
3359 } else if (n & 0x20) {
3360 n = TARGET_FPE_FLTOVF;
3361 } else if (n & 0x10) {
3362 n = TARGET_FPE_FLTUND;
3363 } else if (n & 0x08) {
3364 n = TARGET_FPE_FLTRES;
3365 } else {
3366 /* ??? Quantum exception; BFP, DFP error. */
3367 goto do_sigill_opn;
3369 sig = TARGET_SIGFPE;
3370 goto do_signal_pc;
3373 default:
3374 fprintf(stderr, "Unhandled program exception: %#x\n", n);
3375 cpu_dump_state(cs, stderr, fprintf, 0);
3376 exit(EXIT_FAILURE);
3378 break;
3380 do_signal_pc:
3381 addr = env->psw.addr;
3382 do_signal:
3383 info.si_signo = sig;
3384 info.si_errno = 0;
3385 info.si_code = n;
3386 info._sifields._sigfault._addr = addr;
3387 queue_signal(env, info.si_signo, &info);
3388 break;
3390 default:
3391 fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
3392 cpu_dump_state(cs, stderr, fprintf, 0);
3393 exit(EXIT_FAILURE);
3395 process_pending_signals (env);
3399 #endif /* TARGET_S390X */
3401 #ifdef TARGET_TILEGX
3403 static void gen_sigill_reg(CPUTLGState *env)
3405 target_siginfo_t info;
3407 info.si_signo = TARGET_SIGILL;
3408 info.si_errno = 0;
3409 info.si_code = TARGET_ILL_PRVREG;
3410 info._sifields._sigfault._addr = env->pc;
3411 queue_signal(env, info.si_signo, &info);
3414 static void do_signal(CPUTLGState *env, int signo, int sigcode)
3416 target_siginfo_t info;
3418 info.si_signo = signo;
3419 info.si_errno = 0;
3420 info._sifields._sigfault._addr = env->pc;
3422 if (signo == TARGET_SIGSEGV) {
3423 /* The passed in sigcode is a dummy; check for a page mapping
3424 and pass either MAPERR or ACCERR. */
3425 target_ulong addr = env->excaddr;
3426 info._sifields._sigfault._addr = addr;
3427 if (page_check_range(addr, 1, PAGE_VALID) < 0) {
3428 sigcode = TARGET_SEGV_MAPERR;
3429 } else {
3430 sigcode = TARGET_SEGV_ACCERR;
3433 info.si_code = sigcode;
3435 queue_signal(env, info.si_signo, &info);
3438 static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
3440 env->excaddr = addr;
3441 do_signal(env, TARGET_SIGSEGV, 0);
3444 static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val)
3446 if (unlikely(reg >= TILEGX_R_COUNT)) {
3447 switch (reg) {
3448 case TILEGX_R_SN:
3449 case TILEGX_R_ZERO:
3450 return;
3451 case TILEGX_R_IDN0:
3452 case TILEGX_R_IDN1:
3453 case TILEGX_R_UDN0:
3454 case TILEGX_R_UDN1:
3455 case TILEGX_R_UDN2:
3456 case TILEGX_R_UDN3:
3457 gen_sigill_reg(env);
3458 return;
3459 default:
3460 g_assert_not_reached();
3463 env->regs[reg] = val;
3467 * Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
3468 * memory at the address held in the first source register. If the values are
3469 * not equal, then no memory operation is performed. If the values are equal,
3470 * the 8-byte quantity from the second source register is written into memory
3471 * at the address held in the first source register. In either case, the result
3472 * of the instruction is the value read from memory. The compare and write to
3473 * memory are atomic and thus can be used for synchronization purposes. This
3474 * instruction only operates for addresses aligned to a 8-byte boundary.
3475 * Unaligned memory access causes an Unaligned Data Reference interrupt.
3477 * Functional Description (64-bit)
3478 * uint64_t memVal = memoryReadDoubleWord (rf[SrcA]);
3479 * rf[Dest] = memVal;
3480 * if (memVal == SPR[CmpValueSPR])
3481 * memoryWriteDoubleWord (rf[SrcA], rf[SrcB]);
3483 * Functional Description (32-bit)
3484 * uint64_t memVal = signExtend32 (memoryReadWord (rf[SrcA]));
3485 * rf[Dest] = memVal;
3486 * if (memVal == signExtend32 (SPR[CmpValueSPR]))
3487 * memoryWriteWord (rf[SrcA], rf[SrcB]);
3490 * This function also processes exch and exch4 which need not process SPR.
3492 static void do_exch(CPUTLGState *env, bool quad, bool cmp)
3494 target_ulong addr;
3495 target_long val, sprval;
3497 start_exclusive();
3499 addr = env->atomic_srca;
3500 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
3501 goto sigsegv_maperr;
3504 if (cmp) {
3505 if (quad) {
3506 sprval = env->spregs[TILEGX_SPR_CMPEXCH];
3507 } else {
3508 sprval = sextract64(env->spregs[TILEGX_SPR_CMPEXCH], 0, 32);
3512 if (!cmp || val == sprval) {
3513 target_long valb = env->atomic_srcb;
3514 if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
3515 goto sigsegv_maperr;
3519 set_regval(env, env->atomic_dstr, val);
3520 end_exclusive();
3521 return;
3523 sigsegv_maperr:
3524 end_exclusive();
3525 gen_sigsegv_maperr(env, addr);
3528 static void do_fetch(CPUTLGState *env, int trapnr, bool quad)
3530 int8_t write = 1;
3531 target_ulong addr;
3532 target_long val, valb;
3534 start_exclusive();
3536 addr = env->atomic_srca;
3537 valb = env->atomic_srcb;
3538 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
3539 goto sigsegv_maperr;
3542 switch (trapnr) {
3543 case TILEGX_EXCP_OPCODE_FETCHADD:
3544 case TILEGX_EXCP_OPCODE_FETCHADD4:
3545 valb += val;
3546 break;
3547 case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
3548 valb += val;
3549 if (valb < 0) {
3550 write = 0;
3552 break;
3553 case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
3554 valb += val;
3555 if ((int32_t)valb < 0) {
3556 write = 0;
3558 break;
3559 case TILEGX_EXCP_OPCODE_FETCHAND:
3560 case TILEGX_EXCP_OPCODE_FETCHAND4:
3561 valb &= val;
3562 break;
3563 case TILEGX_EXCP_OPCODE_FETCHOR:
3564 case TILEGX_EXCP_OPCODE_FETCHOR4:
3565 valb |= val;
3566 break;
3567 default:
3568 g_assert_not_reached();
3571 if (write) {
3572 if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
3573 goto sigsegv_maperr;
3577 set_regval(env, env->atomic_dstr, val);
3578 end_exclusive();
3579 return;
3581 sigsegv_maperr:
3582 end_exclusive();
3583 gen_sigsegv_maperr(env, addr);
3586 void cpu_loop(CPUTLGState *env)
3588 CPUState *cs = CPU(tilegx_env_get_cpu(env));
3589 int trapnr;
3591 while (1) {
3592 cpu_exec_start(cs);
3593 trapnr = cpu_tilegx_exec(cs);
3594 cpu_exec_end(cs);
3595 switch (trapnr) {
3596 case TILEGX_EXCP_SYSCALL:
3597 env->regs[TILEGX_R_RE] = do_syscall(env, env->regs[TILEGX_R_NR],
3598 env->regs[0], env->regs[1],
3599 env->regs[2], env->regs[3],
3600 env->regs[4], env->regs[5],
3601 env->regs[6], env->regs[7]);
3602 env->regs[TILEGX_R_ERR] = TILEGX_IS_ERRNO(env->regs[TILEGX_R_RE])
3603 ? - env->regs[TILEGX_R_RE]
3604 : 0;
3605 break;
3606 case TILEGX_EXCP_OPCODE_EXCH:
3607 do_exch(env, true, false);
3608 break;
3609 case TILEGX_EXCP_OPCODE_EXCH4:
3610 do_exch(env, false, false);
3611 break;
3612 case TILEGX_EXCP_OPCODE_CMPEXCH:
3613 do_exch(env, true, true);
3614 break;
3615 case TILEGX_EXCP_OPCODE_CMPEXCH4:
3616 do_exch(env, false, true);
3617 break;
3618 case TILEGX_EXCP_OPCODE_FETCHADD:
3619 case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
3620 case TILEGX_EXCP_OPCODE_FETCHAND:
3621 case TILEGX_EXCP_OPCODE_FETCHOR:
3622 do_fetch(env, trapnr, true);
3623 break;
3624 case TILEGX_EXCP_OPCODE_FETCHADD4:
3625 case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
3626 case TILEGX_EXCP_OPCODE_FETCHAND4:
3627 case TILEGX_EXCP_OPCODE_FETCHOR4:
3628 do_fetch(env, trapnr, false);
3629 break;
3630 case TILEGX_EXCP_SIGNAL:
3631 do_signal(env, env->signo, env->sigcode);
3632 break;
3633 case TILEGX_EXCP_REG_IDN_ACCESS:
3634 case TILEGX_EXCP_REG_UDN_ACCESS:
3635 gen_sigill_reg(env);
3636 break;
3637 default:
3638 fprintf(stderr, "trapnr is %d[0x%x].\n", trapnr, trapnr);
3639 g_assert_not_reached();
3641 process_pending_signals(env);
3645 #endif
3647 THREAD CPUState *thread_cpu;
3649 void task_settid(TaskState *ts)
3651 if (ts->ts_tid == 0) {
3652 ts->ts_tid = (pid_t)syscall(SYS_gettid);
3656 void stop_all_tasks(void)
3659 * We trust that when using NPTL, start_exclusive()
3660 * handles thread stopping correctly.
3662 start_exclusive();
3665 /* Assumes contents are already zeroed. */
3666 void init_task_state(TaskState *ts)
3668 int i;
3670 ts->used = 1;
3671 ts->first_free = ts->sigqueue_table;
3672 for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
3673 ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
3675 ts->sigqueue_table[i].next = NULL;
3678 CPUArchState *cpu_copy(CPUArchState *env)
3680 CPUState *cpu = ENV_GET_CPU(env);
3681 CPUState *new_cpu = cpu_init(cpu_model);
3682 CPUArchState *new_env = new_cpu->env_ptr;
3683 CPUBreakpoint *bp;
3684 CPUWatchpoint *wp;
3686 /* Reset non arch specific state */
3687 cpu_reset(new_cpu);
3689 memcpy(new_env, env, sizeof(CPUArchState));
3691 /* Clone all break/watchpoints.
3692 Note: Once we support ptrace with hw-debug register access, make sure
3693 BP_CPU break/watchpoints are handled correctly on clone. */
3694 QTAILQ_INIT(&new_cpu->breakpoints);
3695 QTAILQ_INIT(&new_cpu->watchpoints);
3696 QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
3697 cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
3699 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
3700 cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
3703 return new_env;
3706 static void handle_arg_help(const char *arg)
3708 usage(EXIT_SUCCESS);
3711 static void handle_arg_log(const char *arg)
3713 int mask;
3715 mask = qemu_str_to_log_mask(arg);
3716 if (!mask) {
3717 qemu_print_log_usage(stdout);
3718 exit(EXIT_FAILURE);
3720 qemu_set_log(mask);
3723 static void handle_arg_log_filename(const char *arg)
3725 qemu_set_log_filename(arg);
3728 static void handle_arg_set_env(const char *arg)
3730 char *r, *p, *token;
3731 r = p = strdup(arg);
3732 while ((token = strsep(&p, ",")) != NULL) {
3733 if (envlist_setenv(envlist, token) != 0) {
3734 usage(EXIT_FAILURE);
3737 free(r);
3740 static void handle_arg_unset_env(const char *arg)
3742 char *r, *p, *token;
3743 r = p = strdup(arg);
3744 while ((token = strsep(&p, ",")) != NULL) {
3745 if (envlist_unsetenv(envlist, token) != 0) {
3746 usage(EXIT_FAILURE);
3749 free(r);
3752 static void handle_arg_argv0(const char *arg)
3754 argv0 = strdup(arg);
3757 static void handle_arg_stack_size(const char *arg)
3759 char *p;
3760 guest_stack_size = strtoul(arg, &p, 0);
3761 if (guest_stack_size == 0) {
3762 usage(EXIT_FAILURE);
3765 if (*p == 'M') {
3766 guest_stack_size *= 1024 * 1024;
3767 } else if (*p == 'k' || *p == 'K') {
3768 guest_stack_size *= 1024;
3772 static void handle_arg_ld_prefix(const char *arg)
3774 interp_prefix = strdup(arg);
3777 static void handle_arg_pagesize(const char *arg)
3779 qemu_host_page_size = atoi(arg);
3780 if (qemu_host_page_size == 0 ||
3781 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
3782 fprintf(stderr, "page size must be a power of two\n");
3783 exit(EXIT_FAILURE);
3787 static void handle_arg_randseed(const char *arg)
3789 unsigned long long seed;
3791 if (parse_uint_full(arg, &seed, 0) != 0 || seed > UINT_MAX) {
3792 fprintf(stderr, "Invalid seed number: %s\n", arg);
3793 exit(EXIT_FAILURE);
3795 srand(seed);
3798 static void handle_arg_gdb(const char *arg)
3800 gdbstub_port = atoi(arg);
3803 static void handle_arg_uname(const char *arg)
3805 qemu_uname_release = strdup(arg);
3808 static void handle_arg_cpu(const char *arg)
3810 cpu_model = strdup(arg);
3811 if (cpu_model == NULL || is_help_option(cpu_model)) {
3812 /* XXX: implement xxx_cpu_list for targets that still miss it */
3813 #if defined(cpu_list)
3814 cpu_list(stdout, &fprintf);
3815 #endif
3816 exit(EXIT_FAILURE);
3820 static void handle_arg_guest_base(const char *arg)
3822 guest_base = strtol(arg, NULL, 0);
3823 have_guest_base = 1;
3826 static void handle_arg_reserved_va(const char *arg)
3828 char *p;
3829 int shift = 0;
3830 reserved_va = strtoul(arg, &p, 0);
3831 switch (*p) {
3832 case 'k':
3833 case 'K':
3834 shift = 10;
3835 break;
3836 case 'M':
3837 shift = 20;
3838 break;
3839 case 'G':
3840 shift = 30;
3841 break;
3843 if (shift) {
3844 unsigned long unshifted = reserved_va;
3845 p++;
3846 reserved_va <<= shift;
3847 if (((reserved_va >> shift) != unshifted)
3848 #if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
3849 || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
3850 #endif
3852 fprintf(stderr, "Reserved virtual address too big\n");
3853 exit(EXIT_FAILURE);
3856 if (*p) {
3857 fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
3858 exit(EXIT_FAILURE);
3862 static void handle_arg_singlestep(const char *arg)
3864 singlestep = 1;
3867 static void handle_arg_strace(const char *arg)
3869 do_strace = 1;
3872 static void handle_arg_version(const char *arg)
3874 printf("qemu-" TARGET_NAME " version " QEMU_VERSION QEMU_PKGVERSION
3875 ", Copyright (c) 2003-2008 Fabrice Bellard\n");
3876 exit(EXIT_SUCCESS);
3879 struct qemu_argument {
3880 const char *argv;
3881 const char *env;
3882 bool has_arg;
3883 void (*handle_opt)(const char *arg);
3884 const char *example;
3885 const char *help;
3888 static const struct qemu_argument arg_table[] = {
3889 {"h", "", false, handle_arg_help,
3890 "", "print this help"},
3891 {"help", "", false, handle_arg_help,
3892 "", ""},
3893 {"g", "QEMU_GDB", true, handle_arg_gdb,
3894 "port", "wait gdb connection to 'port'"},
3895 {"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix,
3896 "path", "set the elf interpreter prefix to 'path'"},
3897 {"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
3898 "size", "set the stack size to 'size' bytes"},
3899 {"cpu", "QEMU_CPU", true, handle_arg_cpu,
3900 "model", "select CPU (-cpu help for list)"},
3901 {"E", "QEMU_SET_ENV", true, handle_arg_set_env,
3902 "var=value", "sets targets environment variable (see below)"},
3903 {"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
3904 "var", "unsets targets environment variable (see below)"},
3905 {"0", "QEMU_ARGV0", true, handle_arg_argv0,
3906 "argv0", "forces target process argv[0] to be 'argv0'"},
3907 {"r", "QEMU_UNAME", true, handle_arg_uname,
3908 "uname", "set qemu uname release string to 'uname'"},
3909 {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base,
3910 "address", "set guest_base address to 'address'"},
3911 {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
3912 "size", "reserve 'size' bytes for guest virtual address space"},
3913 {"d", "QEMU_LOG", true, handle_arg_log,
3914 "item[,...]", "enable logging of specified items "
3915 "(use '-d help' for a list of items)"},
3916 {"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
3917 "logfile", "write logs to 'logfile' (default stderr)"},
3918 {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
3919 "pagesize", "set the host page size to 'pagesize'"},
3920 {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
3921 "", "run in singlestep mode"},
3922 {"strace", "QEMU_STRACE", false, handle_arg_strace,
3923 "", "log system calls"},
3924 {"seed", "QEMU_RAND_SEED", true, handle_arg_randseed,
3925 "", "Seed for pseudo-random number generator"},
3926 {"version", "QEMU_VERSION", false, handle_arg_version,
3927 "", "display version information and exit"},
3928 {NULL, NULL, false, NULL, NULL, NULL}
3931 static void usage(int exitcode)
3933 const struct qemu_argument *arginfo;
3934 int maxarglen;
3935 int maxenvlen;
3937 printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
3938 "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
3939 "\n"
3940 "Options and associated environment variables:\n"
3941 "\n");
3943 /* Calculate column widths. We must always have at least enough space
3944 * for the column header.
3946 maxarglen = strlen("Argument");
3947 maxenvlen = strlen("Env-variable");
3949 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3950 int arglen = strlen(arginfo->argv);
3951 if (arginfo->has_arg) {
3952 arglen += strlen(arginfo->example) + 1;
3954 if (strlen(arginfo->env) > maxenvlen) {
3955 maxenvlen = strlen(arginfo->env);
3957 if (arglen > maxarglen) {
3958 maxarglen = arglen;
3962 printf("%-*s %-*s Description\n", maxarglen+1, "Argument",
3963 maxenvlen, "Env-variable");
3965 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3966 if (arginfo->has_arg) {
3967 printf("-%s %-*s %-*s %s\n", arginfo->argv,
3968 (int)(maxarglen - strlen(arginfo->argv) - 1),
3969 arginfo->example, maxenvlen, arginfo->env, arginfo->help);
3970 } else {
3971 printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv,
3972 maxenvlen, arginfo->env,
3973 arginfo->help);
3977 printf("\n"
3978 "Defaults:\n"
3979 "QEMU_LD_PREFIX = %s\n"
3980 "QEMU_STACK_SIZE = %ld byte\n",
3981 interp_prefix,
3982 guest_stack_size);
3984 printf("\n"
3985 "You can use -E and -U options or the QEMU_SET_ENV and\n"
3986 "QEMU_UNSET_ENV environment variables to set and unset\n"
3987 "environment variables for the target process.\n"
3988 "It is possible to provide several variables by separating them\n"
3989 "by commas in getsubopt(3) style. Additionally it is possible to\n"
3990 "provide the -E and -U options multiple times.\n"
3991 "The following lines are equivalent:\n"
3992 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
3993 " -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
3994 " QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
3995 "Note that if you provide several changes to a single variable\n"
3996 "the last change will stay in effect.\n");
3998 exit(exitcode);
4001 static int parse_args(int argc, char **argv)
4003 const char *r;
4004 int optind;
4005 const struct qemu_argument *arginfo;
4007 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
4008 if (arginfo->env == NULL) {
4009 continue;
4012 r = getenv(arginfo->env);
4013 if (r != NULL) {
4014 arginfo->handle_opt(r);
4018 optind = 1;
4019 for (;;) {
4020 if (optind >= argc) {
4021 break;
4023 r = argv[optind];
4024 if (r[0] != '-') {
4025 break;
4027 optind++;
4028 r++;
4029 if (!strcmp(r, "-")) {
4030 break;
4032 /* Treat --foo the same as -foo. */
4033 if (r[0] == '-') {
4034 r++;
4037 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
4038 if (!strcmp(r, arginfo->argv)) {
4039 if (arginfo->has_arg) {
4040 if (optind >= argc) {
4041 (void) fprintf(stderr,
4042 "qemu: missing argument for option '%s'\n", r);
4043 exit(EXIT_FAILURE);
4045 arginfo->handle_opt(argv[optind]);
4046 optind++;
4047 } else {
4048 arginfo->handle_opt(NULL);
4050 break;
4054 /* no option matched the current argv */
4055 if (arginfo->handle_opt == NULL) {
4056 (void) fprintf(stderr, "qemu: unknown option '%s'\n", r);
4057 exit(EXIT_FAILURE);
4061 if (optind >= argc) {
4062 (void) fprintf(stderr, "qemu: no user program specified\n");
4063 exit(EXIT_FAILURE);
4066 filename = argv[optind];
4067 exec_path = argv[optind];
4069 return optind;
4072 int main(int argc, char **argv, char **envp)
4074 struct target_pt_regs regs1, *regs = &regs1;
4075 struct image_info info1, *info = &info1;
4076 struct linux_binprm bprm;
4077 TaskState *ts;
4078 CPUArchState *env;
4079 CPUState *cpu;
4080 int optind;
4081 char **target_environ, **wrk;
4082 char **target_argv;
4083 int target_argc;
4084 int i;
4085 int ret;
4086 int execfd;
4088 module_call_init(MODULE_INIT_QOM);
4090 if ((envlist = envlist_create()) == NULL) {
4091 (void) fprintf(stderr, "Unable to allocate envlist\n");
4092 exit(EXIT_FAILURE);
4095 /* add current environment into the list */
4096 for (wrk = environ; *wrk != NULL; wrk++) {
4097 (void) envlist_setenv(envlist, *wrk);
4100 /* Read the stack limit from the kernel. If it's "unlimited",
4101 then we can do little else besides use the default. */
4103 struct rlimit lim;
4104 if (getrlimit(RLIMIT_STACK, &lim) == 0
4105 && lim.rlim_cur != RLIM_INFINITY
4106 && lim.rlim_cur == (target_long)lim.rlim_cur) {
4107 guest_stack_size = lim.rlim_cur;
4111 cpu_model = NULL;
4112 #if defined(cpudef_setup)
4113 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
4114 #endif
4116 srand(time(NULL));
4118 optind = parse_args(argc, argv);
4120 /* Zero out regs */
4121 memset(regs, 0, sizeof(struct target_pt_regs));
4123 /* Zero out image_info */
4124 memset(info, 0, sizeof(struct image_info));
4126 memset(&bprm, 0, sizeof (bprm));
4128 /* Scan interp_prefix dir for replacement files. */
4129 init_paths(interp_prefix);
4131 init_qemu_uname_release();
4133 if (cpu_model == NULL) {
4134 #if defined(TARGET_I386)
4135 #ifdef TARGET_X86_64
4136 cpu_model = "qemu64";
4137 #else
4138 cpu_model = "qemu32";
4139 #endif
4140 #elif defined(TARGET_ARM)
4141 cpu_model = "any";
4142 #elif defined(TARGET_UNICORE32)
4143 cpu_model = "any";
4144 #elif defined(TARGET_M68K)
4145 cpu_model = "any";
4146 #elif defined(TARGET_SPARC)
4147 #ifdef TARGET_SPARC64
4148 cpu_model = "TI UltraSparc II";
4149 #else
4150 cpu_model = "Fujitsu MB86904";
4151 #endif
4152 #elif defined(TARGET_MIPS)
4153 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
4154 cpu_model = "5KEf";
4155 #else
4156 cpu_model = "24Kf";
4157 #endif
4158 #elif defined TARGET_OPENRISC
4159 cpu_model = "or1200";
4160 #elif defined(TARGET_PPC)
4161 # ifdef TARGET_PPC64
4162 cpu_model = "POWER7";
4163 # else
4164 cpu_model = "750";
4165 # endif
4166 #elif defined TARGET_SH4
4167 cpu_model = TYPE_SH7785_CPU;
4168 #else
4169 cpu_model = "any";
4170 #endif
4172 tcg_exec_init(0);
4173 /* NOTE: we need to init the CPU at this stage to get
4174 qemu_host_page_size */
4175 cpu = cpu_init(cpu_model);
4176 if (!cpu) {
4177 fprintf(stderr, "Unable to find CPU definition\n");
4178 exit(EXIT_FAILURE);
4180 env = cpu->env_ptr;
4181 cpu_reset(cpu);
4183 thread_cpu = cpu;
4185 if (getenv("QEMU_STRACE")) {
4186 do_strace = 1;
4189 if (getenv("QEMU_RAND_SEED")) {
4190 handle_arg_randseed(getenv("QEMU_RAND_SEED"));
4193 target_environ = envlist_to_environ(envlist, NULL);
4194 envlist_free(envlist);
4197 * Now that page sizes are configured in cpu_init() we can do
4198 * proper page alignment for guest_base.
4200 guest_base = HOST_PAGE_ALIGN(guest_base);
4202 if (reserved_va || have_guest_base) {
4203 guest_base = init_guest_space(guest_base, reserved_va, 0,
4204 have_guest_base);
4205 if (guest_base == (unsigned long)-1) {
4206 fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
4207 "space for use as guest address space (check your virtual "
4208 "memory ulimit setting or reserve less using -R option)\n",
4209 reserved_va);
4210 exit(EXIT_FAILURE);
4213 if (reserved_va) {
4214 mmap_next_start = reserved_va;
4219 * Read in mmap_min_addr kernel parameter. This value is used
4220 * When loading the ELF image to determine whether guest_base
4221 * is needed. It is also used in mmap_find_vma.
4224 FILE *fp;
4226 if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
4227 unsigned long tmp;
4228 if (fscanf(fp, "%lu", &tmp) == 1) {
4229 mmap_min_addr = tmp;
4230 qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
4232 fclose(fp);
4237 * Prepare copy of argv vector for target.
4239 target_argc = argc - optind;
4240 target_argv = calloc(target_argc + 1, sizeof (char *));
4241 if (target_argv == NULL) {
4242 (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
4243 exit(EXIT_FAILURE);
4247 * If argv0 is specified (using '-0' switch) we replace
4248 * argv[0] pointer with the given one.
4250 i = 0;
4251 if (argv0 != NULL) {
4252 target_argv[i++] = strdup(argv0);
4254 for (; i < target_argc; i++) {
4255 target_argv[i] = strdup(argv[optind + i]);
4257 target_argv[target_argc] = NULL;
4259 ts = g_new0(TaskState, 1);
4260 init_task_state(ts);
4261 /* build Task State */
4262 ts->info = info;
4263 ts->bprm = &bprm;
4264 cpu->opaque = ts;
4265 task_settid(ts);
4267 execfd = qemu_getauxval(AT_EXECFD);
4268 if (execfd == 0) {
4269 execfd = open(filename, O_RDONLY);
4270 if (execfd < 0) {
4271 printf("Error while loading %s: %s\n", filename, strerror(errno));
4272 _exit(EXIT_FAILURE);
4276 ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
4277 info, &bprm);
4278 if (ret != 0) {
4279 printf("Error while loading %s: %s\n", filename, strerror(-ret));
4280 _exit(EXIT_FAILURE);
4283 for (wrk = target_environ; *wrk; wrk++) {
4284 free(*wrk);
4287 free(target_environ);
4289 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
4290 qemu_log("guest_base 0x%lx\n", guest_base);
4291 log_page_dump();
4293 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
4294 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
4295 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
4296 info->start_code);
4297 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
4298 info->start_data);
4299 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
4300 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
4301 info->start_stack);
4302 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
4303 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
4306 target_set_brk(info->brk);
4307 syscall_init();
4308 signal_init();
4310 /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
4311 generating the prologue until now so that the prologue can take
4312 the real value of GUEST_BASE into account. */
4313 tcg_prologue_init(&tcg_ctx);
4315 #if defined(TARGET_I386)
4316 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
4317 env->hflags |= HF_PE_MASK | HF_CPL_MASK;
4318 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
4319 env->cr[4] |= CR4_OSFXSR_MASK;
4320 env->hflags |= HF_OSFXSR_MASK;
4322 #ifndef TARGET_ABI32
4323 /* enable 64 bit mode if possible */
4324 if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
4325 fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
4326 exit(EXIT_FAILURE);
4328 env->cr[4] |= CR4_PAE_MASK;
4329 env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
4330 env->hflags |= HF_LMA_MASK;
4331 #endif
4333 /* flags setup : we activate the IRQs by default as in user mode */
4334 env->eflags |= IF_MASK;
4336 /* linux register setup */
4337 #ifndef TARGET_ABI32
4338 env->regs[R_EAX] = regs->rax;
4339 env->regs[R_EBX] = regs->rbx;
4340 env->regs[R_ECX] = regs->rcx;
4341 env->regs[R_EDX] = regs->rdx;
4342 env->regs[R_ESI] = regs->rsi;
4343 env->regs[R_EDI] = regs->rdi;
4344 env->regs[R_EBP] = regs->rbp;
4345 env->regs[R_ESP] = regs->rsp;
4346 env->eip = regs->rip;
4347 #else
4348 env->regs[R_EAX] = regs->eax;
4349 env->regs[R_EBX] = regs->ebx;
4350 env->regs[R_ECX] = regs->ecx;
4351 env->regs[R_EDX] = regs->edx;
4352 env->regs[R_ESI] = regs->esi;
4353 env->regs[R_EDI] = regs->edi;
4354 env->regs[R_EBP] = regs->ebp;
4355 env->regs[R_ESP] = regs->esp;
4356 env->eip = regs->eip;
4357 #endif
4359 /* linux interrupt setup */
4360 #ifndef TARGET_ABI32
4361 env->idt.limit = 511;
4362 #else
4363 env->idt.limit = 255;
4364 #endif
4365 env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
4366 PROT_READ|PROT_WRITE,
4367 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4368 idt_table = g2h(env->idt.base);
4369 set_idt(0, 0);
4370 set_idt(1, 0);
4371 set_idt(2, 0);
4372 set_idt(3, 3);
4373 set_idt(4, 3);
4374 set_idt(5, 0);
4375 set_idt(6, 0);
4376 set_idt(7, 0);
4377 set_idt(8, 0);
4378 set_idt(9, 0);
4379 set_idt(10, 0);
4380 set_idt(11, 0);
4381 set_idt(12, 0);
4382 set_idt(13, 0);
4383 set_idt(14, 0);
4384 set_idt(15, 0);
4385 set_idt(16, 0);
4386 set_idt(17, 0);
4387 set_idt(18, 0);
4388 set_idt(19, 0);
4389 set_idt(0x80, 3);
4391 /* linux segment setup */
4393 uint64_t *gdt_table;
4394 env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
4395 PROT_READ|PROT_WRITE,
4396 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4397 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
4398 gdt_table = g2h(env->gdt.base);
4399 #ifdef TARGET_ABI32
4400 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
4401 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4402 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
4403 #else
4404 /* 64 bit code segment */
4405 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
4406 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4407 DESC_L_MASK |
4408 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
4409 #endif
4410 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
4411 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
4412 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
4414 cpu_x86_load_seg(env, R_CS, __USER_CS);
4415 cpu_x86_load_seg(env, R_SS, __USER_DS);
4416 #ifdef TARGET_ABI32
4417 cpu_x86_load_seg(env, R_DS, __USER_DS);
4418 cpu_x86_load_seg(env, R_ES, __USER_DS);
4419 cpu_x86_load_seg(env, R_FS, __USER_DS);
4420 cpu_x86_load_seg(env, R_GS, __USER_DS);
4421 /* This hack makes Wine work... */
4422 env->segs[R_FS].selector = 0;
4423 #else
4424 cpu_x86_load_seg(env, R_DS, 0);
4425 cpu_x86_load_seg(env, R_ES, 0);
4426 cpu_x86_load_seg(env, R_FS, 0);
4427 cpu_x86_load_seg(env, R_GS, 0);
4428 #endif
4429 #elif defined(TARGET_AARCH64)
4431 int i;
4433 if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
4434 fprintf(stderr,
4435 "The selected ARM CPU does not support 64 bit mode\n");
4436 exit(EXIT_FAILURE);
4439 for (i = 0; i < 31; i++) {
4440 env->xregs[i] = regs->regs[i];
4442 env->pc = regs->pc;
4443 env->xregs[31] = regs->sp;
4445 #elif defined(TARGET_ARM)
4447 int i;
4448 cpsr_write(env, regs->uregs[16], 0xffffffff);
4449 for(i = 0; i < 16; i++) {
4450 env->regs[i] = regs->uregs[i];
4452 /* Enable BE8. */
4453 if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
4454 && (info->elf_flags & EF_ARM_BE8)) {
4455 env->bswap_code = 1;
4458 #elif defined(TARGET_UNICORE32)
4460 int i;
4461 cpu_asr_write(env, regs->uregs[32], 0xffffffff);
4462 for (i = 0; i < 32; i++) {
4463 env->regs[i] = regs->uregs[i];
4466 #elif defined(TARGET_SPARC)
4468 int i;
4469 env->pc = regs->pc;
4470 env->npc = regs->npc;
4471 env->y = regs->y;
4472 for(i = 0; i < 8; i++)
4473 env->gregs[i] = regs->u_regs[i];
4474 for(i = 0; i < 8; i++)
4475 env->regwptr[i] = regs->u_regs[i + 8];
4477 #elif defined(TARGET_PPC)
4479 int i;
4481 #if defined(TARGET_PPC64)
4482 #if defined(TARGET_ABI32)
4483 env->msr &= ~((target_ulong)1 << MSR_SF);
4484 #else
4485 env->msr |= (target_ulong)1 << MSR_SF;
4486 #endif
4487 #endif
4488 env->nip = regs->nip;
4489 for(i = 0; i < 32; i++) {
4490 env->gpr[i] = regs->gpr[i];
4493 #elif defined(TARGET_M68K)
4495 env->pc = regs->pc;
4496 env->dregs[0] = regs->d0;
4497 env->dregs[1] = regs->d1;
4498 env->dregs[2] = regs->d2;
4499 env->dregs[3] = regs->d3;
4500 env->dregs[4] = regs->d4;
4501 env->dregs[5] = regs->d5;
4502 env->dregs[6] = regs->d6;
4503 env->dregs[7] = regs->d7;
4504 env->aregs[0] = regs->a0;
4505 env->aregs[1] = regs->a1;
4506 env->aregs[2] = regs->a2;
4507 env->aregs[3] = regs->a3;
4508 env->aregs[4] = regs->a4;
4509 env->aregs[5] = regs->a5;
4510 env->aregs[6] = regs->a6;
4511 env->aregs[7] = regs->usp;
4512 env->sr = regs->sr;
4513 ts->sim_syscalls = 1;
4515 #elif defined(TARGET_MICROBLAZE)
4517 env->regs[0] = regs->r0;
4518 env->regs[1] = regs->r1;
4519 env->regs[2] = regs->r2;
4520 env->regs[3] = regs->r3;
4521 env->regs[4] = regs->r4;
4522 env->regs[5] = regs->r5;
4523 env->regs[6] = regs->r6;
4524 env->regs[7] = regs->r7;
4525 env->regs[8] = regs->r8;
4526 env->regs[9] = regs->r9;
4527 env->regs[10] = regs->r10;
4528 env->regs[11] = regs->r11;
4529 env->regs[12] = regs->r12;
4530 env->regs[13] = regs->r13;
4531 env->regs[14] = regs->r14;
4532 env->regs[15] = regs->r15;
4533 env->regs[16] = regs->r16;
4534 env->regs[17] = regs->r17;
4535 env->regs[18] = regs->r18;
4536 env->regs[19] = regs->r19;
4537 env->regs[20] = regs->r20;
4538 env->regs[21] = regs->r21;
4539 env->regs[22] = regs->r22;
4540 env->regs[23] = regs->r23;
4541 env->regs[24] = regs->r24;
4542 env->regs[25] = regs->r25;
4543 env->regs[26] = regs->r26;
4544 env->regs[27] = regs->r27;
4545 env->regs[28] = regs->r28;
4546 env->regs[29] = regs->r29;
4547 env->regs[30] = regs->r30;
4548 env->regs[31] = regs->r31;
4549 env->sregs[SR_PC] = regs->pc;
4551 #elif defined(TARGET_MIPS)
4553 int i;
4555 for(i = 0; i < 32; i++) {
4556 env->active_tc.gpr[i] = regs->regs[i];
4558 env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1;
4559 if (regs->cp0_epc & 1) {
4560 env->hflags |= MIPS_HFLAG_M16;
4563 #elif defined(TARGET_OPENRISC)
4565 int i;
4567 for (i = 0; i < 32; i++) {
4568 env->gpr[i] = regs->gpr[i];
4571 env->sr = regs->sr;
4572 env->pc = regs->pc;
4574 #elif defined(TARGET_SH4)
4576 int i;
4578 for(i = 0; i < 16; i++) {
4579 env->gregs[i] = regs->regs[i];
4581 env->pc = regs->pc;
4583 #elif defined(TARGET_ALPHA)
4585 int i;
4587 for(i = 0; i < 28; i++) {
4588 env->ir[i] = ((abi_ulong *)regs)[i];
4590 env->ir[IR_SP] = regs->usp;
4591 env->pc = regs->pc;
4593 #elif defined(TARGET_CRIS)
4595 env->regs[0] = regs->r0;
4596 env->regs[1] = regs->r1;
4597 env->regs[2] = regs->r2;
4598 env->regs[3] = regs->r3;
4599 env->regs[4] = regs->r4;
4600 env->regs[5] = regs->r5;
4601 env->regs[6] = regs->r6;
4602 env->regs[7] = regs->r7;
4603 env->regs[8] = regs->r8;
4604 env->regs[9] = regs->r9;
4605 env->regs[10] = regs->r10;
4606 env->regs[11] = regs->r11;
4607 env->regs[12] = regs->r12;
4608 env->regs[13] = regs->r13;
4609 env->regs[14] = info->start_stack;
4610 env->regs[15] = regs->acr;
4611 env->pc = regs->erp;
4613 #elif defined(TARGET_S390X)
4615 int i;
4616 for (i = 0; i < 16; i++) {
4617 env->regs[i] = regs->gprs[i];
4619 env->psw.mask = regs->psw.mask;
4620 env->psw.addr = regs->psw.addr;
4622 #elif defined(TARGET_TILEGX)
4624 int i;
4625 for (i = 0; i < TILEGX_R_COUNT; i++) {
4626 env->regs[i] = regs->regs[i];
4628 for (i = 0; i < TILEGX_SPR_COUNT; i++) {
4629 env->spregs[i] = 0;
4631 env->pc = regs->pc;
4633 #else
4634 #error unsupported target CPU
4635 #endif
4637 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4638 ts->stack_base = info->start_stack;
4639 ts->heap_base = info->brk;
4640 /* This will be filled in on the first SYS_HEAPINFO call. */
4641 ts->heap_limit = 0;
4642 #endif
4644 if (gdbstub_port) {
4645 if (gdbserver_start(gdbstub_port) < 0) {
4646 fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
4647 gdbstub_port);
4648 exit(EXIT_FAILURE);
4650 gdb_handlesig(cpu, 0);
4652 cpu_loop(env);
4653 /* never exits */
4654 return 0;