spice: Convert core to QEMU thread API
[qemu.git] / linux-user / main.c
blobe7dad547b81c42b9aecf2f37adf857788dd3e374
1 /*
2 * qemu user main
4 * Copyright (c) 2003-2008 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <sys/mman.h>
26 #include <sys/syscall.h>
27 #include <sys/resource.h>
29 #include "qemu.h"
30 #include "qemu-common.h"
31 #include "cache-utils.h"
32 #include "cpu.h"
33 #include "tcg.h"
34 #include "qemu-timer.h"
35 #include "envlist.h"
37 #define DEBUG_LOGFILE "/tmp/qemu.log"
39 char *exec_path;
41 int singlestep;
42 const char *filename;
43 const char *argv0;
44 int gdbstub_port;
45 envlist_t *envlist;
46 const char *cpu_model;
47 unsigned long mmap_min_addr;
48 #if defined(CONFIG_USE_GUEST_BASE)
49 unsigned long guest_base;
50 int have_guest_base;
51 unsigned long reserved_va;
52 #endif
54 static void usage(void);
56 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
57 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
59 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
60 we allocate a bigger stack. Need a better solution, for example
61 by remapping the process stack directly at the right place */
62 unsigned long guest_stack_size = 8 * 1024 * 1024UL;
64 void gemu_log(const char *fmt, ...)
66 va_list ap;
68 va_start(ap, fmt);
69 vfprintf(stderr, fmt, ap);
70 va_end(ap);
73 #if defined(TARGET_I386)
74 int cpu_get_pic_interrupt(CPUState *env)
76 return -1;
78 #endif
80 /* timers for rdtsc */
82 #if 0
84 static uint64_t emu_time;
86 int64_t cpu_get_real_ticks(void)
88 return emu_time++;
91 #endif
93 #if defined(CONFIG_USE_NPTL)
94 /***********************************************************/
95 /* Helper routines for implementing atomic operations. */
97 /* To implement exclusive operations we force all cpus to syncronise.
98 We don't require a full sync, only that no cpus are executing guest code.
99 The alternative is to map target atomic ops onto host equivalents,
100 which requires quite a lot of per host/target work. */
101 static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
102 static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
103 static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
104 static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
105 static int pending_cpus;
107 /* Make sure everything is in a consistent state for calling fork(). */
108 void fork_start(void)
110 pthread_mutex_lock(&tb_lock);
111 pthread_mutex_lock(&exclusive_lock);
112 mmap_fork_start();
115 void fork_end(int child)
117 mmap_fork_end(child);
118 if (child) {
119 /* Child processes created by fork() only have a single thread.
120 Discard information about the parent threads. */
121 first_cpu = thread_env;
122 thread_env->next_cpu = NULL;
123 pending_cpus = 0;
124 pthread_mutex_init(&exclusive_lock, NULL);
125 pthread_mutex_init(&cpu_list_mutex, NULL);
126 pthread_cond_init(&exclusive_cond, NULL);
127 pthread_cond_init(&exclusive_resume, NULL);
128 pthread_mutex_init(&tb_lock, NULL);
129 gdbserver_fork(thread_env);
130 } else {
131 pthread_mutex_unlock(&exclusive_lock);
132 pthread_mutex_unlock(&tb_lock);
136 /* Wait for pending exclusive operations to complete. The exclusive lock
137 must be held. */
138 static inline void exclusive_idle(void)
140 while (pending_cpus) {
141 pthread_cond_wait(&exclusive_resume, &exclusive_lock);
145 /* Start an exclusive operation.
146 Must only be called from outside cpu_arm_exec. */
147 static inline void start_exclusive(void)
149 CPUState *other;
150 pthread_mutex_lock(&exclusive_lock);
151 exclusive_idle();
153 pending_cpus = 1;
154 /* Make all other cpus stop executing. */
155 for (other = first_cpu; other; other = other->next_cpu) {
156 if (other->running) {
157 pending_cpus++;
158 cpu_exit(other);
161 if (pending_cpus > 1) {
162 pthread_cond_wait(&exclusive_cond, &exclusive_lock);
166 /* Finish an exclusive operation. */
167 static inline void end_exclusive(void)
169 pending_cpus = 0;
170 pthread_cond_broadcast(&exclusive_resume);
171 pthread_mutex_unlock(&exclusive_lock);
174 /* Wait for exclusive ops to finish, and begin cpu execution. */
175 static inline void cpu_exec_start(CPUState *env)
177 pthread_mutex_lock(&exclusive_lock);
178 exclusive_idle();
179 env->running = 1;
180 pthread_mutex_unlock(&exclusive_lock);
183 /* Mark cpu as not executing, and release pending exclusive ops. */
184 static inline void cpu_exec_end(CPUState *env)
186 pthread_mutex_lock(&exclusive_lock);
187 env->running = 0;
188 if (pending_cpus > 1) {
189 pending_cpus--;
190 if (pending_cpus == 1) {
191 pthread_cond_signal(&exclusive_cond);
194 exclusive_idle();
195 pthread_mutex_unlock(&exclusive_lock);
198 void cpu_list_lock(void)
200 pthread_mutex_lock(&cpu_list_mutex);
203 void cpu_list_unlock(void)
205 pthread_mutex_unlock(&cpu_list_mutex);
207 #else /* if !CONFIG_USE_NPTL */
208 /* These are no-ops because we are not threadsafe. */
209 static inline void cpu_exec_start(CPUState *env)
213 static inline void cpu_exec_end(CPUState *env)
217 static inline void start_exclusive(void)
221 static inline void end_exclusive(void)
225 void fork_start(void)
229 void fork_end(int child)
231 if (child) {
232 gdbserver_fork(thread_env);
236 void cpu_list_lock(void)
240 void cpu_list_unlock(void)
243 #endif
246 #ifdef TARGET_I386
247 /***********************************************************/
248 /* CPUX86 core interface */
250 void cpu_smm_update(CPUState *env)
254 uint64_t cpu_get_tsc(CPUX86State *env)
256 return cpu_get_real_ticks();
259 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
260 int flags)
262 unsigned int e1, e2;
263 uint32_t *p;
264 e1 = (addr << 16) | (limit & 0xffff);
265 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
266 e2 |= flags;
267 p = ptr;
268 p[0] = tswap32(e1);
269 p[1] = tswap32(e2);
272 static uint64_t *idt_table;
273 #ifdef TARGET_X86_64
274 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
275 uint64_t addr, unsigned int sel)
277 uint32_t *p, e1, e2;
278 e1 = (addr & 0xffff) | (sel << 16);
279 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
280 p = ptr;
281 p[0] = tswap32(e1);
282 p[1] = tswap32(e2);
283 p[2] = tswap32(addr >> 32);
284 p[3] = 0;
286 /* only dpl matters as we do only user space emulation */
287 static void set_idt(int n, unsigned int dpl)
289 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
291 #else
292 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
293 uint32_t addr, unsigned int sel)
295 uint32_t *p, e1, e2;
296 e1 = (addr & 0xffff) | (sel << 16);
297 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
298 p = ptr;
299 p[0] = tswap32(e1);
300 p[1] = tswap32(e2);
303 /* only dpl matters as we do only user space emulation */
304 static void set_idt(int n, unsigned int dpl)
306 set_gate(idt_table + n, 0, dpl, 0, 0);
308 #endif
310 void cpu_loop(CPUX86State *env)
312 int trapnr;
313 abi_ulong pc;
314 target_siginfo_t info;
316 for(;;) {
317 trapnr = cpu_x86_exec(env);
318 switch(trapnr) {
319 case 0x80:
320 /* linux syscall from int $0x80 */
321 env->regs[R_EAX] = do_syscall(env,
322 env->regs[R_EAX],
323 env->regs[R_EBX],
324 env->regs[R_ECX],
325 env->regs[R_EDX],
326 env->regs[R_ESI],
327 env->regs[R_EDI],
328 env->regs[R_EBP],
329 0, 0);
330 break;
331 #ifndef TARGET_ABI32
332 case EXCP_SYSCALL:
333 /* linux syscall from syscall instruction */
334 env->regs[R_EAX] = do_syscall(env,
335 env->regs[R_EAX],
336 env->regs[R_EDI],
337 env->regs[R_ESI],
338 env->regs[R_EDX],
339 env->regs[10],
340 env->regs[8],
341 env->regs[9],
342 0, 0);
343 env->eip = env->exception_next_eip;
344 break;
345 #endif
346 case EXCP0B_NOSEG:
347 case EXCP0C_STACK:
348 info.si_signo = SIGBUS;
349 info.si_errno = 0;
350 info.si_code = TARGET_SI_KERNEL;
351 info._sifields._sigfault._addr = 0;
352 queue_signal(env, info.si_signo, &info);
353 break;
354 case EXCP0D_GPF:
355 /* XXX: potential problem if ABI32 */
356 #ifndef TARGET_X86_64
357 if (env->eflags & VM_MASK) {
358 handle_vm86_fault(env);
359 } else
360 #endif
362 info.si_signo = SIGSEGV;
363 info.si_errno = 0;
364 info.si_code = TARGET_SI_KERNEL;
365 info._sifields._sigfault._addr = 0;
366 queue_signal(env, info.si_signo, &info);
368 break;
369 case EXCP0E_PAGE:
370 info.si_signo = SIGSEGV;
371 info.si_errno = 0;
372 if (!(env->error_code & 1))
373 info.si_code = TARGET_SEGV_MAPERR;
374 else
375 info.si_code = TARGET_SEGV_ACCERR;
376 info._sifields._sigfault._addr = env->cr[2];
377 queue_signal(env, info.si_signo, &info);
378 break;
379 case EXCP00_DIVZ:
380 #ifndef TARGET_X86_64
381 if (env->eflags & VM_MASK) {
382 handle_vm86_trap(env, trapnr);
383 } else
384 #endif
386 /* division by zero */
387 info.si_signo = SIGFPE;
388 info.si_errno = 0;
389 info.si_code = TARGET_FPE_INTDIV;
390 info._sifields._sigfault._addr = env->eip;
391 queue_signal(env, info.si_signo, &info);
393 break;
394 case EXCP01_DB:
395 case EXCP03_INT3:
396 #ifndef TARGET_X86_64
397 if (env->eflags & VM_MASK) {
398 handle_vm86_trap(env, trapnr);
399 } else
400 #endif
402 info.si_signo = SIGTRAP;
403 info.si_errno = 0;
404 if (trapnr == EXCP01_DB) {
405 info.si_code = TARGET_TRAP_BRKPT;
406 info._sifields._sigfault._addr = env->eip;
407 } else {
408 info.si_code = TARGET_SI_KERNEL;
409 info._sifields._sigfault._addr = 0;
411 queue_signal(env, info.si_signo, &info);
413 break;
414 case EXCP04_INTO:
415 case EXCP05_BOUND:
416 #ifndef TARGET_X86_64
417 if (env->eflags & VM_MASK) {
418 handle_vm86_trap(env, trapnr);
419 } else
420 #endif
422 info.si_signo = SIGSEGV;
423 info.si_errno = 0;
424 info.si_code = TARGET_SI_KERNEL;
425 info._sifields._sigfault._addr = 0;
426 queue_signal(env, info.si_signo, &info);
428 break;
429 case EXCP06_ILLOP:
430 info.si_signo = SIGILL;
431 info.si_errno = 0;
432 info.si_code = TARGET_ILL_ILLOPN;
433 info._sifields._sigfault._addr = env->eip;
434 queue_signal(env, info.si_signo, &info);
435 break;
436 case EXCP_INTERRUPT:
437 /* just indicate that signals should be handled asap */
438 break;
439 case EXCP_DEBUG:
441 int sig;
443 sig = gdb_handlesig (env, TARGET_SIGTRAP);
444 if (sig)
446 info.si_signo = sig;
447 info.si_errno = 0;
448 info.si_code = TARGET_TRAP_BRKPT;
449 queue_signal(env, info.si_signo, &info);
452 break;
453 default:
454 pc = env->segs[R_CS].base + env->eip;
455 fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
456 (long)pc, trapnr);
457 abort();
459 process_pending_signals(env);
462 #endif
464 #ifdef TARGET_ARM
467 * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
468 * Input:
469 * r0 = pointer to oldval
470 * r1 = pointer to newval
471 * r2 = pointer to target value
473 * Output:
474 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
475 * C set if *ptr was changed, clear if no exchange happened
477 * Note segv's in kernel helpers are a bit tricky, we can set the
478 * data address sensibly but the PC address is just the entry point.
480 static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
482 uint64_t oldval, newval, val;
483 uint32_t addr, cpsr;
484 target_siginfo_t info;
486 /* Based on the 32 bit code in do_kernel_trap */
488 /* XXX: This only works between threads, not between processes.
489 It's probably possible to implement this with native host
490 operations. However things like ldrex/strex are much harder so
491 there's not much point trying. */
492 start_exclusive();
493 cpsr = cpsr_read(env);
494 addr = env->regs[2];
496 if (get_user_u64(oldval, env->regs[0])) {
497 env->cp15.c6_data = env->regs[0];
498 goto segv;
501 if (get_user_u64(newval, env->regs[1])) {
502 env->cp15.c6_data = env->regs[1];
503 goto segv;
506 if (get_user_u64(val, addr)) {
507 env->cp15.c6_data = addr;
508 goto segv;
511 if (val == oldval) {
512 val = newval;
514 if (put_user_u64(val, addr)) {
515 env->cp15.c6_data = addr;
516 goto segv;
519 env->regs[0] = 0;
520 cpsr |= CPSR_C;
521 } else {
522 env->regs[0] = -1;
523 cpsr &= ~CPSR_C;
525 cpsr_write(env, cpsr, CPSR_C);
526 end_exclusive();
527 return;
529 segv:
530 end_exclusive();
531 /* We get the PC of the entry address - which is as good as anything,
532 on a real kernel what you get depends on which mode it uses. */
533 info.si_signo = SIGSEGV;
534 info.si_errno = 0;
535 /* XXX: check env->error_code */
536 info.si_code = TARGET_SEGV_MAPERR;
537 info._sifields._sigfault._addr = env->cp15.c6_data;
538 queue_signal(env, info.si_signo, &info);
540 end_exclusive();
543 /* Handle a jump to the kernel code page. */
544 static int
545 do_kernel_trap(CPUARMState *env)
547 uint32_t addr;
548 uint32_t cpsr;
549 uint32_t val;
551 switch (env->regs[15]) {
552 case 0xffff0fa0: /* __kernel_memory_barrier */
553 /* ??? No-op. Will need to do better for SMP. */
554 break;
555 case 0xffff0fc0: /* __kernel_cmpxchg */
556 /* XXX: This only works between threads, not between processes.
557 It's probably possible to implement this with native host
558 operations. However things like ldrex/strex are much harder so
559 there's not much point trying. */
560 start_exclusive();
561 cpsr = cpsr_read(env);
562 addr = env->regs[2];
563 /* FIXME: This should SEGV if the access fails. */
564 if (get_user_u32(val, addr))
565 val = ~env->regs[0];
566 if (val == env->regs[0]) {
567 val = env->regs[1];
568 /* FIXME: Check for segfaults. */
569 put_user_u32(val, addr);
570 env->regs[0] = 0;
571 cpsr |= CPSR_C;
572 } else {
573 env->regs[0] = -1;
574 cpsr &= ~CPSR_C;
576 cpsr_write(env, cpsr, CPSR_C);
577 end_exclusive();
578 break;
579 case 0xffff0fe0: /* __kernel_get_tls */
580 env->regs[0] = env->cp15.c13_tls2;
581 break;
582 case 0xffff0f60: /* __kernel_cmpxchg64 */
583 arm_kernel_cmpxchg64_helper(env);
584 break;
586 default:
587 return 1;
589 /* Jump back to the caller. */
590 addr = env->regs[14];
591 if (addr & 1) {
592 env->thumb = 1;
593 addr &= ~1;
595 env->regs[15] = addr;
597 return 0;
600 static int do_strex(CPUARMState *env)
602 uint32_t val;
603 int size;
604 int rc = 1;
605 int segv = 0;
606 uint32_t addr;
607 start_exclusive();
608 addr = env->exclusive_addr;
609 if (addr != env->exclusive_test) {
610 goto fail;
612 size = env->exclusive_info & 0xf;
613 switch (size) {
614 case 0:
615 segv = get_user_u8(val, addr);
616 break;
617 case 1:
618 segv = get_user_u16(val, addr);
619 break;
620 case 2:
621 case 3:
622 segv = get_user_u32(val, addr);
623 break;
624 default:
625 abort();
627 if (segv) {
628 env->cp15.c6_data = addr;
629 goto done;
631 if (val != env->exclusive_val) {
632 goto fail;
634 if (size == 3) {
635 segv = get_user_u32(val, addr + 4);
636 if (segv) {
637 env->cp15.c6_data = addr + 4;
638 goto done;
640 if (val != env->exclusive_high) {
641 goto fail;
644 val = env->regs[(env->exclusive_info >> 8) & 0xf];
645 switch (size) {
646 case 0:
647 segv = put_user_u8(val, addr);
648 break;
649 case 1:
650 segv = put_user_u16(val, addr);
651 break;
652 case 2:
653 case 3:
654 segv = put_user_u32(val, addr);
655 break;
657 if (segv) {
658 env->cp15.c6_data = addr;
659 goto done;
661 if (size == 3) {
662 val = env->regs[(env->exclusive_info >> 12) & 0xf];
663 segv = put_user_u32(val, addr + 4);
664 if (segv) {
665 env->cp15.c6_data = addr + 4;
666 goto done;
669 rc = 0;
670 fail:
671 env->regs[15] += 4;
672 env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
673 done:
674 end_exclusive();
675 return segv;
678 void cpu_loop(CPUARMState *env)
680 int trapnr;
681 unsigned int n, insn;
682 target_siginfo_t info;
683 uint32_t addr;
685 for(;;) {
686 cpu_exec_start(env);
687 trapnr = cpu_arm_exec(env);
688 cpu_exec_end(env);
689 switch(trapnr) {
690 case EXCP_UDEF:
692 TaskState *ts = env->opaque;
693 uint32_t opcode;
694 int rc;
696 /* we handle the FPU emulation here, as Linux */
697 /* we get the opcode */
698 /* FIXME - what to do if get_user() fails? */
699 get_user_u32(opcode, env->regs[15]);
701 rc = EmulateAll(opcode, &ts->fpa, env);
702 if (rc == 0) { /* illegal instruction */
703 info.si_signo = SIGILL;
704 info.si_errno = 0;
705 info.si_code = TARGET_ILL_ILLOPN;
706 info._sifields._sigfault._addr = env->regs[15];
707 queue_signal(env, info.si_signo, &info);
708 } else if (rc < 0) { /* FP exception */
709 int arm_fpe=0;
711 /* translate softfloat flags to FPSR flags */
712 if (-rc & float_flag_invalid)
713 arm_fpe |= BIT_IOC;
714 if (-rc & float_flag_divbyzero)
715 arm_fpe |= BIT_DZC;
716 if (-rc & float_flag_overflow)
717 arm_fpe |= BIT_OFC;
718 if (-rc & float_flag_underflow)
719 arm_fpe |= BIT_UFC;
720 if (-rc & float_flag_inexact)
721 arm_fpe |= BIT_IXC;
723 FPSR fpsr = ts->fpa.fpsr;
724 //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
726 if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
727 info.si_signo = SIGFPE;
728 info.si_errno = 0;
730 /* ordered by priority, least first */
731 if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
732 if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
733 if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
734 if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
735 if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
737 info._sifields._sigfault._addr = env->regs[15];
738 queue_signal(env, info.si_signo, &info);
739 } else {
740 env->regs[15] += 4;
743 /* accumulate unenabled exceptions */
744 if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
745 fpsr |= BIT_IXC;
746 if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
747 fpsr |= BIT_UFC;
748 if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
749 fpsr |= BIT_OFC;
750 if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
751 fpsr |= BIT_DZC;
752 if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
753 fpsr |= BIT_IOC;
754 ts->fpa.fpsr=fpsr;
755 } else { /* everything OK */
756 /* increment PC */
757 env->regs[15] += 4;
760 break;
761 case EXCP_SWI:
762 case EXCP_BKPT:
764 env->eabi = 1;
765 /* system call */
766 if (trapnr == EXCP_BKPT) {
767 if (env->thumb) {
768 /* FIXME - what to do if get_user() fails? */
769 get_user_u16(insn, env->regs[15]);
770 n = insn & 0xff;
771 env->regs[15] += 2;
772 } else {
773 /* FIXME - what to do if get_user() fails? */
774 get_user_u32(insn, env->regs[15]);
775 n = (insn & 0xf) | ((insn >> 4) & 0xff0);
776 env->regs[15] += 4;
778 } else {
779 if (env->thumb) {
780 /* FIXME - what to do if get_user() fails? */
781 get_user_u16(insn, env->regs[15] - 2);
782 n = insn & 0xff;
783 } else {
784 /* FIXME - what to do if get_user() fails? */
785 get_user_u32(insn, env->regs[15] - 4);
786 n = insn & 0xffffff;
790 if (n == ARM_NR_cacheflush) {
791 /* nop */
792 } else if (n == ARM_NR_semihosting
793 || n == ARM_NR_thumb_semihosting) {
794 env->regs[0] = do_arm_semihosting (env);
795 } else if (n == 0 || n >= ARM_SYSCALL_BASE
796 || (env->thumb && n == ARM_THUMB_SYSCALL)) {
797 /* linux syscall */
798 if (env->thumb || n == 0) {
799 n = env->regs[7];
800 } else {
801 n -= ARM_SYSCALL_BASE;
802 env->eabi = 0;
804 if ( n > ARM_NR_BASE) {
805 switch (n) {
806 case ARM_NR_cacheflush:
807 /* nop */
808 break;
809 case ARM_NR_set_tls:
810 cpu_set_tls(env, env->regs[0]);
811 env->regs[0] = 0;
812 break;
813 default:
814 gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
816 env->regs[0] = -TARGET_ENOSYS;
817 break;
819 } else {
820 env->regs[0] = do_syscall(env,
822 env->regs[0],
823 env->regs[1],
824 env->regs[2],
825 env->regs[3],
826 env->regs[4],
827 env->regs[5],
828 0, 0);
830 } else {
831 goto error;
834 break;
835 case EXCP_INTERRUPT:
836 /* just indicate that signals should be handled asap */
837 break;
838 case EXCP_PREFETCH_ABORT:
839 addr = env->cp15.c6_insn;
840 goto do_segv;
841 case EXCP_DATA_ABORT:
842 addr = env->cp15.c6_data;
843 do_segv:
845 info.si_signo = SIGSEGV;
846 info.si_errno = 0;
847 /* XXX: check env->error_code */
848 info.si_code = TARGET_SEGV_MAPERR;
849 info._sifields._sigfault._addr = addr;
850 queue_signal(env, info.si_signo, &info);
852 break;
853 case EXCP_DEBUG:
855 int sig;
857 sig = gdb_handlesig (env, TARGET_SIGTRAP);
858 if (sig)
860 info.si_signo = sig;
861 info.si_errno = 0;
862 info.si_code = TARGET_TRAP_BRKPT;
863 queue_signal(env, info.si_signo, &info);
866 break;
867 case EXCP_KERNEL_TRAP:
868 if (do_kernel_trap(env))
869 goto error;
870 break;
871 case EXCP_STREX:
872 if (do_strex(env)) {
873 addr = env->cp15.c6_data;
874 goto do_segv;
876 break;
877 default:
878 error:
879 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
880 trapnr);
881 cpu_dump_state(env, stderr, fprintf, 0);
882 abort();
884 process_pending_signals(env);
888 #endif
890 #ifdef TARGET_UNICORE32
892 void cpu_loop(CPUState *env)
894 int trapnr;
895 unsigned int n, insn;
896 target_siginfo_t info;
898 for (;;) {
899 cpu_exec_start(env);
900 trapnr = uc32_cpu_exec(env);
901 cpu_exec_end(env);
902 switch (trapnr) {
903 case UC32_EXCP_PRIV:
905 /* system call */
906 get_user_u32(insn, env->regs[31] - 4);
907 n = insn & 0xffffff;
909 if (n >= UC32_SYSCALL_BASE) {
910 /* linux syscall */
911 n -= UC32_SYSCALL_BASE;
912 if (n == UC32_SYSCALL_NR_set_tls) {
913 cpu_set_tls(env, env->regs[0]);
914 env->regs[0] = 0;
915 } else {
916 env->regs[0] = do_syscall(env,
918 env->regs[0],
919 env->regs[1],
920 env->regs[2],
921 env->regs[3],
922 env->regs[4],
923 env->regs[5],
924 0, 0);
926 } else {
927 goto error;
930 break;
931 case UC32_EXCP_TRAP:
932 info.si_signo = SIGSEGV;
933 info.si_errno = 0;
934 /* XXX: check env->error_code */
935 info.si_code = TARGET_SEGV_MAPERR;
936 info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
937 queue_signal(env, info.si_signo, &info);
938 break;
939 case EXCP_INTERRUPT:
940 /* just indicate that signals should be handled asap */
941 break;
942 case EXCP_DEBUG:
944 int sig;
946 sig = gdb_handlesig(env, TARGET_SIGTRAP);
947 if (sig) {
948 info.si_signo = sig;
949 info.si_errno = 0;
950 info.si_code = TARGET_TRAP_BRKPT;
951 queue_signal(env, info.si_signo, &info);
954 break;
955 default:
956 goto error;
958 process_pending_signals(env);
961 error:
962 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
963 cpu_dump_state(env, stderr, fprintf, 0);
964 abort();
966 #endif
968 #ifdef TARGET_SPARC
969 #define SPARC64_STACK_BIAS 2047
971 //#define DEBUG_WIN
973 /* WARNING: dealing with register windows _is_ complicated. More info
974 can be found at http://www.sics.se/~psm/sparcstack.html */
975 static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
977 index = (index + cwp * 16) % (16 * env->nwindows);
978 /* wrap handling : if cwp is on the last window, then we use the
979 registers 'after' the end */
980 if (index < 8 && env->cwp == env->nwindows - 1)
981 index += 16 * env->nwindows;
982 return index;
985 /* save the register window 'cwp1' */
986 static inline void save_window_offset(CPUSPARCState *env, int cwp1)
988 unsigned int i;
989 abi_ulong sp_ptr;
991 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
992 #ifdef TARGET_SPARC64
993 if (sp_ptr & 3)
994 sp_ptr += SPARC64_STACK_BIAS;
995 #endif
996 #if defined(DEBUG_WIN)
997 printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
998 sp_ptr, cwp1);
999 #endif
1000 for(i = 0; i < 16; i++) {
1001 /* FIXME - what to do if put_user() fails? */
1002 put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
1003 sp_ptr += sizeof(abi_ulong);
1007 static void save_window(CPUSPARCState *env)
1009 #ifndef TARGET_SPARC64
1010 unsigned int new_wim;
1011 new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
1012 ((1LL << env->nwindows) - 1);
1013 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1014 env->wim = new_wim;
1015 #else
1016 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1017 env->cansave++;
1018 env->canrestore--;
1019 #endif
1022 static void restore_window(CPUSPARCState *env)
1024 #ifndef TARGET_SPARC64
1025 unsigned int new_wim;
1026 #endif
1027 unsigned int i, cwp1;
1028 abi_ulong sp_ptr;
1030 #ifndef TARGET_SPARC64
1031 new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
1032 ((1LL << env->nwindows) - 1);
1033 #endif
1035 /* restore the invalid window */
1036 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1037 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1038 #ifdef TARGET_SPARC64
1039 if (sp_ptr & 3)
1040 sp_ptr += SPARC64_STACK_BIAS;
1041 #endif
1042 #if defined(DEBUG_WIN)
1043 printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
1044 sp_ptr, cwp1);
1045 #endif
1046 for(i = 0; i < 16; i++) {
1047 /* FIXME - what to do if get_user() fails? */
1048 get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
1049 sp_ptr += sizeof(abi_ulong);
1051 #ifdef TARGET_SPARC64
1052 env->canrestore++;
1053 if (env->cleanwin < env->nwindows - 1)
1054 env->cleanwin++;
1055 env->cansave--;
1056 #else
1057 env->wim = new_wim;
1058 #endif
1061 static void flush_windows(CPUSPARCState *env)
1063 int offset, cwp1;
1065 offset = 1;
1066 for(;;) {
1067 /* if restore would invoke restore_window(), then we can stop */
1068 cwp1 = cpu_cwp_inc(env, env->cwp + offset);
1069 #ifndef TARGET_SPARC64
1070 if (env->wim & (1 << cwp1))
1071 break;
1072 #else
1073 if (env->canrestore == 0)
1074 break;
1075 env->cansave++;
1076 env->canrestore--;
1077 #endif
1078 save_window_offset(env, cwp1);
1079 offset++;
1081 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1082 #ifndef TARGET_SPARC64
1083 /* set wim so that restore will reload the registers */
1084 env->wim = 1 << cwp1;
1085 #endif
1086 #if defined(DEBUG_WIN)
1087 printf("flush_windows: nb=%d\n", offset - 1);
1088 #endif
1091 void cpu_loop (CPUSPARCState *env)
1093 int trapnr;
1094 abi_long ret;
1095 target_siginfo_t info;
1097 while (1) {
1098 trapnr = cpu_sparc_exec (env);
1100 switch (trapnr) {
1101 #ifndef TARGET_SPARC64
1102 case 0x88:
1103 case 0x90:
1104 #else
1105 case 0x110:
1106 case 0x16d:
1107 #endif
1108 ret = do_syscall (env, env->gregs[1],
1109 env->regwptr[0], env->regwptr[1],
1110 env->regwptr[2], env->regwptr[3],
1111 env->regwptr[4], env->regwptr[5],
1112 0, 0);
1113 if ((abi_ulong)ret >= (abi_ulong)(-515)) {
1114 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1115 env->xcc |= PSR_CARRY;
1116 #else
1117 env->psr |= PSR_CARRY;
1118 #endif
1119 ret = -ret;
1120 } else {
1121 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1122 env->xcc &= ~PSR_CARRY;
1123 #else
1124 env->psr &= ~PSR_CARRY;
1125 #endif
1127 env->regwptr[0] = ret;
1128 /* next instruction */
1129 env->pc = env->npc;
1130 env->npc = env->npc + 4;
1131 break;
1132 case 0x83: /* flush windows */
1133 #ifdef TARGET_ABI32
1134 case 0x103:
1135 #endif
1136 flush_windows(env);
1137 /* next instruction */
1138 env->pc = env->npc;
1139 env->npc = env->npc + 4;
1140 break;
1141 #ifndef TARGET_SPARC64
1142 case TT_WIN_OVF: /* window overflow */
1143 save_window(env);
1144 break;
1145 case TT_WIN_UNF: /* window underflow */
1146 restore_window(env);
1147 break;
1148 case TT_TFAULT:
1149 case TT_DFAULT:
1151 info.si_signo = SIGSEGV;
1152 info.si_errno = 0;
1153 /* XXX: check env->error_code */
1154 info.si_code = TARGET_SEGV_MAPERR;
1155 info._sifields._sigfault._addr = env->mmuregs[4];
1156 queue_signal(env, info.si_signo, &info);
1158 break;
1159 #else
1160 case TT_SPILL: /* window overflow */
1161 save_window(env);
1162 break;
1163 case TT_FILL: /* window underflow */
1164 restore_window(env);
1165 break;
1166 case TT_TFAULT:
1167 case TT_DFAULT:
1169 info.si_signo = SIGSEGV;
1170 info.si_errno = 0;
1171 /* XXX: check env->error_code */
1172 info.si_code = TARGET_SEGV_MAPERR;
1173 if (trapnr == TT_DFAULT)
1174 info._sifields._sigfault._addr = env->dmmuregs[4];
1175 else
1176 info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
1177 queue_signal(env, info.si_signo, &info);
1179 break;
1180 #ifndef TARGET_ABI32
1181 case 0x16e:
1182 flush_windows(env);
1183 sparc64_get_context(env);
1184 break;
1185 case 0x16f:
1186 flush_windows(env);
1187 sparc64_set_context(env);
1188 break;
1189 #endif
1190 #endif
1191 case EXCP_INTERRUPT:
1192 /* just indicate that signals should be handled asap */
1193 break;
1194 case EXCP_DEBUG:
1196 int sig;
1198 sig = gdb_handlesig (env, TARGET_SIGTRAP);
1199 if (sig)
1201 info.si_signo = sig;
1202 info.si_errno = 0;
1203 info.si_code = TARGET_TRAP_BRKPT;
1204 queue_signal(env, info.si_signo, &info);
1207 break;
1208 default:
1209 printf ("Unhandled trap: 0x%x\n", trapnr);
1210 cpu_dump_state(env, stderr, fprintf, 0);
1211 exit (1);
1213 process_pending_signals (env);
1217 #endif
1219 #ifdef TARGET_PPC
1220 static inline uint64_t cpu_ppc_get_tb (CPUState *env)
1222 /* TO FIX */
1223 return 0;
1226 uint64_t cpu_ppc_load_tbl (CPUState *env)
1228 return cpu_ppc_get_tb(env);
1231 uint32_t cpu_ppc_load_tbu (CPUState *env)
1233 return cpu_ppc_get_tb(env) >> 32;
1236 uint64_t cpu_ppc_load_atbl (CPUState *env)
1238 return cpu_ppc_get_tb(env);
1241 uint32_t cpu_ppc_load_atbu (CPUState *env)
1243 return cpu_ppc_get_tb(env) >> 32;
1246 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
1247 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
1249 uint32_t cpu_ppc601_load_rtcl (CPUState *env)
1251 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
1254 /* XXX: to be fixed */
1255 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
1257 return -1;
1260 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
1262 return -1;
1265 #define EXCP_DUMP(env, fmt, ...) \
1266 do { \
1267 fprintf(stderr, fmt , ## __VA_ARGS__); \
1268 cpu_dump_state(env, stderr, fprintf, 0); \
1269 qemu_log(fmt, ## __VA_ARGS__); \
1270 if (logfile) \
1271 log_cpu_state(env, 0); \
1272 } while (0)
1274 static int do_store_exclusive(CPUPPCState *env)
1276 target_ulong addr;
1277 target_ulong page_addr;
1278 target_ulong val;
1279 int flags;
1280 int segv = 0;
1282 addr = env->reserve_ea;
1283 page_addr = addr & TARGET_PAGE_MASK;
1284 start_exclusive();
1285 mmap_lock();
1286 flags = page_get_flags(page_addr);
1287 if ((flags & PAGE_READ) == 0) {
1288 segv = 1;
1289 } else {
1290 int reg = env->reserve_info & 0x1f;
1291 int size = (env->reserve_info >> 5) & 0xf;
1292 int stored = 0;
1294 if (addr == env->reserve_addr) {
1295 switch (size) {
1296 case 1: segv = get_user_u8(val, addr); break;
1297 case 2: segv = get_user_u16(val, addr); break;
1298 case 4: segv = get_user_u32(val, addr); break;
1299 #if defined(TARGET_PPC64)
1300 case 8: segv = get_user_u64(val, addr); break;
1301 #endif
1302 default: abort();
1304 if (!segv && val == env->reserve_val) {
1305 val = env->gpr[reg];
1306 switch (size) {
1307 case 1: segv = put_user_u8(val, addr); break;
1308 case 2: segv = put_user_u16(val, addr); break;
1309 case 4: segv = put_user_u32(val, addr); break;
1310 #if defined(TARGET_PPC64)
1311 case 8: segv = put_user_u64(val, addr); break;
1312 #endif
1313 default: abort();
1315 if (!segv) {
1316 stored = 1;
1320 env->crf[0] = (stored << 1) | xer_so;
1321 env->reserve_addr = (target_ulong)-1;
1323 if (!segv) {
1324 env->nip += 4;
1326 mmap_unlock();
1327 end_exclusive();
1328 return segv;
1331 void cpu_loop(CPUPPCState *env)
1333 target_siginfo_t info;
1334 int trapnr;
1335 uint32_t ret;
1337 for(;;) {
1338 cpu_exec_start(env);
1339 trapnr = cpu_ppc_exec(env);
1340 cpu_exec_end(env);
1341 switch(trapnr) {
1342 case POWERPC_EXCP_NONE:
1343 /* Just go on */
1344 break;
1345 case POWERPC_EXCP_CRITICAL: /* Critical input */
1346 cpu_abort(env, "Critical interrupt while in user mode. "
1347 "Aborting\n");
1348 break;
1349 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1350 cpu_abort(env, "Machine check exception while in user mode. "
1351 "Aborting\n");
1352 break;
1353 case POWERPC_EXCP_DSI: /* Data storage exception */
1354 EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",
1355 env->spr[SPR_DAR]);
1356 /* XXX: check this. Seems bugged */
1357 switch (env->error_code & 0xFF000000) {
1358 case 0x40000000:
1359 info.si_signo = TARGET_SIGSEGV;
1360 info.si_errno = 0;
1361 info.si_code = TARGET_SEGV_MAPERR;
1362 break;
1363 case 0x04000000:
1364 info.si_signo = TARGET_SIGILL;
1365 info.si_errno = 0;
1366 info.si_code = TARGET_ILL_ILLADR;
1367 break;
1368 case 0x08000000:
1369 info.si_signo = TARGET_SIGSEGV;
1370 info.si_errno = 0;
1371 info.si_code = TARGET_SEGV_ACCERR;
1372 break;
1373 default:
1374 /* Let's send a regular segfault... */
1375 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1376 env->error_code);
1377 info.si_signo = TARGET_SIGSEGV;
1378 info.si_errno = 0;
1379 info.si_code = TARGET_SEGV_MAPERR;
1380 break;
1382 info._sifields._sigfault._addr = env->nip;
1383 queue_signal(env, info.si_signo, &info);
1384 break;
1385 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1386 EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx
1387 "\n", env->spr[SPR_SRR0]);
1388 /* XXX: check this */
1389 switch (env->error_code & 0xFF000000) {
1390 case 0x40000000:
1391 info.si_signo = TARGET_SIGSEGV;
1392 info.si_errno = 0;
1393 info.si_code = TARGET_SEGV_MAPERR;
1394 break;
1395 case 0x10000000:
1396 case 0x08000000:
1397 info.si_signo = TARGET_SIGSEGV;
1398 info.si_errno = 0;
1399 info.si_code = TARGET_SEGV_ACCERR;
1400 break;
1401 default:
1402 /* Let's send a regular segfault... */
1403 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1404 env->error_code);
1405 info.si_signo = TARGET_SIGSEGV;
1406 info.si_errno = 0;
1407 info.si_code = TARGET_SEGV_MAPERR;
1408 break;
1410 info._sifields._sigfault._addr = env->nip - 4;
1411 queue_signal(env, info.si_signo, &info);
1412 break;
1413 case POWERPC_EXCP_EXTERNAL: /* External input */
1414 cpu_abort(env, "External interrupt while in user mode. "
1415 "Aborting\n");
1416 break;
1417 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1418 EXCP_DUMP(env, "Unaligned memory access\n");
1419 /* XXX: check this */
1420 info.si_signo = TARGET_SIGBUS;
1421 info.si_errno = 0;
1422 info.si_code = TARGET_BUS_ADRALN;
1423 info._sifields._sigfault._addr = env->nip - 4;
1424 queue_signal(env, info.si_signo, &info);
1425 break;
1426 case POWERPC_EXCP_PROGRAM: /* Program exception */
1427 /* XXX: check this */
1428 switch (env->error_code & ~0xF) {
1429 case POWERPC_EXCP_FP:
1430 EXCP_DUMP(env, "Floating point program exception\n");
1431 info.si_signo = TARGET_SIGFPE;
1432 info.si_errno = 0;
1433 switch (env->error_code & 0xF) {
1434 case POWERPC_EXCP_FP_OX:
1435 info.si_code = TARGET_FPE_FLTOVF;
1436 break;
1437 case POWERPC_EXCP_FP_UX:
1438 info.si_code = TARGET_FPE_FLTUND;
1439 break;
1440 case POWERPC_EXCP_FP_ZX:
1441 case POWERPC_EXCP_FP_VXZDZ:
1442 info.si_code = TARGET_FPE_FLTDIV;
1443 break;
1444 case POWERPC_EXCP_FP_XX:
1445 info.si_code = TARGET_FPE_FLTRES;
1446 break;
1447 case POWERPC_EXCP_FP_VXSOFT:
1448 info.si_code = TARGET_FPE_FLTINV;
1449 break;
1450 case POWERPC_EXCP_FP_VXSNAN:
1451 case POWERPC_EXCP_FP_VXISI:
1452 case POWERPC_EXCP_FP_VXIDI:
1453 case POWERPC_EXCP_FP_VXIMZ:
1454 case POWERPC_EXCP_FP_VXVC:
1455 case POWERPC_EXCP_FP_VXSQRT:
1456 case POWERPC_EXCP_FP_VXCVI:
1457 info.si_code = TARGET_FPE_FLTSUB;
1458 break;
1459 default:
1460 EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
1461 env->error_code);
1462 break;
1464 break;
1465 case POWERPC_EXCP_INVAL:
1466 EXCP_DUMP(env, "Invalid instruction\n");
1467 info.si_signo = TARGET_SIGILL;
1468 info.si_errno = 0;
1469 switch (env->error_code & 0xF) {
1470 case POWERPC_EXCP_INVAL_INVAL:
1471 info.si_code = TARGET_ILL_ILLOPC;
1472 break;
1473 case POWERPC_EXCP_INVAL_LSWX:
1474 info.si_code = TARGET_ILL_ILLOPN;
1475 break;
1476 case POWERPC_EXCP_INVAL_SPR:
1477 info.si_code = TARGET_ILL_PRVREG;
1478 break;
1479 case POWERPC_EXCP_INVAL_FP:
1480 info.si_code = TARGET_ILL_COPROC;
1481 break;
1482 default:
1483 EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
1484 env->error_code & 0xF);
1485 info.si_code = TARGET_ILL_ILLADR;
1486 break;
1488 break;
1489 case POWERPC_EXCP_PRIV:
1490 EXCP_DUMP(env, "Privilege violation\n");
1491 info.si_signo = TARGET_SIGILL;
1492 info.si_errno = 0;
1493 switch (env->error_code & 0xF) {
1494 case POWERPC_EXCP_PRIV_OPC:
1495 info.si_code = TARGET_ILL_PRVOPC;
1496 break;
1497 case POWERPC_EXCP_PRIV_REG:
1498 info.si_code = TARGET_ILL_PRVREG;
1499 break;
1500 default:
1501 EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
1502 env->error_code & 0xF);
1503 info.si_code = TARGET_ILL_PRVOPC;
1504 break;
1506 break;
1507 case POWERPC_EXCP_TRAP:
1508 cpu_abort(env, "Tried to call a TRAP\n");
1509 break;
1510 default:
1511 /* Should not happen ! */
1512 cpu_abort(env, "Unknown program exception (%02x)\n",
1513 env->error_code);
1514 break;
1516 info._sifields._sigfault._addr = env->nip - 4;
1517 queue_signal(env, info.si_signo, &info);
1518 break;
1519 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1520 EXCP_DUMP(env, "No floating point allowed\n");
1521 info.si_signo = TARGET_SIGILL;
1522 info.si_errno = 0;
1523 info.si_code = TARGET_ILL_COPROC;
1524 info._sifields._sigfault._addr = env->nip - 4;
1525 queue_signal(env, info.si_signo, &info);
1526 break;
1527 case POWERPC_EXCP_SYSCALL: /* System call exception */
1528 cpu_abort(env, "Syscall exception while in user mode. "
1529 "Aborting\n");
1530 break;
1531 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1532 EXCP_DUMP(env, "No APU instruction allowed\n");
1533 info.si_signo = TARGET_SIGILL;
1534 info.si_errno = 0;
1535 info.si_code = TARGET_ILL_COPROC;
1536 info._sifields._sigfault._addr = env->nip - 4;
1537 queue_signal(env, info.si_signo, &info);
1538 break;
1539 case POWERPC_EXCP_DECR: /* Decrementer exception */
1540 cpu_abort(env, "Decrementer interrupt while in user mode. "
1541 "Aborting\n");
1542 break;
1543 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1544 cpu_abort(env, "Fix interval timer interrupt while in user mode. "
1545 "Aborting\n");
1546 break;
1547 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1548 cpu_abort(env, "Watchdog timer interrupt while in user mode. "
1549 "Aborting\n");
1550 break;
1551 case POWERPC_EXCP_DTLB: /* Data TLB error */
1552 cpu_abort(env, "Data TLB exception while in user mode. "
1553 "Aborting\n");
1554 break;
1555 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1556 cpu_abort(env, "Instruction TLB exception while in user mode. "
1557 "Aborting\n");
1558 break;
1559 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
1560 EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
1561 info.si_signo = TARGET_SIGILL;
1562 info.si_errno = 0;
1563 info.si_code = TARGET_ILL_COPROC;
1564 info._sifields._sigfault._addr = env->nip - 4;
1565 queue_signal(env, info.si_signo, &info);
1566 break;
1567 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
1568 cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
1569 break;
1570 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
1571 cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
1572 break;
1573 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
1574 cpu_abort(env, "Performance monitor exception not handled\n");
1575 break;
1576 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1577 cpu_abort(env, "Doorbell interrupt while in user mode. "
1578 "Aborting\n");
1579 break;
1580 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1581 cpu_abort(env, "Doorbell critical interrupt while in user mode. "
1582 "Aborting\n");
1583 break;
1584 case POWERPC_EXCP_RESET: /* System reset exception */
1585 cpu_abort(env, "Reset interrupt while in user mode. "
1586 "Aborting\n");
1587 break;
1588 case POWERPC_EXCP_DSEG: /* Data segment exception */
1589 cpu_abort(env, "Data segment exception while in user mode. "
1590 "Aborting\n");
1591 break;
1592 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1593 cpu_abort(env, "Instruction segment exception "
1594 "while in user mode. Aborting\n");
1595 break;
1596 /* PowerPC 64 with hypervisor mode support */
1597 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1598 cpu_abort(env, "Hypervisor decrementer interrupt "
1599 "while in user mode. Aborting\n");
1600 break;
1601 case POWERPC_EXCP_TRACE: /* Trace exception */
1602 /* Nothing to do:
1603 * we use this exception to emulate step-by-step execution mode.
1605 break;
1606 /* PowerPC 64 with hypervisor mode support */
1607 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1608 cpu_abort(env, "Hypervisor data storage exception "
1609 "while in user mode. Aborting\n");
1610 break;
1611 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
1612 cpu_abort(env, "Hypervisor instruction storage exception "
1613 "while in user mode. Aborting\n");
1614 break;
1615 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
1616 cpu_abort(env, "Hypervisor data segment exception "
1617 "while in user mode. Aborting\n");
1618 break;
1619 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
1620 cpu_abort(env, "Hypervisor instruction segment exception "
1621 "while in user mode. Aborting\n");
1622 break;
1623 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1624 EXCP_DUMP(env, "No Altivec instructions allowed\n");
1625 info.si_signo = TARGET_SIGILL;
1626 info.si_errno = 0;
1627 info.si_code = TARGET_ILL_COPROC;
1628 info._sifields._sigfault._addr = env->nip - 4;
1629 queue_signal(env, info.si_signo, &info);
1630 break;
1631 case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
1632 cpu_abort(env, "Programable interval timer interrupt "
1633 "while in user mode. Aborting\n");
1634 break;
1635 case POWERPC_EXCP_IO: /* IO error exception */
1636 cpu_abort(env, "IO error exception while in user mode. "
1637 "Aborting\n");
1638 break;
1639 case POWERPC_EXCP_RUNM: /* Run mode exception */
1640 cpu_abort(env, "Run mode exception while in user mode. "
1641 "Aborting\n");
1642 break;
1643 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
1644 cpu_abort(env, "Emulation trap exception not handled\n");
1645 break;
1646 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
1647 cpu_abort(env, "Instruction fetch TLB exception "
1648 "while in user-mode. Aborting");
1649 break;
1650 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
1651 cpu_abort(env, "Data load TLB exception while in user-mode. "
1652 "Aborting");
1653 break;
1654 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
1655 cpu_abort(env, "Data store TLB exception while in user-mode. "
1656 "Aborting");
1657 break;
1658 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
1659 cpu_abort(env, "Floating-point assist exception not handled\n");
1660 break;
1661 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
1662 cpu_abort(env, "Instruction address breakpoint exception "
1663 "not handled\n");
1664 break;
1665 case POWERPC_EXCP_SMI: /* System management interrupt */
1666 cpu_abort(env, "System management interrupt while in user mode. "
1667 "Aborting\n");
1668 break;
1669 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1670 cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
1671 "Aborting\n");
1672 break;
1673 case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
1674 cpu_abort(env, "Performance monitor exception not handled\n");
1675 break;
1676 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1677 cpu_abort(env, "Vector assist exception not handled\n");
1678 break;
1679 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
1680 cpu_abort(env, "Soft patch exception not handled\n");
1681 break;
1682 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1683 cpu_abort(env, "Maintenance exception while in user mode. "
1684 "Aborting\n");
1685 break;
1686 case POWERPC_EXCP_STOP: /* stop translation */
1687 /* We did invalidate the instruction cache. Go on */
1688 break;
1689 case POWERPC_EXCP_BRANCH: /* branch instruction: */
1690 /* We just stopped because of a branch. Go on */
1691 break;
1692 case POWERPC_EXCP_SYSCALL_USER:
1693 /* system call in user-mode emulation */
1694 /* WARNING:
1695 * PPC ABI uses overflow flag in cr0 to signal an error
1696 * in syscalls.
1698 #if 0
1699 printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
1700 env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
1701 #endif
1702 env->crf[0] &= ~0x1;
1703 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
1704 env->gpr[5], env->gpr[6], env->gpr[7],
1705 env->gpr[8], 0, 0);
1706 if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) {
1707 /* Returning from a successful sigreturn syscall.
1708 Avoid corrupting register state. */
1709 break;
1711 if (ret > (uint32_t)(-515)) {
1712 env->crf[0] |= 0x1;
1713 ret = -ret;
1715 env->gpr[3] = ret;
1716 #if 0
1717 printf("syscall returned 0x%08x (%d)\n", ret, ret);
1718 #endif
1719 break;
1720 case POWERPC_EXCP_STCX:
1721 if (do_store_exclusive(env)) {
1722 info.si_signo = TARGET_SIGSEGV;
1723 info.si_errno = 0;
1724 info.si_code = TARGET_SEGV_MAPERR;
1725 info._sifields._sigfault._addr = env->nip;
1726 queue_signal(env, info.si_signo, &info);
1728 break;
1729 case EXCP_DEBUG:
1731 int sig;
1733 sig = gdb_handlesig(env, TARGET_SIGTRAP);
1734 if (sig) {
1735 info.si_signo = sig;
1736 info.si_errno = 0;
1737 info.si_code = TARGET_TRAP_BRKPT;
1738 queue_signal(env, info.si_signo, &info);
1741 break;
1742 case EXCP_INTERRUPT:
1743 /* just indicate that signals should be handled asap */
1744 break;
1745 default:
1746 cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
1747 break;
1749 process_pending_signals(env);
1752 #endif
1754 #ifdef TARGET_MIPS
1756 #define MIPS_SYS(name, args) args,
1758 static const uint8_t mips_syscall_args[] = {
1759 MIPS_SYS(sys_syscall , 8) /* 4000 */
1760 MIPS_SYS(sys_exit , 1)
1761 MIPS_SYS(sys_fork , 0)
1762 MIPS_SYS(sys_read , 3)
1763 MIPS_SYS(sys_write , 3)
1764 MIPS_SYS(sys_open , 3) /* 4005 */
1765 MIPS_SYS(sys_close , 1)
1766 MIPS_SYS(sys_waitpid , 3)
1767 MIPS_SYS(sys_creat , 2)
1768 MIPS_SYS(sys_link , 2)
1769 MIPS_SYS(sys_unlink , 1) /* 4010 */
1770 MIPS_SYS(sys_execve , 0)
1771 MIPS_SYS(sys_chdir , 1)
1772 MIPS_SYS(sys_time , 1)
1773 MIPS_SYS(sys_mknod , 3)
1774 MIPS_SYS(sys_chmod , 2) /* 4015 */
1775 MIPS_SYS(sys_lchown , 3)
1776 MIPS_SYS(sys_ni_syscall , 0)
1777 MIPS_SYS(sys_ni_syscall , 0) /* was sys_stat */
1778 MIPS_SYS(sys_lseek , 3)
1779 MIPS_SYS(sys_getpid , 0) /* 4020 */
1780 MIPS_SYS(sys_mount , 5)
1781 MIPS_SYS(sys_oldumount , 1)
1782 MIPS_SYS(sys_setuid , 1)
1783 MIPS_SYS(sys_getuid , 0)
1784 MIPS_SYS(sys_stime , 1) /* 4025 */
1785 MIPS_SYS(sys_ptrace , 4)
1786 MIPS_SYS(sys_alarm , 1)
1787 MIPS_SYS(sys_ni_syscall , 0) /* was sys_fstat */
1788 MIPS_SYS(sys_pause , 0)
1789 MIPS_SYS(sys_utime , 2) /* 4030 */
1790 MIPS_SYS(sys_ni_syscall , 0)
1791 MIPS_SYS(sys_ni_syscall , 0)
1792 MIPS_SYS(sys_access , 2)
1793 MIPS_SYS(sys_nice , 1)
1794 MIPS_SYS(sys_ni_syscall , 0) /* 4035 */
1795 MIPS_SYS(sys_sync , 0)
1796 MIPS_SYS(sys_kill , 2)
1797 MIPS_SYS(sys_rename , 2)
1798 MIPS_SYS(sys_mkdir , 2)
1799 MIPS_SYS(sys_rmdir , 1) /* 4040 */
1800 MIPS_SYS(sys_dup , 1)
1801 MIPS_SYS(sys_pipe , 0)
1802 MIPS_SYS(sys_times , 1)
1803 MIPS_SYS(sys_ni_syscall , 0)
1804 MIPS_SYS(sys_brk , 1) /* 4045 */
1805 MIPS_SYS(sys_setgid , 1)
1806 MIPS_SYS(sys_getgid , 0)
1807 MIPS_SYS(sys_ni_syscall , 0) /* was signal(2) */
1808 MIPS_SYS(sys_geteuid , 0)
1809 MIPS_SYS(sys_getegid , 0) /* 4050 */
1810 MIPS_SYS(sys_acct , 0)
1811 MIPS_SYS(sys_umount , 2)
1812 MIPS_SYS(sys_ni_syscall , 0)
1813 MIPS_SYS(sys_ioctl , 3)
1814 MIPS_SYS(sys_fcntl , 3) /* 4055 */
1815 MIPS_SYS(sys_ni_syscall , 2)
1816 MIPS_SYS(sys_setpgid , 2)
1817 MIPS_SYS(sys_ni_syscall , 0)
1818 MIPS_SYS(sys_olduname , 1)
1819 MIPS_SYS(sys_umask , 1) /* 4060 */
1820 MIPS_SYS(sys_chroot , 1)
1821 MIPS_SYS(sys_ustat , 2)
1822 MIPS_SYS(sys_dup2 , 2)
1823 MIPS_SYS(sys_getppid , 0)
1824 MIPS_SYS(sys_getpgrp , 0) /* 4065 */
1825 MIPS_SYS(sys_setsid , 0)
1826 MIPS_SYS(sys_sigaction , 3)
1827 MIPS_SYS(sys_sgetmask , 0)
1828 MIPS_SYS(sys_ssetmask , 1)
1829 MIPS_SYS(sys_setreuid , 2) /* 4070 */
1830 MIPS_SYS(sys_setregid , 2)
1831 MIPS_SYS(sys_sigsuspend , 0)
1832 MIPS_SYS(sys_sigpending , 1)
1833 MIPS_SYS(sys_sethostname , 2)
1834 MIPS_SYS(sys_setrlimit , 2) /* 4075 */
1835 MIPS_SYS(sys_getrlimit , 2)
1836 MIPS_SYS(sys_getrusage , 2)
1837 MIPS_SYS(sys_gettimeofday, 2)
1838 MIPS_SYS(sys_settimeofday, 2)
1839 MIPS_SYS(sys_getgroups , 2) /* 4080 */
1840 MIPS_SYS(sys_setgroups , 2)
1841 MIPS_SYS(sys_ni_syscall , 0) /* old_select */
1842 MIPS_SYS(sys_symlink , 2)
1843 MIPS_SYS(sys_ni_syscall , 0) /* was sys_lstat */
1844 MIPS_SYS(sys_readlink , 3) /* 4085 */
1845 MIPS_SYS(sys_uselib , 1)
1846 MIPS_SYS(sys_swapon , 2)
1847 MIPS_SYS(sys_reboot , 3)
1848 MIPS_SYS(old_readdir , 3)
1849 MIPS_SYS(old_mmap , 6) /* 4090 */
1850 MIPS_SYS(sys_munmap , 2)
1851 MIPS_SYS(sys_truncate , 2)
1852 MIPS_SYS(sys_ftruncate , 2)
1853 MIPS_SYS(sys_fchmod , 2)
1854 MIPS_SYS(sys_fchown , 3) /* 4095 */
1855 MIPS_SYS(sys_getpriority , 2)
1856 MIPS_SYS(sys_setpriority , 3)
1857 MIPS_SYS(sys_ni_syscall , 0)
1858 MIPS_SYS(sys_statfs , 2)
1859 MIPS_SYS(sys_fstatfs , 2) /* 4100 */
1860 MIPS_SYS(sys_ni_syscall , 0) /* was ioperm(2) */
1861 MIPS_SYS(sys_socketcall , 2)
1862 MIPS_SYS(sys_syslog , 3)
1863 MIPS_SYS(sys_setitimer , 3)
1864 MIPS_SYS(sys_getitimer , 2) /* 4105 */
1865 MIPS_SYS(sys_newstat , 2)
1866 MIPS_SYS(sys_newlstat , 2)
1867 MIPS_SYS(sys_newfstat , 2)
1868 MIPS_SYS(sys_uname , 1)
1869 MIPS_SYS(sys_ni_syscall , 0) /* 4110 was iopl(2) */
1870 MIPS_SYS(sys_vhangup , 0)
1871 MIPS_SYS(sys_ni_syscall , 0) /* was sys_idle() */
1872 MIPS_SYS(sys_ni_syscall , 0) /* was sys_vm86 */
1873 MIPS_SYS(sys_wait4 , 4)
1874 MIPS_SYS(sys_swapoff , 1) /* 4115 */
1875 MIPS_SYS(sys_sysinfo , 1)
1876 MIPS_SYS(sys_ipc , 6)
1877 MIPS_SYS(sys_fsync , 1)
1878 MIPS_SYS(sys_sigreturn , 0)
1879 MIPS_SYS(sys_clone , 6) /* 4120 */
1880 MIPS_SYS(sys_setdomainname, 2)
1881 MIPS_SYS(sys_newuname , 1)
1882 MIPS_SYS(sys_ni_syscall , 0) /* sys_modify_ldt */
1883 MIPS_SYS(sys_adjtimex , 1)
1884 MIPS_SYS(sys_mprotect , 3) /* 4125 */
1885 MIPS_SYS(sys_sigprocmask , 3)
1886 MIPS_SYS(sys_ni_syscall , 0) /* was create_module */
1887 MIPS_SYS(sys_init_module , 5)
1888 MIPS_SYS(sys_delete_module, 1)
1889 MIPS_SYS(sys_ni_syscall , 0) /* 4130 was get_kernel_syms */
1890 MIPS_SYS(sys_quotactl , 0)
1891 MIPS_SYS(sys_getpgid , 1)
1892 MIPS_SYS(sys_fchdir , 1)
1893 MIPS_SYS(sys_bdflush , 2)
1894 MIPS_SYS(sys_sysfs , 3) /* 4135 */
1895 MIPS_SYS(sys_personality , 1)
1896 MIPS_SYS(sys_ni_syscall , 0) /* for afs_syscall */
1897 MIPS_SYS(sys_setfsuid , 1)
1898 MIPS_SYS(sys_setfsgid , 1)
1899 MIPS_SYS(sys_llseek , 5) /* 4140 */
1900 MIPS_SYS(sys_getdents , 3)
1901 MIPS_SYS(sys_select , 5)
1902 MIPS_SYS(sys_flock , 2)
1903 MIPS_SYS(sys_msync , 3)
1904 MIPS_SYS(sys_readv , 3) /* 4145 */
1905 MIPS_SYS(sys_writev , 3)
1906 MIPS_SYS(sys_cacheflush , 3)
1907 MIPS_SYS(sys_cachectl , 3)
1908 MIPS_SYS(sys_sysmips , 4)
1909 MIPS_SYS(sys_ni_syscall , 0) /* 4150 */
1910 MIPS_SYS(sys_getsid , 1)
1911 MIPS_SYS(sys_fdatasync , 0)
1912 MIPS_SYS(sys_sysctl , 1)
1913 MIPS_SYS(sys_mlock , 2)
1914 MIPS_SYS(sys_munlock , 2) /* 4155 */
1915 MIPS_SYS(sys_mlockall , 1)
1916 MIPS_SYS(sys_munlockall , 0)
1917 MIPS_SYS(sys_sched_setparam, 2)
1918 MIPS_SYS(sys_sched_getparam, 2)
1919 MIPS_SYS(sys_sched_setscheduler, 3) /* 4160 */
1920 MIPS_SYS(sys_sched_getscheduler, 1)
1921 MIPS_SYS(sys_sched_yield , 0)
1922 MIPS_SYS(sys_sched_get_priority_max, 1)
1923 MIPS_SYS(sys_sched_get_priority_min, 1)
1924 MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */
1925 MIPS_SYS(sys_nanosleep, 2)
1926 MIPS_SYS(sys_mremap , 4)
1927 MIPS_SYS(sys_accept , 3)
1928 MIPS_SYS(sys_bind , 3)
1929 MIPS_SYS(sys_connect , 3) /* 4170 */
1930 MIPS_SYS(sys_getpeername , 3)
1931 MIPS_SYS(sys_getsockname , 3)
1932 MIPS_SYS(sys_getsockopt , 5)
1933 MIPS_SYS(sys_listen , 2)
1934 MIPS_SYS(sys_recv , 4) /* 4175 */
1935 MIPS_SYS(sys_recvfrom , 6)
1936 MIPS_SYS(sys_recvmsg , 3)
1937 MIPS_SYS(sys_send , 4)
1938 MIPS_SYS(sys_sendmsg , 3)
1939 MIPS_SYS(sys_sendto , 6) /* 4180 */
1940 MIPS_SYS(sys_setsockopt , 5)
1941 MIPS_SYS(sys_shutdown , 2)
1942 MIPS_SYS(sys_socket , 3)
1943 MIPS_SYS(sys_socketpair , 4)
1944 MIPS_SYS(sys_setresuid , 3) /* 4185 */
1945 MIPS_SYS(sys_getresuid , 3)
1946 MIPS_SYS(sys_ni_syscall , 0) /* was sys_query_module */
1947 MIPS_SYS(sys_poll , 3)
1948 MIPS_SYS(sys_nfsservctl , 3)
1949 MIPS_SYS(sys_setresgid , 3) /* 4190 */
1950 MIPS_SYS(sys_getresgid , 3)
1951 MIPS_SYS(sys_prctl , 5)
1952 MIPS_SYS(sys_rt_sigreturn, 0)
1953 MIPS_SYS(sys_rt_sigaction, 4)
1954 MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
1955 MIPS_SYS(sys_rt_sigpending, 2)
1956 MIPS_SYS(sys_rt_sigtimedwait, 4)
1957 MIPS_SYS(sys_rt_sigqueueinfo, 3)
1958 MIPS_SYS(sys_rt_sigsuspend, 0)
1959 MIPS_SYS(sys_pread64 , 6) /* 4200 */
1960 MIPS_SYS(sys_pwrite64 , 6)
1961 MIPS_SYS(sys_chown , 3)
1962 MIPS_SYS(sys_getcwd , 2)
1963 MIPS_SYS(sys_capget , 2)
1964 MIPS_SYS(sys_capset , 2) /* 4205 */
1965 MIPS_SYS(sys_sigaltstack , 2)
1966 MIPS_SYS(sys_sendfile , 4)
1967 MIPS_SYS(sys_ni_syscall , 0)
1968 MIPS_SYS(sys_ni_syscall , 0)
1969 MIPS_SYS(sys_mmap2 , 6) /* 4210 */
1970 MIPS_SYS(sys_truncate64 , 4)
1971 MIPS_SYS(sys_ftruncate64 , 4)
1972 MIPS_SYS(sys_stat64 , 2)
1973 MIPS_SYS(sys_lstat64 , 2)
1974 MIPS_SYS(sys_fstat64 , 2) /* 4215 */
1975 MIPS_SYS(sys_pivot_root , 2)
1976 MIPS_SYS(sys_mincore , 3)
1977 MIPS_SYS(sys_madvise , 3)
1978 MIPS_SYS(sys_getdents64 , 3)
1979 MIPS_SYS(sys_fcntl64 , 3) /* 4220 */
1980 MIPS_SYS(sys_ni_syscall , 0)
1981 MIPS_SYS(sys_gettid , 0)
1982 MIPS_SYS(sys_readahead , 5)
1983 MIPS_SYS(sys_setxattr , 5)
1984 MIPS_SYS(sys_lsetxattr , 5) /* 4225 */
1985 MIPS_SYS(sys_fsetxattr , 5)
1986 MIPS_SYS(sys_getxattr , 4)
1987 MIPS_SYS(sys_lgetxattr , 4)
1988 MIPS_SYS(sys_fgetxattr , 4)
1989 MIPS_SYS(sys_listxattr , 3) /* 4230 */
1990 MIPS_SYS(sys_llistxattr , 3)
1991 MIPS_SYS(sys_flistxattr , 3)
1992 MIPS_SYS(sys_removexattr , 2)
1993 MIPS_SYS(sys_lremovexattr, 2)
1994 MIPS_SYS(sys_fremovexattr, 2) /* 4235 */
1995 MIPS_SYS(sys_tkill , 2)
1996 MIPS_SYS(sys_sendfile64 , 5)
1997 MIPS_SYS(sys_futex , 2)
1998 MIPS_SYS(sys_sched_setaffinity, 3)
1999 MIPS_SYS(sys_sched_getaffinity, 3) /* 4240 */
2000 MIPS_SYS(sys_io_setup , 2)
2001 MIPS_SYS(sys_io_destroy , 1)
2002 MIPS_SYS(sys_io_getevents, 5)
2003 MIPS_SYS(sys_io_submit , 3)
2004 MIPS_SYS(sys_io_cancel , 3) /* 4245 */
2005 MIPS_SYS(sys_exit_group , 1)
2006 MIPS_SYS(sys_lookup_dcookie, 3)
2007 MIPS_SYS(sys_epoll_create, 1)
2008 MIPS_SYS(sys_epoll_ctl , 4)
2009 MIPS_SYS(sys_epoll_wait , 3) /* 4250 */
2010 MIPS_SYS(sys_remap_file_pages, 5)
2011 MIPS_SYS(sys_set_tid_address, 1)
2012 MIPS_SYS(sys_restart_syscall, 0)
2013 MIPS_SYS(sys_fadvise64_64, 7)
2014 MIPS_SYS(sys_statfs64 , 3) /* 4255 */
2015 MIPS_SYS(sys_fstatfs64 , 2)
2016 MIPS_SYS(sys_timer_create, 3)
2017 MIPS_SYS(sys_timer_settime, 4)
2018 MIPS_SYS(sys_timer_gettime, 2)
2019 MIPS_SYS(sys_timer_getoverrun, 1) /* 4260 */
2020 MIPS_SYS(sys_timer_delete, 1)
2021 MIPS_SYS(sys_clock_settime, 2)
2022 MIPS_SYS(sys_clock_gettime, 2)
2023 MIPS_SYS(sys_clock_getres, 2)
2024 MIPS_SYS(sys_clock_nanosleep, 4) /* 4265 */
2025 MIPS_SYS(sys_tgkill , 3)
2026 MIPS_SYS(sys_utimes , 2)
2027 MIPS_SYS(sys_mbind , 4)
2028 MIPS_SYS(sys_ni_syscall , 0) /* sys_get_mempolicy */
2029 MIPS_SYS(sys_ni_syscall , 0) /* 4270 sys_set_mempolicy */
2030 MIPS_SYS(sys_mq_open , 4)
2031 MIPS_SYS(sys_mq_unlink , 1)
2032 MIPS_SYS(sys_mq_timedsend, 5)
2033 MIPS_SYS(sys_mq_timedreceive, 5)
2034 MIPS_SYS(sys_mq_notify , 2) /* 4275 */
2035 MIPS_SYS(sys_mq_getsetattr, 3)
2036 MIPS_SYS(sys_ni_syscall , 0) /* sys_vserver */
2037 MIPS_SYS(sys_waitid , 4)
2038 MIPS_SYS(sys_ni_syscall , 0) /* available, was setaltroot */
2039 MIPS_SYS(sys_add_key , 5)
2040 MIPS_SYS(sys_request_key, 4)
2041 MIPS_SYS(sys_keyctl , 5)
2042 MIPS_SYS(sys_set_thread_area, 1)
2043 MIPS_SYS(sys_inotify_init, 0)
2044 MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
2045 MIPS_SYS(sys_inotify_rm_watch, 2)
2046 MIPS_SYS(sys_migrate_pages, 4)
2047 MIPS_SYS(sys_openat, 4)
2048 MIPS_SYS(sys_mkdirat, 3)
2049 MIPS_SYS(sys_mknodat, 4) /* 4290 */
2050 MIPS_SYS(sys_fchownat, 5)
2051 MIPS_SYS(sys_futimesat, 3)
2052 MIPS_SYS(sys_fstatat64, 4)
2053 MIPS_SYS(sys_unlinkat, 3)
2054 MIPS_SYS(sys_renameat, 4) /* 4295 */
2055 MIPS_SYS(sys_linkat, 5)
2056 MIPS_SYS(sys_symlinkat, 3)
2057 MIPS_SYS(sys_readlinkat, 4)
2058 MIPS_SYS(sys_fchmodat, 3)
2059 MIPS_SYS(sys_faccessat, 3) /* 4300 */
2060 MIPS_SYS(sys_pselect6, 6)
2061 MIPS_SYS(sys_ppoll, 5)
2062 MIPS_SYS(sys_unshare, 1)
2063 MIPS_SYS(sys_splice, 4)
2064 MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
2065 MIPS_SYS(sys_tee, 4)
2066 MIPS_SYS(sys_vmsplice, 4)
2067 MIPS_SYS(sys_move_pages, 6)
2068 MIPS_SYS(sys_set_robust_list, 2)
2069 MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
2070 MIPS_SYS(sys_kexec_load, 4)
2071 MIPS_SYS(sys_getcpu, 3)
2072 MIPS_SYS(sys_epoll_pwait, 6)
2073 MIPS_SYS(sys_ioprio_set, 3)
2074 MIPS_SYS(sys_ioprio_get, 2)
2075 MIPS_SYS(sys_utimensat, 4)
2076 MIPS_SYS(sys_signalfd, 3)
2077 MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
2078 MIPS_SYS(sys_eventfd, 1)
2079 MIPS_SYS(sys_fallocate, 6) /* 4320 */
2080 MIPS_SYS(sys_timerfd_create, 2)
2081 MIPS_SYS(sys_timerfd_gettime, 2)
2082 MIPS_SYS(sys_timerfd_settime, 4)
2083 MIPS_SYS(sys_signalfd4, 4)
2084 MIPS_SYS(sys_eventfd2, 2) /* 4325 */
2085 MIPS_SYS(sys_epoll_create1, 1)
2086 MIPS_SYS(sys_dup3, 3)
2087 MIPS_SYS(sys_pipe2, 2)
2088 MIPS_SYS(sys_inotify_init1, 1)
2089 MIPS_SYS(sys_preadv, 6) /* 4330 */
2090 MIPS_SYS(sys_pwritev, 6)
2091 MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
2092 MIPS_SYS(sys_perf_event_open, 5)
2093 MIPS_SYS(sys_accept4, 4)
2094 MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
2095 MIPS_SYS(sys_fanotify_init, 2)
2096 MIPS_SYS(sys_fanotify_mark, 6)
2097 MIPS_SYS(sys_prlimit64, 4)
2098 MIPS_SYS(sys_name_to_handle_at, 5)
2099 MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
2100 MIPS_SYS(sys_clock_adjtime, 2)
2101 MIPS_SYS(sys_syncfs, 1)
2104 #undef MIPS_SYS
2106 static int do_store_exclusive(CPUMIPSState *env)
2108 target_ulong addr;
2109 target_ulong page_addr;
2110 target_ulong val;
2111 int flags;
2112 int segv = 0;
2113 int reg;
2114 int d;
2116 addr = env->lladdr;
2117 page_addr = addr & TARGET_PAGE_MASK;
2118 start_exclusive();
2119 mmap_lock();
2120 flags = page_get_flags(page_addr);
2121 if ((flags & PAGE_READ) == 0) {
2122 segv = 1;
2123 } else {
2124 reg = env->llreg & 0x1f;
2125 d = (env->llreg & 0x20) != 0;
2126 if (d) {
2127 segv = get_user_s64(val, addr);
2128 } else {
2129 segv = get_user_s32(val, addr);
2131 if (!segv) {
2132 if (val != env->llval) {
2133 env->active_tc.gpr[reg] = 0;
2134 } else {
2135 if (d) {
2136 segv = put_user_u64(env->llnewval, addr);
2137 } else {
2138 segv = put_user_u32(env->llnewval, addr);
2140 if (!segv) {
2141 env->active_tc.gpr[reg] = 1;
2146 env->lladdr = -1;
2147 if (!segv) {
2148 env->active_tc.PC += 4;
2150 mmap_unlock();
2151 end_exclusive();
2152 return segv;
2155 void cpu_loop(CPUMIPSState *env)
2157 target_siginfo_t info;
2158 int trapnr, ret;
2159 unsigned int syscall_num;
2161 for(;;) {
2162 cpu_exec_start(env);
2163 trapnr = cpu_mips_exec(env);
2164 cpu_exec_end(env);
2165 switch(trapnr) {
2166 case EXCP_SYSCALL:
2167 syscall_num = env->active_tc.gpr[2] - 4000;
2168 env->active_tc.PC += 4;
2169 if (syscall_num >= sizeof(mips_syscall_args)) {
2170 ret = -TARGET_ENOSYS;
2171 } else {
2172 int nb_args;
2173 abi_ulong sp_reg;
2174 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
2176 nb_args = mips_syscall_args[syscall_num];
2177 sp_reg = env->active_tc.gpr[29];
2178 switch (nb_args) {
2179 /* these arguments are taken from the stack */
2180 case 8:
2181 if ((ret = get_user_ual(arg8, sp_reg + 28)) != 0) {
2182 goto done_syscall;
2184 case 7:
2185 if ((ret = get_user_ual(arg7, sp_reg + 24)) != 0) {
2186 goto done_syscall;
2188 case 6:
2189 if ((ret = get_user_ual(arg6, sp_reg + 20)) != 0) {
2190 goto done_syscall;
2192 case 5:
2193 if ((ret = get_user_ual(arg5, sp_reg + 16)) != 0) {
2194 goto done_syscall;
2196 default:
2197 break;
2199 ret = do_syscall(env, env->active_tc.gpr[2],
2200 env->active_tc.gpr[4],
2201 env->active_tc.gpr[5],
2202 env->active_tc.gpr[6],
2203 env->active_tc.gpr[7],
2204 arg5, arg6, arg7, arg8);
2206 done_syscall:
2207 if (ret == -TARGET_QEMU_ESIGRETURN) {
2208 /* Returning from a successful sigreturn syscall.
2209 Avoid clobbering register state. */
2210 break;
2212 if ((unsigned int)ret >= (unsigned int)(-1133)) {
2213 env->active_tc.gpr[7] = 1; /* error flag */
2214 ret = -ret;
2215 } else {
2216 env->active_tc.gpr[7] = 0; /* error flag */
2218 env->active_tc.gpr[2] = ret;
2219 break;
2220 case EXCP_TLBL:
2221 case EXCP_TLBS:
2222 case EXCP_AdEL:
2223 case EXCP_AdES:
2224 info.si_signo = TARGET_SIGSEGV;
2225 info.si_errno = 0;
2226 /* XXX: check env->error_code */
2227 info.si_code = TARGET_SEGV_MAPERR;
2228 info._sifields._sigfault._addr = env->CP0_BadVAddr;
2229 queue_signal(env, info.si_signo, &info);
2230 break;
2231 case EXCP_CpU:
2232 case EXCP_RI:
2233 info.si_signo = TARGET_SIGILL;
2234 info.si_errno = 0;
2235 info.si_code = 0;
2236 queue_signal(env, info.si_signo, &info);
2237 break;
2238 case EXCP_INTERRUPT:
2239 /* just indicate that signals should be handled asap */
2240 break;
2241 case EXCP_DEBUG:
2243 int sig;
2245 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2246 if (sig)
2248 info.si_signo = sig;
2249 info.si_errno = 0;
2250 info.si_code = TARGET_TRAP_BRKPT;
2251 queue_signal(env, info.si_signo, &info);
2254 break;
2255 case EXCP_SC:
2256 if (do_store_exclusive(env)) {
2257 info.si_signo = TARGET_SIGSEGV;
2258 info.si_errno = 0;
2259 info.si_code = TARGET_SEGV_MAPERR;
2260 info._sifields._sigfault._addr = env->active_tc.PC;
2261 queue_signal(env, info.si_signo, &info);
2263 break;
2264 default:
2265 // error:
2266 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
2267 trapnr);
2268 cpu_dump_state(env, stderr, fprintf, 0);
2269 abort();
2271 process_pending_signals(env);
2274 #endif
2276 #ifdef TARGET_SH4
2277 void cpu_loop (CPUState *env)
2279 int trapnr, ret;
2280 target_siginfo_t info;
2282 while (1) {
2283 trapnr = cpu_sh4_exec (env);
2285 switch (trapnr) {
2286 case 0x160:
2287 env->pc += 2;
2288 ret = do_syscall(env,
2289 env->gregs[3],
2290 env->gregs[4],
2291 env->gregs[5],
2292 env->gregs[6],
2293 env->gregs[7],
2294 env->gregs[0],
2295 env->gregs[1],
2296 0, 0);
2297 env->gregs[0] = ret;
2298 break;
2299 case EXCP_INTERRUPT:
2300 /* just indicate that signals should be handled asap */
2301 break;
2302 case EXCP_DEBUG:
2304 int sig;
2306 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2307 if (sig)
2309 info.si_signo = sig;
2310 info.si_errno = 0;
2311 info.si_code = TARGET_TRAP_BRKPT;
2312 queue_signal(env, info.si_signo, &info);
2315 break;
2316 case 0xa0:
2317 case 0xc0:
2318 info.si_signo = SIGSEGV;
2319 info.si_errno = 0;
2320 info.si_code = TARGET_SEGV_MAPERR;
2321 info._sifields._sigfault._addr = env->tea;
2322 queue_signal(env, info.si_signo, &info);
2323 break;
2325 default:
2326 printf ("Unhandled trap: 0x%x\n", trapnr);
2327 cpu_dump_state(env, stderr, fprintf, 0);
2328 exit (1);
2330 process_pending_signals (env);
2333 #endif
2335 #ifdef TARGET_CRIS
2336 void cpu_loop (CPUState *env)
2338 int trapnr, ret;
2339 target_siginfo_t info;
2341 while (1) {
2342 trapnr = cpu_cris_exec (env);
2343 switch (trapnr) {
2344 case 0xaa:
2346 info.si_signo = SIGSEGV;
2347 info.si_errno = 0;
2348 /* XXX: check env->error_code */
2349 info.si_code = TARGET_SEGV_MAPERR;
2350 info._sifields._sigfault._addr = env->pregs[PR_EDA];
2351 queue_signal(env, info.si_signo, &info);
2353 break;
2354 case EXCP_INTERRUPT:
2355 /* just indicate that signals should be handled asap */
2356 break;
2357 case EXCP_BREAK:
2358 ret = do_syscall(env,
2359 env->regs[9],
2360 env->regs[10],
2361 env->regs[11],
2362 env->regs[12],
2363 env->regs[13],
2364 env->pregs[7],
2365 env->pregs[11],
2366 0, 0);
2367 env->regs[10] = ret;
2368 break;
2369 case EXCP_DEBUG:
2371 int sig;
2373 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2374 if (sig)
2376 info.si_signo = sig;
2377 info.si_errno = 0;
2378 info.si_code = TARGET_TRAP_BRKPT;
2379 queue_signal(env, info.si_signo, &info);
2382 break;
2383 default:
2384 printf ("Unhandled trap: 0x%x\n", trapnr);
2385 cpu_dump_state(env, stderr, fprintf, 0);
2386 exit (1);
2388 process_pending_signals (env);
2391 #endif
2393 #ifdef TARGET_MICROBLAZE
2394 void cpu_loop (CPUState *env)
2396 int trapnr, ret;
2397 target_siginfo_t info;
2399 while (1) {
2400 trapnr = cpu_mb_exec (env);
2401 switch (trapnr) {
2402 case 0xaa:
2404 info.si_signo = SIGSEGV;
2405 info.si_errno = 0;
2406 /* XXX: check env->error_code */
2407 info.si_code = TARGET_SEGV_MAPERR;
2408 info._sifields._sigfault._addr = 0;
2409 queue_signal(env, info.si_signo, &info);
2411 break;
2412 case EXCP_INTERRUPT:
2413 /* just indicate that signals should be handled asap */
2414 break;
2415 case EXCP_BREAK:
2416 /* Return address is 4 bytes after the call. */
2417 env->regs[14] += 4;
2418 ret = do_syscall(env,
2419 env->regs[12],
2420 env->regs[5],
2421 env->regs[6],
2422 env->regs[7],
2423 env->regs[8],
2424 env->regs[9],
2425 env->regs[10],
2426 0, 0);
2427 env->regs[3] = ret;
2428 env->sregs[SR_PC] = env->regs[14];
2429 break;
2430 case EXCP_HW_EXCP:
2431 env->regs[17] = env->sregs[SR_PC] + 4;
2432 if (env->iflags & D_FLAG) {
2433 env->sregs[SR_ESR] |= 1 << 12;
2434 env->sregs[SR_PC] -= 4;
2435 /* FIXME: if branch was immed, replay the imm aswell. */
2438 env->iflags &= ~(IMM_FLAG | D_FLAG);
2440 switch (env->sregs[SR_ESR] & 31) {
2441 case ESR_EC_DIVZERO:
2442 info.si_signo = SIGFPE;
2443 info.si_errno = 0;
2444 info.si_code = TARGET_FPE_FLTDIV;
2445 info._sifields._sigfault._addr = 0;
2446 queue_signal(env, info.si_signo, &info);
2447 break;
2448 case ESR_EC_FPU:
2449 info.si_signo = SIGFPE;
2450 info.si_errno = 0;
2451 if (env->sregs[SR_FSR] & FSR_IO) {
2452 info.si_code = TARGET_FPE_FLTINV;
2454 if (env->sregs[SR_FSR] & FSR_DZ) {
2455 info.si_code = TARGET_FPE_FLTDIV;
2457 info._sifields._sigfault._addr = 0;
2458 queue_signal(env, info.si_signo, &info);
2459 break;
2460 default:
2461 printf ("Unhandled hw-exception: 0x%x\n",
2462 env->sregs[SR_ESR] & ESR_EC_MASK);
2463 cpu_dump_state(env, stderr, fprintf, 0);
2464 exit (1);
2465 break;
2467 break;
2468 case EXCP_DEBUG:
2470 int sig;
2472 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2473 if (sig)
2475 info.si_signo = sig;
2476 info.si_errno = 0;
2477 info.si_code = TARGET_TRAP_BRKPT;
2478 queue_signal(env, info.si_signo, &info);
2481 break;
2482 default:
2483 printf ("Unhandled trap: 0x%x\n", trapnr);
2484 cpu_dump_state(env, stderr, fprintf, 0);
2485 exit (1);
2487 process_pending_signals (env);
2490 #endif
2492 #ifdef TARGET_M68K
2494 void cpu_loop(CPUM68KState *env)
2496 int trapnr;
2497 unsigned int n;
2498 target_siginfo_t info;
2499 TaskState *ts = env->opaque;
2501 for(;;) {
2502 trapnr = cpu_m68k_exec(env);
2503 switch(trapnr) {
2504 case EXCP_ILLEGAL:
2506 if (ts->sim_syscalls) {
2507 uint16_t nr;
2508 nr = lduw(env->pc + 2);
2509 env->pc += 4;
2510 do_m68k_simcall(env, nr);
2511 } else {
2512 goto do_sigill;
2515 break;
2516 case EXCP_HALT_INSN:
2517 /* Semihosing syscall. */
2518 env->pc += 4;
2519 do_m68k_semihosting(env, env->dregs[0]);
2520 break;
2521 case EXCP_LINEA:
2522 case EXCP_LINEF:
2523 case EXCP_UNSUPPORTED:
2524 do_sigill:
2525 info.si_signo = SIGILL;
2526 info.si_errno = 0;
2527 info.si_code = TARGET_ILL_ILLOPN;
2528 info._sifields._sigfault._addr = env->pc;
2529 queue_signal(env, info.si_signo, &info);
2530 break;
2531 case EXCP_TRAP0:
2533 ts->sim_syscalls = 0;
2534 n = env->dregs[0];
2535 env->pc += 2;
2536 env->dregs[0] = do_syscall(env,
2538 env->dregs[1],
2539 env->dregs[2],
2540 env->dregs[3],
2541 env->dregs[4],
2542 env->dregs[5],
2543 env->aregs[0],
2544 0, 0);
2546 break;
2547 case EXCP_INTERRUPT:
2548 /* just indicate that signals should be handled asap */
2549 break;
2550 case EXCP_ACCESS:
2552 info.si_signo = SIGSEGV;
2553 info.si_errno = 0;
2554 /* XXX: check env->error_code */
2555 info.si_code = TARGET_SEGV_MAPERR;
2556 info._sifields._sigfault._addr = env->mmu.ar;
2557 queue_signal(env, info.si_signo, &info);
2559 break;
2560 case EXCP_DEBUG:
2562 int sig;
2564 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2565 if (sig)
2567 info.si_signo = sig;
2568 info.si_errno = 0;
2569 info.si_code = TARGET_TRAP_BRKPT;
2570 queue_signal(env, info.si_signo, &info);
2573 break;
2574 default:
2575 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
2576 trapnr);
2577 cpu_dump_state(env, stderr, fprintf, 0);
2578 abort();
2580 process_pending_signals(env);
2583 #endif /* TARGET_M68K */
2585 #ifdef TARGET_ALPHA
2586 static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
2588 target_ulong addr, val, tmp;
2589 target_siginfo_t info;
2590 int ret = 0;
2592 addr = env->lock_addr;
2593 tmp = env->lock_st_addr;
2594 env->lock_addr = -1;
2595 env->lock_st_addr = 0;
2597 start_exclusive();
2598 mmap_lock();
2600 if (addr == tmp) {
2601 if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
2602 goto do_sigsegv;
2605 if (val == env->lock_value) {
2606 tmp = env->ir[reg];
2607 if (quad ? put_user_u64(tmp, addr) : put_user_u32(tmp, addr)) {
2608 goto do_sigsegv;
2610 ret = 1;
2613 env->ir[reg] = ret;
2614 env->pc += 4;
2616 mmap_unlock();
2617 end_exclusive();
2618 return;
2620 do_sigsegv:
2621 mmap_unlock();
2622 end_exclusive();
2624 info.si_signo = TARGET_SIGSEGV;
2625 info.si_errno = 0;
2626 info.si_code = TARGET_SEGV_MAPERR;
2627 info._sifields._sigfault._addr = addr;
2628 queue_signal(env, TARGET_SIGSEGV, &info);
2631 void cpu_loop (CPUState *env)
2633 int trapnr;
2634 target_siginfo_t info;
2635 abi_long sysret;
2637 while (1) {
2638 trapnr = cpu_alpha_exec (env);
2640 /* All of the traps imply a transition through PALcode, which
2641 implies an REI instruction has been executed. Which means
2642 that the intr_flag should be cleared. */
2643 env->intr_flag = 0;
2645 switch (trapnr) {
2646 case EXCP_RESET:
2647 fprintf(stderr, "Reset requested. Exit\n");
2648 exit(1);
2649 break;
2650 case EXCP_MCHK:
2651 fprintf(stderr, "Machine check exception. Exit\n");
2652 exit(1);
2653 break;
2654 case EXCP_SMP_INTERRUPT:
2655 case EXCP_CLK_INTERRUPT:
2656 case EXCP_DEV_INTERRUPT:
2657 fprintf(stderr, "External interrupt. Exit\n");
2658 exit(1);
2659 break;
2660 case EXCP_MMFAULT:
2661 env->lock_addr = -1;
2662 info.si_signo = TARGET_SIGSEGV;
2663 info.si_errno = 0;
2664 info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
2665 ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
2666 info._sifields._sigfault._addr = env->trap_arg0;
2667 queue_signal(env, info.si_signo, &info);
2668 break;
2669 case EXCP_UNALIGN:
2670 env->lock_addr = -1;
2671 info.si_signo = TARGET_SIGBUS;
2672 info.si_errno = 0;
2673 info.si_code = TARGET_BUS_ADRALN;
2674 info._sifields._sigfault._addr = env->trap_arg0;
2675 queue_signal(env, info.si_signo, &info);
2676 break;
2677 case EXCP_OPCDEC:
2678 do_sigill:
2679 env->lock_addr = -1;
2680 info.si_signo = TARGET_SIGILL;
2681 info.si_errno = 0;
2682 info.si_code = TARGET_ILL_ILLOPC;
2683 info._sifields._sigfault._addr = env->pc;
2684 queue_signal(env, info.si_signo, &info);
2685 break;
2686 case EXCP_ARITH:
2687 env->lock_addr = -1;
2688 info.si_signo = TARGET_SIGFPE;
2689 info.si_errno = 0;
2690 info.si_code = TARGET_FPE_FLTINV;
2691 info._sifields._sigfault._addr = env->pc;
2692 queue_signal(env, info.si_signo, &info);
2693 break;
2694 case EXCP_FEN:
2695 /* No-op. Linux simply re-enables the FPU. */
2696 break;
2697 case EXCP_CALL_PAL:
2698 env->lock_addr = -1;
2699 switch (env->error_code) {
2700 case 0x80:
2701 /* BPT */
2702 info.si_signo = TARGET_SIGTRAP;
2703 info.si_errno = 0;
2704 info.si_code = TARGET_TRAP_BRKPT;
2705 info._sifields._sigfault._addr = env->pc;
2706 queue_signal(env, info.si_signo, &info);
2707 break;
2708 case 0x81:
2709 /* BUGCHK */
2710 info.si_signo = TARGET_SIGTRAP;
2711 info.si_errno = 0;
2712 info.si_code = 0;
2713 info._sifields._sigfault._addr = env->pc;
2714 queue_signal(env, info.si_signo, &info);
2715 break;
2716 case 0x83:
2717 /* CALLSYS */
2718 trapnr = env->ir[IR_V0];
2719 sysret = do_syscall(env, trapnr,
2720 env->ir[IR_A0], env->ir[IR_A1],
2721 env->ir[IR_A2], env->ir[IR_A3],
2722 env->ir[IR_A4], env->ir[IR_A5],
2723 0, 0);
2724 if (trapnr == TARGET_NR_sigreturn
2725 || trapnr == TARGET_NR_rt_sigreturn) {
2726 break;
2728 /* Syscall writes 0 to V0 to bypass error check, similar
2729 to how this is handled internal to Linux kernel. */
2730 if (env->ir[IR_V0] == 0) {
2731 env->ir[IR_V0] = sysret;
2732 } else {
2733 env->ir[IR_V0] = (sysret < 0 ? -sysret : sysret);
2734 env->ir[IR_A3] = (sysret < 0);
2736 break;
2737 case 0x86:
2738 /* IMB */
2739 /* ??? We can probably elide the code using page_unprotect
2740 that is checking for self-modifying code. Instead we
2741 could simply call tb_flush here. Until we work out the
2742 changes required to turn off the extra write protection,
2743 this can be a no-op. */
2744 break;
2745 case 0x9E:
2746 /* RDUNIQUE */
2747 /* Handled in the translator for usermode. */
2748 abort();
2749 case 0x9F:
2750 /* WRUNIQUE */
2751 /* Handled in the translator for usermode. */
2752 abort();
2753 case 0xAA:
2754 /* GENTRAP */
2755 info.si_signo = TARGET_SIGFPE;
2756 switch (env->ir[IR_A0]) {
2757 case TARGET_GEN_INTOVF:
2758 info.si_code = TARGET_FPE_INTOVF;
2759 break;
2760 case TARGET_GEN_INTDIV:
2761 info.si_code = TARGET_FPE_INTDIV;
2762 break;
2763 case TARGET_GEN_FLTOVF:
2764 info.si_code = TARGET_FPE_FLTOVF;
2765 break;
2766 case TARGET_GEN_FLTUND:
2767 info.si_code = TARGET_FPE_FLTUND;
2768 break;
2769 case TARGET_GEN_FLTINV:
2770 info.si_code = TARGET_FPE_FLTINV;
2771 break;
2772 case TARGET_GEN_FLTINE:
2773 info.si_code = TARGET_FPE_FLTRES;
2774 break;
2775 case TARGET_GEN_ROPRAND:
2776 info.si_code = 0;
2777 break;
2778 default:
2779 info.si_signo = TARGET_SIGTRAP;
2780 info.si_code = 0;
2781 break;
2783 info.si_errno = 0;
2784 info._sifields._sigfault._addr = env->pc;
2785 queue_signal(env, info.si_signo, &info);
2786 break;
2787 default:
2788 goto do_sigill;
2790 break;
2791 case EXCP_DEBUG:
2792 info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
2793 if (info.si_signo) {
2794 env->lock_addr = -1;
2795 info.si_errno = 0;
2796 info.si_code = TARGET_TRAP_BRKPT;
2797 queue_signal(env, info.si_signo, &info);
2799 break;
2800 case EXCP_STL_C:
2801 case EXCP_STQ_C:
2802 do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C);
2803 break;
2804 default:
2805 printf ("Unhandled trap: 0x%x\n", trapnr);
2806 cpu_dump_state(env, stderr, fprintf, 0);
2807 exit (1);
2809 process_pending_signals (env);
2812 #endif /* TARGET_ALPHA */
2814 #ifdef TARGET_S390X
2815 void cpu_loop(CPUS390XState *env)
2817 int trapnr;
2818 target_siginfo_t info;
2820 while (1) {
2821 trapnr = cpu_s390x_exec (env);
2823 switch (trapnr) {
2824 case EXCP_INTERRUPT:
2825 /* just indicate that signals should be handled asap */
2826 break;
2827 case EXCP_DEBUG:
2829 int sig;
2831 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2832 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 case EXCP_SVC:
2842 int n = env->int_svc_code;
2843 if (!n) {
2844 /* syscalls > 255 */
2845 n = env->regs[1];
2847 env->psw.addr += env->int_svc_ilc;
2848 env->regs[2] = do_syscall(env, n,
2849 env->regs[2],
2850 env->regs[3],
2851 env->regs[4],
2852 env->regs[5],
2853 env->regs[6],
2854 env->regs[7],
2855 0, 0);
2857 break;
2858 case EXCP_ADDR:
2860 info.si_signo = SIGSEGV;
2861 info.si_errno = 0;
2862 /* XXX: check env->error_code */
2863 info.si_code = TARGET_SEGV_MAPERR;
2864 info._sifields._sigfault._addr = env->__excp_addr;
2865 queue_signal(env, info.si_signo, &info);
2867 break;
2868 case EXCP_SPEC:
2870 fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4));
2871 info.si_signo = SIGILL;
2872 info.si_errno = 0;
2873 info.si_code = TARGET_ILL_ILLOPC;
2874 info._sifields._sigfault._addr = env->__excp_addr;
2875 queue_signal(env, info.si_signo, &info);
2877 break;
2878 default:
2879 printf ("Unhandled trap: 0x%x\n", trapnr);
2880 cpu_dump_state(env, stderr, fprintf, 0);
2881 exit (1);
2883 process_pending_signals (env);
2887 #endif /* TARGET_S390X */
2889 THREAD CPUState *thread_env;
2891 void task_settid(TaskState *ts)
2893 if (ts->ts_tid == 0) {
2894 #ifdef CONFIG_USE_NPTL
2895 ts->ts_tid = (pid_t)syscall(SYS_gettid);
2896 #else
2897 /* when no threads are used, tid becomes pid */
2898 ts->ts_tid = getpid();
2899 #endif
2903 void stop_all_tasks(void)
2906 * We trust that when using NPTL, start_exclusive()
2907 * handles thread stopping correctly.
2909 start_exclusive();
2912 /* Assumes contents are already zeroed. */
2913 void init_task_state(TaskState *ts)
2915 int i;
2917 ts->used = 1;
2918 ts->first_free = ts->sigqueue_table;
2919 for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
2920 ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
2922 ts->sigqueue_table[i].next = NULL;
2925 static void handle_arg_help(const char *arg)
2927 usage();
2930 static void handle_arg_log(const char *arg)
2932 int mask;
2933 const CPULogItem *item;
2935 mask = cpu_str_to_log_mask(arg);
2936 if (!mask) {
2937 printf("Log items (comma separated):\n");
2938 for (item = cpu_log_items; item->mask != 0; item++) {
2939 printf("%-10s %s\n", item->name, item->help);
2941 exit(1);
2943 cpu_set_log(mask);
2946 static void handle_arg_set_env(const char *arg)
2948 char *r, *p, *token;
2949 r = p = strdup(arg);
2950 while ((token = strsep(&p, ",")) != NULL) {
2951 if (envlist_setenv(envlist, token) != 0) {
2952 usage();
2955 free(r);
2958 static void handle_arg_unset_env(const char *arg)
2960 char *r, *p, *token;
2961 r = p = strdup(arg);
2962 while ((token = strsep(&p, ",")) != NULL) {
2963 if (envlist_unsetenv(envlist, token) != 0) {
2964 usage();
2967 free(r);
2970 static void handle_arg_argv0(const char *arg)
2972 argv0 = strdup(arg);
2975 static void handle_arg_stack_size(const char *arg)
2977 char *p;
2978 guest_stack_size = strtoul(arg, &p, 0);
2979 if (guest_stack_size == 0) {
2980 usage();
2983 if (*p == 'M') {
2984 guest_stack_size *= 1024 * 1024;
2985 } else if (*p == 'k' || *p == 'K') {
2986 guest_stack_size *= 1024;
2990 static void handle_arg_ld_prefix(const char *arg)
2992 interp_prefix = strdup(arg);
2995 static void handle_arg_pagesize(const char *arg)
2997 qemu_host_page_size = atoi(arg);
2998 if (qemu_host_page_size == 0 ||
2999 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
3000 fprintf(stderr, "page size must be a power of two\n");
3001 exit(1);
3005 static void handle_arg_gdb(const char *arg)
3007 gdbstub_port = atoi(arg);
3010 static void handle_arg_uname(const char *arg)
3012 qemu_uname_release = strdup(arg);
3015 static void handle_arg_cpu(const char *arg)
3017 cpu_model = strdup(arg);
3018 if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
3019 /* XXX: implement xxx_cpu_list for targets that still miss it */
3020 #if defined(cpu_list_id)
3021 cpu_list_id(stdout, &fprintf, "");
3022 #elif defined(cpu_list)
3023 cpu_list(stdout, &fprintf); /* deprecated */
3024 #endif
3025 exit(1);
3029 #if defined(CONFIG_USE_GUEST_BASE)
3030 static void handle_arg_guest_base(const char *arg)
3032 guest_base = strtol(arg, NULL, 0);
3033 have_guest_base = 1;
3036 static void handle_arg_reserved_va(const char *arg)
3038 char *p;
3039 int shift = 0;
3040 reserved_va = strtoul(arg, &p, 0);
3041 switch (*p) {
3042 case 'k':
3043 case 'K':
3044 shift = 10;
3045 break;
3046 case 'M':
3047 shift = 20;
3048 break;
3049 case 'G':
3050 shift = 30;
3051 break;
3053 if (shift) {
3054 unsigned long unshifted = reserved_va;
3055 p++;
3056 reserved_va <<= shift;
3057 if (((reserved_va >> shift) != unshifted)
3058 #if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
3059 || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
3060 #endif
3062 fprintf(stderr, "Reserved virtual address too big\n");
3063 exit(1);
3066 if (*p) {
3067 fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
3068 exit(1);
3071 #endif
3073 static void handle_arg_singlestep(const char *arg)
3075 singlestep = 1;
3078 static void handle_arg_strace(const char *arg)
3080 do_strace = 1;
3083 static void handle_arg_version(const char *arg)
3085 printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION
3086 ", Copyright (c) 2003-2008 Fabrice Bellard\n");
3087 exit(0);
3090 struct qemu_argument {
3091 const char *argv;
3092 const char *env;
3093 bool has_arg;
3094 void (*handle_opt)(const char *arg);
3095 const char *example;
3096 const char *help;
3099 struct qemu_argument arg_table[] = {
3100 {"h", "", false, handle_arg_help,
3101 "", "print this help"},
3102 {"g", "QEMU_GDB", true, handle_arg_gdb,
3103 "port", "wait gdb connection to 'port'"},
3104 {"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix,
3105 "path", "set the elf interpreter prefix to 'path'"},
3106 {"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
3107 "size", "set the stack size to 'size' bytes"},
3108 {"cpu", "QEMU_CPU", true, handle_arg_cpu,
3109 "model", "select CPU (-cpu ? for list)"},
3110 {"E", "QEMU_SET_ENV", true, handle_arg_set_env,
3111 "var=value", "sets targets environment variable (see below)"},
3112 {"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
3113 "var", "unsets targets environment variable (see below)"},
3114 {"0", "QEMU_ARGV0", true, handle_arg_argv0,
3115 "argv0", "forces target process argv[0] to be 'argv0'"},
3116 {"r", "QEMU_UNAME", true, handle_arg_uname,
3117 "uname", "set qemu uname release string to 'uname'"},
3118 #if defined(CONFIG_USE_GUEST_BASE)
3119 {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base,
3120 "address", "set guest_base address to 'address'"},
3121 {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
3122 "size", "reserve 'size' bytes for guest virtual address space"},
3123 #endif
3124 {"d", "QEMU_LOG", true, handle_arg_log,
3125 "options", "activate log"},
3126 {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
3127 "pagesize", "set the host page size to 'pagesize'"},
3128 {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
3129 "", "run in singlestep mode"},
3130 {"strace", "QEMU_STRACE", false, handle_arg_strace,
3131 "", "log system calls"},
3132 {"version", "QEMU_VERSION", false, handle_arg_version,
3133 "", "display version information and exit"},
3134 {NULL, NULL, false, NULL, NULL, NULL}
3137 static void usage(void)
3139 struct qemu_argument *arginfo;
3140 int maxarglen;
3141 int maxenvlen;
3143 printf("usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
3144 "Linux CPU emulator (compiled for " TARGET_ARCH " emulation)\n"
3145 "\n"
3146 "Options and associated environment variables:\n"
3147 "\n");
3149 maxarglen = maxenvlen = 0;
3151 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3152 if (strlen(arginfo->env) > maxenvlen) {
3153 maxenvlen = strlen(arginfo->env);
3155 if (strlen(arginfo->argv) > maxarglen) {
3156 maxarglen = strlen(arginfo->argv);
3160 printf("%-*s%-*sDescription\n", maxarglen+3, "Argument",
3161 maxenvlen+1, "Env-variable");
3163 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3164 if (arginfo->has_arg) {
3165 printf("-%s %-*s %-*s %s\n", arginfo->argv,
3166 (int)(maxarglen-strlen(arginfo->argv)), arginfo->example,
3167 maxenvlen, arginfo->env, arginfo->help);
3168 } else {
3169 printf("-%-*s %-*s %s\n", maxarglen+1, arginfo->argv,
3170 maxenvlen, arginfo->env,
3171 arginfo->help);
3175 printf("\n"
3176 "Defaults:\n"
3177 "QEMU_LD_PREFIX = %s\n"
3178 "QEMU_STACK_SIZE = %ld byte\n"
3179 "QEMU_LOG = %s\n",
3180 interp_prefix,
3181 guest_stack_size,
3182 DEBUG_LOGFILE);
3184 printf("\n"
3185 "You can use -E and -U options or the QEMU_SET_ENV and\n"
3186 "QEMU_UNSET_ENV environment variables to set and unset\n"
3187 "environment variables for the target process.\n"
3188 "It is possible to provide several variables by separating them\n"
3189 "by commas in getsubopt(3) style. Additionally it is possible to\n"
3190 "provide the -E and -U options multiple times.\n"
3191 "The following lines are equivalent:\n"
3192 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
3193 " -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
3194 " QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
3195 "Note that if you provide several changes to a single variable\n"
3196 "the last change will stay in effect.\n");
3198 exit(1);
3201 static int parse_args(int argc, char **argv)
3203 const char *r;
3204 int optind;
3205 struct qemu_argument *arginfo;
3207 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3208 if (arginfo->env == NULL) {
3209 continue;
3212 r = getenv(arginfo->env);
3213 if (r != NULL) {
3214 arginfo->handle_opt(r);
3218 optind = 1;
3219 for (;;) {
3220 if (optind >= argc) {
3221 break;
3223 r = argv[optind];
3224 if (r[0] != '-') {
3225 break;
3227 optind++;
3228 r++;
3229 if (!strcmp(r, "-")) {
3230 break;
3233 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
3234 if (!strcmp(r, arginfo->argv)) {
3235 if (arginfo->has_arg) {
3236 if (optind >= argc) {
3237 usage();
3239 arginfo->handle_opt(argv[optind]);
3240 optind++;
3241 } else {
3242 arginfo->handle_opt(NULL);
3244 break;
3248 /* no option matched the current argv */
3249 if (arginfo->handle_opt == NULL) {
3250 usage();
3254 if (optind >= argc) {
3255 usage();
3258 filename = argv[optind];
3259 exec_path = argv[optind];
3261 return optind;
3264 int main(int argc, char **argv, char **envp)
3266 const char *log_file = DEBUG_LOGFILE;
3267 struct target_pt_regs regs1, *regs = &regs1;
3268 struct image_info info1, *info = &info1;
3269 struct linux_binprm bprm;
3270 TaskState *ts;
3271 CPUState *env;
3272 int optind;
3273 char **target_environ, **wrk;
3274 char **target_argv;
3275 int target_argc;
3276 int i;
3277 int ret;
3279 qemu_cache_utils_init(envp);
3281 if ((envlist = envlist_create()) == NULL) {
3282 (void) fprintf(stderr, "Unable to allocate envlist\n");
3283 exit(1);
3286 /* add current environment into the list */
3287 for (wrk = environ; *wrk != NULL; wrk++) {
3288 (void) envlist_setenv(envlist, *wrk);
3291 /* Read the stack limit from the kernel. If it's "unlimited",
3292 then we can do little else besides use the default. */
3294 struct rlimit lim;
3295 if (getrlimit(RLIMIT_STACK, &lim) == 0
3296 && lim.rlim_cur != RLIM_INFINITY
3297 && lim.rlim_cur == (target_long)lim.rlim_cur) {
3298 guest_stack_size = lim.rlim_cur;
3302 cpu_model = NULL;
3303 #if defined(cpudef_setup)
3304 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
3305 #endif
3307 /* init debug */
3308 cpu_set_log_filename(log_file);
3309 optind = parse_args(argc, argv);
3311 /* Zero out regs */
3312 memset(regs, 0, sizeof(struct target_pt_regs));
3314 /* Zero out image_info */
3315 memset(info, 0, sizeof(struct image_info));
3317 memset(&bprm, 0, sizeof (bprm));
3319 /* Scan interp_prefix dir for replacement files. */
3320 init_paths(interp_prefix);
3322 if (cpu_model == NULL) {
3323 #if defined(TARGET_I386)
3324 #ifdef TARGET_X86_64
3325 cpu_model = "qemu64";
3326 #else
3327 cpu_model = "qemu32";
3328 #endif
3329 #elif defined(TARGET_ARM)
3330 cpu_model = "any";
3331 #elif defined(TARGET_UNICORE32)
3332 cpu_model = "any";
3333 #elif defined(TARGET_M68K)
3334 cpu_model = "any";
3335 #elif defined(TARGET_SPARC)
3336 #ifdef TARGET_SPARC64
3337 cpu_model = "TI UltraSparc II";
3338 #else
3339 cpu_model = "Fujitsu MB86904";
3340 #endif
3341 #elif defined(TARGET_MIPS)
3342 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
3343 cpu_model = "20Kc";
3344 #else
3345 cpu_model = "24Kf";
3346 #endif
3347 #elif defined(TARGET_PPC)
3348 #ifdef TARGET_PPC64
3349 cpu_model = "970fx";
3350 #else
3351 cpu_model = "750";
3352 #endif
3353 #else
3354 cpu_model = "any";
3355 #endif
3357 tcg_exec_init(0);
3358 cpu_exec_init_all();
3359 /* NOTE: we need to init the CPU at this stage to get
3360 qemu_host_page_size */
3361 env = cpu_init(cpu_model);
3362 if (!env) {
3363 fprintf(stderr, "Unable to find CPU definition\n");
3364 exit(1);
3366 #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3367 cpu_reset(env);
3368 #endif
3370 thread_env = env;
3372 if (getenv("QEMU_STRACE")) {
3373 do_strace = 1;
3376 target_environ = envlist_to_environ(envlist, NULL);
3377 envlist_free(envlist);
3379 #if defined(CONFIG_USE_GUEST_BASE)
3381 * Now that page sizes are configured in cpu_init() we can do
3382 * proper page alignment for guest_base.
3384 guest_base = HOST_PAGE_ALIGN(guest_base);
3386 if (reserved_va) {
3387 void *p;
3388 int flags;
3390 flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
3391 if (have_guest_base) {
3392 flags |= MAP_FIXED;
3394 p = mmap((void *)guest_base, reserved_va, PROT_NONE, flags, -1, 0);
3395 if (p == MAP_FAILED) {
3396 fprintf(stderr, "Unable to reserve guest address space\n");
3397 exit(1);
3399 guest_base = (unsigned long)p;
3400 /* Make sure the address is properly aligned. */
3401 if (guest_base & ~qemu_host_page_mask) {
3402 munmap(p, reserved_va);
3403 p = mmap((void *)guest_base, reserved_va + qemu_host_page_size,
3404 PROT_NONE, flags, -1, 0);
3405 if (p == MAP_FAILED) {
3406 fprintf(stderr, "Unable to reserve guest address space\n");
3407 exit(1);
3409 guest_base = HOST_PAGE_ALIGN((unsigned long)p);
3411 qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va);
3414 if (reserved_va || have_guest_base) {
3415 if (!guest_validate_base(guest_base)) {
3416 fprintf(stderr, "Guest base/Reserved VA rejected by guest code\n");
3417 exit(1);
3420 #endif /* CONFIG_USE_GUEST_BASE */
3423 * Read in mmap_min_addr kernel parameter. This value is used
3424 * When loading the ELF image to determine whether guest_base
3425 * is needed. It is also used in mmap_find_vma.
3428 FILE *fp;
3430 if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
3431 unsigned long tmp;
3432 if (fscanf(fp, "%lu", &tmp) == 1) {
3433 mmap_min_addr = tmp;
3434 qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
3436 fclose(fp);
3441 * Prepare copy of argv vector for target.
3443 target_argc = argc - optind;
3444 target_argv = calloc(target_argc + 1, sizeof (char *));
3445 if (target_argv == NULL) {
3446 (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
3447 exit(1);
3451 * If argv0 is specified (using '-0' switch) we replace
3452 * argv[0] pointer with the given one.
3454 i = 0;
3455 if (argv0 != NULL) {
3456 target_argv[i++] = strdup(argv0);
3458 for (; i < target_argc; i++) {
3459 target_argv[i] = strdup(argv[optind + i]);
3461 target_argv[target_argc] = NULL;
3463 ts = g_malloc0 (sizeof(TaskState));
3464 init_task_state(ts);
3465 /* build Task State */
3466 ts->info = info;
3467 ts->bprm = &bprm;
3468 env->opaque = ts;
3469 task_settid(ts);
3471 ret = loader_exec(filename, target_argv, target_environ, regs,
3472 info, &bprm);
3473 if (ret != 0) {
3474 printf("Error %d while loading %s\n", ret, filename);
3475 _exit(1);
3478 for (i = 0; i < target_argc; i++) {
3479 free(target_argv[i]);
3481 free(target_argv);
3483 for (wrk = target_environ; *wrk; wrk++) {
3484 free(*wrk);
3487 free(target_environ);
3489 if (qemu_log_enabled()) {
3490 #if defined(CONFIG_USE_GUEST_BASE)
3491 qemu_log("guest_base 0x%lx\n", guest_base);
3492 #endif
3493 log_page_dump();
3495 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
3496 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
3497 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
3498 info->start_code);
3499 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
3500 info->start_data);
3501 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
3502 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
3503 info->start_stack);
3504 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
3505 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
3508 target_set_brk(info->brk);
3509 syscall_init();
3510 signal_init();
3512 #if defined(CONFIG_USE_GUEST_BASE)
3513 /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
3514 generating the prologue until now so that the prologue can take
3515 the real value of GUEST_BASE into account. */
3516 tcg_prologue_init(&tcg_ctx);
3517 #endif
3519 #if defined(TARGET_I386)
3520 cpu_x86_set_cpl(env, 3);
3522 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
3523 env->hflags |= HF_PE_MASK;
3524 if (env->cpuid_features & CPUID_SSE) {
3525 env->cr[4] |= CR4_OSFXSR_MASK;
3526 env->hflags |= HF_OSFXSR_MASK;
3528 #ifndef TARGET_ABI32
3529 /* enable 64 bit mode if possible */
3530 if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
3531 fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
3532 exit(1);
3534 env->cr[4] |= CR4_PAE_MASK;
3535 env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
3536 env->hflags |= HF_LMA_MASK;
3537 #endif
3539 /* flags setup : we activate the IRQs by default as in user mode */
3540 env->eflags |= IF_MASK;
3542 /* linux register setup */
3543 #ifndef TARGET_ABI32
3544 env->regs[R_EAX] = regs->rax;
3545 env->regs[R_EBX] = regs->rbx;
3546 env->regs[R_ECX] = regs->rcx;
3547 env->regs[R_EDX] = regs->rdx;
3548 env->regs[R_ESI] = regs->rsi;
3549 env->regs[R_EDI] = regs->rdi;
3550 env->regs[R_EBP] = regs->rbp;
3551 env->regs[R_ESP] = regs->rsp;
3552 env->eip = regs->rip;
3553 #else
3554 env->regs[R_EAX] = regs->eax;
3555 env->regs[R_EBX] = regs->ebx;
3556 env->regs[R_ECX] = regs->ecx;
3557 env->regs[R_EDX] = regs->edx;
3558 env->regs[R_ESI] = regs->esi;
3559 env->regs[R_EDI] = regs->edi;
3560 env->regs[R_EBP] = regs->ebp;
3561 env->regs[R_ESP] = regs->esp;
3562 env->eip = regs->eip;
3563 #endif
3565 /* linux interrupt setup */
3566 #ifndef TARGET_ABI32
3567 env->idt.limit = 511;
3568 #else
3569 env->idt.limit = 255;
3570 #endif
3571 env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
3572 PROT_READ|PROT_WRITE,
3573 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3574 idt_table = g2h(env->idt.base);
3575 set_idt(0, 0);
3576 set_idt(1, 0);
3577 set_idt(2, 0);
3578 set_idt(3, 3);
3579 set_idt(4, 3);
3580 set_idt(5, 0);
3581 set_idt(6, 0);
3582 set_idt(7, 0);
3583 set_idt(8, 0);
3584 set_idt(9, 0);
3585 set_idt(10, 0);
3586 set_idt(11, 0);
3587 set_idt(12, 0);
3588 set_idt(13, 0);
3589 set_idt(14, 0);
3590 set_idt(15, 0);
3591 set_idt(16, 0);
3592 set_idt(17, 0);
3593 set_idt(18, 0);
3594 set_idt(19, 0);
3595 set_idt(0x80, 3);
3597 /* linux segment setup */
3599 uint64_t *gdt_table;
3600 env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
3601 PROT_READ|PROT_WRITE,
3602 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3603 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
3604 gdt_table = g2h(env->gdt.base);
3605 #ifdef TARGET_ABI32
3606 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
3607 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
3608 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
3609 #else
3610 /* 64 bit code segment */
3611 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
3612 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
3613 DESC_L_MASK |
3614 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
3615 #endif
3616 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
3617 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
3618 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
3620 cpu_x86_load_seg(env, R_CS, __USER_CS);
3621 cpu_x86_load_seg(env, R_SS, __USER_DS);
3622 #ifdef TARGET_ABI32
3623 cpu_x86_load_seg(env, R_DS, __USER_DS);
3624 cpu_x86_load_seg(env, R_ES, __USER_DS);
3625 cpu_x86_load_seg(env, R_FS, __USER_DS);
3626 cpu_x86_load_seg(env, R_GS, __USER_DS);
3627 /* This hack makes Wine work... */
3628 env->segs[R_FS].selector = 0;
3629 #else
3630 cpu_x86_load_seg(env, R_DS, 0);
3631 cpu_x86_load_seg(env, R_ES, 0);
3632 cpu_x86_load_seg(env, R_FS, 0);
3633 cpu_x86_load_seg(env, R_GS, 0);
3634 #endif
3635 #elif defined(TARGET_ARM)
3637 int i;
3638 cpsr_write(env, regs->uregs[16], 0xffffffff);
3639 for(i = 0; i < 16; i++) {
3640 env->regs[i] = regs->uregs[i];
3643 #elif defined(TARGET_UNICORE32)
3645 int i;
3646 cpu_asr_write(env, regs->uregs[32], 0xffffffff);
3647 for (i = 0; i < 32; i++) {
3648 env->regs[i] = regs->uregs[i];
3651 #elif defined(TARGET_SPARC)
3653 int i;
3654 env->pc = regs->pc;
3655 env->npc = regs->npc;
3656 env->y = regs->y;
3657 for(i = 0; i < 8; i++)
3658 env->gregs[i] = regs->u_regs[i];
3659 for(i = 0; i < 8; i++)
3660 env->regwptr[i] = regs->u_regs[i + 8];
3662 #elif defined(TARGET_PPC)
3664 int i;
3666 #if defined(TARGET_PPC64)
3667 #if defined(TARGET_ABI32)
3668 env->msr &= ~((target_ulong)1 << MSR_SF);
3669 #else
3670 env->msr |= (target_ulong)1 << MSR_SF;
3671 #endif
3672 #endif
3673 env->nip = regs->nip;
3674 for(i = 0; i < 32; i++) {
3675 env->gpr[i] = regs->gpr[i];
3678 #elif defined(TARGET_M68K)
3680 env->pc = regs->pc;
3681 env->dregs[0] = regs->d0;
3682 env->dregs[1] = regs->d1;
3683 env->dregs[2] = regs->d2;
3684 env->dregs[3] = regs->d3;
3685 env->dregs[4] = regs->d4;
3686 env->dregs[5] = regs->d5;
3687 env->dregs[6] = regs->d6;
3688 env->dregs[7] = regs->d7;
3689 env->aregs[0] = regs->a0;
3690 env->aregs[1] = regs->a1;
3691 env->aregs[2] = regs->a2;
3692 env->aregs[3] = regs->a3;
3693 env->aregs[4] = regs->a4;
3694 env->aregs[5] = regs->a5;
3695 env->aregs[6] = regs->a6;
3696 env->aregs[7] = regs->usp;
3697 env->sr = regs->sr;
3698 ts->sim_syscalls = 1;
3700 #elif defined(TARGET_MICROBLAZE)
3702 env->regs[0] = regs->r0;
3703 env->regs[1] = regs->r1;
3704 env->regs[2] = regs->r2;
3705 env->regs[3] = regs->r3;
3706 env->regs[4] = regs->r4;
3707 env->regs[5] = regs->r5;
3708 env->regs[6] = regs->r6;
3709 env->regs[7] = regs->r7;
3710 env->regs[8] = regs->r8;
3711 env->regs[9] = regs->r9;
3712 env->regs[10] = regs->r10;
3713 env->regs[11] = regs->r11;
3714 env->regs[12] = regs->r12;
3715 env->regs[13] = regs->r13;
3716 env->regs[14] = regs->r14;
3717 env->regs[15] = regs->r15;
3718 env->regs[16] = regs->r16;
3719 env->regs[17] = regs->r17;
3720 env->regs[18] = regs->r18;
3721 env->regs[19] = regs->r19;
3722 env->regs[20] = regs->r20;
3723 env->regs[21] = regs->r21;
3724 env->regs[22] = regs->r22;
3725 env->regs[23] = regs->r23;
3726 env->regs[24] = regs->r24;
3727 env->regs[25] = regs->r25;
3728 env->regs[26] = regs->r26;
3729 env->regs[27] = regs->r27;
3730 env->regs[28] = regs->r28;
3731 env->regs[29] = regs->r29;
3732 env->regs[30] = regs->r30;
3733 env->regs[31] = regs->r31;
3734 env->sregs[SR_PC] = regs->pc;
3736 #elif defined(TARGET_MIPS)
3738 int i;
3740 for(i = 0; i < 32; i++) {
3741 env->active_tc.gpr[i] = regs->regs[i];
3743 env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1;
3744 if (regs->cp0_epc & 1) {
3745 env->hflags |= MIPS_HFLAG_M16;
3748 #elif defined(TARGET_SH4)
3750 int i;
3752 for(i = 0; i < 16; i++) {
3753 env->gregs[i] = regs->regs[i];
3755 env->pc = regs->pc;
3757 #elif defined(TARGET_ALPHA)
3759 int i;
3761 for(i = 0; i < 28; i++) {
3762 env->ir[i] = ((abi_ulong *)regs)[i];
3764 env->ir[IR_SP] = regs->usp;
3765 env->pc = regs->pc;
3767 #elif defined(TARGET_CRIS)
3769 env->regs[0] = regs->r0;
3770 env->regs[1] = regs->r1;
3771 env->regs[2] = regs->r2;
3772 env->regs[3] = regs->r3;
3773 env->regs[4] = regs->r4;
3774 env->regs[5] = regs->r5;
3775 env->regs[6] = regs->r6;
3776 env->regs[7] = regs->r7;
3777 env->regs[8] = regs->r8;
3778 env->regs[9] = regs->r9;
3779 env->regs[10] = regs->r10;
3780 env->regs[11] = regs->r11;
3781 env->regs[12] = regs->r12;
3782 env->regs[13] = regs->r13;
3783 env->regs[14] = info->start_stack;
3784 env->regs[15] = regs->acr;
3785 env->pc = regs->erp;
3787 #elif defined(TARGET_S390X)
3789 int i;
3790 for (i = 0; i < 16; i++) {
3791 env->regs[i] = regs->gprs[i];
3793 env->psw.mask = regs->psw.mask;
3794 env->psw.addr = regs->psw.addr;
3796 #else
3797 #error unsupported target CPU
3798 #endif
3800 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
3801 ts->stack_base = info->start_stack;
3802 ts->heap_base = info->brk;
3803 /* This will be filled in on the first SYS_HEAPINFO call. */
3804 ts->heap_limit = 0;
3805 #endif
3807 if (gdbstub_port) {
3808 if (gdbserver_start(gdbstub_port) < 0) {
3809 fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
3810 gdbstub_port);
3811 exit(1);
3813 gdb_handlesig(env, 0);
3815 cpu_loop(env);
3816 /* never exits */
3817 return 0;