cirrus: fix off-by-one in cirrus_bitblt_rop_bkwd_transp_*_16
[qemu.git] / linux-user / main.c
1 /*
2 * qemu user main
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "qemu/osdep.h"
20 #include "qemu-version.h"
21 #include <sys/syscall.h>
22 #include <sys/resource.h>
23
24 #include "qapi/error.h"
25 #include "qemu.h"
26 #include "qemu/path.h"
27 #include "qemu/config-file.h"
28 #include "qemu/cutils.h"
29 #include "qemu/help_option.h"
30 #include "cpu.h"
31 #include "exec/exec-all.h"
32 #include "tcg.h"
33 #include "qemu/timer.h"
34 #include "qemu/envlist.h"
35 #include "elf.h"
36 #include "exec/log.h"
37 #include "trace/control.h"
38 #include "glib-compat.h"
39
40 char *exec_path;
41
42 int singlestep;
43 static const char *filename;
44 static const char *argv0;
45 static int gdbstub_port;
46 static envlist_t *envlist;
47 static const char *cpu_model;
48 unsigned long mmap_min_addr;
49 unsigned long guest_base;
50 int have_guest_base;
51
52 #define EXCP_DUMP(env, fmt, ...) \
53 do { \
54 CPUState *cs = ENV_GET_CPU(env); \
55 fprintf(stderr, fmt , ## __VA_ARGS__); \
56 cpu_dump_state(cs, stderr, fprintf, 0); \
57 if (qemu_log_separate()) { \
58 qemu_log(fmt, ## __VA_ARGS__); \
59 log_cpu_state(cs, 0); \
60 } \
61 } while (0)
62
63 #if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
64 /*
65 * When running 32-on-64 we should make sure we can fit all of the possible
66 * guest address space into a contiguous chunk of virtual host memory.
67 *
68 * This way we will never overlap with our own libraries or binaries or stack
69 * or anything else that QEMU maps.
70 */
71 # if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
72 /*
73 * MIPS only supports 31 bits of virtual address space for user space.
74 * Nios2 also only supports 31 bits.
75 */
76 unsigned long reserved_va = 0x77000000;
77 # else
78 unsigned long reserved_va = 0xf7000000;
79 # endif
80 #else
81 unsigned long reserved_va;
82 #endif
83
84 static void usage(int exitcode);
85
86 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
87 const char *qemu_uname_release;
88
89 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
90 we allocate a bigger stack. Need a better solution, for example
91 by remapping the process stack directly at the right place */
92 unsigned long guest_stack_size = 8 * 1024 * 1024UL;
93
94 void gemu_log(const char *fmt, ...)
95 {
96 va_list ap;
97
98 va_start(ap, fmt);
99 vfprintf(stderr, fmt, ap);
100 va_end(ap);
101 }
102
103 #if defined(TARGET_I386)
104 int cpu_get_pic_interrupt(CPUX86State *env)
105 {
106 return -1;
107 }
108 #endif
109
110 /***********************************************************/
111 /* Helper routines for implementing atomic operations. */
112
113 /* Make sure everything is in a consistent state for calling fork(). */
114 void fork_start(void)
115 {
116 cpu_list_lock();
117 qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
118 mmap_fork_start();
119 }
120
121 void fork_end(int child)
122 {
123 mmap_fork_end(child);
124 if (child) {
125 CPUState *cpu, *next_cpu;
126 /* Child processes created by fork() only have a single thread.
127 Discard information about the parent threads. */
128 CPU_FOREACH_SAFE(cpu, next_cpu) {
129 if (cpu != thread_cpu) {
130 QTAILQ_REMOVE(&cpus, cpu, node);
131 }
132 }
133 qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
134 qemu_init_cpu_list();
135 gdbserver_fork(thread_cpu);
136 } else {
137 qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
138 cpu_list_unlock();
139 }
140 }
141
142 #ifdef TARGET_I386
143 /***********************************************************/
144 /* CPUX86 core interface */
145
146 uint64_t cpu_get_tsc(CPUX86State *env)
147 {
148 return cpu_get_host_ticks();
149 }
150
151 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
152 int flags)
153 {
154 unsigned int e1, e2;
155 uint32_t *p;
156 e1 = (addr << 16) | (limit & 0xffff);
157 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
158 e2 |= flags;
159 p = ptr;
160 p[0] = tswap32(e1);
161 p[1] = tswap32(e2);
162 }
163
164 static uint64_t *idt_table;
165 #ifdef TARGET_X86_64
166 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
167 uint64_t addr, unsigned int sel)
168 {
169 uint32_t *p, e1, e2;
170 e1 = (addr & 0xffff) | (sel << 16);
171 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
172 p = ptr;
173 p[0] = tswap32(e1);
174 p[1] = tswap32(e2);
175 p[2] = tswap32(addr >> 32);
176 p[3] = 0;
177 }
178 /* only dpl matters as we do only user space emulation */
179 static void set_idt(int n, unsigned int dpl)
180 {
181 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
182 }
183 #else
184 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
185 uint32_t addr, unsigned int sel)
186 {
187 uint32_t *p, e1, e2;
188 e1 = (addr & 0xffff) | (sel << 16);
189 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
190 p = ptr;
191 p[0] = tswap32(e1);
192 p[1] = tswap32(e2);
193 }
194
195 /* only dpl matters as we do only user space emulation */
196 static void set_idt(int n, unsigned int dpl)
197 {
198 set_gate(idt_table + n, 0, dpl, 0, 0);
199 }
200 #endif
201
202 void cpu_loop(CPUX86State *env)
203 {
204 CPUState *cs = CPU(x86_env_get_cpu(env));
205 int trapnr;
206 abi_ulong pc;
207 abi_ulong ret;
208 target_siginfo_t info;
209
210 for(;;) {
211 cpu_exec_start(cs);
212 trapnr = cpu_exec(cs);
213 cpu_exec_end(cs);
214 process_queued_cpu_work(cs);
215
216 switch(trapnr) {
217 case 0x80:
218 /* linux syscall from int $0x80 */
219 ret = do_syscall(env,
220 env->regs[R_EAX],
221 env->regs[R_EBX],
222 env->regs[R_ECX],
223 env->regs[R_EDX],
224 env->regs[R_ESI],
225 env->regs[R_EDI],
226 env->regs[R_EBP],
227 0, 0);
228 if (ret == -TARGET_ERESTARTSYS) {
229 env->eip -= 2;
230 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
231 env->regs[R_EAX] = ret;
232 }
233 break;
234 #ifndef TARGET_ABI32
235 case EXCP_SYSCALL:
236 /* linux syscall from syscall instruction */
237 ret = do_syscall(env,
238 env->regs[R_EAX],
239 env->regs[R_EDI],
240 env->regs[R_ESI],
241 env->regs[R_EDX],
242 env->regs[10],
243 env->regs[8],
244 env->regs[9],
245 0, 0);
246 if (ret == -TARGET_ERESTARTSYS) {
247 env->eip -= 2;
248 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
249 env->regs[R_EAX] = ret;
250 }
251 break;
252 #endif
253 case EXCP0B_NOSEG:
254 case EXCP0C_STACK:
255 info.si_signo = TARGET_SIGBUS;
256 info.si_errno = 0;
257 info.si_code = TARGET_SI_KERNEL;
258 info._sifields._sigfault._addr = 0;
259 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
260 break;
261 case EXCP0D_GPF:
262 /* XXX: potential problem if ABI32 */
263 #ifndef TARGET_X86_64
264 if (env->eflags & VM_MASK) {
265 handle_vm86_fault(env);
266 } else
267 #endif
268 {
269 info.si_signo = TARGET_SIGSEGV;
270 info.si_errno = 0;
271 info.si_code = TARGET_SI_KERNEL;
272 info._sifields._sigfault._addr = 0;
273 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
274 }
275 break;
276 case EXCP0E_PAGE:
277 info.si_signo = TARGET_SIGSEGV;
278 info.si_errno = 0;
279 if (!(env->error_code & 1))
280 info.si_code = TARGET_SEGV_MAPERR;
281 else
282 info.si_code = TARGET_SEGV_ACCERR;
283 info._sifields._sigfault._addr = env->cr[2];
284 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
285 break;
286 case EXCP00_DIVZ:
287 #ifndef TARGET_X86_64
288 if (env->eflags & VM_MASK) {
289 handle_vm86_trap(env, trapnr);
290 } else
291 #endif
292 {
293 /* division by zero */
294 info.si_signo = TARGET_SIGFPE;
295 info.si_errno = 0;
296 info.si_code = TARGET_FPE_INTDIV;
297 info._sifields._sigfault._addr = env->eip;
298 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
299 }
300 break;
301 case EXCP01_DB:
302 case EXCP03_INT3:
303 #ifndef TARGET_X86_64
304 if (env->eflags & VM_MASK) {
305 handle_vm86_trap(env, trapnr);
306 } else
307 #endif
308 {
309 info.si_signo = TARGET_SIGTRAP;
310 info.si_errno = 0;
311 if (trapnr == EXCP01_DB) {
312 info.si_code = TARGET_TRAP_BRKPT;
313 info._sifields._sigfault._addr = env->eip;
314 } else {
315 info.si_code = TARGET_SI_KERNEL;
316 info._sifields._sigfault._addr = 0;
317 }
318 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
319 }
320 break;
321 case EXCP04_INTO:
322 case EXCP05_BOUND:
323 #ifndef TARGET_X86_64
324 if (env->eflags & VM_MASK) {
325 handle_vm86_trap(env, trapnr);
326 } else
327 #endif
328 {
329 info.si_signo = TARGET_SIGSEGV;
330 info.si_errno = 0;
331 info.si_code = TARGET_SI_KERNEL;
332 info._sifields._sigfault._addr = 0;
333 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
334 }
335 break;
336 case EXCP06_ILLOP:
337 info.si_signo = TARGET_SIGILL;
338 info.si_errno = 0;
339 info.si_code = TARGET_ILL_ILLOPN;
340 info._sifields._sigfault._addr = env->eip;
341 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
342 break;
343 case EXCP_INTERRUPT:
344 /* just indicate that signals should be handled asap */
345 break;
346 case EXCP_DEBUG:
347 {
348 int sig;
349
350 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
351 if (sig)
352 {
353 info.si_signo = sig;
354 info.si_errno = 0;
355 info.si_code = TARGET_TRAP_BRKPT;
356 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
357 }
358 }
359 break;
360 case EXCP_ATOMIC:
361 cpu_exec_step_atomic(cs);
362 break;
363 default:
364 pc = env->segs[R_CS].base + env->eip;
365 EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
366 (long)pc, trapnr);
367 abort();
368 }
369 process_pending_signals(env);
370 }
371 }
372 #endif
373
374 #ifdef TARGET_ARM
375
376 #define get_user_code_u32(x, gaddr, env) \
377 ({ abi_long __r = get_user_u32((x), (gaddr)); \
378 if (!__r && bswap_code(arm_sctlr_b(env))) { \
379 (x) = bswap32(x); \
380 } \
381 __r; \
382 })
383
384 #define get_user_code_u16(x, gaddr, env) \
385 ({ abi_long __r = get_user_u16((x), (gaddr)); \
386 if (!__r && bswap_code(arm_sctlr_b(env))) { \
387 (x) = bswap16(x); \
388 } \
389 __r; \
390 })
391
392 #define get_user_data_u32(x, gaddr, env) \
393 ({ abi_long __r = get_user_u32((x), (gaddr)); \
394 if (!__r && arm_cpu_bswap_data(env)) { \
395 (x) = bswap32(x); \
396 } \
397 __r; \
398 })
399
400 #define get_user_data_u16(x, gaddr, env) \
401 ({ abi_long __r = get_user_u16((x), (gaddr)); \
402 if (!__r && arm_cpu_bswap_data(env)) { \
403 (x) = bswap16(x); \
404 } \
405 __r; \
406 })
407
408 #define put_user_data_u32(x, gaddr, env) \
409 ({ typeof(x) __x = (x); \
410 if (arm_cpu_bswap_data(env)) { \
411 __x = bswap32(__x); \
412 } \
413 put_user_u32(__x, (gaddr)); \
414 })
415
416 #define put_user_data_u16(x, gaddr, env) \
417 ({ typeof(x) __x = (x); \
418 if (arm_cpu_bswap_data(env)) { \
419 __x = bswap16(__x); \
420 } \
421 put_user_u16(__x, (gaddr)); \
422 })
423
424 #ifdef TARGET_ABI32
425 /* Commpage handling -- there is no commpage for AArch64 */
426
427 /*
428 * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
429 * Input:
430 * r0 = pointer to oldval
431 * r1 = pointer to newval
432 * r2 = pointer to target value
433 *
434 * Output:
435 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
436 * C set if *ptr was changed, clear if no exchange happened
437 *
438 * Note segv's in kernel helpers are a bit tricky, we can set the
439 * data address sensibly but the PC address is just the entry point.
440 */
441 static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
442 {
443 uint64_t oldval, newval, val;
444 uint32_t addr, cpsr;
445 target_siginfo_t info;
446
447 /* Based on the 32 bit code in do_kernel_trap */
448
449 /* XXX: This only works between threads, not between processes.
450 It's probably possible to implement this with native host
451 operations. However things like ldrex/strex are much harder so
452 there's not much point trying. */
453 start_exclusive();
454 cpsr = cpsr_read(env);
455 addr = env->regs[2];
456
457 if (get_user_u64(oldval, env->regs[0])) {
458 env->exception.vaddress = env->regs[0];
459 goto segv;
460 };
461
462 if (get_user_u64(newval, env->regs[1])) {
463 env->exception.vaddress = env->regs[1];
464 goto segv;
465 };
466
467 if (get_user_u64(val, addr)) {
468 env->exception.vaddress = addr;
469 goto segv;
470 }
471
472 if (val == oldval) {
473 val = newval;
474
475 if (put_user_u64(val, addr)) {
476 env->exception.vaddress = addr;
477 goto segv;
478 };
479
480 env->regs[0] = 0;
481 cpsr |= CPSR_C;
482 } else {
483 env->regs[0] = -1;
484 cpsr &= ~CPSR_C;
485 }
486 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
487 end_exclusive();
488 return;
489
490 segv:
491 end_exclusive();
492 /* We get the PC of the entry address - which is as good as anything,
493 on a real kernel what you get depends on which mode it uses. */
494 info.si_signo = TARGET_SIGSEGV;
495 info.si_errno = 0;
496 /* XXX: check env->error_code */
497 info.si_code = TARGET_SEGV_MAPERR;
498 info._sifields._sigfault._addr = env->exception.vaddress;
499 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
500 }
501
502 /* Handle a jump to the kernel code page. */
503 static int
504 do_kernel_trap(CPUARMState *env)
505 {
506 uint32_t addr;
507 uint32_t cpsr;
508 uint32_t val;
509
510 switch (env->regs[15]) {
511 case 0xffff0fa0: /* __kernel_memory_barrier */
512 /* ??? No-op. Will need to do better for SMP. */
513 break;
514 case 0xffff0fc0: /* __kernel_cmpxchg */
515 /* XXX: This only works between threads, not between processes.
516 It's probably possible to implement this with native host
517 operations. However things like ldrex/strex are much harder so
518 there's not much point trying. */
519 start_exclusive();
520 cpsr = cpsr_read(env);
521 addr = env->regs[2];
522 /* FIXME: This should SEGV if the access fails. */
523 if (get_user_u32(val, addr))
524 val = ~env->regs[0];
525 if (val == env->regs[0]) {
526 val = env->regs[1];
527 /* FIXME: Check for segfaults. */
528 put_user_u32(val, addr);
529 env->regs[0] = 0;
530 cpsr |= CPSR_C;
531 } else {
532 env->regs[0] = -1;
533 cpsr &= ~CPSR_C;
534 }
535 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
536 end_exclusive();
537 break;
538 case 0xffff0fe0: /* __kernel_get_tls */
539 env->regs[0] = cpu_get_tls(env);
540 break;
541 case 0xffff0f60: /* __kernel_cmpxchg64 */
542 arm_kernel_cmpxchg64_helper(env);
543 break;
544
545 default:
546 return 1;
547 }
548 /* Jump back to the caller. */
549 addr = env->regs[14];
550 if (addr & 1) {
551 env->thumb = 1;
552 addr &= ~1;
553 }
554 env->regs[15] = addr;
555
556 return 0;
557 }
558
559 void cpu_loop(CPUARMState *env)
560 {
561 CPUState *cs = CPU(arm_env_get_cpu(env));
562 int trapnr;
563 unsigned int n, insn;
564 target_siginfo_t info;
565 uint32_t addr;
566 abi_ulong ret;
567
568 for(;;) {
569 cpu_exec_start(cs);
570 trapnr = cpu_exec(cs);
571 cpu_exec_end(cs);
572 process_queued_cpu_work(cs);
573
574 switch(trapnr) {
575 case EXCP_UDEF:
576 case EXCP_NOCP:
577 case EXCP_INVSTATE:
578 {
579 TaskState *ts = cs->opaque;
580 uint32_t opcode;
581 int rc;
582
583 /* we handle the FPU emulation here, as Linux */
584 /* we get the opcode */
585 /* FIXME - what to do if get_user() fails? */
586 get_user_code_u32(opcode, env->regs[15], env);
587
588 rc = EmulateAll(opcode, &ts->fpa, env);
589 if (rc == 0) { /* illegal instruction */
590 info.si_signo = TARGET_SIGILL;
591 info.si_errno = 0;
592 info.si_code = TARGET_ILL_ILLOPN;
593 info._sifields._sigfault._addr = env->regs[15];
594 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
595 } else if (rc < 0) { /* FP exception */
596 int arm_fpe=0;
597
598 /* translate softfloat flags to FPSR flags */
599 if (-rc & float_flag_invalid)
600 arm_fpe |= BIT_IOC;
601 if (-rc & float_flag_divbyzero)
602 arm_fpe |= BIT_DZC;
603 if (-rc & float_flag_overflow)
604 arm_fpe |= BIT_OFC;
605 if (-rc & float_flag_underflow)
606 arm_fpe |= BIT_UFC;
607 if (-rc & float_flag_inexact)
608 arm_fpe |= BIT_IXC;
609
610 FPSR fpsr = ts->fpa.fpsr;
611 //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
612
613 if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
614 info.si_signo = TARGET_SIGFPE;
615 info.si_errno = 0;
616
617 /* ordered by priority, least first */
618 if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
619 if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
620 if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
621 if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
622 if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
623
624 info._sifields._sigfault._addr = env->regs[15];
625 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
626 } else {
627 env->regs[15] += 4;
628 }
629
630 /* accumulate unenabled exceptions */
631 if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
632 fpsr |= BIT_IXC;
633 if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
634 fpsr |= BIT_UFC;
635 if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
636 fpsr |= BIT_OFC;
637 if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
638 fpsr |= BIT_DZC;
639 if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
640 fpsr |= BIT_IOC;
641 ts->fpa.fpsr=fpsr;
642 } else { /* everything OK */
643 /* increment PC */
644 env->regs[15] += 4;
645 }
646 }
647 break;
648 case EXCP_SWI:
649 case EXCP_BKPT:
650 {
651 env->eabi = 1;
652 /* system call */
653 if (trapnr == EXCP_BKPT) {
654 if (env->thumb) {
655 /* FIXME - what to do if get_user() fails? */
656 get_user_code_u16(insn, env->regs[15], env);
657 n = insn & 0xff;
658 env->regs[15] += 2;
659 } else {
660 /* FIXME - what to do if get_user() fails? */
661 get_user_code_u32(insn, env->regs[15], env);
662 n = (insn & 0xf) | ((insn >> 4) & 0xff0);
663 env->regs[15] += 4;
664 }
665 } else {
666 if (env->thumb) {
667 /* FIXME - what to do if get_user() fails? */
668 get_user_code_u16(insn, env->regs[15] - 2, env);
669 n = insn & 0xff;
670 } else {
671 /* FIXME - what to do if get_user() fails? */
672 get_user_code_u32(insn, env->regs[15] - 4, env);
673 n = insn & 0xffffff;
674 }
675 }
676
677 if (n == ARM_NR_cacheflush) {
678 /* nop */
679 } else if (n == ARM_NR_semihosting
680 || n == ARM_NR_thumb_semihosting) {
681 env->regs[0] = do_arm_semihosting (env);
682 } else if (n == 0 || n >= ARM_SYSCALL_BASE || env->thumb) {
683 /* linux syscall */
684 if (env->thumb || n == 0) {
685 n = env->regs[7];
686 } else {
687 n -= ARM_SYSCALL_BASE;
688 env->eabi = 0;
689 }
690 if ( n > ARM_NR_BASE) {
691 switch (n) {
692 case ARM_NR_cacheflush:
693 /* nop */
694 break;
695 case ARM_NR_set_tls:
696 cpu_set_tls(env, env->regs[0]);
697 env->regs[0] = 0;
698 break;
699 case ARM_NR_breakpoint:
700 env->regs[15] -= env->thumb ? 2 : 4;
701 goto excp_debug;
702 default:
703 gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
704 n);
705 env->regs[0] = -TARGET_ENOSYS;
706 break;
707 }
708 } else {
709 ret = do_syscall(env,
710 n,
711 env->regs[0],
712 env->regs[1],
713 env->regs[2],
714 env->regs[3],
715 env->regs[4],
716 env->regs[5],
717 0, 0);
718 if (ret == -TARGET_ERESTARTSYS) {
719 env->regs[15] -= env->thumb ? 2 : 4;
720 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
721 env->regs[0] = ret;
722 }
723 }
724 } else {
725 goto error;
726 }
727 }
728 break;
729 case EXCP_SEMIHOST:
730 env->regs[0] = do_arm_semihosting(env);
731 break;
732 case EXCP_INTERRUPT:
733 /* just indicate that signals should be handled asap */
734 break;
735 case EXCP_PREFETCH_ABORT:
736 case EXCP_DATA_ABORT:
737 addr = env->exception.vaddress;
738 {
739 info.si_signo = TARGET_SIGSEGV;
740 info.si_errno = 0;
741 /* XXX: check env->error_code */
742 info.si_code = TARGET_SEGV_MAPERR;
743 info._sifields._sigfault._addr = addr;
744 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
745 }
746 break;
747 case EXCP_DEBUG:
748 excp_debug:
749 {
750 int sig;
751
752 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
753 if (sig)
754 {
755 info.si_signo = sig;
756 info.si_errno = 0;
757 info.si_code = TARGET_TRAP_BRKPT;
758 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
759 }
760 }
761 break;
762 case EXCP_KERNEL_TRAP:
763 if (do_kernel_trap(env))
764 goto error;
765 break;
766 case EXCP_YIELD:
767 /* nothing to do here for user-mode, just resume guest code */
768 break;
769 case EXCP_ATOMIC:
770 cpu_exec_step_atomic(cs);
771 break;
772 default:
773 error:
774 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
775 abort();
776 }
777 process_pending_signals(env);
778 }
779 }
780
781 #else
782
783 /* AArch64 main loop */
784 void cpu_loop(CPUARMState *env)
785 {
786 CPUState *cs = CPU(arm_env_get_cpu(env));
787 int trapnr, sig;
788 abi_long ret;
789 target_siginfo_t info;
790
791 for (;;) {
792 cpu_exec_start(cs);
793 trapnr = cpu_exec(cs);
794 cpu_exec_end(cs);
795 process_queued_cpu_work(cs);
796
797 switch (trapnr) {
798 case EXCP_SWI:
799 ret = do_syscall(env,
800 env->xregs[8],
801 env->xregs[0],
802 env->xregs[1],
803 env->xregs[2],
804 env->xregs[3],
805 env->xregs[4],
806 env->xregs[5],
807 0, 0);
808 if (ret == -TARGET_ERESTARTSYS) {
809 env->pc -= 4;
810 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
811 env->xregs[0] = ret;
812 }
813 break;
814 case EXCP_INTERRUPT:
815 /* just indicate that signals should be handled asap */
816 break;
817 case EXCP_UDEF:
818 info.si_signo = TARGET_SIGILL;
819 info.si_errno = 0;
820 info.si_code = TARGET_ILL_ILLOPN;
821 info._sifields._sigfault._addr = env->pc;
822 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
823 break;
824 case EXCP_PREFETCH_ABORT:
825 case EXCP_DATA_ABORT:
826 info.si_signo = TARGET_SIGSEGV;
827 info.si_errno = 0;
828 /* XXX: check env->error_code */
829 info.si_code = TARGET_SEGV_MAPERR;
830 info._sifields._sigfault._addr = env->exception.vaddress;
831 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
832 break;
833 case EXCP_DEBUG:
834 case EXCP_BKPT:
835 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
836 if (sig) {
837 info.si_signo = sig;
838 info.si_errno = 0;
839 info.si_code = TARGET_TRAP_BRKPT;
840 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
841 }
842 break;
843 case EXCP_SEMIHOST:
844 env->xregs[0] = do_arm_semihosting(env);
845 break;
846 case EXCP_YIELD:
847 /* nothing to do here for user-mode, just resume guest code */
848 break;
849 case EXCP_ATOMIC:
850 cpu_exec_step_atomic(cs);
851 break;
852 default:
853 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
854 abort();
855 }
856 process_pending_signals(env);
857 /* Exception return on AArch64 always clears the exclusive monitor,
858 * so any return to running guest code implies this.
859 */
860 env->exclusive_addr = -1;
861 }
862 }
863 #endif /* ndef TARGET_ABI32 */
864
865 #endif
866
867 #ifdef TARGET_UNICORE32
868
869 void cpu_loop(CPUUniCore32State *env)
870 {
871 CPUState *cs = CPU(uc32_env_get_cpu(env));
872 int trapnr;
873 unsigned int n, insn;
874 target_siginfo_t info;
875
876 for (;;) {
877 cpu_exec_start(cs);
878 trapnr = cpu_exec(cs);
879 cpu_exec_end(cs);
880 process_queued_cpu_work(cs);
881
882 switch (trapnr) {
883 case UC32_EXCP_PRIV:
884 {
885 /* system call */
886 get_user_u32(insn, env->regs[31] - 4);
887 n = insn & 0xffffff;
888
889 if (n >= UC32_SYSCALL_BASE) {
890 /* linux syscall */
891 n -= UC32_SYSCALL_BASE;
892 if (n == UC32_SYSCALL_NR_set_tls) {
893 cpu_set_tls(env, env->regs[0]);
894 env->regs[0] = 0;
895 } else {
896 abi_long ret = do_syscall(env,
897 n,
898 env->regs[0],
899 env->regs[1],
900 env->regs[2],
901 env->regs[3],
902 env->regs[4],
903 env->regs[5],
904 0, 0);
905 if (ret == -TARGET_ERESTARTSYS) {
906 env->regs[31] -= 4;
907 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
908 env->regs[0] = ret;
909 }
910 }
911 } else {
912 goto error;
913 }
914 }
915 break;
916 case UC32_EXCP_DTRAP:
917 case UC32_EXCP_ITRAP:
918 info.si_signo = TARGET_SIGSEGV;
919 info.si_errno = 0;
920 /* XXX: check env->error_code */
921 info.si_code = TARGET_SEGV_MAPERR;
922 info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
923 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
924 break;
925 case EXCP_INTERRUPT:
926 /* just indicate that signals should be handled asap */
927 break;
928 case EXCP_DEBUG:
929 {
930 int sig;
931
932 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
933 if (sig) {
934 info.si_signo = sig;
935 info.si_errno = 0;
936 info.si_code = TARGET_TRAP_BRKPT;
937 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
938 }
939 }
940 break;
941 case EXCP_ATOMIC:
942 cpu_exec_step_atomic(cs);
943 break;
944 default:
945 goto error;
946 }
947 process_pending_signals(env);
948 }
949
950 error:
951 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
952 abort();
953 }
954 #endif
955
956 #ifdef TARGET_SPARC
957 #define SPARC64_STACK_BIAS 2047
958
959 //#define DEBUG_WIN
960
961 /* WARNING: dealing with register windows _is_ complicated. More info
962 can be found at http://www.sics.se/~psm/sparcstack.html */
963 static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
964 {
965 index = (index + cwp * 16) % (16 * env->nwindows);
966 /* wrap handling : if cwp is on the last window, then we use the
967 registers 'after' the end */
968 if (index < 8 && env->cwp == env->nwindows - 1)
969 index += 16 * env->nwindows;
970 return index;
971 }
972
973 /* save the register window 'cwp1' */
974 static inline void save_window_offset(CPUSPARCState *env, int cwp1)
975 {
976 unsigned int i;
977 abi_ulong sp_ptr;
978
979 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
980 #ifdef TARGET_SPARC64
981 if (sp_ptr & 3)
982 sp_ptr += SPARC64_STACK_BIAS;
983 #endif
984 #if defined(DEBUG_WIN)
985 printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
986 sp_ptr, cwp1);
987 #endif
988 for(i = 0; i < 16; i++) {
989 /* FIXME - what to do if put_user() fails? */
990 put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
991 sp_ptr += sizeof(abi_ulong);
992 }
993 }
994
995 static void save_window(CPUSPARCState *env)
996 {
997 #ifndef TARGET_SPARC64
998 unsigned int new_wim;
999 new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
1000 ((1LL << env->nwindows) - 1);
1001 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1002 env->wim = new_wim;
1003 #else
1004 save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1005 env->cansave++;
1006 env->canrestore--;
1007 #endif
1008 }
1009
1010 static void restore_window(CPUSPARCState *env)
1011 {
1012 #ifndef TARGET_SPARC64
1013 unsigned int new_wim;
1014 #endif
1015 unsigned int i, cwp1;
1016 abi_ulong sp_ptr;
1017
1018 #ifndef TARGET_SPARC64
1019 new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
1020 ((1LL << env->nwindows) - 1);
1021 #endif
1022
1023 /* restore the invalid window */
1024 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1025 sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1026 #ifdef TARGET_SPARC64
1027 if (sp_ptr & 3)
1028 sp_ptr += SPARC64_STACK_BIAS;
1029 #endif
1030 #if defined(DEBUG_WIN)
1031 printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
1032 sp_ptr, cwp1);
1033 #endif
1034 for(i = 0; i < 16; i++) {
1035 /* FIXME - what to do if get_user() fails? */
1036 get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
1037 sp_ptr += sizeof(abi_ulong);
1038 }
1039 #ifdef TARGET_SPARC64
1040 env->canrestore++;
1041 if (env->cleanwin < env->nwindows - 1)
1042 env->cleanwin++;
1043 env->cansave--;
1044 #else
1045 env->wim = new_wim;
1046 #endif
1047 }
1048
1049 static void flush_windows(CPUSPARCState *env)
1050 {
1051 int offset, cwp1;
1052
1053 offset = 1;
1054 for(;;) {
1055 /* if restore would invoke restore_window(), then we can stop */
1056 cwp1 = cpu_cwp_inc(env, env->cwp + offset);
1057 #ifndef TARGET_SPARC64
1058 if (env->wim & (1 << cwp1))
1059 break;
1060 #else
1061 if (env->canrestore == 0)
1062 break;
1063 env->cansave++;
1064 env->canrestore--;
1065 #endif
1066 save_window_offset(env, cwp1);
1067 offset++;
1068 }
1069 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1070 #ifndef TARGET_SPARC64
1071 /* set wim so that restore will reload the registers */
1072 env->wim = 1 << cwp1;
1073 #endif
1074 #if defined(DEBUG_WIN)
1075 printf("flush_windows: nb=%d\n", offset - 1);
1076 #endif
1077 }
1078
1079 void cpu_loop (CPUSPARCState *env)
1080 {
1081 CPUState *cs = CPU(sparc_env_get_cpu(env));
1082 int trapnr;
1083 abi_long ret;
1084 target_siginfo_t info;
1085
1086 while (1) {
1087 cpu_exec_start(cs);
1088 trapnr = cpu_exec(cs);
1089 cpu_exec_end(cs);
1090 process_queued_cpu_work(cs);
1091
1092 /* Compute PSR before exposing state. */
1093 if (env->cc_op != CC_OP_FLAGS) {
1094 cpu_get_psr(env);
1095 }
1096
1097 switch (trapnr) {
1098 #ifndef TARGET_SPARC64
1099 case 0x88:
1100 case 0x90:
1101 #else
1102 case 0x110:
1103 case 0x16d:
1104 #endif
1105 ret = do_syscall (env, env->gregs[1],
1106 env->regwptr[0], env->regwptr[1],
1107 env->regwptr[2], env->regwptr[3],
1108 env->regwptr[4], env->regwptr[5],
1109 0, 0);
1110 if (ret == -TARGET_ERESTARTSYS || ret == -TARGET_QEMU_ESIGRETURN) {
1111 break;
1112 }
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
1126 }
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:
1150 {
1151 info.si_signo = TARGET_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, QEMU_SI_FAULT, &info);
1157 }
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:
1168 {
1169 info.si_signo = TARGET_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->dmmu.mmuregs[4];
1175 else
1176 info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
1177 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1178 }
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 TT_ILL_INSN:
1195 {
1196 info.si_signo = TARGET_SIGILL;
1197 info.si_errno = 0;
1198 info.si_code = TARGET_ILL_ILLOPC;
1199 info._sifields._sigfault._addr = env->pc;
1200 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1201 }
1202 break;
1203 case EXCP_DEBUG:
1204 {
1205 int sig;
1206
1207 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1208 if (sig)
1209 {
1210 info.si_signo = sig;
1211 info.si_errno = 0;
1212 info.si_code = TARGET_TRAP_BRKPT;
1213 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1214 }
1215 }
1216 break;
1217 case EXCP_ATOMIC:
1218 cpu_exec_step_atomic(cs);
1219 break;
1220 default:
1221 printf ("Unhandled trap: 0x%x\n", trapnr);
1222 cpu_dump_state(cs, stderr, fprintf, 0);
1223 exit(EXIT_FAILURE);
1224 }
1225 process_pending_signals (env);
1226 }
1227 }
1228
1229 #endif
1230
1231 #ifdef TARGET_PPC
1232 static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
1233 {
1234 return cpu_get_host_ticks();
1235 }
1236
1237 uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
1238 {
1239 return cpu_ppc_get_tb(env);
1240 }
1241
1242 uint32_t cpu_ppc_load_tbu(CPUPPCState *env)
1243 {
1244 return cpu_ppc_get_tb(env) >> 32;
1245 }
1246
1247 uint64_t cpu_ppc_load_atbl(CPUPPCState *env)
1248 {
1249 return cpu_ppc_get_tb(env);
1250 }
1251
1252 uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
1253 {
1254 return cpu_ppc_get_tb(env) >> 32;
1255 }
1256
1257 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
1258 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
1259
1260 uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
1261 {
1262 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
1263 }
1264
1265 /* XXX: to be fixed */
1266 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
1267 {
1268 return -1;
1269 }
1270
1271 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
1272 {
1273 return -1;
1274 }
1275
1276 static int do_store_exclusive(CPUPPCState *env)
1277 {
1278 target_ulong addr;
1279 target_ulong page_addr;
1280 target_ulong val, val2 __attribute__((unused)) = 0;
1281 int flags;
1282 int segv = 0;
1283
1284 addr = env->reserve_ea;
1285 page_addr = addr & TARGET_PAGE_MASK;
1286 start_exclusive();
1287 mmap_lock();
1288 flags = page_get_flags(page_addr);
1289 if ((flags & PAGE_READ) == 0) {
1290 segv = 1;
1291 } else {
1292 int reg = env->reserve_info & 0x1f;
1293 int size = env->reserve_info >> 5;
1294 int stored = 0;
1295
1296 if (addr == env->reserve_addr) {
1297 switch (size) {
1298 case 1: segv = get_user_u8(val, addr); break;
1299 case 2: segv = get_user_u16(val, addr); break;
1300 case 4: segv = get_user_u32(val, addr); break;
1301 #if defined(TARGET_PPC64)
1302 case 8: segv = get_user_u64(val, addr); break;
1303 case 16: {
1304 segv = get_user_u64(val, addr);
1305 if (!segv) {
1306 segv = get_user_u64(val2, addr + 8);
1307 }
1308 break;
1309 }
1310 #endif
1311 default: abort();
1312 }
1313 if (!segv && val == env->reserve_val) {
1314 val = env->gpr[reg];
1315 switch (size) {
1316 case 1: segv = put_user_u8(val, addr); break;
1317 case 2: segv = put_user_u16(val, addr); break;
1318 case 4: segv = put_user_u32(val, addr); break;
1319 #if defined(TARGET_PPC64)
1320 case 8: segv = put_user_u64(val, addr); break;
1321 case 16: {
1322 if (val2 == env->reserve_val2) {
1323 if (msr_le) {
1324 val2 = val;
1325 val = env->gpr[reg+1];
1326 } else {
1327 val2 = env->gpr[reg+1];
1328 }
1329 segv = put_user_u64(val, addr);
1330 if (!segv) {
1331 segv = put_user_u64(val2, addr + 8);
1332 }
1333 }
1334 break;
1335 }
1336 #endif
1337 default: abort();
1338 }
1339 if (!segv) {
1340 stored = 1;
1341 }
1342 }
1343 }
1344 env->crf[0] = (stored << 1) | xer_so;
1345 env->reserve_addr = (target_ulong)-1;
1346 }
1347 if (!segv) {
1348 env->nip += 4;
1349 }
1350 mmap_unlock();
1351 end_exclusive();
1352 return segv;
1353 }
1354
1355 void cpu_loop(CPUPPCState *env)
1356 {
1357 CPUState *cs = CPU(ppc_env_get_cpu(env));
1358 target_siginfo_t info;
1359 int trapnr;
1360 target_ulong ret;
1361
1362 for(;;) {
1363 cpu_exec_start(cs);
1364 trapnr = cpu_exec(cs);
1365 cpu_exec_end(cs);
1366 process_queued_cpu_work(cs);
1367
1368 switch(trapnr) {
1369 case POWERPC_EXCP_NONE:
1370 /* Just go on */
1371 break;
1372 case POWERPC_EXCP_CRITICAL: /* Critical input */
1373 cpu_abort(cs, "Critical interrupt while in user mode. "
1374 "Aborting\n");
1375 break;
1376 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1377 cpu_abort(cs, "Machine check exception while in user mode. "
1378 "Aborting\n");
1379 break;
1380 case POWERPC_EXCP_DSI: /* Data storage exception */
1381 /* XXX: check this. Seems bugged */
1382 switch (env->error_code & 0xFF000000) {
1383 case 0x40000000:
1384 case 0x42000000:
1385 info.si_signo = TARGET_SIGSEGV;
1386 info.si_errno = 0;
1387 info.si_code = TARGET_SEGV_MAPERR;
1388 break;
1389 case 0x04000000:
1390 info.si_signo = TARGET_SIGILL;
1391 info.si_errno = 0;
1392 info.si_code = TARGET_ILL_ILLADR;
1393 break;
1394 case 0x08000000:
1395 info.si_signo = TARGET_SIGSEGV;
1396 info.si_errno = 0;
1397 info.si_code = TARGET_SEGV_ACCERR;
1398 break;
1399 default:
1400 /* Let's send a regular segfault... */
1401 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1402 env->error_code);
1403 info.si_signo = TARGET_SIGSEGV;
1404 info.si_errno = 0;
1405 info.si_code = TARGET_SEGV_MAPERR;
1406 break;
1407 }
1408 info._sifields._sigfault._addr = env->nip;
1409 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1410 break;
1411 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1412 /* XXX: check this */
1413 switch (env->error_code & 0xFF000000) {
1414 case 0x40000000:
1415 info.si_signo = TARGET_SIGSEGV;
1416 info.si_errno = 0;
1417 info.si_code = TARGET_SEGV_MAPERR;
1418 break;
1419 case 0x10000000:
1420 case 0x08000000:
1421 info.si_signo = TARGET_SIGSEGV;
1422 info.si_errno = 0;
1423 info.si_code = TARGET_SEGV_ACCERR;
1424 break;
1425 default:
1426 /* Let's send a regular segfault... */
1427 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1428 env->error_code);
1429 info.si_signo = TARGET_SIGSEGV;
1430 info.si_errno = 0;
1431 info.si_code = TARGET_SEGV_MAPERR;
1432 break;
1433 }
1434 info._sifields._sigfault._addr = env->nip - 4;
1435 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1436 break;
1437 case POWERPC_EXCP_EXTERNAL: /* External input */
1438 cpu_abort(cs, "External interrupt while in user mode. "
1439 "Aborting\n");
1440 break;
1441 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1442 /* XXX: check this */
1443 info.si_signo = TARGET_SIGBUS;
1444 info.si_errno = 0;
1445 info.si_code = TARGET_BUS_ADRALN;
1446 info._sifields._sigfault._addr = env->nip;
1447 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1448 break;
1449 case POWERPC_EXCP_PROGRAM: /* Program exception */
1450 case POWERPC_EXCP_HV_EMU: /* HV emulation */
1451 /* XXX: check this */
1452 switch (env->error_code & ~0xF) {
1453 case POWERPC_EXCP_FP:
1454 info.si_signo = TARGET_SIGFPE;
1455 info.si_errno = 0;
1456 switch (env->error_code & 0xF) {
1457 case POWERPC_EXCP_FP_OX:
1458 info.si_code = TARGET_FPE_FLTOVF;
1459 break;
1460 case POWERPC_EXCP_FP_UX:
1461 info.si_code = TARGET_FPE_FLTUND;
1462 break;
1463 case POWERPC_EXCP_FP_ZX:
1464 case POWERPC_EXCP_FP_VXZDZ:
1465 info.si_code = TARGET_FPE_FLTDIV;
1466 break;
1467 case POWERPC_EXCP_FP_XX:
1468 info.si_code = TARGET_FPE_FLTRES;
1469 break;
1470 case POWERPC_EXCP_FP_VXSOFT:
1471 info.si_code = TARGET_FPE_FLTINV;
1472 break;
1473 case POWERPC_EXCP_FP_VXSNAN:
1474 case POWERPC_EXCP_FP_VXISI:
1475 case POWERPC_EXCP_FP_VXIDI:
1476 case POWERPC_EXCP_FP_VXIMZ:
1477 case POWERPC_EXCP_FP_VXVC:
1478 case POWERPC_EXCP_FP_VXSQRT:
1479 case POWERPC_EXCP_FP_VXCVI:
1480 info.si_code = TARGET_FPE_FLTSUB;
1481 break;
1482 default:
1483 EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
1484 env->error_code);
1485 break;
1486 }
1487 break;
1488 case POWERPC_EXCP_INVAL:
1489 info.si_signo = TARGET_SIGILL;
1490 info.si_errno = 0;
1491 switch (env->error_code & 0xF) {
1492 case POWERPC_EXCP_INVAL_INVAL:
1493 info.si_code = TARGET_ILL_ILLOPC;
1494 break;
1495 case POWERPC_EXCP_INVAL_LSWX:
1496 info.si_code = TARGET_ILL_ILLOPN;
1497 break;
1498 case POWERPC_EXCP_INVAL_SPR:
1499 info.si_code = TARGET_ILL_PRVREG;
1500 break;
1501 case POWERPC_EXCP_INVAL_FP:
1502 info.si_code = TARGET_ILL_COPROC;
1503 break;
1504 default:
1505 EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
1506 env->error_code & 0xF);
1507 info.si_code = TARGET_ILL_ILLADR;
1508 break;
1509 }
1510 break;
1511 case POWERPC_EXCP_PRIV:
1512 info.si_signo = TARGET_SIGILL;
1513 info.si_errno = 0;
1514 switch (env->error_code & 0xF) {
1515 case POWERPC_EXCP_PRIV_OPC:
1516 info.si_code = TARGET_ILL_PRVOPC;
1517 break;
1518 case POWERPC_EXCP_PRIV_REG:
1519 info.si_code = TARGET_ILL_PRVREG;
1520 break;
1521 default:
1522 EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
1523 env->error_code & 0xF);
1524 info.si_code = TARGET_ILL_PRVOPC;
1525 break;
1526 }
1527 break;
1528 case POWERPC_EXCP_TRAP:
1529 cpu_abort(cs, "Tried to call a TRAP\n");
1530 break;
1531 default:
1532 /* Should not happen ! */
1533 cpu_abort(cs, "Unknown program exception (%02x)\n",
1534 env->error_code);
1535 break;
1536 }
1537 info._sifields._sigfault._addr = env->nip;
1538 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1539 break;
1540 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1541 info.si_signo = TARGET_SIGILL;
1542 info.si_errno = 0;
1543 info.si_code = TARGET_ILL_COPROC;
1544 info._sifields._sigfault._addr = env->nip;
1545 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1546 break;
1547 case POWERPC_EXCP_SYSCALL: /* System call exception */
1548 cpu_abort(cs, "Syscall exception while in user mode. "
1549 "Aborting\n");
1550 break;
1551 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1552 info.si_signo = TARGET_SIGILL;
1553 info.si_errno = 0;
1554 info.si_code = TARGET_ILL_COPROC;
1555 info._sifields._sigfault._addr = env->nip;
1556 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1557 break;
1558 case POWERPC_EXCP_DECR: /* Decrementer exception */
1559 cpu_abort(cs, "Decrementer interrupt while in user mode. "
1560 "Aborting\n");
1561 break;
1562 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1563 cpu_abort(cs, "Fix interval timer interrupt while in user mode. "
1564 "Aborting\n");
1565 break;
1566 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1567 cpu_abort(cs, "Watchdog timer interrupt while in user mode. "
1568 "Aborting\n");
1569 break;
1570 case POWERPC_EXCP_DTLB: /* Data TLB error */
1571 cpu_abort(cs, "Data TLB exception while in user mode. "
1572 "Aborting\n");
1573 break;
1574 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1575 cpu_abort(cs, "Instruction TLB exception while in user mode. "
1576 "Aborting\n");
1577 break;
1578 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
1579 info.si_signo = TARGET_SIGILL;
1580 info.si_errno = 0;
1581 info.si_code = TARGET_ILL_COPROC;
1582 info._sifields._sigfault._addr = env->nip;
1583 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1584 break;
1585 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
1586 cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
1587 break;
1588 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
1589 cpu_abort(cs, "Embedded floating-point round IRQ not handled\n");
1590 break;
1591 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
1592 cpu_abort(cs, "Performance monitor exception not handled\n");
1593 break;
1594 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1595 cpu_abort(cs, "Doorbell interrupt while in user mode. "
1596 "Aborting\n");
1597 break;
1598 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1599 cpu_abort(cs, "Doorbell critical interrupt while in user mode. "
1600 "Aborting\n");
1601 break;
1602 case POWERPC_EXCP_RESET: /* System reset exception */
1603 cpu_abort(cs, "Reset interrupt while in user mode. "
1604 "Aborting\n");
1605 break;
1606 case POWERPC_EXCP_DSEG: /* Data segment exception */
1607 cpu_abort(cs, "Data segment exception while in user mode. "
1608 "Aborting\n");
1609 break;
1610 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1611 cpu_abort(cs, "Instruction segment exception "
1612 "while in user mode. Aborting\n");
1613 break;
1614 /* PowerPC 64 with hypervisor mode support */
1615 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1616 cpu_abort(cs, "Hypervisor decrementer interrupt "
1617 "while in user mode. Aborting\n");
1618 break;
1619 case POWERPC_EXCP_TRACE: /* Trace exception */
1620 /* Nothing to do:
1621 * we use this exception to emulate step-by-step execution mode.
1622 */
1623 break;
1624 /* PowerPC 64 with hypervisor mode support */
1625 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1626 cpu_abort(cs, "Hypervisor data storage exception "
1627 "while in user mode. Aborting\n");
1628 break;
1629 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
1630 cpu_abort(cs, "Hypervisor instruction storage exception "
1631 "while in user mode. Aborting\n");
1632 break;
1633 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
1634 cpu_abort(cs, "Hypervisor data segment exception "
1635 "while in user mode. Aborting\n");
1636 break;
1637 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
1638 cpu_abort(cs, "Hypervisor instruction segment exception "
1639 "while in user mode. Aborting\n");
1640 break;
1641 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1642 info.si_signo = TARGET_SIGILL;
1643 info.si_errno = 0;
1644 info.si_code = TARGET_ILL_COPROC;
1645 info._sifields._sigfault._addr = env->nip;
1646 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1647 break;
1648 case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
1649 cpu_abort(cs, "Programmable interval timer interrupt "
1650 "while in user mode. Aborting\n");
1651 break;
1652 case POWERPC_EXCP_IO: /* IO error exception */
1653 cpu_abort(cs, "IO error exception while in user mode. "
1654 "Aborting\n");
1655 break;
1656 case POWERPC_EXCP_RUNM: /* Run mode exception */
1657 cpu_abort(cs, "Run mode exception while in user mode. "
1658 "Aborting\n");
1659 break;
1660 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
1661 cpu_abort(cs, "Emulation trap exception not handled\n");
1662 break;
1663 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
1664 cpu_abort(cs, "Instruction fetch TLB exception "
1665 "while in user-mode. Aborting");
1666 break;
1667 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
1668 cpu_abort(cs, "Data load TLB exception while in user-mode. "
1669 "Aborting");
1670 break;
1671 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
1672 cpu_abort(cs, "Data store TLB exception while in user-mode. "
1673 "Aborting");
1674 break;
1675 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
1676 cpu_abort(cs, "Floating-point assist exception not handled\n");
1677 break;
1678 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
1679 cpu_abort(cs, "Instruction address breakpoint exception "
1680 "not handled\n");
1681 break;
1682 case POWERPC_EXCP_SMI: /* System management interrupt */
1683 cpu_abort(cs, "System management interrupt while in user mode. "
1684 "Aborting\n");
1685 break;
1686 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1687 cpu_abort(cs, "Thermal interrupt interrupt while in user mode. "
1688 "Aborting\n");
1689 break;
1690 case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
1691 cpu_abort(cs, "Performance monitor exception not handled\n");
1692 break;
1693 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1694 cpu_abort(cs, "Vector assist exception not handled\n");
1695 break;
1696 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
1697 cpu_abort(cs, "Soft patch exception not handled\n");
1698 break;
1699 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1700 cpu_abort(cs, "Maintenance exception while in user mode. "
1701 "Aborting\n");
1702 break;
1703 case POWERPC_EXCP_STOP: /* stop translation */
1704 /* We did invalidate the instruction cache. Go on */
1705 break;
1706 case POWERPC_EXCP_BRANCH: /* branch instruction: */
1707 /* We just stopped because of a branch. Go on */
1708 break;
1709 case POWERPC_EXCP_SYSCALL_USER:
1710 /* system call in user-mode emulation */
1711 /* WARNING:
1712 * PPC ABI uses overflow flag in cr0 to signal an error
1713 * in syscalls.
1714 */
1715 env->crf[0] &= ~0x1;
1716 env->nip += 4;
1717 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
1718 env->gpr[5], env->gpr[6], env->gpr[7],
1719 env->gpr[8], 0, 0);
1720 if (ret == -TARGET_ERESTARTSYS) {
1721 env->nip -= 4;
1722 break;
1723 }
1724 if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
1725 /* Returning from a successful sigreturn syscall.
1726 Avoid corrupting register state. */
1727 break;
1728 }
1729 if (ret > (target_ulong)(-515)) {
1730 env->crf[0] |= 0x1;
1731 ret = -ret;
1732 }
1733 env->gpr[3] = ret;
1734 break;
1735 case POWERPC_EXCP_STCX:
1736 if (do_store_exclusive(env)) {
1737 info.si_signo = TARGET_SIGSEGV;
1738 info.si_errno = 0;
1739 info.si_code = TARGET_SEGV_MAPERR;
1740 info._sifields._sigfault._addr = env->nip;
1741 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1742 }
1743 break;
1744 case EXCP_DEBUG:
1745 {
1746 int sig;
1747
1748 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
1749 if (sig) {
1750 info.si_signo = sig;
1751 info.si_errno = 0;
1752 info.si_code = TARGET_TRAP_BRKPT;
1753 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
1754 }
1755 }
1756 break;
1757 case EXCP_INTERRUPT:
1758 /* just indicate that signals should be handled asap */
1759 break;
1760 case EXCP_ATOMIC:
1761 cpu_exec_step_atomic(cs);
1762 break;
1763 default:
1764 cpu_abort(cs, "Unknown exception 0x%x. Aborting\n", trapnr);
1765 break;
1766 }
1767 process_pending_signals(env);
1768 }
1769 }
1770 #endif
1771
1772 #ifdef TARGET_MIPS
1773
1774 # ifdef TARGET_ABI_MIPSO32
1775 # define MIPS_SYS(name, args) args,
1776 static const uint8_t mips_syscall_args[] = {
1777 MIPS_SYS(sys_syscall , 8) /* 4000 */
1778 MIPS_SYS(sys_exit , 1)
1779 MIPS_SYS(sys_fork , 0)
1780 MIPS_SYS(sys_read , 3)
1781 MIPS_SYS(sys_write , 3)
1782 MIPS_SYS(sys_open , 3) /* 4005 */
1783 MIPS_SYS(sys_close , 1)
1784 MIPS_SYS(sys_waitpid , 3)
1785 MIPS_SYS(sys_creat , 2)
1786 MIPS_SYS(sys_link , 2)
1787 MIPS_SYS(sys_unlink , 1) /* 4010 */
1788 MIPS_SYS(sys_execve , 0)
1789 MIPS_SYS(sys_chdir , 1)
1790 MIPS_SYS(sys_time , 1)
1791 MIPS_SYS(sys_mknod , 3)
1792 MIPS_SYS(sys_chmod , 2) /* 4015 */
1793 MIPS_SYS(sys_lchown , 3)
1794 MIPS_SYS(sys_ni_syscall , 0)
1795 MIPS_SYS(sys_ni_syscall , 0) /* was sys_stat */
1796 MIPS_SYS(sys_lseek , 3)
1797 MIPS_SYS(sys_getpid , 0) /* 4020 */
1798 MIPS_SYS(sys_mount , 5)
1799 MIPS_SYS(sys_umount , 1)
1800 MIPS_SYS(sys_setuid , 1)
1801 MIPS_SYS(sys_getuid , 0)
1802 MIPS_SYS(sys_stime , 1) /* 4025 */
1803 MIPS_SYS(sys_ptrace , 4)
1804 MIPS_SYS(sys_alarm , 1)
1805 MIPS_SYS(sys_ni_syscall , 0) /* was sys_fstat */
1806 MIPS_SYS(sys_pause , 0)
1807 MIPS_SYS(sys_utime , 2) /* 4030 */
1808 MIPS_SYS(sys_ni_syscall , 0)
1809 MIPS_SYS(sys_ni_syscall , 0)
1810 MIPS_SYS(sys_access , 2)
1811 MIPS_SYS(sys_nice , 1)
1812 MIPS_SYS(sys_ni_syscall , 0) /* 4035 */
1813 MIPS_SYS(sys_sync , 0)
1814 MIPS_SYS(sys_kill , 2)
1815 MIPS_SYS(sys_rename , 2)
1816 MIPS_SYS(sys_mkdir , 2)
1817 MIPS_SYS(sys_rmdir , 1) /* 4040 */
1818 MIPS_SYS(sys_dup , 1)
1819 MIPS_SYS(sys_pipe , 0)
1820 MIPS_SYS(sys_times , 1)
1821 MIPS_SYS(sys_ni_syscall , 0)
1822 MIPS_SYS(sys_brk , 1) /* 4045 */
1823 MIPS_SYS(sys_setgid , 1)
1824 MIPS_SYS(sys_getgid , 0)
1825 MIPS_SYS(sys_ni_syscall , 0) /* was signal(2) */
1826 MIPS_SYS(sys_geteuid , 0)
1827 MIPS_SYS(sys_getegid , 0) /* 4050 */
1828 MIPS_SYS(sys_acct , 0)
1829 MIPS_SYS(sys_umount2 , 2)
1830 MIPS_SYS(sys_ni_syscall , 0)
1831 MIPS_SYS(sys_ioctl , 3)
1832 MIPS_SYS(sys_fcntl , 3) /* 4055 */
1833 MIPS_SYS(sys_ni_syscall , 2)
1834 MIPS_SYS(sys_setpgid , 2)
1835 MIPS_SYS(sys_ni_syscall , 0)
1836 MIPS_SYS(sys_olduname , 1)
1837 MIPS_SYS(sys_umask , 1) /* 4060 */
1838 MIPS_SYS(sys_chroot , 1)
1839 MIPS_SYS(sys_ustat , 2)
1840 MIPS_SYS(sys_dup2 , 2)
1841 MIPS_SYS(sys_getppid , 0)
1842 MIPS_SYS(sys_getpgrp , 0) /* 4065 */
1843 MIPS_SYS(sys_setsid , 0)
1844 MIPS_SYS(sys_sigaction , 3)
1845 MIPS_SYS(sys_sgetmask , 0)
1846 MIPS_SYS(sys_ssetmask , 1)
1847 MIPS_SYS(sys_setreuid , 2) /* 4070 */
1848 MIPS_SYS(sys_setregid , 2)
1849 MIPS_SYS(sys_sigsuspend , 0)
1850 MIPS_SYS(sys_sigpending , 1)
1851 MIPS_SYS(sys_sethostname , 2)
1852 MIPS_SYS(sys_setrlimit , 2) /* 4075 */
1853 MIPS_SYS(sys_getrlimit , 2)
1854 MIPS_SYS(sys_getrusage , 2)
1855 MIPS_SYS(sys_gettimeofday, 2)
1856 MIPS_SYS(sys_settimeofday, 2)
1857 MIPS_SYS(sys_getgroups , 2) /* 4080 */
1858 MIPS_SYS(sys_setgroups , 2)
1859 MIPS_SYS(sys_ni_syscall , 0) /* old_select */
1860 MIPS_SYS(sys_symlink , 2)
1861 MIPS_SYS(sys_ni_syscall , 0) /* was sys_lstat */
1862 MIPS_SYS(sys_readlink , 3) /* 4085 */
1863 MIPS_SYS(sys_uselib , 1)
1864 MIPS_SYS(sys_swapon , 2)
1865 MIPS_SYS(sys_reboot , 3)
1866 MIPS_SYS(old_readdir , 3)
1867 MIPS_SYS(old_mmap , 6) /* 4090 */
1868 MIPS_SYS(sys_munmap , 2)
1869 MIPS_SYS(sys_truncate , 2)
1870 MIPS_SYS(sys_ftruncate , 2)
1871 MIPS_SYS(sys_fchmod , 2)
1872 MIPS_SYS(sys_fchown , 3) /* 4095 */
1873 MIPS_SYS(sys_getpriority , 2)
1874 MIPS_SYS(sys_setpriority , 3)
1875 MIPS_SYS(sys_ni_syscall , 0)
1876 MIPS_SYS(sys_statfs , 2)
1877 MIPS_SYS(sys_fstatfs , 2) /* 4100 */
1878 MIPS_SYS(sys_ni_syscall , 0) /* was ioperm(2) */
1879 MIPS_SYS(sys_socketcall , 2)
1880 MIPS_SYS(sys_syslog , 3)
1881 MIPS_SYS(sys_setitimer , 3)
1882 MIPS_SYS(sys_getitimer , 2) /* 4105 */
1883 MIPS_SYS(sys_newstat , 2)
1884 MIPS_SYS(sys_newlstat , 2)
1885 MIPS_SYS(sys_newfstat , 2)
1886 MIPS_SYS(sys_uname , 1)
1887 MIPS_SYS(sys_ni_syscall , 0) /* 4110 was iopl(2) */
1888 MIPS_SYS(sys_vhangup , 0)
1889 MIPS_SYS(sys_ni_syscall , 0) /* was sys_idle() */
1890 MIPS_SYS(sys_ni_syscall , 0) /* was sys_vm86 */
1891 MIPS_SYS(sys_wait4 , 4)
1892 MIPS_SYS(sys_swapoff , 1) /* 4115 */
1893 MIPS_SYS(sys_sysinfo , 1)
1894 MIPS_SYS(sys_ipc , 6)
1895 MIPS_SYS(sys_fsync , 1)
1896 MIPS_SYS(sys_sigreturn , 0)
1897 MIPS_SYS(sys_clone , 6) /* 4120 */
1898 MIPS_SYS(sys_setdomainname, 2)
1899 MIPS_SYS(sys_newuname , 1)
1900 MIPS_SYS(sys_ni_syscall , 0) /* sys_modify_ldt */
1901 MIPS_SYS(sys_adjtimex , 1)
1902 MIPS_SYS(sys_mprotect , 3) /* 4125 */
1903 MIPS_SYS(sys_sigprocmask , 3)
1904 MIPS_SYS(sys_ni_syscall , 0) /* was create_module */
1905 MIPS_SYS(sys_init_module , 5)
1906 MIPS_SYS(sys_delete_module, 1)
1907 MIPS_SYS(sys_ni_syscall , 0) /* 4130 was get_kernel_syms */
1908 MIPS_SYS(sys_quotactl , 0)
1909 MIPS_SYS(sys_getpgid , 1)
1910 MIPS_SYS(sys_fchdir , 1)
1911 MIPS_SYS(sys_bdflush , 2)
1912 MIPS_SYS(sys_sysfs , 3) /* 4135 */
1913 MIPS_SYS(sys_personality , 1)
1914 MIPS_SYS(sys_ni_syscall , 0) /* for afs_syscall */
1915 MIPS_SYS(sys_setfsuid , 1)
1916 MIPS_SYS(sys_setfsgid , 1)
1917 MIPS_SYS(sys_llseek , 5) /* 4140 */
1918 MIPS_SYS(sys_getdents , 3)
1919 MIPS_SYS(sys_select , 5)
1920 MIPS_SYS(sys_flock , 2)
1921 MIPS_SYS(sys_msync , 3)
1922 MIPS_SYS(sys_readv , 3) /* 4145 */
1923 MIPS_SYS(sys_writev , 3)
1924 MIPS_SYS(sys_cacheflush , 3)
1925 MIPS_SYS(sys_cachectl , 3)
1926 MIPS_SYS(sys_sysmips , 4)
1927 MIPS_SYS(sys_ni_syscall , 0) /* 4150 */
1928 MIPS_SYS(sys_getsid , 1)
1929 MIPS_SYS(sys_fdatasync , 0)
1930 MIPS_SYS(sys_sysctl , 1)
1931 MIPS_SYS(sys_mlock , 2)
1932 MIPS_SYS(sys_munlock , 2) /* 4155 */
1933 MIPS_SYS(sys_mlockall , 1)
1934 MIPS_SYS(sys_munlockall , 0)
1935 MIPS_SYS(sys_sched_setparam, 2)
1936 MIPS_SYS(sys_sched_getparam, 2)
1937 MIPS_SYS(sys_sched_setscheduler, 3) /* 4160 */
1938 MIPS_SYS(sys_sched_getscheduler, 1)
1939 MIPS_SYS(sys_sched_yield , 0)
1940 MIPS_SYS(sys_sched_get_priority_max, 1)
1941 MIPS_SYS(sys_sched_get_priority_min, 1)
1942 MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */
1943 MIPS_SYS(sys_nanosleep, 2)
1944 MIPS_SYS(sys_mremap , 5)
1945 MIPS_SYS(sys_accept , 3)
1946 MIPS_SYS(sys_bind , 3)
1947 MIPS_SYS(sys_connect , 3) /* 4170 */
1948 MIPS_SYS(sys_getpeername , 3)
1949 MIPS_SYS(sys_getsockname , 3)
1950 MIPS_SYS(sys_getsockopt , 5)
1951 MIPS_SYS(sys_listen , 2)
1952 MIPS_SYS(sys_recv , 4) /* 4175 */
1953 MIPS_SYS(sys_recvfrom , 6)
1954 MIPS_SYS(sys_recvmsg , 3)
1955 MIPS_SYS(sys_send , 4)
1956 MIPS_SYS(sys_sendmsg , 3)
1957 MIPS_SYS(sys_sendto , 6) /* 4180 */
1958 MIPS_SYS(sys_setsockopt , 5)
1959 MIPS_SYS(sys_shutdown , 2)
1960 MIPS_SYS(sys_socket , 3)
1961 MIPS_SYS(sys_socketpair , 4)
1962 MIPS_SYS(sys_setresuid , 3) /* 4185 */
1963 MIPS_SYS(sys_getresuid , 3)
1964 MIPS_SYS(sys_ni_syscall , 0) /* was sys_query_module */
1965 MIPS_SYS(sys_poll , 3)
1966 MIPS_SYS(sys_nfsservctl , 3)
1967 MIPS_SYS(sys_setresgid , 3) /* 4190 */
1968 MIPS_SYS(sys_getresgid , 3)
1969 MIPS_SYS(sys_prctl , 5)
1970 MIPS_SYS(sys_rt_sigreturn, 0)
1971 MIPS_SYS(sys_rt_sigaction, 4)
1972 MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
1973 MIPS_SYS(sys_rt_sigpending, 2)
1974 MIPS_SYS(sys_rt_sigtimedwait, 4)
1975 MIPS_SYS(sys_rt_sigqueueinfo, 3)
1976 MIPS_SYS(sys_rt_sigsuspend, 0)
1977 MIPS_SYS(sys_pread64 , 6) /* 4200 */
1978 MIPS_SYS(sys_pwrite64 , 6)
1979 MIPS_SYS(sys_chown , 3)
1980 MIPS_SYS(sys_getcwd , 2)
1981 MIPS_SYS(sys_capget , 2)
1982 MIPS_SYS(sys_capset , 2) /* 4205 */
1983 MIPS_SYS(sys_sigaltstack , 2)
1984 MIPS_SYS(sys_sendfile , 4)
1985 MIPS_SYS(sys_ni_syscall , 0)
1986 MIPS_SYS(sys_ni_syscall , 0)
1987 MIPS_SYS(sys_mmap2 , 6) /* 4210 */
1988 MIPS_SYS(sys_truncate64 , 4)
1989 MIPS_SYS(sys_ftruncate64 , 4)
1990 MIPS_SYS(sys_stat64 , 2)
1991 MIPS_SYS(sys_lstat64 , 2)
1992 MIPS_SYS(sys_fstat64 , 2) /* 4215 */
1993 MIPS_SYS(sys_pivot_root , 2)
1994 MIPS_SYS(sys_mincore , 3)
1995 MIPS_SYS(sys_madvise , 3)
1996 MIPS_SYS(sys_getdents64 , 3)
1997 MIPS_SYS(sys_fcntl64 , 3) /* 4220 */
1998 MIPS_SYS(sys_ni_syscall , 0)
1999 MIPS_SYS(sys_gettid , 0)
2000 MIPS_SYS(sys_readahead , 5)
2001 MIPS_SYS(sys_setxattr , 5)
2002 MIPS_SYS(sys_lsetxattr , 5) /* 4225 */
2003 MIPS_SYS(sys_fsetxattr , 5)
2004 MIPS_SYS(sys_getxattr , 4)
2005 MIPS_SYS(sys_lgetxattr , 4)
2006 MIPS_SYS(sys_fgetxattr , 4)
2007 MIPS_SYS(sys_listxattr , 3) /* 4230 */
2008 MIPS_SYS(sys_llistxattr , 3)
2009 MIPS_SYS(sys_flistxattr , 3)
2010 MIPS_SYS(sys_removexattr , 2)
2011 MIPS_SYS(sys_lremovexattr, 2)
2012 MIPS_SYS(sys_fremovexattr, 2) /* 4235 */
2013 MIPS_SYS(sys_tkill , 2)
2014 MIPS_SYS(sys_sendfile64 , 5)
2015 MIPS_SYS(sys_futex , 6)
2016 MIPS_SYS(sys_sched_setaffinity, 3)
2017 MIPS_SYS(sys_sched_getaffinity, 3) /* 4240 */
2018 MIPS_SYS(sys_io_setup , 2)
2019 MIPS_SYS(sys_io_destroy , 1)
2020 MIPS_SYS(sys_io_getevents, 5)
2021 MIPS_SYS(sys_io_submit , 3)
2022 MIPS_SYS(sys_io_cancel , 3) /* 4245 */
2023 MIPS_SYS(sys_exit_group , 1)
2024 MIPS_SYS(sys_lookup_dcookie, 3)
2025 MIPS_SYS(sys_epoll_create, 1)
2026 MIPS_SYS(sys_epoll_ctl , 4)
2027 MIPS_SYS(sys_epoll_wait , 3) /* 4250 */
2028 MIPS_SYS(sys_remap_file_pages, 5)
2029 MIPS_SYS(sys_set_tid_address, 1)
2030 MIPS_SYS(sys_restart_syscall, 0)
2031 MIPS_SYS(sys_fadvise64_64, 7)
2032 MIPS_SYS(sys_statfs64 , 3) /* 4255 */
2033 MIPS_SYS(sys_fstatfs64 , 2)
2034 MIPS_SYS(sys_timer_create, 3)
2035 MIPS_SYS(sys_timer_settime, 4)
2036 MIPS_SYS(sys_timer_gettime, 2)
2037 MIPS_SYS(sys_timer_getoverrun, 1) /* 4260 */
2038 MIPS_SYS(sys_timer_delete, 1)
2039 MIPS_SYS(sys_clock_settime, 2)
2040 MIPS_SYS(sys_clock_gettime, 2)
2041 MIPS_SYS(sys_clock_getres, 2)
2042 MIPS_SYS(sys_clock_nanosleep, 4) /* 4265 */
2043 MIPS_SYS(sys_tgkill , 3)
2044 MIPS_SYS(sys_utimes , 2)
2045 MIPS_SYS(sys_mbind , 4)
2046 MIPS_SYS(sys_ni_syscall , 0) /* sys_get_mempolicy */
2047 MIPS_SYS(sys_ni_syscall , 0) /* 4270 sys_set_mempolicy */
2048 MIPS_SYS(sys_mq_open , 4)
2049 MIPS_SYS(sys_mq_unlink , 1)
2050 MIPS_SYS(sys_mq_timedsend, 5)
2051 MIPS_SYS(sys_mq_timedreceive, 5)
2052 MIPS_SYS(sys_mq_notify , 2) /* 4275 */
2053 MIPS_SYS(sys_mq_getsetattr, 3)
2054 MIPS_SYS(sys_ni_syscall , 0) /* sys_vserver */
2055 MIPS_SYS(sys_waitid , 4)
2056 MIPS_SYS(sys_ni_syscall , 0) /* available, was setaltroot */
2057 MIPS_SYS(sys_add_key , 5)
2058 MIPS_SYS(sys_request_key, 4)
2059 MIPS_SYS(sys_keyctl , 5)
2060 MIPS_SYS(sys_set_thread_area, 1)
2061 MIPS_SYS(sys_inotify_init, 0)
2062 MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
2063 MIPS_SYS(sys_inotify_rm_watch, 2)
2064 MIPS_SYS(sys_migrate_pages, 4)
2065 MIPS_SYS(sys_openat, 4)
2066 MIPS_SYS(sys_mkdirat, 3)
2067 MIPS_SYS(sys_mknodat, 4) /* 4290 */
2068 MIPS_SYS(sys_fchownat, 5)
2069 MIPS_SYS(sys_futimesat, 3)
2070 MIPS_SYS(sys_fstatat64, 4)
2071 MIPS_SYS(sys_unlinkat, 3)
2072 MIPS_SYS(sys_renameat, 4) /* 4295 */
2073 MIPS_SYS(sys_linkat, 5)
2074 MIPS_SYS(sys_symlinkat, 3)
2075 MIPS_SYS(sys_readlinkat, 4)
2076 MIPS_SYS(sys_fchmodat, 3)
2077 MIPS_SYS(sys_faccessat, 3) /* 4300 */
2078 MIPS_SYS(sys_pselect6, 6)
2079 MIPS_SYS(sys_ppoll, 5)
2080 MIPS_SYS(sys_unshare, 1)
2081 MIPS_SYS(sys_splice, 6)
2082 MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
2083 MIPS_SYS(sys_tee, 4)
2084 MIPS_SYS(sys_vmsplice, 4)
2085 MIPS_SYS(sys_move_pages, 6)
2086 MIPS_SYS(sys_set_robust_list, 2)
2087 MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
2088 MIPS_SYS(sys_kexec_load, 4)
2089 MIPS_SYS(sys_getcpu, 3)
2090 MIPS_SYS(sys_epoll_pwait, 6)
2091 MIPS_SYS(sys_ioprio_set, 3)
2092 MIPS_SYS(sys_ioprio_get, 2)
2093 MIPS_SYS(sys_utimensat, 4)
2094 MIPS_SYS(sys_signalfd, 3)
2095 MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
2096 MIPS_SYS(sys_eventfd, 1)
2097 MIPS_SYS(sys_fallocate, 6) /* 4320 */
2098 MIPS_SYS(sys_timerfd_create, 2)
2099 MIPS_SYS(sys_timerfd_gettime, 2)
2100 MIPS_SYS(sys_timerfd_settime, 4)
2101 MIPS_SYS(sys_signalfd4, 4)
2102 MIPS_SYS(sys_eventfd2, 2) /* 4325 */
2103 MIPS_SYS(sys_epoll_create1, 1)
2104 MIPS_SYS(sys_dup3, 3)
2105 MIPS_SYS(sys_pipe2, 2)
2106 MIPS_SYS(sys_inotify_init1, 1)
2107 MIPS_SYS(sys_preadv, 5) /* 4330 */
2108 MIPS_SYS(sys_pwritev, 5)
2109 MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
2110 MIPS_SYS(sys_perf_event_open, 5)
2111 MIPS_SYS(sys_accept4, 4)
2112 MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
2113 MIPS_SYS(sys_fanotify_init, 2)
2114 MIPS_SYS(sys_fanotify_mark, 6)
2115 MIPS_SYS(sys_prlimit64, 4)
2116 MIPS_SYS(sys_name_to_handle_at, 5)
2117 MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
2118 MIPS_SYS(sys_clock_adjtime, 2)
2119 MIPS_SYS(sys_syncfs, 1)
2120 MIPS_SYS(sys_sendmmsg, 4)
2121 MIPS_SYS(sys_setns, 2)
2122 MIPS_SYS(sys_process_vm_readv, 6) /* 345 */
2123 MIPS_SYS(sys_process_vm_writev, 6)
2124 MIPS_SYS(sys_kcmp, 5)
2125 MIPS_SYS(sys_finit_module, 3)
2126 MIPS_SYS(sys_sched_setattr, 2)
2127 MIPS_SYS(sys_sched_getattr, 3) /* 350 */
2128 MIPS_SYS(sys_renameat2, 5)
2129 MIPS_SYS(sys_seccomp, 3)
2130 MIPS_SYS(sys_getrandom, 3)
2131 MIPS_SYS(sys_memfd_create, 2)
2132 MIPS_SYS(sys_bpf, 3) /* 355 */
2133 MIPS_SYS(sys_execveat, 5)
2134 MIPS_SYS(sys_userfaultfd, 1)
2135 MIPS_SYS(sys_membarrier, 2)
2136 MIPS_SYS(sys_mlock2, 3)
2137 MIPS_SYS(sys_copy_file_range, 6) /* 360 */
2138 MIPS_SYS(sys_preadv2, 6)
2139 MIPS_SYS(sys_pwritev2, 6)
2140 };
2141 # undef MIPS_SYS
2142 # endif /* O32 */
2143
2144 static int do_store_exclusive(CPUMIPSState *env)
2145 {
2146 target_ulong addr;
2147 target_ulong page_addr;
2148 target_ulong val;
2149 int flags;
2150 int segv = 0;
2151 int reg;
2152 int d;
2153
2154 addr = env->lladdr;
2155 page_addr = addr & TARGET_PAGE_MASK;
2156 start_exclusive();
2157 mmap_lock();
2158 flags = page_get_flags(page_addr);
2159 if ((flags & PAGE_READ) == 0) {
2160 segv = 1;
2161 } else {
2162 reg = env->llreg & 0x1f;
2163 d = (env->llreg & 0x20) != 0;
2164 if (d) {
2165 segv = get_user_s64(val, addr);
2166 } else {
2167 segv = get_user_s32(val, addr);
2168 }
2169 if (!segv) {
2170 if (val != env->llval) {
2171 env->active_tc.gpr[reg] = 0;
2172 } else {
2173 if (d) {
2174 segv = put_user_u64(env->llnewval, addr);
2175 } else {
2176 segv = put_user_u32(env->llnewval, addr);
2177 }
2178 if (!segv) {
2179 env->active_tc.gpr[reg] = 1;
2180 }
2181 }
2182 }
2183 }
2184 env->lladdr = -1;
2185 if (!segv) {
2186 env->active_tc.PC += 4;
2187 }
2188 mmap_unlock();
2189 end_exclusive();
2190 return segv;
2191 }
2192
2193 /* Break codes */
2194 enum {
2195 BRK_OVERFLOW = 6,
2196 BRK_DIVZERO = 7
2197 };
2198
2199 static int do_break(CPUMIPSState *env, target_siginfo_t *info,
2200 unsigned int code)
2201 {
2202 int ret = -1;
2203
2204 switch (code) {
2205 case BRK_OVERFLOW:
2206 case BRK_DIVZERO:
2207 info->si_signo = TARGET_SIGFPE;
2208 info->si_errno = 0;
2209 info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
2210 queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
2211 ret = 0;
2212 break;
2213 default:
2214 info->si_signo = TARGET_SIGTRAP;
2215 info->si_errno = 0;
2216 queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
2217 ret = 0;
2218 break;
2219 }
2220
2221 return ret;
2222 }
2223
2224 void cpu_loop(CPUMIPSState *env)
2225 {
2226 CPUState *cs = CPU(mips_env_get_cpu(env));
2227 target_siginfo_t info;
2228 int trapnr;
2229 abi_long ret;
2230 # ifdef TARGET_ABI_MIPSO32
2231 unsigned int syscall_num;
2232 # endif
2233
2234 for(;;) {
2235 cpu_exec_start(cs);
2236 trapnr = cpu_exec(cs);
2237 cpu_exec_end(cs);
2238 process_queued_cpu_work(cs);
2239
2240 switch(trapnr) {
2241 case EXCP_SYSCALL:
2242 env->active_tc.PC += 4;
2243 # ifdef TARGET_ABI_MIPSO32
2244 syscall_num = env->active_tc.gpr[2] - 4000;
2245 if (syscall_num >= sizeof(mips_syscall_args)) {
2246 ret = -TARGET_ENOSYS;
2247 } else {
2248 int nb_args;
2249 abi_ulong sp_reg;
2250 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
2251
2252 nb_args = mips_syscall_args[syscall_num];
2253 sp_reg = env->active_tc.gpr[29];
2254 switch (nb_args) {
2255 /* these arguments are taken from the stack */
2256 case 8:
2257 if ((ret = get_user_ual(arg8, sp_reg + 28)) != 0) {
2258 goto done_syscall;
2259 }
2260 case 7:
2261 if ((ret = get_user_ual(arg7, sp_reg + 24)) != 0) {
2262 goto done_syscall;
2263 }
2264 case 6:
2265 if ((ret = get_user_ual(arg6, sp_reg + 20)) != 0) {
2266 goto done_syscall;
2267 }
2268 case 5:
2269 if ((ret = get_user_ual(arg5, sp_reg + 16)) != 0) {
2270 goto done_syscall;
2271 }
2272 default:
2273 break;
2274 }
2275 ret = do_syscall(env, env->active_tc.gpr[2],
2276 env->active_tc.gpr[4],
2277 env->active_tc.gpr[5],
2278 env->active_tc.gpr[6],
2279 env->active_tc.gpr[7],
2280 arg5, arg6, arg7, arg8);
2281 }
2282 done_syscall:
2283 # else
2284 ret = do_syscall(env, env->active_tc.gpr[2],
2285 env->active_tc.gpr[4], env->active_tc.gpr[5],
2286 env->active_tc.gpr[6], env->active_tc.gpr[7],
2287 env->active_tc.gpr[8], env->active_tc.gpr[9],
2288 env->active_tc.gpr[10], env->active_tc.gpr[11]);
2289 # endif /* O32 */
2290 if (ret == -TARGET_ERESTARTSYS) {
2291 env->active_tc.PC -= 4;
2292 break;
2293 }
2294 if (ret == -TARGET_QEMU_ESIGRETURN) {
2295 /* Returning from a successful sigreturn syscall.
2296 Avoid clobbering register state. */
2297 break;
2298 }
2299 if ((abi_ulong)ret >= (abi_ulong)-1133) {
2300 env->active_tc.gpr[7] = 1; /* error flag */
2301 ret = -ret;
2302 } else {
2303 env->active_tc.gpr[7] = 0; /* error flag */
2304 }
2305 env->active_tc.gpr[2] = ret;
2306 break;
2307 case EXCP_TLBL:
2308 case EXCP_TLBS:
2309 case EXCP_AdEL:
2310 case EXCP_AdES:
2311 info.si_signo = TARGET_SIGSEGV;
2312 info.si_errno = 0;
2313 /* XXX: check env->error_code */
2314 info.si_code = TARGET_SEGV_MAPERR;
2315 info._sifields._sigfault._addr = env->CP0_BadVAddr;
2316 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2317 break;
2318 case EXCP_CpU:
2319 case EXCP_RI:
2320 info.si_signo = TARGET_SIGILL;
2321 info.si_errno = 0;
2322 info.si_code = 0;
2323 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2324 break;
2325 case EXCP_INTERRUPT:
2326 /* just indicate that signals should be handled asap */
2327 break;
2328 case EXCP_DEBUG:
2329 {
2330 int sig;
2331
2332 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2333 if (sig)
2334 {
2335 info.si_signo = sig;
2336 info.si_errno = 0;
2337 info.si_code = TARGET_TRAP_BRKPT;
2338 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2339 }
2340 }
2341 break;
2342 case EXCP_SC:
2343 if (do_store_exclusive(env)) {
2344 info.si_signo = TARGET_SIGSEGV;
2345 info.si_errno = 0;
2346 info.si_code = TARGET_SEGV_MAPERR;
2347 info._sifields._sigfault._addr = env->active_tc.PC;
2348 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2349 }
2350 break;
2351 case EXCP_DSPDIS:
2352 info.si_signo = TARGET_SIGILL;
2353 info.si_errno = 0;
2354 info.si_code = TARGET_ILL_ILLOPC;
2355 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2356 break;
2357 /* The code below was inspired by the MIPS Linux kernel trap
2358 * handling code in arch/mips/kernel/traps.c.
2359 */
2360 case EXCP_BREAK:
2361 {
2362 abi_ulong trap_instr;
2363 unsigned int code;
2364
2365 if (env->hflags & MIPS_HFLAG_M16) {
2366 if (env->insn_flags & ASE_MICROMIPS) {
2367 /* microMIPS mode */
2368 ret = get_user_u16(trap_instr, env->active_tc.PC);
2369 if (ret != 0) {
2370 goto error;
2371 }
2372
2373 if ((trap_instr >> 10) == 0x11) {
2374 /* 16-bit instruction */
2375 code = trap_instr & 0xf;
2376 } else {
2377 /* 32-bit instruction */
2378 abi_ulong instr_lo;
2379
2380 ret = get_user_u16(instr_lo,
2381 env->active_tc.PC + 2);
2382 if (ret != 0) {
2383 goto error;
2384 }
2385 trap_instr = (trap_instr << 16) | instr_lo;
2386 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2387 /* Unfortunately, microMIPS also suffers from
2388 the old assembler bug... */
2389 if (code >= (1 << 10)) {
2390 code >>= 10;
2391 }
2392 }
2393 } else {
2394 /* MIPS16e mode */
2395 ret = get_user_u16(trap_instr, env->active_tc.PC);
2396 if (ret != 0) {
2397 goto error;
2398 }
2399 code = (trap_instr >> 6) & 0x3f;
2400 }
2401 } else {
2402 ret = get_user_u32(trap_instr, env->active_tc.PC);
2403 if (ret != 0) {
2404 goto error;
2405 }
2406
2407 /* As described in the original Linux kernel code, the
2408 * below checks on 'code' are to work around an old
2409 * assembly bug.
2410 */
2411 code = ((trap_instr >> 6) & ((1 << 20) - 1));
2412 if (code >= (1 << 10)) {
2413 code >>= 10;
2414 }
2415 }
2416
2417 if (do_break(env, &info, code) != 0) {
2418 goto error;
2419 }
2420 }
2421 break;
2422 case EXCP_TRAP:
2423 {
2424 abi_ulong trap_instr;
2425 unsigned int code = 0;
2426
2427 if (env->hflags & MIPS_HFLAG_M16) {
2428 /* microMIPS mode */
2429 abi_ulong instr[2];
2430
2431 ret = get_user_u16(instr[0], env->active_tc.PC) ||
2432 get_user_u16(instr[1], env->active_tc.PC + 2);
2433
2434 trap_instr = (instr[0] << 16) | instr[1];
2435 } else {
2436 ret = get_user_u32(trap_instr, env->active_tc.PC);
2437 }
2438
2439 if (ret != 0) {
2440 goto error;
2441 }
2442
2443 /* The immediate versions don't provide a code. */
2444 if (!(trap_instr & 0xFC000000)) {
2445 if (env->hflags & MIPS_HFLAG_M16) {
2446 /* microMIPS mode */
2447 code = ((trap_instr >> 12) & ((1 << 4) - 1));
2448 } else {
2449 code = ((trap_instr >> 6) & ((1 << 10) - 1));
2450 }
2451 }
2452
2453 if (do_break(env, &info, code) != 0) {
2454 goto error;
2455 }
2456 }
2457 break;
2458 case EXCP_ATOMIC:
2459 cpu_exec_step_atomic(cs);
2460 break;
2461 default:
2462 error:
2463 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
2464 abort();
2465 }
2466 process_pending_signals(env);
2467 }
2468 }
2469 #endif
2470
2471 #ifdef TARGET_NIOS2
2472
2473 void cpu_loop(CPUNios2State *env)
2474 {
2475 CPUState *cs = ENV_GET_CPU(env);
2476 Nios2CPU *cpu = NIOS2_CPU(cs);
2477 target_siginfo_t info;
2478 int trapnr, gdbsig, ret;
2479
2480 for (;;) {
2481 cpu_exec_start(cs);
2482 trapnr = cpu_exec(cs);
2483 cpu_exec_end(cs);
2484 gdbsig = 0;
2485
2486 switch (trapnr) {
2487 case EXCP_INTERRUPT:
2488 /* just indicate that signals should be handled asap */
2489 break;
2490 case EXCP_TRAP:
2491 if (env->regs[R_AT] == 0) {
2492 abi_long ret;
2493 qemu_log_mask(CPU_LOG_INT, "\nSyscall\n");
2494
2495 ret = do_syscall(env, env->regs[2],
2496 env->regs[4], env->regs[5], env->regs[6],
2497 env->regs[7], env->regs[8], env->regs[9],
2498 0, 0);
2499
2500 if (env->regs[2] == 0) { /* FIXME: syscall 0 workaround */
2501 ret = 0;
2502 }
2503
2504 env->regs[2] = abs(ret);
2505 /* Return value is 0..4096 */
2506 env->regs[7] = (ret > 0xfffffffffffff000ULL);
2507 env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
2508 env->regs[CR_STATUS] &= ~0x3;
2509 env->regs[R_EA] = env->regs[R_PC] + 4;
2510 env->regs[R_PC] += 4;
2511 break;
2512 } else {
2513 qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
2514
2515 env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
2516 env->regs[CR_STATUS] &= ~0x3;
2517 env->regs[R_EA] = env->regs[R_PC] + 4;
2518 env->regs[R_PC] = cpu->exception_addr;
2519
2520 gdbsig = TARGET_SIGTRAP;
2521 break;
2522 }
2523 case 0xaa:
2524 switch (env->regs[R_PC]) {
2525 /*case 0x1000:*/ /* TODO:__kuser_helper_version */
2526 case 0x1004: /* __kuser_cmpxchg */
2527 start_exclusive();
2528 if (env->regs[4] & 0x3) {
2529 goto kuser_fail;
2530 }
2531 ret = get_user_u32(env->regs[2], env->regs[4]);
2532 if (ret) {
2533 end_exclusive();
2534 goto kuser_fail;
2535 }
2536 env->regs[2] -= env->regs[5];
2537 if (env->regs[2] == 0) {
2538 put_user_u32(env->regs[6], env->regs[4]);
2539 }
2540 end_exclusive();
2541 env->regs[R_PC] = env->regs[R_RA];
2542 break;
2543 /*case 0x1040:*/ /* TODO:__kuser_sigtramp */
2544 default:
2545 ;
2546 kuser_fail:
2547 info.si_signo = TARGET_SIGSEGV;
2548 info.si_errno = 0;
2549 /* TODO: check env->error_code */
2550 info.si_code = TARGET_SEGV_MAPERR;
2551 info._sifields._sigfault._addr = env->regs[R_PC];
2552 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2553 }
2554 break;
2555 default:
2556 EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
2557 trapnr);
2558 gdbsig = TARGET_SIGILL;
2559 break;
2560 }
2561 if (gdbsig) {
2562 gdb_handlesig(cs, gdbsig);
2563 if (gdbsig != TARGET_SIGTRAP) {
2564 exit(EXIT_FAILURE);
2565 }
2566 }
2567
2568 process_pending_signals(env);
2569 }
2570 }
2571
2572 #endif /* TARGET_NIOS2 */
2573
2574 #ifdef TARGET_OPENRISC
2575
2576 void cpu_loop(CPUOpenRISCState *env)
2577 {
2578 CPUState *cs = CPU(openrisc_env_get_cpu(env));
2579 int trapnr;
2580 abi_long ret;
2581 target_siginfo_t info;
2582
2583 for (;;) {
2584 cpu_exec_start(cs);
2585 trapnr = cpu_exec(cs);
2586 cpu_exec_end(cs);
2587 process_queued_cpu_work(cs);
2588
2589 switch (trapnr) {
2590 case EXCP_SYSCALL:
2591 env->pc += 4; /* 0xc00; */
2592 ret = do_syscall(env,
2593 env->gpr[11], /* return value */
2594 env->gpr[3], /* r3 - r7 are params */
2595 env->gpr[4],
2596 env->gpr[5],
2597 env->gpr[6],
2598 env->gpr[7],
2599 env->gpr[8], 0, 0);
2600 if (ret == -TARGET_ERESTARTSYS) {
2601 env->pc -= 4;
2602 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2603 env->gpr[11] = ret;
2604 }
2605 break;
2606 case EXCP_DPF:
2607 case EXCP_IPF:
2608 case EXCP_RANGE:
2609 info.si_signo = TARGET_SIGSEGV;
2610 info.si_errno = 0;
2611 info.si_code = TARGET_SEGV_MAPERR;
2612 info._sifields._sigfault._addr = env->pc;
2613 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2614 break;
2615 case EXCP_ALIGN:
2616 info.si_signo = TARGET_SIGBUS;
2617 info.si_errno = 0;
2618 info.si_code = TARGET_BUS_ADRALN;
2619 info._sifields._sigfault._addr = env->pc;
2620 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2621 break;
2622 case EXCP_ILLEGAL:
2623 info.si_signo = TARGET_SIGILL;
2624 info.si_errno = 0;
2625 info.si_code = TARGET_ILL_ILLOPC;
2626 info._sifields._sigfault._addr = env->pc;
2627 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2628 break;
2629 case EXCP_FPE:
2630 info.si_signo = TARGET_SIGFPE;
2631 info.si_errno = 0;
2632 info.si_code = 0;
2633 info._sifields._sigfault._addr = env->pc;
2634 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2635 break;
2636 case EXCP_INTERRUPT:
2637 /* We processed the pending cpu work above. */
2638 break;
2639 case EXCP_DEBUG:
2640 trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
2641 if (trapnr) {
2642 info.si_signo = trapnr;
2643 info.si_errno = 0;
2644 info.si_code = TARGET_TRAP_BRKPT;
2645 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2646 }
2647 break;
2648 case EXCP_ATOMIC:
2649 cpu_exec_step_atomic(cs);
2650 break;
2651 default:
2652 g_assert_not_reached();
2653 }
2654 process_pending_signals(env);
2655 }
2656 }
2657
2658 #endif /* TARGET_OPENRISC */
2659
2660 #ifdef TARGET_SH4
2661 void cpu_loop(CPUSH4State *env)
2662 {
2663 CPUState *cs = CPU(sh_env_get_cpu(env));
2664 int trapnr, ret;
2665 target_siginfo_t info;
2666
2667 while (1) {
2668 cpu_exec_start(cs);
2669 trapnr = cpu_exec(cs);
2670 cpu_exec_end(cs);
2671 process_queued_cpu_work(cs);
2672
2673 switch (trapnr) {
2674 case 0x160:
2675 env->pc += 2;
2676 ret = do_syscall(env,
2677 env->gregs[3],
2678 env->gregs[4],
2679 env->gregs[5],
2680 env->gregs[6],
2681 env->gregs[7],
2682 env->gregs[0],
2683 env->gregs[1],
2684 0, 0);
2685 if (ret == -TARGET_ERESTARTSYS) {
2686 env->pc -= 2;
2687 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2688 env->gregs[0] = ret;
2689 }
2690 break;
2691 case EXCP_INTERRUPT:
2692 /* just indicate that signals should be handled asap */
2693 break;
2694 case EXCP_DEBUG:
2695 {
2696 int sig;
2697
2698 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2699 if (sig)
2700 {
2701 info.si_signo = sig;
2702 info.si_errno = 0;
2703 info.si_code = TARGET_TRAP_BRKPT;
2704 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2705 }
2706 }
2707 break;
2708 case 0xa0:
2709 case 0xc0:
2710 info.si_signo = TARGET_SIGSEGV;
2711 info.si_errno = 0;
2712 info.si_code = TARGET_SEGV_MAPERR;
2713 info._sifields._sigfault._addr = env->tea;
2714 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2715 break;
2716
2717 case EXCP_ATOMIC:
2718 cpu_exec_step_atomic(cs);
2719 break;
2720 default:
2721 printf ("Unhandled trap: 0x%x\n", trapnr);
2722 cpu_dump_state(cs, stderr, fprintf, 0);
2723 exit(EXIT_FAILURE);
2724 }
2725 process_pending_signals (env);
2726 }
2727 }
2728 #endif
2729
2730 #ifdef TARGET_CRIS
2731 void cpu_loop(CPUCRISState *env)
2732 {
2733 CPUState *cs = CPU(cris_env_get_cpu(env));
2734 int trapnr, ret;
2735 target_siginfo_t info;
2736
2737 while (1) {
2738 cpu_exec_start(cs);
2739 trapnr = cpu_exec(cs);
2740 cpu_exec_end(cs);
2741 process_queued_cpu_work(cs);
2742
2743 switch (trapnr) {
2744 case 0xaa:
2745 {
2746 info.si_signo = TARGET_SIGSEGV;
2747 info.si_errno = 0;
2748 /* XXX: check env->error_code */
2749 info.si_code = TARGET_SEGV_MAPERR;
2750 info._sifields._sigfault._addr = env->pregs[PR_EDA];
2751 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2752 }
2753 break;
2754 case EXCP_INTERRUPT:
2755 /* just indicate that signals should be handled asap */
2756 break;
2757 case EXCP_BREAK:
2758 ret = do_syscall(env,
2759 env->regs[9],
2760 env->regs[10],
2761 env->regs[11],
2762 env->regs[12],
2763 env->regs[13],
2764 env->pregs[7],
2765 env->pregs[11],
2766 0, 0);
2767 if (ret == -TARGET_ERESTARTSYS) {
2768 env->pc -= 2;
2769 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2770 env->regs[10] = ret;
2771 }
2772 break;
2773 case EXCP_DEBUG:
2774 {
2775 int sig;
2776
2777 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2778 if (sig)
2779 {
2780 info.si_signo = sig;
2781 info.si_errno = 0;
2782 info.si_code = TARGET_TRAP_BRKPT;
2783 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2784 }
2785 }
2786 break;
2787 case EXCP_ATOMIC:
2788 cpu_exec_step_atomic(cs);
2789 break;
2790 default:
2791 printf ("Unhandled trap: 0x%x\n", trapnr);
2792 cpu_dump_state(cs, stderr, fprintf, 0);
2793 exit(EXIT_FAILURE);
2794 }
2795 process_pending_signals (env);
2796 }
2797 }
2798 #endif
2799
2800 #ifdef TARGET_MICROBLAZE
2801 void cpu_loop(CPUMBState *env)
2802 {
2803 CPUState *cs = CPU(mb_env_get_cpu(env));
2804 int trapnr, ret;
2805 target_siginfo_t info;
2806
2807 while (1) {
2808 cpu_exec_start(cs);
2809 trapnr = cpu_exec(cs);
2810 cpu_exec_end(cs);
2811 process_queued_cpu_work(cs);
2812
2813 switch (trapnr) {
2814 case 0xaa:
2815 {
2816 info.si_signo = TARGET_SIGSEGV;
2817 info.si_errno = 0;
2818 /* XXX: check env->error_code */
2819 info.si_code = TARGET_SEGV_MAPERR;
2820 info._sifields._sigfault._addr = 0;
2821 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2822 }
2823 break;
2824 case EXCP_INTERRUPT:
2825 /* just indicate that signals should be handled asap */
2826 break;
2827 case EXCP_BREAK:
2828 /* Return address is 4 bytes after the call. */
2829 env->regs[14] += 4;
2830 env->sregs[SR_PC] = env->regs[14];
2831 ret = do_syscall(env,
2832 env->regs[12],
2833 env->regs[5],
2834 env->regs[6],
2835 env->regs[7],
2836 env->regs[8],
2837 env->regs[9],
2838 env->regs[10],
2839 0, 0);
2840 if (ret == -TARGET_ERESTARTSYS) {
2841 /* Wind back to before the syscall. */
2842 env->sregs[SR_PC] -= 4;
2843 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2844 env->regs[3] = ret;
2845 }
2846 /* All syscall exits result in guest r14 being equal to the
2847 * PC we return to, because the kernel syscall exit "rtbd" does
2848 * this. (This is true even for sigreturn(); note that r14 is
2849 * not a userspace-usable register, as the kernel may clobber it
2850 * at any point.)
2851 */
2852 env->regs[14] = env->sregs[SR_PC];
2853 break;
2854 case EXCP_HW_EXCP:
2855 env->regs[17] = env->sregs[SR_PC] + 4;
2856 if (env->iflags & D_FLAG) {
2857 env->sregs[SR_ESR] |= 1 << 12;
2858 env->sregs[SR_PC] -= 4;
2859 /* FIXME: if branch was immed, replay the imm as well. */
2860 }
2861
2862 env->iflags &= ~(IMM_FLAG | D_FLAG);
2863
2864 switch (env->sregs[SR_ESR] & 31) {
2865 case ESR_EC_DIVZERO:
2866 info.si_signo = TARGET_SIGFPE;
2867 info.si_errno = 0;
2868 info.si_code = TARGET_FPE_FLTDIV;
2869 info._sifields._sigfault._addr = 0;
2870 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2871 break;
2872 case ESR_EC_FPU:
2873 info.si_signo = TARGET_SIGFPE;
2874 info.si_errno = 0;
2875 if (env->sregs[SR_FSR] & FSR_IO) {
2876 info.si_code = TARGET_FPE_FLTINV;
2877 }
2878 if (env->sregs[SR_FSR] & FSR_DZ) {
2879 info.si_code = TARGET_FPE_FLTDIV;
2880 }
2881 info._sifields._sigfault._addr = 0;
2882 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2883 break;
2884 default:
2885 printf ("Unhandled hw-exception: 0x%x\n",
2886 env->sregs[SR_ESR] & ESR_EC_MASK);
2887 cpu_dump_state(cs, stderr, fprintf, 0);
2888 exit(EXIT_FAILURE);
2889 break;
2890 }
2891 break;
2892 case EXCP_DEBUG:
2893 {
2894 int sig;
2895
2896 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
2897 if (sig)
2898 {
2899 info.si_signo = sig;
2900 info.si_errno = 0;
2901 info.si_code = TARGET_TRAP_BRKPT;
2902 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2903 }
2904 }
2905 break;
2906 case EXCP_ATOMIC:
2907 cpu_exec_step_atomic(cs);
2908 break;
2909 default:
2910 printf ("Unhandled trap: 0x%x\n", trapnr);
2911 cpu_dump_state(cs, stderr, fprintf, 0);
2912 exit(EXIT_FAILURE);
2913 }
2914 process_pending_signals (env);
2915 }
2916 }
2917 #endif
2918
2919 #ifdef TARGET_M68K
2920
2921 void cpu_loop(CPUM68KState *env)
2922 {
2923 CPUState *cs = CPU(m68k_env_get_cpu(env));
2924 int trapnr;
2925 unsigned int n;
2926 target_siginfo_t info;
2927 TaskState *ts = cs->opaque;
2928
2929 for(;;) {
2930 cpu_exec_start(cs);
2931 trapnr = cpu_exec(cs);
2932 cpu_exec_end(cs);
2933 process_queued_cpu_work(cs);
2934
2935 switch(trapnr) {
2936 case EXCP_ILLEGAL:
2937 {
2938 if (ts->sim_syscalls) {
2939 uint16_t nr;
2940 get_user_u16(nr, env->pc + 2);
2941 env->pc += 4;
2942 do_m68k_simcall(env, nr);
2943 } else {
2944 goto do_sigill;
2945 }
2946 }
2947 break;
2948 case EXCP_HALT_INSN:
2949 /* Semihosing syscall. */
2950 env->pc += 4;
2951 do_m68k_semihosting(env, env->dregs[0]);
2952 break;
2953 case EXCP_LINEA:
2954 case EXCP_LINEF:
2955 case EXCP_UNSUPPORTED:
2956 do_sigill:
2957 info.si_signo = TARGET_SIGILL;
2958 info.si_errno = 0;
2959 info.si_code = TARGET_ILL_ILLOPN;
2960 info._sifields._sigfault._addr = env->pc;
2961 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2962 break;
2963 case EXCP_DIV0:
2964 info.si_signo = TARGET_SIGFPE;
2965 info.si_errno = 0;
2966 info.si_code = TARGET_FPE_INTDIV;
2967 info._sifields._sigfault._addr = env->pc;
2968 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
2969 break;
2970 case EXCP_TRAP0:
2971 {
2972 abi_long ret;
2973 ts->sim_syscalls = 0;
2974 n = env->dregs[0];
2975 env->pc += 2;
2976 ret = do_syscall(env,
2977 n,
2978 env->dregs[1],
2979 env->dregs[2],
2980 env->dregs[3],
2981 env->dregs[4],
2982 env->dregs[5],
2983 env->aregs[0],
2984 0, 0);
2985 if (ret == -TARGET_ERESTARTSYS) {
2986 env->pc -= 2;
2987 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
2988 env->dregs[0] = ret;
2989 }
2990 }
2991 break;
2992 case EXCP_INTERRUPT:
2993 /* just indicate that signals should be handled asap */
2994 break;
2995 case EXCP_ACCESS:
2996 {
2997 info.si_signo = TARGET_SIGSEGV;
2998 info.si_errno = 0;
2999 /* XXX: check env->error_code */
3000 info.si_code = TARGET_SEGV_MAPERR;
3001 info._sifields._sigfault._addr = env->mmu.ar;
3002 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3003 }
3004 break;
3005 case EXCP_DEBUG:
3006 {
3007 int sig;
3008
3009 sig = gdb_handlesig(cs, TARGET_SIGTRAP);
3010 if (sig)
3011 {
3012 info.si_signo = sig;
3013 info.si_errno = 0;
3014 info.si_code = TARGET_TRAP_BRKPT;
3015 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3016 }
3017 }
3018 break;
3019 case EXCP_ATOMIC:
3020 cpu_exec_step_atomic(cs);
3021 break;
3022 default:
3023 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
3024 abort();
3025 }
3026 process_pending_signals(env);
3027 }
3028 }
3029 #endif /* TARGET_M68K */
3030
3031 #ifdef TARGET_ALPHA
3032 void cpu_loop(CPUAlphaState *env)
3033 {
3034 CPUState *cs = CPU(alpha_env_get_cpu(env));
3035 int trapnr;
3036 target_siginfo_t info;
3037 abi_long sysret;
3038
3039 while (1) {
3040 cpu_exec_start(cs);
3041 trapnr = cpu_exec(cs);
3042 cpu_exec_end(cs);
3043 process_queued_cpu_work(cs);
3044
3045 /* All of the traps imply a transition through PALcode, which
3046 implies an REI instruction has been executed. Which means
3047 that the intr_flag should be cleared. */
3048 env->intr_flag = 0;
3049
3050 switch (trapnr) {
3051 case EXCP_RESET:
3052 fprintf(stderr, "Reset requested. Exit\n");
3053 exit(EXIT_FAILURE);
3054 break;
3055 case EXCP_MCHK:
3056 fprintf(stderr, "Machine check exception. Exit\n");
3057 exit(EXIT_FAILURE);
3058 break;
3059 case EXCP_SMP_INTERRUPT:
3060 case EXCP_CLK_INTERRUPT:
3061 case EXCP_DEV_INTERRUPT:
3062 fprintf(stderr, "External interrupt. Exit\n");
3063 exit(EXIT_FAILURE);
3064 break;
3065 case EXCP_MMFAULT:
3066 env->lock_addr = -1;
3067 info.si_signo = TARGET_SIGSEGV;
3068 info.si_errno = 0;
3069 info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
3070 ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
3071 info._sifields._sigfault._addr = env->trap_arg0;
3072 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3073 break;
3074 case EXCP_UNALIGN:
3075 env->lock_addr = -1;
3076 info.si_signo = TARGET_SIGBUS;
3077 info.si_errno = 0;
3078 info.si_code = TARGET_BUS_ADRALN;
3079 info._sifields._sigfault._addr = env->trap_arg0;
3080 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3081 break;
3082 case EXCP_OPCDEC:
3083 do_sigill:
3084 env->lock_addr = -1;
3085 info.si_signo = TARGET_SIGILL;
3086 info.si_errno = 0;
3087 info.si_code = TARGET_ILL_ILLOPC;
3088 info._sifields._sigfault._addr = env->pc;
3089 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3090 break;
3091 case EXCP_ARITH:
3092 env->lock_addr = -1;
3093 info.si_signo = TARGET_SIGFPE;
3094 info.si_errno = 0;
3095 info.si_code = TARGET_FPE_FLTINV;
3096 info._sifields._sigfault._addr = env->pc;
3097 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3098 break;
3099 case EXCP_FEN:
3100 /* No-op. Linux simply re-enables the FPU. */
3101 break;
3102 case EXCP_CALL_PAL:
3103 env->lock_addr = -1;
3104 switch (env->error_code) {
3105 case 0x80:
3106 /* BPT */
3107 info.si_signo = TARGET_SIGTRAP;
3108 info.si_errno = 0;
3109 info.si_code = TARGET_TRAP_BRKPT;
3110 info._sifields._sigfault._addr = env->pc;
3111 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3112 break;
3113 case 0x81:
3114 /* BUGCHK */
3115 info.si_signo = TARGET_SIGTRAP;
3116 info.si_errno = 0;
3117 info.si_code = 0;
3118 info._sifields._sigfault._addr = env->pc;
3119 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3120 break;
3121 case 0x83:
3122 /* CALLSYS */
3123 trapnr = env->ir[IR_V0];
3124 sysret = do_syscall(env, trapnr,
3125 env->ir[IR_A0], env->ir[IR_A1],
3126 env->ir[IR_A2], env->ir[IR_A3],
3127 env->ir[IR_A4], env->ir[IR_A5],
3128 0, 0);
3129 if (sysret == -TARGET_ERESTARTSYS) {
3130 env->pc -= 4;
3131 break;
3132 }
3133 if (sysret == -TARGET_QEMU_ESIGRETURN) {
3134 break;
3135 }
3136 /* Syscall writes 0 to V0 to bypass error check, similar
3137 to how this is handled internal to Linux kernel.
3138 (Ab)use trapnr temporarily as boolean indicating error. */
3139 trapnr = (env->ir[IR_V0] != 0 && sysret < 0);
3140 env->ir[IR_V0] = (trapnr ? -sysret : sysret);
3141 env->ir[IR_A3] = trapnr;
3142 break;
3143 case 0x86:
3144 /* IMB */
3145 /* ??? We can probably elide the code using page_unprotect
3146 that is checking for self-modifying code. Instead we
3147 could simply call tb_flush here. Until we work out the
3148 changes required to turn off the extra write protection,
3149 this can be a no-op. */
3150 break;
3151 case 0x9E:
3152 /* RDUNIQUE */
3153 /* Handled in the translator for usermode. */
3154 abort();
3155 case 0x9F:
3156 /* WRUNIQUE */
3157 /* Handled in the translator for usermode. */
3158 abort();
3159 case 0xAA:
3160 /* GENTRAP */
3161 info.si_signo = TARGET_SIGFPE;
3162 switch (env->ir[IR_A0]) {
3163 case TARGET_GEN_INTOVF:
3164 info.si_code = TARGET_FPE_INTOVF;
3165 break;
3166 case TARGET_GEN_INTDIV:
3167 info.si_code = TARGET_FPE_INTDIV;
3168 break;
3169 case TARGET_GEN_FLTOVF:
3170 info.si_code = TARGET_FPE_FLTOVF;
3171 break;
3172 case TARGET_GEN_FLTUND:
3173 info.si_code = TARGET_FPE_FLTUND;
3174 break;
3175 case TARGET_GEN_FLTINV:
3176 info.si_code = TARGET_FPE_FLTINV;
3177 break;
3178 case TARGET_GEN_FLTINE:
3179 info.si_code = TARGET_FPE_FLTRES;
3180 break;
3181 case TARGET_GEN_ROPRAND:
3182 info.si_code = 0;
3183 break;
3184 default:
3185 info.si_signo = TARGET_SIGTRAP;
3186 info.si_code = 0;
3187 break;
3188 }
3189 info.si_errno = 0;
3190 info._sifields._sigfault._addr = env->pc;
3191 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
3192 break;
3193 default:
3194 goto do_sigill;
3195 }
3196 break;
3197 case EXCP_DEBUG:
3198 info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
3199 if (info.si_signo) {
3200 env->lock_addr = -1;