xref: /qemu/linux-user/main.c (revision 27524dc3)
131e31b8aSbellard /*
293ac68bcSbellard  *  qemu user main
331e31b8aSbellard  *
431e31b8aSbellard  *  Copyright (c) 2003 Fabrice Bellard
531e31b8aSbellard  *
631e31b8aSbellard  *  This program is free software; you can redistribute it and/or modify
731e31b8aSbellard  *  it under the terms of the GNU General Public License as published by
831e31b8aSbellard  *  the Free Software Foundation; either version 2 of the License, or
931e31b8aSbellard  *  (at your option) any later version.
1031e31b8aSbellard  *
1131e31b8aSbellard  *  This program is distributed in the hope that it will be useful,
1231e31b8aSbellard  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1331e31b8aSbellard  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1431e31b8aSbellard  *  GNU General Public License for more details.
1531e31b8aSbellard  *
1631e31b8aSbellard  *  You should have received a copy of the GNU General Public License
1731e31b8aSbellard  *  along with this program; if not, write to the Free Software
1831e31b8aSbellard  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1931e31b8aSbellard  */
2031e31b8aSbellard #include <stdlib.h>
2131e31b8aSbellard #include <stdio.h>
2231e31b8aSbellard #include <stdarg.h>
2304369ff2Sbellard #include <string.h>
2431e31b8aSbellard #include <errno.h>
250ecfa993Sbellard #include <unistd.h>
2631e31b8aSbellard 
273ef693a0Sbellard #include "qemu.h"
2831e31b8aSbellard 
293ef693a0Sbellard #define DEBUG_LOGFILE "/tmp/qemu.log"
30586314f2Sbellard 
3174cd30b8Sbellard static const char *interp_prefix = CONFIG_QEMU_PREFIX;
32c5937220Spbrook const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
33586314f2Sbellard 
343a4739d6Sbellard #if defined(__i386__) && !defined(CONFIG_STATIC)
35f801f97eSbellard /* Force usage of an ELF interpreter even if it is an ELF shared
36f801f97eSbellard    object ! */
37f801f97eSbellard const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
384304763bSbellard #endif
3974cd30b8Sbellard 
4093ac68bcSbellard /* for recent libc, we add these dummy symbols which are not declared
4174cd30b8Sbellard    when generating a linked object (bug in ld ?) */
42fbf59244Sbellard #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC)
4346027c07Sbellard asm(".globl __preinit_array_start\n"
4446027c07Sbellard     ".globl __preinit_array_end\n"
4546027c07Sbellard     ".globl __init_array_start\n"
4646027c07Sbellard     ".globl __init_array_end\n"
4746027c07Sbellard     ".globl __fini_array_start\n"
4846027c07Sbellard     ".globl __fini_array_end\n"
4946027c07Sbellard     ".section \".rodata\"\n"
5046027c07Sbellard     "__preinit_array_start:\n"
5146027c07Sbellard     "__preinit_array_end:\n"
5246027c07Sbellard     "__init_array_start:\n"
5346027c07Sbellard     "__init_array_end:\n"
5446027c07Sbellard     "__fini_array_start:\n"
5546027c07Sbellard     "__fini_array_end:\n"
5646027c07Sbellard     ".long 0\n");
5774cd30b8Sbellard #endif
5874cd30b8Sbellard 
599de5e440Sbellard /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
609de5e440Sbellard    we allocate a bigger stack. Need a better solution, for example
619de5e440Sbellard    by remapping the process stack directly at the right place */
629de5e440Sbellard unsigned long x86_stack_size = 512 * 1024;
6331e31b8aSbellard 
6431e31b8aSbellard void gemu_log(const char *fmt, ...)
6531e31b8aSbellard {
6631e31b8aSbellard     va_list ap;
6731e31b8aSbellard 
6831e31b8aSbellard     va_start(ap, fmt);
6931e31b8aSbellard     vfprintf(stderr, fmt, ap);
7031e31b8aSbellard     va_end(ap);
7131e31b8aSbellard }
7231e31b8aSbellard 
7361190b14Sbellard void cpu_outb(CPUState *env, int addr, int val)
74367e86e8Sbellard {
75367e86e8Sbellard     fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
76367e86e8Sbellard }
77367e86e8Sbellard 
7861190b14Sbellard void cpu_outw(CPUState *env, int addr, int val)
79367e86e8Sbellard {
80367e86e8Sbellard     fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
81367e86e8Sbellard }
82367e86e8Sbellard 
8361190b14Sbellard void cpu_outl(CPUState *env, int addr, int val)
84367e86e8Sbellard {
85367e86e8Sbellard     fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
86367e86e8Sbellard }
87367e86e8Sbellard 
8861190b14Sbellard int cpu_inb(CPUState *env, int addr)
89367e86e8Sbellard {
90367e86e8Sbellard     fprintf(stderr, "inb: port=0x%04x\n", addr);
91367e86e8Sbellard     return 0;
92367e86e8Sbellard }
93367e86e8Sbellard 
9461190b14Sbellard int cpu_inw(CPUState *env, int addr)
95367e86e8Sbellard {
96367e86e8Sbellard     fprintf(stderr, "inw: port=0x%04x\n", addr);
97367e86e8Sbellard     return 0;
98367e86e8Sbellard }
99367e86e8Sbellard 
10061190b14Sbellard int cpu_inl(CPUState *env, int addr)
101367e86e8Sbellard {
102367e86e8Sbellard     fprintf(stderr, "inl: port=0x%04x\n", addr);
103367e86e8Sbellard     return 0;
104367e86e8Sbellard }
105367e86e8Sbellard 
106a541f297Sbellard int cpu_get_pic_interrupt(CPUState *env)
10792ccca6aSbellard {
10892ccca6aSbellard     return -1;
10992ccca6aSbellard }
11092ccca6aSbellard 
11128ab0e2eSbellard /* timers for rdtsc */
11228ab0e2eSbellard 
1131dce7c3cSbellard #if 0
11428ab0e2eSbellard 
11528ab0e2eSbellard static uint64_t emu_time;
11628ab0e2eSbellard 
11728ab0e2eSbellard int64_t cpu_get_real_ticks(void)
11828ab0e2eSbellard {
11928ab0e2eSbellard     return emu_time++;
12028ab0e2eSbellard }
12128ab0e2eSbellard 
12228ab0e2eSbellard #endif
12328ab0e2eSbellard 
124a541f297Sbellard #ifdef TARGET_I386
125a541f297Sbellard /***********************************************************/
126a541f297Sbellard /* CPUX86 core interface */
127a541f297Sbellard 
12802a1602eSbellard void cpu_smm_update(CPUState *env)
12902a1602eSbellard {
13002a1602eSbellard }
13102a1602eSbellard 
13228ab0e2eSbellard uint64_t cpu_get_tsc(CPUX86State *env)
13328ab0e2eSbellard {
13428ab0e2eSbellard     return cpu_get_real_ticks();
13528ab0e2eSbellard }
13628ab0e2eSbellard 
137f4beb510Sbellard static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
138f4beb510Sbellard                      int flags)
1396dbad63eSbellard {
140f4beb510Sbellard     unsigned int e1, e2;
14153a5960aSpbrook     uint32_t *p;
1426dbad63eSbellard     e1 = (addr << 16) | (limit & 0xffff);
1436dbad63eSbellard     e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
144f4beb510Sbellard     e2 |= flags;
14553a5960aSpbrook     p = ptr;
14653a5960aSpbrook     p[0] = tswapl(e1);
14753a5960aSpbrook     p[1] = tswapl(e2);
148f4beb510Sbellard }
149f4beb510Sbellard 
150f4beb510Sbellard static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
151f4beb510Sbellard                      unsigned long addr, unsigned int sel)
152f4beb510Sbellard {
153f4beb510Sbellard     unsigned int e1, e2;
15453a5960aSpbrook     uint32_t *p;
155f4beb510Sbellard     e1 = (addr & 0xffff) | (sel << 16);
156f4beb510Sbellard     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
15753a5960aSpbrook     p = ptr;
15853a5960aSpbrook     p[0] = tswapl(e1);
15953a5960aSpbrook     p[1] = tswapl(e2);
1606dbad63eSbellard }
1616dbad63eSbellard 
1626dbad63eSbellard uint64_t gdt_table[6];
163f4beb510Sbellard uint64_t idt_table[256];
164f4beb510Sbellard 
165f4beb510Sbellard /* only dpl matters as we do only user space emulation */
166f4beb510Sbellard static void set_idt(int n, unsigned int dpl)
167f4beb510Sbellard {
168f4beb510Sbellard     set_gate(idt_table + n, 0, dpl, 0, 0);
169f4beb510Sbellard }
17031e31b8aSbellard 
17189e957e7Sbellard void cpu_loop(CPUX86State *env)
172bc8a22ccSbellard {
173bc8a22ccSbellard     int trapnr;
174992f48a0Sblueswir1     abi_ulong pc;
175bc8a22ccSbellard     target_siginfo_t info;
176bc8a22ccSbellard 
177bc8a22ccSbellard     for(;;) {
178bc8a22ccSbellard         trapnr = cpu_x86_exec(env);
179bc8a22ccSbellard         switch(trapnr) {
180f4beb510Sbellard         case 0x80:
181f4beb510Sbellard             /* linux syscall */
1821b6b029eSbellard             env->regs[R_EAX] = do_syscall(env,
1831b6b029eSbellard                                           env->regs[R_EAX],
1841b6b029eSbellard                                           env->regs[R_EBX],
1851b6b029eSbellard                                           env->regs[R_ECX],
1861b6b029eSbellard                                           env->regs[R_EDX],
1871b6b029eSbellard                                           env->regs[R_ESI],
1881b6b029eSbellard                                           env->regs[R_EDI],
1891b6b029eSbellard                                           env->regs[R_EBP]);
190f4beb510Sbellard             break;
191f4beb510Sbellard         case EXCP0B_NOSEG:
192f4beb510Sbellard         case EXCP0C_STACK:
193f4beb510Sbellard             info.si_signo = SIGBUS;
194f4beb510Sbellard             info.si_errno = 0;
195f4beb510Sbellard             info.si_code = TARGET_SI_KERNEL;
196f4beb510Sbellard             info._sifields._sigfault._addr = 0;
197f4beb510Sbellard             queue_signal(info.si_signo, &info);
198f4beb510Sbellard             break;
199f4beb510Sbellard         case EXCP0D_GPF:
20084409ddbSj_mayer #ifndef TARGET_X86_64
201f4beb510Sbellard             if (env->eflags & VM_MASK) {
202f4beb510Sbellard                 handle_vm86_fault(env);
20384409ddbSj_mayer             } else
20484409ddbSj_mayer #endif
20584409ddbSj_mayer             {
2069de5e440Sbellard                 info.si_signo = SIGSEGV;
2079de5e440Sbellard                 info.si_errno = 0;
208b689bc57Sbellard                 info.si_code = TARGET_SI_KERNEL;
2099de5e440Sbellard                 info._sifields._sigfault._addr = 0;
2109de5e440Sbellard                 queue_signal(info.si_signo, &info);
2111b6b029eSbellard             }
2121b6b029eSbellard             break;
213b689bc57Sbellard         case EXCP0E_PAGE:
214b689bc57Sbellard             info.si_signo = SIGSEGV;
215b689bc57Sbellard             info.si_errno = 0;
216b689bc57Sbellard             if (!(env->error_code & 1))
217b689bc57Sbellard                 info.si_code = TARGET_SEGV_MAPERR;
218b689bc57Sbellard             else
219b689bc57Sbellard                 info.si_code = TARGET_SEGV_ACCERR;
220970a87a6Sbellard             info._sifields._sigfault._addr = env->cr[2];
221b689bc57Sbellard             queue_signal(info.si_signo, &info);
222b689bc57Sbellard             break;
2239de5e440Sbellard         case EXCP00_DIVZ:
22484409ddbSj_mayer #ifndef TARGET_X86_64
225bc8a22ccSbellard             if (env->eflags & VM_MASK) {
226447db213Sbellard                 handle_vm86_trap(env, trapnr);
22784409ddbSj_mayer             } else
22884409ddbSj_mayer #endif
22984409ddbSj_mayer             {
2309de5e440Sbellard                 /* division by zero */
2319de5e440Sbellard                 info.si_signo = SIGFPE;
2329de5e440Sbellard                 info.si_errno = 0;
2339de5e440Sbellard                 info.si_code = TARGET_FPE_INTDIV;
2349de5e440Sbellard                 info._sifields._sigfault._addr = env->eip;
2359de5e440Sbellard                 queue_signal(info.si_signo, &info);
236bc8a22ccSbellard             }
2379de5e440Sbellard             break;
238447db213Sbellard         case EXCP01_SSTP:
239447db213Sbellard         case EXCP03_INT3:
24084409ddbSj_mayer #ifndef TARGET_X86_64
241447db213Sbellard             if (env->eflags & VM_MASK) {
242447db213Sbellard                 handle_vm86_trap(env, trapnr);
24384409ddbSj_mayer             } else
24484409ddbSj_mayer #endif
24584409ddbSj_mayer             {
246447db213Sbellard                 info.si_signo = SIGTRAP;
247447db213Sbellard                 info.si_errno = 0;
248447db213Sbellard                 if (trapnr == EXCP01_SSTP) {
249447db213Sbellard                     info.si_code = TARGET_TRAP_BRKPT;
250447db213Sbellard                     info._sifields._sigfault._addr = env->eip;
251447db213Sbellard                 } else {
252447db213Sbellard                     info.si_code = TARGET_SI_KERNEL;
253447db213Sbellard                     info._sifields._sigfault._addr = 0;
254447db213Sbellard                 }
255447db213Sbellard                 queue_signal(info.si_signo, &info);
256447db213Sbellard             }
257447db213Sbellard             break;
2589de5e440Sbellard         case EXCP04_INTO:
2599de5e440Sbellard         case EXCP05_BOUND:
26084409ddbSj_mayer #ifndef TARGET_X86_64
261bc8a22ccSbellard             if (env->eflags & VM_MASK) {
262447db213Sbellard                 handle_vm86_trap(env, trapnr);
26384409ddbSj_mayer             } else
26484409ddbSj_mayer #endif
26584409ddbSj_mayer             {
2669de5e440Sbellard                 info.si_signo = SIGSEGV;
2679de5e440Sbellard                 info.si_errno = 0;
268b689bc57Sbellard                 info.si_code = TARGET_SI_KERNEL;
2699de5e440Sbellard                 info._sifields._sigfault._addr = 0;
2709de5e440Sbellard                 queue_signal(info.si_signo, &info);
271bc8a22ccSbellard             }
2729de5e440Sbellard             break;
2739de5e440Sbellard         case EXCP06_ILLOP:
2749de5e440Sbellard             info.si_signo = SIGILL;
2759de5e440Sbellard             info.si_errno = 0;
2769de5e440Sbellard             info.si_code = TARGET_ILL_ILLOPN;
2779de5e440Sbellard             info._sifields._sigfault._addr = env->eip;
2789de5e440Sbellard             queue_signal(info.si_signo, &info);
2799de5e440Sbellard             break;
2809de5e440Sbellard         case EXCP_INTERRUPT:
2819de5e440Sbellard             /* just indicate that signals should be handled asap */
2829de5e440Sbellard             break;
2831fddef4bSbellard         case EXCP_DEBUG:
2841fddef4bSbellard             {
2851fddef4bSbellard                 int sig;
2861fddef4bSbellard 
2871fddef4bSbellard                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
2881fddef4bSbellard                 if (sig)
2891fddef4bSbellard                   {
2901fddef4bSbellard                     info.si_signo = sig;
2911fddef4bSbellard                     info.si_errno = 0;
2921fddef4bSbellard                     info.si_code = TARGET_TRAP_BRKPT;
2931fddef4bSbellard                     queue_signal(info.si_signo, &info);
2941fddef4bSbellard                   }
2951fddef4bSbellard             }
2961fddef4bSbellard             break;
2971b6b029eSbellard         default:
298970a87a6Sbellard             pc = env->segs[R_CS].base + env->eip;
299bc8a22ccSbellard             fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
300bc8a22ccSbellard                     (long)pc, trapnr);
3011b6b029eSbellard             abort();
3021b6b029eSbellard         }
30366fb9763Sbellard         process_pending_signals(env);
3041b6b029eSbellard     }
3051b6b029eSbellard }
306b346ff46Sbellard #endif
307b346ff46Sbellard 
308b346ff46Sbellard #ifdef TARGET_ARM
309b346ff46Sbellard 
3106f1f31c0Sbellard /* XXX: find a better solution */
311992f48a0Sblueswir1 extern void tb_invalidate_page_range(abi_ulong start, abi_ulong end);
3126f1f31c0Sbellard 
313992f48a0Sblueswir1 static void arm_cache_flush(abi_ulong start, abi_ulong last)
3146f1f31c0Sbellard {
315992f48a0Sblueswir1     abi_ulong addr, last1;
3166f1f31c0Sbellard 
3176f1f31c0Sbellard     if (last < start)
3186f1f31c0Sbellard         return;
3196f1f31c0Sbellard     addr = start;
3206f1f31c0Sbellard     for(;;) {
3216f1f31c0Sbellard         last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1;
3226f1f31c0Sbellard         if (last1 > last)
3236f1f31c0Sbellard             last1 = last;
3246f1f31c0Sbellard         tb_invalidate_page_range(addr, last1 + 1);
3256f1f31c0Sbellard         if (last1 == last)
3266f1f31c0Sbellard             break;
3276f1f31c0Sbellard         addr = last1 + 1;
3286f1f31c0Sbellard     }
3296f1f31c0Sbellard }
3306f1f31c0Sbellard 
331b346ff46Sbellard void cpu_loop(CPUARMState *env)
332b346ff46Sbellard {
333b346ff46Sbellard     int trapnr;
334b346ff46Sbellard     unsigned int n, insn;
335b346ff46Sbellard     target_siginfo_t info;
336b5ff1b31Sbellard     uint32_t addr;
337b346ff46Sbellard 
338b346ff46Sbellard     for(;;) {
339b346ff46Sbellard         trapnr = cpu_arm_exec(env);
340b346ff46Sbellard         switch(trapnr) {
341b346ff46Sbellard         case EXCP_UDEF:
342c6981055Sbellard             {
343c6981055Sbellard                 TaskState *ts = env->opaque;
344c6981055Sbellard                 uint32_t opcode;
345c6981055Sbellard 
346c6981055Sbellard                 /* we handle the FPU emulation here, as Linux */
347c6981055Sbellard                 /* we get the opcode */
34853a5960aSpbrook                 opcode = tget32(env->regs[15]);
349c6981055Sbellard 
35019b045deSpbrook                 if (EmulateAll(opcode, &ts->fpa, env) == 0) {
351b346ff46Sbellard                     info.si_signo = SIGILL;
352b346ff46Sbellard                     info.si_errno = 0;
353b346ff46Sbellard                     info.si_code = TARGET_ILL_ILLOPN;
354b346ff46Sbellard                     info._sifields._sigfault._addr = env->regs[15];
355b346ff46Sbellard                     queue_signal(info.si_signo, &info);
356c6981055Sbellard                 } else {
357c6981055Sbellard                     /* increment PC */
358c6981055Sbellard                     env->regs[15] += 4;
359c6981055Sbellard                 }
360c6981055Sbellard             }
361b346ff46Sbellard             break;
362b346ff46Sbellard         case EXCP_SWI:
36306c949e6Spbrook         case EXCP_BKPT:
364b346ff46Sbellard             {
365ce4defa0Spbrook                 env->eabi = 1;
366b346ff46Sbellard                 /* system call */
36706c949e6Spbrook                 if (trapnr == EXCP_BKPT) {
36806c949e6Spbrook                     if (env->thumb) {
36953a5960aSpbrook                         insn = tget16(env->regs[15]);
37006c949e6Spbrook                         n = insn & 0xff;
37106c949e6Spbrook                         env->regs[15] += 2;
37206c949e6Spbrook                     } else {
37353a5960aSpbrook                         insn = tget32(env->regs[15]);
37406c949e6Spbrook                         n = (insn & 0xf) | ((insn >> 4) & 0xff0);
37506c949e6Spbrook                         env->regs[15] += 4;
37606c949e6Spbrook                     }
37706c949e6Spbrook                 } else {
378192c7bd9Sbellard                     if (env->thumb) {
37953a5960aSpbrook                         insn = tget16(env->regs[15] - 2);
380192c7bd9Sbellard                         n = insn & 0xff;
381192c7bd9Sbellard                     } else {
38253a5960aSpbrook                         insn = tget32(env->regs[15] - 4);
383b346ff46Sbellard                         n = insn & 0xffffff;
384192c7bd9Sbellard                     }
38506c949e6Spbrook                 }
386192c7bd9Sbellard 
3876f1f31c0Sbellard                 if (n == ARM_NR_cacheflush) {
3886f1f31c0Sbellard                     arm_cache_flush(env->regs[0], env->regs[1]);
389a4f81979Sbellard                 } else if (n == ARM_NR_semihosting
390a4f81979Sbellard                            || n == ARM_NR_thumb_semihosting) {
391a4f81979Sbellard                     env->regs[0] = do_arm_semihosting (env);
392ce4defa0Spbrook                 } else if (n == 0 || n >= ARM_SYSCALL_BASE
393192c7bd9Sbellard                            || (env->thumb && n == ARM_THUMB_SYSCALL)) {
394b346ff46Sbellard                     /* linux syscall */
395ce4defa0Spbrook                     if (env->thumb || n == 0) {
396192c7bd9Sbellard                         n = env->regs[7];
397192c7bd9Sbellard                     } else {
398b346ff46Sbellard                         n -= ARM_SYSCALL_BASE;
399ce4defa0Spbrook                         env->eabi = 0;
400192c7bd9Sbellard                     }
401b346ff46Sbellard                     env->regs[0] = do_syscall(env,
402b346ff46Sbellard                                               n,
403b346ff46Sbellard                                               env->regs[0],
404b346ff46Sbellard                                               env->regs[1],
405b346ff46Sbellard                                               env->regs[2],
406b346ff46Sbellard                                               env->regs[3],
407b346ff46Sbellard                                               env->regs[4],
408e1a2849cSbellard                                               env->regs[5]);
409b346ff46Sbellard                 } else {
410b346ff46Sbellard                     goto error;
411b346ff46Sbellard                 }
412b346ff46Sbellard             }
413b346ff46Sbellard             break;
41443fff238Sbellard         case EXCP_INTERRUPT:
41543fff238Sbellard             /* just indicate that signals should be handled asap */
41643fff238Sbellard             break;
41768016c62Sbellard         case EXCP_PREFETCH_ABORT:
418b5ff1b31Sbellard             addr = env->cp15.c6_data;
419b5ff1b31Sbellard             goto do_segv;
42068016c62Sbellard         case EXCP_DATA_ABORT:
421b5ff1b31Sbellard             addr = env->cp15.c6_insn;
422b5ff1b31Sbellard             goto do_segv;
423b5ff1b31Sbellard         do_segv:
42468016c62Sbellard             {
42568016c62Sbellard                 info.si_signo = SIGSEGV;
42668016c62Sbellard                 info.si_errno = 0;
42768016c62Sbellard                 /* XXX: check env->error_code */
42868016c62Sbellard                 info.si_code = TARGET_SEGV_MAPERR;
429b5ff1b31Sbellard                 info._sifields._sigfault._addr = addr;
43068016c62Sbellard                 queue_signal(info.si_signo, &info);
43168016c62Sbellard             }
43268016c62Sbellard             break;
4331fddef4bSbellard         case EXCP_DEBUG:
4341fddef4bSbellard             {
4351fddef4bSbellard                 int sig;
4361fddef4bSbellard 
4371fddef4bSbellard                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
4381fddef4bSbellard                 if (sig)
4391fddef4bSbellard                   {
4401fddef4bSbellard                     info.si_signo = sig;
4411fddef4bSbellard                     info.si_errno = 0;
4421fddef4bSbellard                     info.si_code = TARGET_TRAP_BRKPT;
4431fddef4bSbellard                     queue_signal(info.si_signo, &info);
4441fddef4bSbellard                   }
4451fddef4bSbellard             }
4461fddef4bSbellard             break;
447b346ff46Sbellard         default:
448b346ff46Sbellard         error:
449b346ff46Sbellard             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
450b346ff46Sbellard                     trapnr);
4517fe48483Sbellard             cpu_dump_state(env, stderr, fprintf, 0);
452b346ff46Sbellard             abort();
453b346ff46Sbellard         }
454b346ff46Sbellard         process_pending_signals(env);
455b346ff46Sbellard     }
456b346ff46Sbellard }
457b346ff46Sbellard 
458b346ff46Sbellard #endif
4591b6b029eSbellard 
46093ac68bcSbellard #ifdef TARGET_SPARC
46193ac68bcSbellard 
462060366c5Sbellard //#define DEBUG_WIN
463060366c5Sbellard 
4642623cbafSbellard /* WARNING: dealing with register windows _is_ complicated. More info
4652623cbafSbellard    can be found at http://www.sics.se/~psm/sparcstack.html */
466060366c5Sbellard static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
467060366c5Sbellard {
468060366c5Sbellard     index = (index + cwp * 16) & (16 * NWINDOWS - 1);
469060366c5Sbellard     /* wrap handling : if cwp is on the last window, then we use the
470060366c5Sbellard        registers 'after' the end */
471060366c5Sbellard     if (index < 8 && env->cwp == (NWINDOWS - 1))
472060366c5Sbellard         index += (16 * NWINDOWS);
473060366c5Sbellard     return index;
474060366c5Sbellard }
475060366c5Sbellard 
4762623cbafSbellard /* save the register window 'cwp1' */
4772623cbafSbellard static inline void save_window_offset(CPUSPARCState *env, int cwp1)
478060366c5Sbellard {
4792623cbafSbellard     unsigned int i;
480992f48a0Sblueswir1     abi_ulong sp_ptr;
481060366c5Sbellard 
48253a5960aSpbrook     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
483060366c5Sbellard #if defined(DEBUG_WIN)
484060366c5Sbellard     printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
485060366c5Sbellard            (int)sp_ptr, cwp1);
486060366c5Sbellard #endif
4872623cbafSbellard     for(i = 0; i < 16; i++) {
48853a5960aSpbrook         tputl(sp_ptr, env->regbase[get_reg_index(env, cwp1, 8 + i)]);
489992f48a0Sblueswir1         sp_ptr += sizeof(abi_ulong);
4902623cbafSbellard     }
491060366c5Sbellard }
492060366c5Sbellard 
493060366c5Sbellard static void save_window(CPUSPARCState *env)
494060366c5Sbellard {
4955ef54116Sbellard #ifndef TARGET_SPARC64
4962623cbafSbellard     unsigned int new_wim;
4972623cbafSbellard     new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &
4982623cbafSbellard         ((1LL << NWINDOWS) - 1);
4992623cbafSbellard     save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
5002623cbafSbellard     env->wim = new_wim;
5015ef54116Sbellard #else
5025ef54116Sbellard     save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
5035ef54116Sbellard     env->cansave++;
5045ef54116Sbellard     env->canrestore--;
5055ef54116Sbellard #endif
506060366c5Sbellard }
507060366c5Sbellard 
508060366c5Sbellard static void restore_window(CPUSPARCState *env)
509060366c5Sbellard {
510060366c5Sbellard     unsigned int new_wim, i, cwp1;
511992f48a0Sblueswir1     abi_ulong sp_ptr;
512060366c5Sbellard 
513060366c5Sbellard     new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
514060366c5Sbellard         ((1LL << NWINDOWS) - 1);
515060366c5Sbellard 
516060366c5Sbellard     /* restore the invalid window */
517060366c5Sbellard     cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
51853a5960aSpbrook     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
519060366c5Sbellard #if defined(DEBUG_WIN)
520060366c5Sbellard     printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
521060366c5Sbellard            (int)sp_ptr, cwp1);
522060366c5Sbellard #endif
5232623cbafSbellard     for(i = 0; i < 16; i++) {
52453a5960aSpbrook         env->regbase[get_reg_index(env, cwp1, 8 + i)] = tgetl(sp_ptr);
525992f48a0Sblueswir1         sp_ptr += sizeof(abi_ulong);
5262623cbafSbellard     }
527060366c5Sbellard     env->wim = new_wim;
5285ef54116Sbellard #ifdef TARGET_SPARC64
5295ef54116Sbellard     env->canrestore++;
5305ef54116Sbellard     if (env->cleanwin < NWINDOWS - 1)
5315ef54116Sbellard 	env->cleanwin++;
5325ef54116Sbellard     env->cansave--;
5335ef54116Sbellard #endif
534060366c5Sbellard }
535060366c5Sbellard 
536060366c5Sbellard static void flush_windows(CPUSPARCState *env)
537060366c5Sbellard {
538060366c5Sbellard     int offset, cwp1;
5392623cbafSbellard 
5402623cbafSbellard     offset = 1;
541060366c5Sbellard     for(;;) {
542060366c5Sbellard         /* if restore would invoke restore_window(), then we can stop */
5432623cbafSbellard         cwp1 = (env->cwp + offset) & (NWINDOWS - 1);
544060366c5Sbellard         if (env->wim & (1 << cwp1))
545060366c5Sbellard             break;
5462623cbafSbellard         save_window_offset(env, cwp1);
547060366c5Sbellard         offset++;
548060366c5Sbellard     }
5492623cbafSbellard     /* set wim so that restore will reload the registers */
5502623cbafSbellard     cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
5512623cbafSbellard     env->wim = 1 << cwp1;
5522623cbafSbellard #if defined(DEBUG_WIN)
5532623cbafSbellard     printf("flush_windows: nb=%d\n", offset - 1);
55480a9d035Sbellard #endif
5552623cbafSbellard }
556060366c5Sbellard 
55793ac68bcSbellard void cpu_loop (CPUSPARCState *env)
55893ac68bcSbellard {
559060366c5Sbellard     int trapnr, ret;
56061ff6f58Sbellard     target_siginfo_t info;
56193ac68bcSbellard 
56293ac68bcSbellard     while (1) {
56393ac68bcSbellard         trapnr = cpu_sparc_exec (env);
56493ac68bcSbellard 
56593ac68bcSbellard         switch (trapnr) {
5665ef54116Sbellard #ifndef TARGET_SPARC64
567060366c5Sbellard         case 0x88:
568060366c5Sbellard         case 0x90:
5695ef54116Sbellard #else
570cb33da57Sblueswir1         case 0x110:
5715ef54116Sbellard         case 0x16d:
5725ef54116Sbellard #endif
573060366c5Sbellard             ret = do_syscall (env, env->gregs[1],
574060366c5Sbellard                               env->regwptr[0], env->regwptr[1],
575060366c5Sbellard                               env->regwptr[2], env->regwptr[3],
576060366c5Sbellard                               env->regwptr[4], env->regwptr[5]);
577060366c5Sbellard             if ((unsigned int)ret >= (unsigned int)(-515)) {
578992f48a0Sblueswir1 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
57927908725Sbellard                 env->xcc |= PSR_CARRY;
58027908725Sbellard #else
58193ac68bcSbellard                 env->psr |= PSR_CARRY;
58227908725Sbellard #endif
583060366c5Sbellard                 ret = -ret;
584060366c5Sbellard             } else {
585992f48a0Sblueswir1 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
58627908725Sbellard                 env->xcc &= ~PSR_CARRY;
58727908725Sbellard #else
588060366c5Sbellard                 env->psr &= ~PSR_CARRY;
58927908725Sbellard #endif
590060366c5Sbellard             }
591060366c5Sbellard             env->regwptr[0] = ret;
592060366c5Sbellard             /* next instruction */
593060366c5Sbellard             env->pc = env->npc;
594060366c5Sbellard             env->npc = env->npc + 4;
595060366c5Sbellard             break;
596060366c5Sbellard         case 0x83: /* flush windows */
597992f48a0Sblueswir1 #ifdef TARGET_ABI32
598992f48a0Sblueswir1         case 0x103:
599992f48a0Sblueswir1 #endif
6002623cbafSbellard             flush_windows(env);
601060366c5Sbellard             /* next instruction */
602060366c5Sbellard             env->pc = env->npc;
603060366c5Sbellard             env->npc = env->npc + 4;
604060366c5Sbellard             break;
6053475187dSbellard #ifndef TARGET_SPARC64
606060366c5Sbellard         case TT_WIN_OVF: /* window overflow */
607060366c5Sbellard             save_window(env);
608060366c5Sbellard             break;
609060366c5Sbellard         case TT_WIN_UNF: /* window underflow */
610060366c5Sbellard             restore_window(env);
61193ac68bcSbellard             break;
61261ff6f58Sbellard         case TT_TFAULT:
61361ff6f58Sbellard         case TT_DFAULT:
61461ff6f58Sbellard             {
61561ff6f58Sbellard                 info.si_signo = SIGSEGV;
61661ff6f58Sbellard                 info.si_errno = 0;
61761ff6f58Sbellard                 /* XXX: check env->error_code */
61861ff6f58Sbellard                 info.si_code = TARGET_SEGV_MAPERR;
61961ff6f58Sbellard                 info._sifields._sigfault._addr = env->mmuregs[4];
62061ff6f58Sbellard                 queue_signal(info.si_signo, &info);
62161ff6f58Sbellard             }
62261ff6f58Sbellard             break;
6233475187dSbellard #else
6245ef54116Sbellard         case TT_SPILL: /* window overflow */
6255ef54116Sbellard             save_window(env);
6265ef54116Sbellard             break;
6275ef54116Sbellard         case TT_FILL: /* window underflow */
6285ef54116Sbellard             restore_window(env);
6295ef54116Sbellard             break;
6307f84a729Sblueswir1         case TT_TFAULT:
6317f84a729Sblueswir1         case TT_DFAULT:
6327f84a729Sblueswir1             {
6337f84a729Sblueswir1                 info.si_signo = SIGSEGV;
6347f84a729Sblueswir1                 info.si_errno = 0;
6357f84a729Sblueswir1                 /* XXX: check env->error_code */
6367f84a729Sblueswir1                 info.si_code = TARGET_SEGV_MAPERR;
6377f84a729Sblueswir1                 if (trapnr == TT_DFAULT)
6387f84a729Sblueswir1                     info._sifields._sigfault._addr = env->dmmuregs[4];
6397f84a729Sblueswir1                 else
6407f84a729Sblueswir1                     info._sifields._sigfault._addr = env->tpc[env->tl];
6417f84a729Sblueswir1                 queue_signal(info.si_signo, &info);
6427f84a729Sblueswir1             }
6437f84a729Sblueswir1             break;
644*27524dc3Sbellard #ifndef TARGET_ABI32
6455bfb56b2Sblueswir1         case 0x16e:
6465bfb56b2Sblueswir1             flush_windows(env);
6475bfb56b2Sblueswir1             sparc64_get_context(env);
6485bfb56b2Sblueswir1             break;
6495bfb56b2Sblueswir1         case 0x16f:
6505bfb56b2Sblueswir1             flush_windows(env);
6515bfb56b2Sblueswir1             sparc64_set_context(env);
6525bfb56b2Sblueswir1             break;
6533475187dSbellard #endif
654*27524dc3Sbellard #endif
65548dc41ebSbellard         case EXCP_INTERRUPT:
65648dc41ebSbellard             /* just indicate that signals should be handled asap */
657e80cfcfcSbellard             break;
6581fddef4bSbellard         case EXCP_DEBUG:
6591fddef4bSbellard             {
6601fddef4bSbellard                 int sig;
6611fddef4bSbellard 
6621fddef4bSbellard                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
6631fddef4bSbellard                 if (sig)
6641fddef4bSbellard                   {
6651fddef4bSbellard                     info.si_signo = sig;
6661fddef4bSbellard                     info.si_errno = 0;
6671fddef4bSbellard                     info.si_code = TARGET_TRAP_BRKPT;
6681fddef4bSbellard                     queue_signal(info.si_signo, &info);
6691fddef4bSbellard                   }
6701fddef4bSbellard             }
6711fddef4bSbellard             break;
67293ac68bcSbellard         default:
673060366c5Sbellard             printf ("Unhandled trap: 0x%x\n", trapnr);
6747fe48483Sbellard             cpu_dump_state(env, stderr, fprintf, 0);
67593ac68bcSbellard             exit (1);
67693ac68bcSbellard         }
67793ac68bcSbellard         process_pending_signals (env);
67893ac68bcSbellard     }
67993ac68bcSbellard }
68093ac68bcSbellard 
68193ac68bcSbellard #endif
68293ac68bcSbellard 
68367867308Sbellard #ifdef TARGET_PPC
6849fddaa0cSbellard static inline uint64_t cpu_ppc_get_tb (CPUState *env)
6859fddaa0cSbellard {
6869fddaa0cSbellard     /* TO FIX */
6879fddaa0cSbellard     return 0;
6889fddaa0cSbellard }
6899fddaa0cSbellard 
6909fddaa0cSbellard uint32_t cpu_ppc_load_tbl (CPUState *env)
6919fddaa0cSbellard {
6929fddaa0cSbellard     return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
6939fddaa0cSbellard }
6949fddaa0cSbellard 
6959fddaa0cSbellard uint32_t cpu_ppc_load_tbu (CPUState *env)
6969fddaa0cSbellard {
6979fddaa0cSbellard     return cpu_ppc_get_tb(env) >> 32;
6989fddaa0cSbellard }
6999fddaa0cSbellard 
700a062e36cSj_mayer uint32_t cpu_ppc_load_atbl (CPUState *env)
7019fddaa0cSbellard {
702a062e36cSj_mayer     return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
7039fddaa0cSbellard }
7049fddaa0cSbellard 
705a062e36cSj_mayer uint32_t cpu_ppc_load_atbu (CPUState *env)
7069fddaa0cSbellard {
707a062e36cSj_mayer     return cpu_ppc_get_tb(env) >> 32;
7089fddaa0cSbellard }
7099fddaa0cSbellard 
71076a66253Sj_mayer uint32_t cpu_ppc601_load_rtcu (CPUState *env)
71176a66253Sj_mayer __attribute__ (( alias ("cpu_ppc_load_tbu") ));
71276a66253Sj_mayer 
71376a66253Sj_mayer uint32_t cpu_ppc601_load_rtcl (CPUState *env)
7149fddaa0cSbellard {
71576a66253Sj_mayer     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
7169fddaa0cSbellard }
7179fddaa0cSbellard 
718a750fc0bSj_mayer /* XXX: to be fixed */
719a750fc0bSj_mayer int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
720a750fc0bSj_mayer {
721a750fc0bSj_mayer     return -1;
722a750fc0bSj_mayer }
723a750fc0bSj_mayer 
724a750fc0bSj_mayer int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
725a750fc0bSj_mayer {
726a750fc0bSj_mayer     return -1;
727a750fc0bSj_mayer }
728a750fc0bSj_mayer 
729e1833e1fSj_mayer #define EXCP_DUMP(env, fmt, args...)                                         \
730e1833e1fSj_mayer do {                                                                          \
731e1833e1fSj_mayer     fprintf(stderr, fmt , ##args);                                            \
732e1833e1fSj_mayer     cpu_dump_state(env, stderr, fprintf, 0);                                  \
733e1833e1fSj_mayer     if (loglevel != 0) {                                                      \
734e1833e1fSj_mayer         fprintf(logfile, fmt , ##args);                                       \
735e1833e1fSj_mayer         cpu_dump_state(env, logfile, fprintf, 0);                             \
736e1833e1fSj_mayer     }                                                                         \
737e1833e1fSj_mayer } while (0)
738e1833e1fSj_mayer 
73967867308Sbellard void cpu_loop(CPUPPCState *env)
74067867308Sbellard {
74167867308Sbellard     target_siginfo_t info;
74261190b14Sbellard     int trapnr;
74361190b14Sbellard     uint32_t ret;
74467867308Sbellard 
74567867308Sbellard     for(;;) {
74667867308Sbellard         trapnr = cpu_ppc_exec(env);
74767867308Sbellard         switch(trapnr) {
748e1833e1fSj_mayer         case POWERPC_EXCP_NONE:
749e1833e1fSj_mayer             /* Just go on */
75067867308Sbellard             break;
751e1833e1fSj_mayer         case POWERPC_EXCP_CRITICAL: /* Critical input                        */
752e1833e1fSj_mayer             cpu_abort(env, "Critical interrupt while in user mode. "
753e1833e1fSj_mayer                       "Aborting\n");
754e1833e1fSj_mayer             break;
755e1833e1fSj_mayer         case POWERPC_EXCP_MCHECK:   /* Machine check exception               */
756e1833e1fSj_mayer             cpu_abort(env, "Machine check exception while in user mode. "
757e1833e1fSj_mayer                       "Aborting\n");
758e1833e1fSj_mayer             break;
759e1833e1fSj_mayer         case POWERPC_EXCP_DSI:      /* Data storage exception                */
760e1833e1fSj_mayer             EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
761e1833e1fSj_mayer                       env->spr[SPR_DAR]);
762e1833e1fSj_mayer             /* XXX: check this. Seems bugged */
763e1833e1fSj_mayer             switch (env->error_code & 0xFF000000) {
764e1833e1fSj_mayer             case 0x40000000:
765e1833e1fSj_mayer                 info.si_signo = TARGET_SIGSEGV;
766e1833e1fSj_mayer                 info.si_errno = 0;
767e1833e1fSj_mayer                 info.si_code = TARGET_SEGV_MAPERR;
768e1833e1fSj_mayer                 break;
769e1833e1fSj_mayer             case 0x04000000:
770e1833e1fSj_mayer                 info.si_signo = TARGET_SIGILL;
771e1833e1fSj_mayer                 info.si_errno = 0;
772e1833e1fSj_mayer                 info.si_code = TARGET_ILL_ILLADR;
773e1833e1fSj_mayer                 break;
774e1833e1fSj_mayer             case 0x08000000:
775e1833e1fSj_mayer                 info.si_signo = TARGET_SIGSEGV;
776e1833e1fSj_mayer                 info.si_errno = 0;
777e1833e1fSj_mayer                 info.si_code = TARGET_SEGV_ACCERR;
778e1833e1fSj_mayer                 break;
779e1833e1fSj_mayer             default:
780e1833e1fSj_mayer                 /* Let's send a regular segfault... */
781e1833e1fSj_mayer                 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
782e1833e1fSj_mayer                           env->error_code);
783e1833e1fSj_mayer                 info.si_signo = TARGET_SIGSEGV;
784e1833e1fSj_mayer                 info.si_errno = 0;
785e1833e1fSj_mayer                 info.si_code = TARGET_SEGV_MAPERR;
786e1833e1fSj_mayer                 break;
787e1833e1fSj_mayer             }
788e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip;
789e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
790e1833e1fSj_mayer             break;
791e1833e1fSj_mayer         case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
792e1833e1fSj_mayer             EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
793f10c315fSj_mayer                       env->spr[SPR_SRR0]);
794e1833e1fSj_mayer             /* XXX: check this */
795e1833e1fSj_mayer             switch (env->error_code & 0xFF000000) {
796e1833e1fSj_mayer             case 0x40000000:
797e1833e1fSj_mayer                 info.si_signo = TARGET_SIGSEGV;
798e1833e1fSj_mayer             info.si_errno = 0;
799e1833e1fSj_mayer                 info.si_code = TARGET_SEGV_MAPERR;
800e1833e1fSj_mayer                 break;
801e1833e1fSj_mayer             case 0x10000000:
802e1833e1fSj_mayer             case 0x08000000:
803e1833e1fSj_mayer                 info.si_signo = TARGET_SIGSEGV;
804e1833e1fSj_mayer                 info.si_errno = 0;
805e1833e1fSj_mayer                 info.si_code = TARGET_SEGV_ACCERR;
806e1833e1fSj_mayer                 break;
807e1833e1fSj_mayer             default:
808e1833e1fSj_mayer                 /* Let's send a regular segfault... */
809e1833e1fSj_mayer                 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
810e1833e1fSj_mayer                           env->error_code);
811e1833e1fSj_mayer                 info.si_signo = TARGET_SIGSEGV;
812e1833e1fSj_mayer                 info.si_errno = 0;
813e1833e1fSj_mayer                 info.si_code = TARGET_SEGV_MAPERR;
814e1833e1fSj_mayer                 break;
815e1833e1fSj_mayer             }
816e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
817e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
818e1833e1fSj_mayer             break;
819e1833e1fSj_mayer         case POWERPC_EXCP_EXTERNAL: /* External input                        */
820e1833e1fSj_mayer             cpu_abort(env, "External interrupt while in user mode. "
821e1833e1fSj_mayer                       "Aborting\n");
822e1833e1fSj_mayer             break;
823e1833e1fSj_mayer         case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */
824e1833e1fSj_mayer             EXCP_DUMP(env, "Unaligned memory access\n");
825e1833e1fSj_mayer             /* XXX: check this */
826e1833e1fSj_mayer             info.si_signo = TARGET_SIGBUS;
827e1833e1fSj_mayer             info.si_errno = 0;
828e1833e1fSj_mayer             info.si_code = TARGET_BUS_ADRALN;
829e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
830e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
831e1833e1fSj_mayer             break;
832e1833e1fSj_mayer         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
833e1833e1fSj_mayer             /* XXX: check this */
834e1833e1fSj_mayer             switch (env->error_code & ~0xF) {
835e1833e1fSj_mayer             case POWERPC_EXCP_FP:
836e1833e1fSj_mayer                 EXCP_DUMP(env, "Floating point program exception\n");
837e1833e1fSj_mayer                 info.si_signo = TARGET_SIGFPE;
838e1833e1fSj_mayer                 info.si_errno = 0;
839e1833e1fSj_mayer                 switch (env->error_code & 0xF) {
840e1833e1fSj_mayer                 case POWERPC_EXCP_FP_OX:
841e1833e1fSj_mayer                     info.si_code = TARGET_FPE_FLTOVF;
842e1833e1fSj_mayer                     break;
843e1833e1fSj_mayer                 case POWERPC_EXCP_FP_UX:
844e1833e1fSj_mayer                     info.si_code = TARGET_FPE_FLTUND;
845e1833e1fSj_mayer                     break;
846e1833e1fSj_mayer                 case POWERPC_EXCP_FP_ZX:
847e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXZDZ:
848e1833e1fSj_mayer                     info.si_code = TARGET_FPE_FLTDIV;
849e1833e1fSj_mayer                     break;
850e1833e1fSj_mayer                 case POWERPC_EXCP_FP_XX:
851e1833e1fSj_mayer                     info.si_code = TARGET_FPE_FLTRES;
852e1833e1fSj_mayer                     break;
853e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXSOFT:
854e1833e1fSj_mayer                     info.si_code = TARGET_FPE_FLTINV;
855e1833e1fSj_mayer                     break;
8567c58044cSj_mayer                 case POWERPC_EXCP_FP_VXSNAN:
857e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXISI:
858e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXIDI:
859e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXIMZ:
860e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXVC:
861e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXSQRT:
862e1833e1fSj_mayer                 case POWERPC_EXCP_FP_VXCVI:
863e1833e1fSj_mayer                     info.si_code = TARGET_FPE_FLTSUB;
864e1833e1fSj_mayer                     break;
865e1833e1fSj_mayer                 default:
866e1833e1fSj_mayer                     EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
867e1833e1fSj_mayer                               env->error_code);
868e1833e1fSj_mayer                     break;
869e1833e1fSj_mayer                 }
870e1833e1fSj_mayer                 break;
871e1833e1fSj_mayer             case POWERPC_EXCP_INVAL:
872e1833e1fSj_mayer                 EXCP_DUMP(env, "Invalid instruction\n");
873e1833e1fSj_mayer                 info.si_signo = TARGET_SIGILL;
874e1833e1fSj_mayer                 info.si_errno = 0;
875e1833e1fSj_mayer                 switch (env->error_code & 0xF) {
876e1833e1fSj_mayer                 case POWERPC_EXCP_INVAL_INVAL:
877e1833e1fSj_mayer                     info.si_code = TARGET_ILL_ILLOPC;
878e1833e1fSj_mayer                     break;
879e1833e1fSj_mayer                 case POWERPC_EXCP_INVAL_LSWX:
880e1833e1fSj_mayer                     info.si_code = TARGET_ILL_ILLOPN;
881e1833e1fSj_mayer                     break;
882e1833e1fSj_mayer                 case POWERPC_EXCP_INVAL_SPR:
883e1833e1fSj_mayer                     info.si_code = TARGET_ILL_PRVREG;
884e1833e1fSj_mayer                     break;
885e1833e1fSj_mayer                 case POWERPC_EXCP_INVAL_FP:
886e1833e1fSj_mayer                     info.si_code = TARGET_ILL_COPROC;
887e1833e1fSj_mayer                     break;
888e1833e1fSj_mayer                 default:
889e1833e1fSj_mayer                     EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
890e1833e1fSj_mayer                               env->error_code & 0xF);
891e1833e1fSj_mayer                     info.si_code = TARGET_ILL_ILLADR;
892e1833e1fSj_mayer                     break;
893e1833e1fSj_mayer                 }
894e1833e1fSj_mayer                 break;
895e1833e1fSj_mayer             case POWERPC_EXCP_PRIV:
896e1833e1fSj_mayer                 EXCP_DUMP(env, "Privilege violation\n");
897e1833e1fSj_mayer                 info.si_signo = TARGET_SIGILL;
898e1833e1fSj_mayer                 info.si_errno = 0;
899e1833e1fSj_mayer                 switch (env->error_code & 0xF) {
900e1833e1fSj_mayer                 case POWERPC_EXCP_PRIV_OPC:
901e1833e1fSj_mayer                     info.si_code = TARGET_ILL_PRVOPC;
902e1833e1fSj_mayer                     break;
903e1833e1fSj_mayer                 case POWERPC_EXCP_PRIV_REG:
904e1833e1fSj_mayer                     info.si_code = TARGET_ILL_PRVREG;
905e1833e1fSj_mayer                     break;
906e1833e1fSj_mayer                 default:
907e1833e1fSj_mayer                     EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
908e1833e1fSj_mayer                               env->error_code & 0xF);
909e1833e1fSj_mayer                     info.si_code = TARGET_ILL_PRVOPC;
910e1833e1fSj_mayer                     break;
911e1833e1fSj_mayer                 }
912e1833e1fSj_mayer                 break;
913e1833e1fSj_mayer             case POWERPC_EXCP_TRAP:
914e1833e1fSj_mayer                 cpu_abort(env, "Tried to call a TRAP\n");
915e1833e1fSj_mayer                 break;
916e1833e1fSj_mayer             default:
917e1833e1fSj_mayer                 /* Should not happen ! */
918e1833e1fSj_mayer                 cpu_abort(env, "Unknown program exception (%02x)\n",
919e1833e1fSj_mayer                           env->error_code);
920e1833e1fSj_mayer                 break;
921e1833e1fSj_mayer             }
922e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
923e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
924e1833e1fSj_mayer             break;
925e1833e1fSj_mayer         case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
926e1833e1fSj_mayer             EXCP_DUMP(env, "No floating point allowed\n");
927e1833e1fSj_mayer             info.si_signo = TARGET_SIGILL;
928e1833e1fSj_mayer             info.si_errno = 0;
929e1833e1fSj_mayer             info.si_code = TARGET_ILL_COPROC;
930e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
931e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
932e1833e1fSj_mayer             break;
933e1833e1fSj_mayer         case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
934e1833e1fSj_mayer             cpu_abort(env, "Syscall exception while in user mode. "
935e1833e1fSj_mayer                       "Aborting\n");
936e1833e1fSj_mayer             break;
937e1833e1fSj_mayer         case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */
938e1833e1fSj_mayer             EXCP_DUMP(env, "No APU instruction allowed\n");
939e1833e1fSj_mayer             info.si_signo = TARGET_SIGILL;
940e1833e1fSj_mayer             info.si_errno = 0;
941e1833e1fSj_mayer             info.si_code = TARGET_ILL_COPROC;
942e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
943e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
944e1833e1fSj_mayer             break;
945e1833e1fSj_mayer         case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
946e1833e1fSj_mayer             cpu_abort(env, "Decrementer interrupt while in user mode. "
947e1833e1fSj_mayer                       "Aborting\n");
948e1833e1fSj_mayer             break;
949e1833e1fSj_mayer         case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */
950e1833e1fSj_mayer             cpu_abort(env, "Fix interval timer interrupt while in user mode. "
951e1833e1fSj_mayer                       "Aborting\n");
952e1833e1fSj_mayer             break;
953e1833e1fSj_mayer         case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */
954e1833e1fSj_mayer             cpu_abort(env, "Watchdog timer interrupt while in user mode. "
955e1833e1fSj_mayer                       "Aborting\n");
956e1833e1fSj_mayer             break;
957e1833e1fSj_mayer         case POWERPC_EXCP_DTLB:     /* Data TLB error                        */
958e1833e1fSj_mayer             cpu_abort(env, "Data TLB exception while in user mode. "
959e1833e1fSj_mayer                       "Aborting\n");
960e1833e1fSj_mayer             break;
961e1833e1fSj_mayer         case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */
962e1833e1fSj_mayer             cpu_abort(env, "Instruction TLB exception while in user mode. "
963e1833e1fSj_mayer                       "Aborting\n");
964e1833e1fSj_mayer             break;
965e1833e1fSj_mayer         case POWERPC_EXCP_DEBUG:    /* Debug interrupt                       */
966e1833e1fSj_mayer             /* XXX: check this */
967e1833e1fSj_mayer             {
968e1833e1fSj_mayer                 int sig;
969e1833e1fSj_mayer 
970e1833e1fSj_mayer                 sig = gdb_handlesig(env, TARGET_SIGTRAP);
971e1833e1fSj_mayer                 if (sig) {
972e1833e1fSj_mayer                     info.si_signo = sig;
973e1833e1fSj_mayer                     info.si_errno = 0;
974e1833e1fSj_mayer                     info.si_code = TARGET_TRAP_BRKPT;
975e1833e1fSj_mayer                     queue_signal(info.si_signo, &info);
976e1833e1fSj_mayer                   }
977e1833e1fSj_mayer             }
978e1833e1fSj_mayer             break;
979e1833e1fSj_mayer #if defined(TARGET_PPCEMB)
980e1833e1fSj_mayer         case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
981e1833e1fSj_mayer             EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
982e1833e1fSj_mayer             info.si_signo = TARGET_SIGILL;
983e1833e1fSj_mayer             info.si_errno = 0;
984e1833e1fSj_mayer             info.si_code = TARGET_ILL_COPROC;
985e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
986e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
987e1833e1fSj_mayer             break;
988e1833e1fSj_mayer         case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
989e1833e1fSj_mayer             cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
990e1833e1fSj_mayer             break;
991e1833e1fSj_mayer         case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */
992e1833e1fSj_mayer             cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
993e1833e1fSj_mayer             break;
994e1833e1fSj_mayer         case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */
995e1833e1fSj_mayer             cpu_abort(env, "Performance monitor exception not handled\n");
996e1833e1fSj_mayer             break;
997e1833e1fSj_mayer         case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */
998e1833e1fSj_mayer             cpu_abort(env, "Doorbell interrupt while in user mode. "
999e1833e1fSj_mayer                        "Aborting\n");
1000e1833e1fSj_mayer             break;
1001e1833e1fSj_mayer         case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */
1002e1833e1fSj_mayer             cpu_abort(env, "Doorbell critical interrupt while in user mode. "
1003e1833e1fSj_mayer                       "Aborting\n");
1004e1833e1fSj_mayer             break;
1005e1833e1fSj_mayer         case POWERPC_EXCP_RESET:    /* System reset exception                */
1006e1833e1fSj_mayer             cpu_abort(env, "Reset interrupt while in user mode. "
1007e1833e1fSj_mayer                       "Aborting\n");
1008e1833e1fSj_mayer             break;
1009e1833e1fSj_mayer #endif /* defined(TARGET_PPCEMB) */
1010e85e7c6eSj_mayer #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) /* PowerPC 64 */
1011e1833e1fSj_mayer         case POWERPC_EXCP_DSEG:     /* Data segment exception                */
1012e1833e1fSj_mayer             cpu_abort(env, "Data segment exception while in user mode. "
1013e1833e1fSj_mayer                       "Aborting\n");
1014e1833e1fSj_mayer             break;
1015e1833e1fSj_mayer         case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */
1016e1833e1fSj_mayer             cpu_abort(env, "Instruction segment exception "
1017e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1018e1833e1fSj_mayer             break;
1019e85e7c6eSj_mayer #endif /* defined(TARGET_PPC64) && !defined(TARGET_ABI32) */
1020e85e7c6eSj_mayer #if defined(TARGET_PPC64H) && !defined(TARGET_ABI32)
1021e85e7c6eSj_mayer         /* PowerPC 64 with hypervisor mode support */
1022e1833e1fSj_mayer         case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */
1023e1833e1fSj_mayer             cpu_abort(env, "Hypervisor decrementer interrupt "
1024e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1025e1833e1fSj_mayer             break;
1026e85e7c6eSj_mayer #endif /* defined(TARGET_PPC64H) && !defined(TARGET_ABI32) */
1027e1833e1fSj_mayer         case POWERPC_EXCP_TRACE:    /* Trace exception                       */
1028e1833e1fSj_mayer             /* Nothing to do:
1029e1833e1fSj_mayer              * we use this exception to emulate step-by-step execution mode.
1030e1833e1fSj_mayer              */
1031e1833e1fSj_mayer             break;
1032e85e7c6eSj_mayer #if defined(TARGET_PPC64H) && !defined(TARGET_ABI32)
1033e85e7c6eSj_mayer         /* PowerPC 64 with hypervisor mode support */
1034e1833e1fSj_mayer         case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */
1035e1833e1fSj_mayer             cpu_abort(env, "Hypervisor data storage exception "
1036e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1037e1833e1fSj_mayer             break;
1038e1833e1fSj_mayer         case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */
1039e1833e1fSj_mayer             cpu_abort(env, "Hypervisor instruction storage exception "
1040e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1041e1833e1fSj_mayer             break;
1042e1833e1fSj_mayer         case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */
1043e1833e1fSj_mayer             cpu_abort(env, "Hypervisor data segment exception "
1044e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1045e1833e1fSj_mayer             break;
1046e1833e1fSj_mayer         case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */
1047e1833e1fSj_mayer             cpu_abort(env, "Hypervisor instruction segment exception "
1048e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1049e1833e1fSj_mayer             break;
1050e85e7c6eSj_mayer #endif /* defined(TARGET_PPC64H) && !defined(TARGET_ABI32) */
1051e1833e1fSj_mayer         case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */
1052e1833e1fSj_mayer             EXCP_DUMP(env, "No Altivec instructions allowed\n");
1053e1833e1fSj_mayer             info.si_signo = TARGET_SIGILL;
1054e1833e1fSj_mayer             info.si_errno = 0;
1055e1833e1fSj_mayer             info.si_code = TARGET_ILL_COPROC;
1056e1833e1fSj_mayer             info._sifields._sigfault._addr = env->nip - 4;
1057e1833e1fSj_mayer             queue_signal(info.si_signo, &info);
1058e1833e1fSj_mayer             break;
1059e1833e1fSj_mayer         case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
1060e1833e1fSj_mayer             cpu_abort(env, "Programable interval timer interrupt "
1061e1833e1fSj_mayer                       "while in user mode. Aborting\n");
1062e1833e1fSj_mayer             break;
1063e1833e1fSj_mayer         case POWERPC_EXCP_IO:       /* IO error exception                    */
1064e1833e1fSj_mayer             cpu_abort(env, "IO error exception while in user mode. "
1065e1833e1fSj_mayer                       "Aborting\n");
1066e1833e1fSj_mayer             break;
1067e1833e1fSj_mayer         case POWERPC_EXCP_RUNM:     /* Run mode exception                    */
1068e1833e1fSj_mayer             cpu_abort(env, "Run mode exception while in user mode. "
1069e1833e1fSj_mayer                       "Aborting\n");
1070e1833e1fSj_mayer             break;
1071e1833e1fSj_mayer         case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */
1072e1833e1fSj_mayer             cpu_abort(env, "Emulation trap exception not handled\n");
1073e1833e1fSj_mayer             break;
1074e1833e1fSj_mayer         case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */
1075e1833e1fSj_mayer             cpu_abort(env, "Instruction fetch TLB exception "
1076e1833e1fSj_mayer                       "while in user-mode. Aborting");
1077e1833e1fSj_mayer             break;
1078e1833e1fSj_mayer         case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */
1079e1833e1fSj_mayer             cpu_abort(env, "Data load TLB exception while in user-mode. "
1080e1833e1fSj_mayer                       "Aborting");
1081e1833e1fSj_mayer             break;
1082e1833e1fSj_mayer         case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */
1083e1833e1fSj_mayer             cpu_abort(env, "Data store TLB exception while in user-mode. "
1084e1833e1fSj_mayer                       "Aborting");
1085e1833e1fSj_mayer             break;
1086e1833e1fSj_mayer         case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */
1087e1833e1fSj_mayer             cpu_abort(env, "Floating-point assist exception not handled\n");
1088e1833e1fSj_mayer             break;
1089e1833e1fSj_mayer         case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */
1090e1833e1fSj_mayer             cpu_abort(env, "Instruction address breakpoint exception "
1091e1833e1fSj_mayer                       "not handled\n");
1092e1833e1fSj_mayer             break;
1093e1833e1fSj_mayer         case POWERPC_EXCP_SMI:      /* System management interrupt           */
1094e1833e1fSj_mayer             cpu_abort(env, "System management interrupt while in user mode. "
1095e1833e1fSj_mayer                       "Aborting\n");
1096e1833e1fSj_mayer             break;
1097e1833e1fSj_mayer         case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */
1098e1833e1fSj_mayer             cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
1099e1833e1fSj_mayer                       "Aborting\n");
1100e1833e1fSj_mayer             break;
1101e1833e1fSj_mayer         case POWERPC_EXCP_PERFM:   /* Embedded performance monitor IRQ      */
1102e1833e1fSj_mayer             cpu_abort(env, "Performance monitor exception not handled\n");
1103e1833e1fSj_mayer             break;
1104e1833e1fSj_mayer         case POWERPC_EXCP_VPUA:     /* Vector assist exception               */
1105e1833e1fSj_mayer             cpu_abort(env, "Vector assist exception not handled\n");
1106e1833e1fSj_mayer             break;
1107e1833e1fSj_mayer         case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */
1108e1833e1fSj_mayer             cpu_abort(env, "Soft patch exception not handled\n");
1109e1833e1fSj_mayer             break;
1110e1833e1fSj_mayer         case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */
1111e1833e1fSj_mayer             cpu_abort(env, "Maintenance exception while in user mode. "
1112e1833e1fSj_mayer                       "Aborting\n");
1113e1833e1fSj_mayer             break;
1114e1833e1fSj_mayer         case POWERPC_EXCP_STOP:     /* stop translation                      */
1115e1833e1fSj_mayer             /* We did invalidate the instruction cache. Go on */
1116e1833e1fSj_mayer             break;
1117e1833e1fSj_mayer         case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */
1118e1833e1fSj_mayer             /* We just stopped because of a branch. Go on */
1119e1833e1fSj_mayer             break;
1120e1833e1fSj_mayer         case POWERPC_EXCP_SYSCALL_USER:
1121e1833e1fSj_mayer             /* system call in user-mode emulation */
112267867308Sbellard             /* WARNING:
112367867308Sbellard              * PPC ABI uses overflow flag in cr0 to signal an error
112467867308Sbellard              * in syscalls.
112567867308Sbellard              */
112661190b14Sbellard #if 0
112761190b14Sbellard             printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
112861190b14Sbellard                    env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
112961190b14Sbellard #endif
113067867308Sbellard             env->crf[0] &= ~0x1;
113167867308Sbellard             ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
113267867308Sbellard                              env->gpr[5], env->gpr[6], env->gpr[7],
113367867308Sbellard                              env->gpr[8]);
113467867308Sbellard             if (ret > (uint32_t)(-515)) {
113567867308Sbellard                 env->crf[0] |= 0x1;
113667867308Sbellard                 ret = -ret;
113767867308Sbellard             }
113867867308Sbellard             env->gpr[3] = ret;
113961190b14Sbellard #if 0
114061190b14Sbellard             printf("syscall returned 0x%08x (%d)\n", ret, ret);
114161190b14Sbellard #endif
114261190b14Sbellard             break;
114356ba31ffSj_mayer         case EXCP_INTERRUPT:
114456ba31ffSj_mayer             /* just indicate that signals should be handled asap */
114556ba31ffSj_mayer             break;
114661190b14Sbellard         default:
1147e1833e1fSj_mayer             cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
114867867308Sbellard             break;
114967867308Sbellard         }
115067867308Sbellard         process_pending_signals(env);
115167867308Sbellard     }
115267867308Sbellard }
115367867308Sbellard #endif
115467867308Sbellard 
1155048f6b4dSbellard #ifdef TARGET_MIPS
1156048f6b4dSbellard 
1157048f6b4dSbellard #define MIPS_SYS(name, args) args,
1158048f6b4dSbellard 
1159048f6b4dSbellard static const uint8_t mips_syscall_args[] = {
1160048f6b4dSbellard 	MIPS_SYS(sys_syscall	, 0)	/* 4000 */
1161048f6b4dSbellard 	MIPS_SYS(sys_exit	, 1)
1162048f6b4dSbellard 	MIPS_SYS(sys_fork	, 0)
1163048f6b4dSbellard 	MIPS_SYS(sys_read	, 3)
1164048f6b4dSbellard 	MIPS_SYS(sys_write	, 3)
1165048f6b4dSbellard 	MIPS_SYS(sys_open	, 3)	/* 4005 */
1166048f6b4dSbellard 	MIPS_SYS(sys_close	, 1)
1167048f6b4dSbellard 	MIPS_SYS(sys_waitpid	, 3)
1168048f6b4dSbellard 	MIPS_SYS(sys_creat	, 2)
1169048f6b4dSbellard 	MIPS_SYS(sys_link	, 2)
1170048f6b4dSbellard 	MIPS_SYS(sys_unlink	, 1)	/* 4010 */
1171048f6b4dSbellard 	MIPS_SYS(sys_execve	, 0)
1172048f6b4dSbellard 	MIPS_SYS(sys_chdir	, 1)
1173048f6b4dSbellard 	MIPS_SYS(sys_time	, 1)
1174048f6b4dSbellard 	MIPS_SYS(sys_mknod	, 3)
1175048f6b4dSbellard 	MIPS_SYS(sys_chmod	, 2)	/* 4015 */
1176048f6b4dSbellard 	MIPS_SYS(sys_lchown	, 3)
1177048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1178048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_stat */
1179048f6b4dSbellard 	MIPS_SYS(sys_lseek	, 3)
1180048f6b4dSbellard 	MIPS_SYS(sys_getpid	, 0)	/* 4020 */
1181048f6b4dSbellard 	MIPS_SYS(sys_mount	, 5)
1182048f6b4dSbellard 	MIPS_SYS(sys_oldumount	, 1)
1183048f6b4dSbellard 	MIPS_SYS(sys_setuid	, 1)
1184048f6b4dSbellard 	MIPS_SYS(sys_getuid	, 0)
1185048f6b4dSbellard 	MIPS_SYS(sys_stime	, 1)	/* 4025 */
1186048f6b4dSbellard 	MIPS_SYS(sys_ptrace	, 4)
1187048f6b4dSbellard 	MIPS_SYS(sys_alarm	, 1)
1188048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_fstat */
1189048f6b4dSbellard 	MIPS_SYS(sys_pause	, 0)
1190048f6b4dSbellard 	MIPS_SYS(sys_utime	, 2)	/* 4030 */
1191048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1192048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1193048f6b4dSbellard 	MIPS_SYS(sys_access	, 2)
1194048f6b4dSbellard 	MIPS_SYS(sys_nice	, 1)
1195048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4035 */
1196048f6b4dSbellard 	MIPS_SYS(sys_sync	, 0)
1197048f6b4dSbellard 	MIPS_SYS(sys_kill	, 2)
1198048f6b4dSbellard 	MIPS_SYS(sys_rename	, 2)
1199048f6b4dSbellard 	MIPS_SYS(sys_mkdir	, 2)
1200048f6b4dSbellard 	MIPS_SYS(sys_rmdir	, 1)	/* 4040 */
1201048f6b4dSbellard 	MIPS_SYS(sys_dup		, 1)
1202048f6b4dSbellard 	MIPS_SYS(sys_pipe	, 0)
1203048f6b4dSbellard 	MIPS_SYS(sys_times	, 1)
1204048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1205048f6b4dSbellard 	MIPS_SYS(sys_brk		, 1)	/* 4045 */
1206048f6b4dSbellard 	MIPS_SYS(sys_setgid	, 1)
1207048f6b4dSbellard 	MIPS_SYS(sys_getgid	, 0)
1208048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was signal(2) */
1209048f6b4dSbellard 	MIPS_SYS(sys_geteuid	, 0)
1210048f6b4dSbellard 	MIPS_SYS(sys_getegid	, 0)	/* 4050 */
1211048f6b4dSbellard 	MIPS_SYS(sys_acct	, 0)
1212048f6b4dSbellard 	MIPS_SYS(sys_umount	, 2)
1213048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1214048f6b4dSbellard 	MIPS_SYS(sys_ioctl	, 3)
1215048f6b4dSbellard 	MIPS_SYS(sys_fcntl	, 3)	/* 4055 */
1216048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 2)
1217048f6b4dSbellard 	MIPS_SYS(sys_setpgid	, 2)
1218048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1219048f6b4dSbellard 	MIPS_SYS(sys_olduname	, 1)
1220048f6b4dSbellard 	MIPS_SYS(sys_umask	, 1)	/* 4060 */
1221048f6b4dSbellard 	MIPS_SYS(sys_chroot	, 1)
1222048f6b4dSbellard 	MIPS_SYS(sys_ustat	, 2)
1223048f6b4dSbellard 	MIPS_SYS(sys_dup2	, 2)
1224048f6b4dSbellard 	MIPS_SYS(sys_getppid	, 0)
1225048f6b4dSbellard 	MIPS_SYS(sys_getpgrp	, 0)	/* 4065 */
1226048f6b4dSbellard 	MIPS_SYS(sys_setsid	, 0)
1227048f6b4dSbellard 	MIPS_SYS(sys_sigaction	, 3)
1228048f6b4dSbellard 	MIPS_SYS(sys_sgetmask	, 0)
1229048f6b4dSbellard 	MIPS_SYS(sys_ssetmask	, 1)
1230048f6b4dSbellard 	MIPS_SYS(sys_setreuid	, 2)	/* 4070 */
1231048f6b4dSbellard 	MIPS_SYS(sys_setregid	, 2)
1232048f6b4dSbellard 	MIPS_SYS(sys_sigsuspend	, 0)
1233048f6b4dSbellard 	MIPS_SYS(sys_sigpending	, 1)
1234048f6b4dSbellard 	MIPS_SYS(sys_sethostname	, 2)
1235048f6b4dSbellard 	MIPS_SYS(sys_setrlimit	, 2)	/* 4075 */
1236048f6b4dSbellard 	MIPS_SYS(sys_getrlimit	, 2)
1237048f6b4dSbellard 	MIPS_SYS(sys_getrusage	, 2)
1238048f6b4dSbellard 	MIPS_SYS(sys_gettimeofday, 2)
1239048f6b4dSbellard 	MIPS_SYS(sys_settimeofday, 2)
1240048f6b4dSbellard 	MIPS_SYS(sys_getgroups	, 2)	/* 4080 */
1241048f6b4dSbellard 	MIPS_SYS(sys_setgroups	, 2)
1242048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* old_select */
1243048f6b4dSbellard 	MIPS_SYS(sys_symlink	, 2)
1244048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_lstat */
1245048f6b4dSbellard 	MIPS_SYS(sys_readlink	, 3)	/* 4085 */
1246048f6b4dSbellard 	MIPS_SYS(sys_uselib	, 1)
1247048f6b4dSbellard 	MIPS_SYS(sys_swapon	, 2)
1248048f6b4dSbellard 	MIPS_SYS(sys_reboot	, 3)
1249048f6b4dSbellard 	MIPS_SYS(old_readdir	, 3)
1250048f6b4dSbellard 	MIPS_SYS(old_mmap	, 6)	/* 4090 */
1251048f6b4dSbellard 	MIPS_SYS(sys_munmap	, 2)
1252048f6b4dSbellard 	MIPS_SYS(sys_truncate	, 2)
1253048f6b4dSbellard 	MIPS_SYS(sys_ftruncate	, 2)
1254048f6b4dSbellard 	MIPS_SYS(sys_fchmod	, 2)
1255048f6b4dSbellard 	MIPS_SYS(sys_fchown	, 3)	/* 4095 */
1256048f6b4dSbellard 	MIPS_SYS(sys_getpriority	, 2)
1257048f6b4dSbellard 	MIPS_SYS(sys_setpriority	, 3)
1258048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1259048f6b4dSbellard 	MIPS_SYS(sys_statfs	, 2)
1260048f6b4dSbellard 	MIPS_SYS(sys_fstatfs	, 2)	/* 4100 */
1261048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was ioperm(2) */
1262048f6b4dSbellard 	MIPS_SYS(sys_socketcall	, 2)
1263048f6b4dSbellard 	MIPS_SYS(sys_syslog	, 3)
1264048f6b4dSbellard 	MIPS_SYS(sys_setitimer	, 3)
1265048f6b4dSbellard 	MIPS_SYS(sys_getitimer	, 2)	/* 4105 */
1266048f6b4dSbellard 	MIPS_SYS(sys_newstat	, 2)
1267048f6b4dSbellard 	MIPS_SYS(sys_newlstat	, 2)
1268048f6b4dSbellard 	MIPS_SYS(sys_newfstat	, 2)
1269048f6b4dSbellard 	MIPS_SYS(sys_uname	, 1)
1270048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4110 was iopl(2) */
1271048f6b4dSbellard 	MIPS_SYS(sys_vhangup	, 0)
1272048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_idle() */
1273048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_vm86 */
1274048f6b4dSbellard 	MIPS_SYS(sys_wait4	, 4)
1275048f6b4dSbellard 	MIPS_SYS(sys_swapoff	, 1)	/* 4115 */
1276048f6b4dSbellard 	MIPS_SYS(sys_sysinfo	, 1)
1277048f6b4dSbellard 	MIPS_SYS(sys_ipc		, 6)
1278048f6b4dSbellard 	MIPS_SYS(sys_fsync	, 1)
1279048f6b4dSbellard 	MIPS_SYS(sys_sigreturn	, 0)
1280048f6b4dSbellard 	MIPS_SYS(sys_clone	, 0)	/* 4120 */
1281048f6b4dSbellard 	MIPS_SYS(sys_setdomainname, 2)
1282048f6b4dSbellard 	MIPS_SYS(sys_newuname	, 1)
1283048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* sys_modify_ldt */
1284048f6b4dSbellard 	MIPS_SYS(sys_adjtimex	, 1)
1285048f6b4dSbellard 	MIPS_SYS(sys_mprotect	, 3)	/* 4125 */
1286048f6b4dSbellard 	MIPS_SYS(sys_sigprocmask	, 3)
1287048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was create_module */
1288048f6b4dSbellard 	MIPS_SYS(sys_init_module	, 5)
1289048f6b4dSbellard 	MIPS_SYS(sys_delete_module, 1)
1290048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4130	was get_kernel_syms */
1291048f6b4dSbellard 	MIPS_SYS(sys_quotactl	, 0)
1292048f6b4dSbellard 	MIPS_SYS(sys_getpgid	, 1)
1293048f6b4dSbellard 	MIPS_SYS(sys_fchdir	, 1)
1294048f6b4dSbellard 	MIPS_SYS(sys_bdflush	, 2)
1295048f6b4dSbellard 	MIPS_SYS(sys_sysfs	, 3)	/* 4135 */
1296048f6b4dSbellard 	MIPS_SYS(sys_personality	, 1)
1297048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* for afs_syscall */
1298048f6b4dSbellard 	MIPS_SYS(sys_setfsuid	, 1)
1299048f6b4dSbellard 	MIPS_SYS(sys_setfsgid	, 1)
1300048f6b4dSbellard 	MIPS_SYS(sys_llseek	, 5)	/* 4140 */
1301048f6b4dSbellard 	MIPS_SYS(sys_getdents	, 3)
1302048f6b4dSbellard 	MIPS_SYS(sys_select	, 5)
1303048f6b4dSbellard 	MIPS_SYS(sys_flock	, 2)
1304048f6b4dSbellard 	MIPS_SYS(sys_msync	, 3)
1305048f6b4dSbellard 	MIPS_SYS(sys_readv	, 3)	/* 4145 */
1306048f6b4dSbellard 	MIPS_SYS(sys_writev	, 3)
1307048f6b4dSbellard 	MIPS_SYS(sys_cacheflush	, 3)
1308048f6b4dSbellard 	MIPS_SYS(sys_cachectl	, 3)
1309048f6b4dSbellard 	MIPS_SYS(sys_sysmips	, 4)
1310048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4150 */
1311048f6b4dSbellard 	MIPS_SYS(sys_getsid	, 1)
1312048f6b4dSbellard 	MIPS_SYS(sys_fdatasync	, 0)
1313048f6b4dSbellard 	MIPS_SYS(sys_sysctl	, 1)
1314048f6b4dSbellard 	MIPS_SYS(sys_mlock	, 2)
1315048f6b4dSbellard 	MIPS_SYS(sys_munlock	, 2)	/* 4155 */
1316048f6b4dSbellard 	MIPS_SYS(sys_mlockall	, 1)
1317048f6b4dSbellard 	MIPS_SYS(sys_munlockall	, 0)
1318048f6b4dSbellard 	MIPS_SYS(sys_sched_setparam, 2)
1319048f6b4dSbellard 	MIPS_SYS(sys_sched_getparam, 2)
1320048f6b4dSbellard 	MIPS_SYS(sys_sched_setscheduler, 3)	/* 4160 */
1321048f6b4dSbellard 	MIPS_SYS(sys_sched_getscheduler, 1)
1322048f6b4dSbellard 	MIPS_SYS(sys_sched_yield	, 0)
1323048f6b4dSbellard 	MIPS_SYS(sys_sched_get_priority_max, 1)
1324048f6b4dSbellard 	MIPS_SYS(sys_sched_get_priority_min, 1)
1325048f6b4dSbellard 	MIPS_SYS(sys_sched_rr_get_interval, 2)	/* 4165 */
1326048f6b4dSbellard 	MIPS_SYS(sys_nanosleep,	2)
1327048f6b4dSbellard 	MIPS_SYS(sys_mremap	, 4)
1328048f6b4dSbellard 	MIPS_SYS(sys_accept	, 3)
1329048f6b4dSbellard 	MIPS_SYS(sys_bind	, 3)
1330048f6b4dSbellard 	MIPS_SYS(sys_connect	, 3)	/* 4170 */
1331048f6b4dSbellard 	MIPS_SYS(sys_getpeername	, 3)
1332048f6b4dSbellard 	MIPS_SYS(sys_getsockname	, 3)
1333048f6b4dSbellard 	MIPS_SYS(sys_getsockopt	, 5)
1334048f6b4dSbellard 	MIPS_SYS(sys_listen	, 2)
1335048f6b4dSbellard 	MIPS_SYS(sys_recv	, 4)	/* 4175 */
1336048f6b4dSbellard 	MIPS_SYS(sys_recvfrom	, 6)
1337048f6b4dSbellard 	MIPS_SYS(sys_recvmsg	, 3)
1338048f6b4dSbellard 	MIPS_SYS(sys_send	, 4)
1339048f6b4dSbellard 	MIPS_SYS(sys_sendmsg	, 3)
1340048f6b4dSbellard 	MIPS_SYS(sys_sendto	, 6)	/* 4180 */
1341048f6b4dSbellard 	MIPS_SYS(sys_setsockopt	, 5)
1342048f6b4dSbellard 	MIPS_SYS(sys_shutdown	, 2)
1343048f6b4dSbellard 	MIPS_SYS(sys_socket	, 3)
1344048f6b4dSbellard 	MIPS_SYS(sys_socketpair	, 4)
1345048f6b4dSbellard 	MIPS_SYS(sys_setresuid	, 3)	/* 4185 */
1346048f6b4dSbellard 	MIPS_SYS(sys_getresuid	, 3)
1347048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_query_module */
1348048f6b4dSbellard 	MIPS_SYS(sys_poll	, 3)
1349048f6b4dSbellard 	MIPS_SYS(sys_nfsservctl	, 3)
1350048f6b4dSbellard 	MIPS_SYS(sys_setresgid	, 3)	/* 4190 */
1351048f6b4dSbellard 	MIPS_SYS(sys_getresgid	, 3)
1352048f6b4dSbellard 	MIPS_SYS(sys_prctl	, 5)
1353048f6b4dSbellard 	MIPS_SYS(sys_rt_sigreturn, 0)
1354048f6b4dSbellard 	MIPS_SYS(sys_rt_sigaction, 4)
1355048f6b4dSbellard 	MIPS_SYS(sys_rt_sigprocmask, 4)	/* 4195 */
1356048f6b4dSbellard 	MIPS_SYS(sys_rt_sigpending, 2)
1357048f6b4dSbellard 	MIPS_SYS(sys_rt_sigtimedwait, 4)
1358048f6b4dSbellard 	MIPS_SYS(sys_rt_sigqueueinfo, 3)
1359048f6b4dSbellard 	MIPS_SYS(sys_rt_sigsuspend, 0)
1360048f6b4dSbellard 	MIPS_SYS(sys_pread64	, 6)	/* 4200 */
1361048f6b4dSbellard 	MIPS_SYS(sys_pwrite64	, 6)
1362048f6b4dSbellard 	MIPS_SYS(sys_chown	, 3)
1363048f6b4dSbellard 	MIPS_SYS(sys_getcwd	, 2)
1364048f6b4dSbellard 	MIPS_SYS(sys_capget	, 2)
1365048f6b4dSbellard 	MIPS_SYS(sys_capset	, 2)	/* 4205 */
1366048f6b4dSbellard 	MIPS_SYS(sys_sigaltstack	, 0)
1367048f6b4dSbellard 	MIPS_SYS(sys_sendfile	, 4)
1368048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1369048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1370048f6b4dSbellard 	MIPS_SYS(sys_mmap2	, 6)	/* 4210 */
1371048f6b4dSbellard 	MIPS_SYS(sys_truncate64	, 4)
1372048f6b4dSbellard 	MIPS_SYS(sys_ftruncate64	, 4)
1373048f6b4dSbellard 	MIPS_SYS(sys_stat64	, 2)
1374048f6b4dSbellard 	MIPS_SYS(sys_lstat64	, 2)
1375048f6b4dSbellard 	MIPS_SYS(sys_fstat64	, 2)	/* 4215 */
1376048f6b4dSbellard 	MIPS_SYS(sys_pivot_root	, 2)
1377048f6b4dSbellard 	MIPS_SYS(sys_mincore	, 3)
1378048f6b4dSbellard 	MIPS_SYS(sys_madvise	, 3)
1379048f6b4dSbellard 	MIPS_SYS(sys_getdents64	, 3)
1380048f6b4dSbellard 	MIPS_SYS(sys_fcntl64	, 3)	/* 4220 */
1381048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)
1382048f6b4dSbellard 	MIPS_SYS(sys_gettid	, 0)
1383048f6b4dSbellard 	MIPS_SYS(sys_readahead	, 5)
1384048f6b4dSbellard 	MIPS_SYS(sys_setxattr	, 5)
1385048f6b4dSbellard 	MIPS_SYS(sys_lsetxattr	, 5)	/* 4225 */
1386048f6b4dSbellard 	MIPS_SYS(sys_fsetxattr	, 5)
1387048f6b4dSbellard 	MIPS_SYS(sys_getxattr	, 4)
1388048f6b4dSbellard 	MIPS_SYS(sys_lgetxattr	, 4)
1389048f6b4dSbellard 	MIPS_SYS(sys_fgetxattr	, 4)
1390048f6b4dSbellard 	MIPS_SYS(sys_listxattr	, 3)	/* 4230 */
1391048f6b4dSbellard 	MIPS_SYS(sys_llistxattr	, 3)
1392048f6b4dSbellard 	MIPS_SYS(sys_flistxattr	, 3)
1393048f6b4dSbellard 	MIPS_SYS(sys_removexattr	, 2)
1394048f6b4dSbellard 	MIPS_SYS(sys_lremovexattr, 2)
1395048f6b4dSbellard 	MIPS_SYS(sys_fremovexattr, 2)	/* 4235 */
1396048f6b4dSbellard 	MIPS_SYS(sys_tkill	, 2)
1397048f6b4dSbellard 	MIPS_SYS(sys_sendfile64	, 5)
1398048f6b4dSbellard 	MIPS_SYS(sys_futex	, 2)
1399048f6b4dSbellard 	MIPS_SYS(sys_sched_setaffinity, 3)
1400048f6b4dSbellard 	MIPS_SYS(sys_sched_getaffinity, 3)	/* 4240 */
1401048f6b4dSbellard 	MIPS_SYS(sys_io_setup	, 2)
1402048f6b4dSbellard 	MIPS_SYS(sys_io_destroy	, 1)
1403048f6b4dSbellard 	MIPS_SYS(sys_io_getevents, 5)
1404048f6b4dSbellard 	MIPS_SYS(sys_io_submit	, 3)
1405048f6b4dSbellard 	MIPS_SYS(sys_io_cancel	, 3)	/* 4245 */
1406048f6b4dSbellard 	MIPS_SYS(sys_exit_group	, 1)
1407048f6b4dSbellard 	MIPS_SYS(sys_lookup_dcookie, 3)
1408048f6b4dSbellard 	MIPS_SYS(sys_epoll_create, 1)
1409048f6b4dSbellard 	MIPS_SYS(sys_epoll_ctl	, 4)
1410048f6b4dSbellard 	MIPS_SYS(sys_epoll_wait	, 3)	/* 4250 */
1411048f6b4dSbellard 	MIPS_SYS(sys_remap_file_pages, 5)
1412048f6b4dSbellard 	MIPS_SYS(sys_set_tid_address, 1)
1413048f6b4dSbellard 	MIPS_SYS(sys_restart_syscall, 0)
1414048f6b4dSbellard 	MIPS_SYS(sys_fadvise64_64, 7)
1415048f6b4dSbellard 	MIPS_SYS(sys_statfs64	, 3)	/* 4255 */
1416048f6b4dSbellard 	MIPS_SYS(sys_fstatfs64	, 2)
1417048f6b4dSbellard 	MIPS_SYS(sys_timer_create, 3)
1418048f6b4dSbellard 	MIPS_SYS(sys_timer_settime, 4)
1419048f6b4dSbellard 	MIPS_SYS(sys_timer_gettime, 2)
1420048f6b4dSbellard 	MIPS_SYS(sys_timer_getoverrun, 1)	/* 4260 */
1421048f6b4dSbellard 	MIPS_SYS(sys_timer_delete, 1)
1422048f6b4dSbellard 	MIPS_SYS(sys_clock_settime, 2)
1423048f6b4dSbellard 	MIPS_SYS(sys_clock_gettime, 2)
1424048f6b4dSbellard 	MIPS_SYS(sys_clock_getres, 2)
1425048f6b4dSbellard 	MIPS_SYS(sys_clock_nanosleep, 4)	/* 4265 */
1426048f6b4dSbellard 	MIPS_SYS(sys_tgkill	, 3)
1427048f6b4dSbellard 	MIPS_SYS(sys_utimes	, 2)
1428048f6b4dSbellard 	MIPS_SYS(sys_mbind	, 4)
1429048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* sys_get_mempolicy */
1430048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4270 sys_set_mempolicy */
1431048f6b4dSbellard 	MIPS_SYS(sys_mq_open	, 4)
1432048f6b4dSbellard 	MIPS_SYS(sys_mq_unlink	, 1)
1433048f6b4dSbellard 	MIPS_SYS(sys_mq_timedsend, 5)
1434048f6b4dSbellard 	MIPS_SYS(sys_mq_timedreceive, 5)
1435048f6b4dSbellard 	MIPS_SYS(sys_mq_notify	, 2)	/* 4275 */
1436048f6b4dSbellard 	MIPS_SYS(sys_mq_getsetattr, 3)
1437048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* sys_vserver */
1438048f6b4dSbellard 	MIPS_SYS(sys_waitid	, 4)
1439048f6b4dSbellard 	MIPS_SYS(sys_ni_syscall	, 0)	/* available, was setaltroot */
1440048f6b4dSbellard 	MIPS_SYS(sys_add_key	, 5)
1441048f6b4dSbellard 	MIPS_SYS(sys_request_key, 4)
1442048f6b4dSbellard 	MIPS_SYS(sys_keyctl	, 5)
14436f5b89a0Sths 	MIPS_SYS(sys_set_thread_area, 1)
1444388bb21aSths 	MIPS_SYS(sys_inotify_init, 0)
1445388bb21aSths 	MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
1446388bb21aSths 	MIPS_SYS(sys_inotify_rm_watch, 2)
1447388bb21aSths 	MIPS_SYS(sys_migrate_pages, 4)
1448388bb21aSths 	MIPS_SYS(sys_openat, 4)
1449388bb21aSths 	MIPS_SYS(sys_mkdirat, 3)
1450388bb21aSths 	MIPS_SYS(sys_mknodat, 4)	/* 4290 */
1451388bb21aSths 	MIPS_SYS(sys_fchownat, 5)
1452388bb21aSths 	MIPS_SYS(sys_futimesat, 3)
1453388bb21aSths 	MIPS_SYS(sys_fstatat64, 4)
1454388bb21aSths 	MIPS_SYS(sys_unlinkat, 3)
1455388bb21aSths 	MIPS_SYS(sys_renameat, 4)	/* 4295 */
1456388bb21aSths 	MIPS_SYS(sys_linkat, 5)
1457388bb21aSths 	MIPS_SYS(sys_symlinkat, 3)
1458388bb21aSths 	MIPS_SYS(sys_readlinkat, 4)
1459388bb21aSths 	MIPS_SYS(sys_fchmodat, 3)
1460388bb21aSths 	MIPS_SYS(sys_faccessat, 3)	/* 4300 */
1461388bb21aSths 	MIPS_SYS(sys_pselect6, 6)
1462388bb21aSths 	MIPS_SYS(sys_ppoll, 5)
1463388bb21aSths 	MIPS_SYS(sys_unshare, 1)
1464388bb21aSths 	MIPS_SYS(sys_splice, 4)
1465388bb21aSths 	MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
1466388bb21aSths 	MIPS_SYS(sys_tee, 4)
1467388bb21aSths 	MIPS_SYS(sys_vmsplice, 4)
1468388bb21aSths 	MIPS_SYS(sys_move_pages, 6)
1469388bb21aSths 	MIPS_SYS(sys_set_robust_list, 2)
1470388bb21aSths 	MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
1471388bb21aSths 	MIPS_SYS(sys_kexec_load, 4)
1472388bb21aSths 	MIPS_SYS(sys_getcpu, 3)
1473388bb21aSths 	MIPS_SYS(sys_epoll_pwait, 6)
1474388bb21aSths 	MIPS_SYS(sys_ioprio_set, 3)
1475388bb21aSths 	MIPS_SYS(sys_ioprio_get, 2)
1476048f6b4dSbellard };
1477048f6b4dSbellard 
1478048f6b4dSbellard #undef MIPS_SYS
1479048f6b4dSbellard 
1480048f6b4dSbellard void cpu_loop(CPUMIPSState *env)
1481048f6b4dSbellard {
1482048f6b4dSbellard     target_siginfo_t info;
1483388bb21aSths     int trapnr, ret;
1484048f6b4dSbellard     unsigned int syscall_num;
1485048f6b4dSbellard 
1486048f6b4dSbellard     for(;;) {
1487048f6b4dSbellard         trapnr = cpu_mips_exec(env);
1488048f6b4dSbellard         switch(trapnr) {
1489048f6b4dSbellard         case EXCP_SYSCALL:
1490ead9360eSths             syscall_num = env->gpr[2][env->current_tc] - 4000;
1491ead9360eSths             env->PC[env->current_tc] += 4;
1492048f6b4dSbellard             if (syscall_num >= sizeof(mips_syscall_args)) {
1493048f6b4dSbellard                 ret = -ENOSYS;
1494048f6b4dSbellard             } else {
1495388bb21aSths                 int nb_args;
1496992f48a0Sblueswir1                 abi_ulong sp_reg;
1497992f48a0Sblueswir1                 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
1498388bb21aSths 
1499048f6b4dSbellard                 nb_args = mips_syscall_args[syscall_num];
1500ead9360eSths                 sp_reg = env->gpr[29][env->current_tc];
1501388bb21aSths                 switch (nb_args) {
1502048f6b4dSbellard                 /* these arguments are taken from the stack */
1503388bb21aSths                 case 8: arg8 = tgetl(sp_reg + 28);
1504388bb21aSths                 case 7: arg7 = tgetl(sp_reg + 24);
1505388bb21aSths                 case 6: arg6 = tgetl(sp_reg + 20);
1506388bb21aSths                 case 5: arg5 = tgetl(sp_reg + 16);
1507388bb21aSths                 default:
1508388bb21aSths                     break;
1509048f6b4dSbellard                 }
1510ead9360eSths                 ret = do_syscall(env, env->gpr[2][env->current_tc],
1511ead9360eSths                                  env->gpr[4][env->current_tc],
1512ead9360eSths                                  env->gpr[5][env->current_tc],
1513ead9360eSths                                  env->gpr[6][env->current_tc],
1514ead9360eSths                                  env->gpr[7][env->current_tc],
1515388bb21aSths                                  arg5, arg6/*, arg7, arg8*/);
1516048f6b4dSbellard             }
1517048f6b4dSbellard             if ((unsigned int)ret >= (unsigned int)(-1133)) {
1518ead9360eSths                 env->gpr[7][env->current_tc] = 1; /* error flag */
1519048f6b4dSbellard                 ret = -ret;
1520048f6b4dSbellard             } else {
1521ead9360eSths                 env->gpr[7][env->current_tc] = 0; /* error flag */
1522388bb21aSths             }
1523ead9360eSths             env->gpr[2][env->current_tc] = ret;
1524048f6b4dSbellard             break;
1525ca7c2b1bSths         case EXCP_TLBL:
1526ca7c2b1bSths         case EXCP_TLBS:
15276900e84bSbellard         case EXCP_CpU:
1528048f6b4dSbellard         case EXCP_RI:
1529048f6b4dSbellard             info.si_signo = TARGET_SIGILL;
1530048f6b4dSbellard             info.si_errno = 0;
1531048f6b4dSbellard             info.si_code = 0;
1532048f6b4dSbellard             queue_signal(info.si_signo, &info);
1533048f6b4dSbellard             break;
1534106ec879Sbellard         case EXCP_INTERRUPT:
1535106ec879Sbellard             /* just indicate that signals should be handled asap */
1536106ec879Sbellard             break;
1537d08b2a28Spbrook         case EXCP_DEBUG:
1538d08b2a28Spbrook             {
1539d08b2a28Spbrook                 int sig;
1540d08b2a28Spbrook 
1541d08b2a28Spbrook                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
1542d08b2a28Spbrook                 if (sig)
1543d08b2a28Spbrook                   {
1544d08b2a28Spbrook                     info.si_signo = sig;
1545d08b2a28Spbrook                     info.si_errno = 0;
1546d08b2a28Spbrook                     info.si_code = TARGET_TRAP_BRKPT;
1547d08b2a28Spbrook                     queue_signal(info.si_signo, &info);
1548d08b2a28Spbrook                   }
1549d08b2a28Spbrook             }
1550d08b2a28Spbrook             break;
1551048f6b4dSbellard         default:
1552048f6b4dSbellard             //        error:
1553048f6b4dSbellard             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1554048f6b4dSbellard                     trapnr);
1555048f6b4dSbellard             cpu_dump_state(env, stderr, fprintf, 0);
1556048f6b4dSbellard             abort();
1557048f6b4dSbellard         }
1558048f6b4dSbellard         process_pending_signals(env);
1559048f6b4dSbellard     }
1560048f6b4dSbellard }
1561048f6b4dSbellard #endif
1562048f6b4dSbellard 
1563fdf9b3e8Sbellard #ifdef TARGET_SH4
1564fdf9b3e8Sbellard void cpu_loop (CPUState *env)
1565fdf9b3e8Sbellard {
1566fdf9b3e8Sbellard     int trapnr, ret;
1567355fb23dSpbrook     target_siginfo_t info;
1568fdf9b3e8Sbellard 
1569fdf9b3e8Sbellard     while (1) {
1570fdf9b3e8Sbellard         trapnr = cpu_sh4_exec (env);
1571fdf9b3e8Sbellard 
1572fdf9b3e8Sbellard         switch (trapnr) {
1573fdf9b3e8Sbellard         case 0x160:
1574fdf9b3e8Sbellard             ret = do_syscall(env,
15759c2a9ea1Spbrook                              env->gregs[3],
15769c2a9ea1Spbrook                              env->gregs[4],
15779c2a9ea1Spbrook                              env->gregs[5],
15789c2a9ea1Spbrook                              env->gregs[6],
15799c2a9ea1Spbrook                              env->gregs[7],
15809c2a9ea1Spbrook                              env->gregs[0],
1581fdf9b3e8Sbellard                              0);
15829c2a9ea1Spbrook             env->gregs[0] = ret;
1583fdf9b3e8Sbellard             env->pc += 2;
1584fdf9b3e8Sbellard             break;
1585355fb23dSpbrook         case EXCP_DEBUG:
1586355fb23dSpbrook             {
1587355fb23dSpbrook                 int sig;
1588355fb23dSpbrook 
1589355fb23dSpbrook                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
1590355fb23dSpbrook                 if (sig)
1591355fb23dSpbrook                   {
1592355fb23dSpbrook                     info.si_signo = sig;
1593355fb23dSpbrook                     info.si_errno = 0;
1594355fb23dSpbrook                     info.si_code = TARGET_TRAP_BRKPT;
1595355fb23dSpbrook                     queue_signal(info.si_signo, &info);
1596355fb23dSpbrook                   }
1597355fb23dSpbrook             }
1598355fb23dSpbrook             break;
1599fdf9b3e8Sbellard         default:
1600fdf9b3e8Sbellard             printf ("Unhandled trap: 0x%x\n", trapnr);
1601fdf9b3e8Sbellard             cpu_dump_state(env, stderr, fprintf, 0);
1602fdf9b3e8Sbellard             exit (1);
1603fdf9b3e8Sbellard         }
1604fdf9b3e8Sbellard         process_pending_signals (env);
1605fdf9b3e8Sbellard     }
1606fdf9b3e8Sbellard }
1607fdf9b3e8Sbellard #endif
1608fdf9b3e8Sbellard 
160948733d19Sths #ifdef TARGET_CRIS
161048733d19Sths void cpu_loop (CPUState *env)
161148733d19Sths {
161248733d19Sths     int trapnr, ret;
161348733d19Sths     target_siginfo_t info;
161448733d19Sths 
161548733d19Sths     while (1) {
161648733d19Sths         trapnr = cpu_cris_exec (env);
161748733d19Sths         switch (trapnr) {
161848733d19Sths         case 0xaa:
161948733d19Sths             {
162048733d19Sths                 info.si_signo = SIGSEGV;
162148733d19Sths                 info.si_errno = 0;
162248733d19Sths                 /* XXX: check env->error_code */
162348733d19Sths                 info.si_code = TARGET_SEGV_MAPERR;
162448733d19Sths                 info._sifields._sigfault._addr = env->debug1;
162548733d19Sths                 queue_signal(info.si_signo, &info);
162648733d19Sths             }
162748733d19Sths             break;
162848733d19Sths         case EXCP_BREAK:
162948733d19Sths             ret = do_syscall(env,
163048733d19Sths                              env->regs[9],
163148733d19Sths                              env->regs[10],
163248733d19Sths                              env->regs[11],
163348733d19Sths                              env->regs[12],
163448733d19Sths                              env->regs[13],
163548733d19Sths                              env->pregs[7],
163648733d19Sths                              env->pregs[11]);
163748733d19Sths             env->regs[10] = ret;
163848733d19Sths             env->pc += 2;
163948733d19Sths             break;
164048733d19Sths         case EXCP_DEBUG:
164148733d19Sths             {
164248733d19Sths                 int sig;
164348733d19Sths 
164448733d19Sths                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
164548733d19Sths                 if (sig)
164648733d19Sths                   {
164748733d19Sths                     info.si_signo = sig;
164848733d19Sths                     info.si_errno = 0;
164948733d19Sths                     info.si_code = TARGET_TRAP_BRKPT;
165048733d19Sths                     queue_signal(info.si_signo, &info);
165148733d19Sths                   }
165248733d19Sths             }
165348733d19Sths             break;
165448733d19Sths         default:
165548733d19Sths             printf ("Unhandled trap: 0x%x\n", trapnr);
165648733d19Sths             cpu_dump_state(env, stderr, fprintf, 0);
165748733d19Sths             exit (1);
165848733d19Sths         }
165948733d19Sths         process_pending_signals (env);
166048733d19Sths     }
166148733d19Sths }
166248733d19Sths #endif
166348733d19Sths 
1664e6e5906bSpbrook #ifdef TARGET_M68K
1665e6e5906bSpbrook 
1666e6e5906bSpbrook void cpu_loop(CPUM68KState *env)
1667e6e5906bSpbrook {
1668e6e5906bSpbrook     int trapnr;
1669e6e5906bSpbrook     unsigned int n;
1670e6e5906bSpbrook     target_siginfo_t info;
1671e6e5906bSpbrook     TaskState *ts = env->opaque;
1672e6e5906bSpbrook 
1673e6e5906bSpbrook     for(;;) {
1674e6e5906bSpbrook         trapnr = cpu_m68k_exec(env);
1675e6e5906bSpbrook         switch(trapnr) {
1676e6e5906bSpbrook         case EXCP_ILLEGAL:
1677e6e5906bSpbrook             {
1678e6e5906bSpbrook                 if (ts->sim_syscalls) {
1679e6e5906bSpbrook                     uint16_t nr;
1680e6e5906bSpbrook                     nr = lduw(env->pc + 2);
1681e6e5906bSpbrook                     env->pc += 4;
1682e6e5906bSpbrook                     do_m68k_simcall(env, nr);
1683e6e5906bSpbrook                 } else {
1684e6e5906bSpbrook                     goto do_sigill;
1685e6e5906bSpbrook                 }
1686e6e5906bSpbrook             }
1687e6e5906bSpbrook             break;
1688a87295e8Spbrook         case EXCP_HALT_INSN:
1689e6e5906bSpbrook             /* Semihosing syscall.  */
1690a87295e8Spbrook             env->pc += 4;
1691e6e5906bSpbrook             do_m68k_semihosting(env, env->dregs[0]);
1692e6e5906bSpbrook             break;
1693e6e5906bSpbrook         case EXCP_LINEA:
1694e6e5906bSpbrook         case EXCP_LINEF:
1695e6e5906bSpbrook         case EXCP_UNSUPPORTED:
1696e6e5906bSpbrook         do_sigill:
1697e6e5906bSpbrook             info.si_signo = SIGILL;
1698e6e5906bSpbrook             info.si_errno = 0;
1699e6e5906bSpbrook             info.si_code = TARGET_ILL_ILLOPN;
1700e6e5906bSpbrook             info._sifields._sigfault._addr = env->pc;
1701e6e5906bSpbrook             queue_signal(info.si_signo, &info);
1702e6e5906bSpbrook             break;
1703e6e5906bSpbrook         case EXCP_TRAP0:
1704e6e5906bSpbrook             {
1705e6e5906bSpbrook                 ts->sim_syscalls = 0;
1706e6e5906bSpbrook                 n = env->dregs[0];
1707e6e5906bSpbrook                 env->pc += 2;
1708e6e5906bSpbrook                 env->dregs[0] = do_syscall(env,
1709e6e5906bSpbrook                                           n,
1710e6e5906bSpbrook                                           env->dregs[1],
1711e6e5906bSpbrook                                           env->dregs[2],
1712e6e5906bSpbrook                                           env->dregs[3],
1713e6e5906bSpbrook                                           env->dregs[4],
1714e6e5906bSpbrook                                           env->dregs[5],
1715e6e5906bSpbrook                                           env->dregs[6]);
1716e6e5906bSpbrook             }
1717e6e5906bSpbrook             break;
1718e6e5906bSpbrook         case EXCP_INTERRUPT:
1719e6e5906bSpbrook             /* just indicate that signals should be handled asap */
1720e6e5906bSpbrook             break;
1721e6e5906bSpbrook         case EXCP_ACCESS:
1722e6e5906bSpbrook             {
1723e6e5906bSpbrook                 info.si_signo = SIGSEGV;
1724e6e5906bSpbrook                 info.si_errno = 0;
1725e6e5906bSpbrook                 /* XXX: check env->error_code */
1726e6e5906bSpbrook                 info.si_code = TARGET_SEGV_MAPERR;
1727e6e5906bSpbrook                 info._sifields._sigfault._addr = env->mmu.ar;
1728e6e5906bSpbrook                 queue_signal(info.si_signo, &info);
1729e6e5906bSpbrook             }
1730e6e5906bSpbrook             break;
1731e6e5906bSpbrook         case EXCP_DEBUG:
1732e6e5906bSpbrook             {
1733e6e5906bSpbrook                 int sig;
1734e6e5906bSpbrook 
1735e6e5906bSpbrook                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
1736e6e5906bSpbrook                 if (sig)
1737e6e5906bSpbrook                   {
1738e6e5906bSpbrook                     info.si_signo = sig;
1739e6e5906bSpbrook                     info.si_errno = 0;
1740e6e5906bSpbrook                     info.si_code = TARGET_TRAP_BRKPT;
1741e6e5906bSpbrook                     queue_signal(info.si_signo, &info);
1742e6e5906bSpbrook                   }
1743e6e5906bSpbrook             }
1744e6e5906bSpbrook             break;
1745e6e5906bSpbrook         default:
1746e6e5906bSpbrook             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1747e6e5906bSpbrook                     trapnr);
1748e6e5906bSpbrook             cpu_dump_state(env, stderr, fprintf, 0);
1749e6e5906bSpbrook             abort();
1750e6e5906bSpbrook         }
1751e6e5906bSpbrook         process_pending_signals(env);
1752e6e5906bSpbrook     }
1753e6e5906bSpbrook }
1754e6e5906bSpbrook #endif /* TARGET_M68K */
1755e6e5906bSpbrook 
17567a3148a9Sj_mayer #ifdef TARGET_ALPHA
17577a3148a9Sj_mayer void cpu_loop (CPUState *env)
17587a3148a9Sj_mayer {
1759e96efcfcSj_mayer     int trapnr;
17607a3148a9Sj_mayer     target_siginfo_t info;
17617a3148a9Sj_mayer 
17627a3148a9Sj_mayer     while (1) {
17637a3148a9Sj_mayer         trapnr = cpu_alpha_exec (env);
17647a3148a9Sj_mayer 
17657a3148a9Sj_mayer         switch (trapnr) {
17667a3148a9Sj_mayer         case EXCP_RESET:
17677a3148a9Sj_mayer             fprintf(stderr, "Reset requested. Exit\n");
17687a3148a9Sj_mayer             exit(1);
17697a3148a9Sj_mayer             break;
17707a3148a9Sj_mayer         case EXCP_MCHK:
17717a3148a9Sj_mayer             fprintf(stderr, "Machine check exception. Exit\n");
17727a3148a9Sj_mayer             exit(1);
17737a3148a9Sj_mayer             break;
17747a3148a9Sj_mayer         case EXCP_ARITH:
17757a3148a9Sj_mayer             fprintf(stderr, "Arithmetic trap.\n");
17767a3148a9Sj_mayer             exit(1);
17777a3148a9Sj_mayer             break;
17787a3148a9Sj_mayer         case EXCP_HW_INTERRUPT:
17797a3148a9Sj_mayer             fprintf(stderr, "External interrupt. Exit\n");
17807a3148a9Sj_mayer             exit(1);
17817a3148a9Sj_mayer             break;
17827a3148a9Sj_mayer         case EXCP_DFAULT:
17837a3148a9Sj_mayer             fprintf(stderr, "MMU data fault\n");
17847a3148a9Sj_mayer             exit(1);
17857a3148a9Sj_mayer             break;
17867a3148a9Sj_mayer         case EXCP_DTB_MISS_PAL:
17877a3148a9Sj_mayer             fprintf(stderr, "MMU data TLB miss in PALcode\n");
17887a3148a9Sj_mayer             exit(1);
17897a3148a9Sj_mayer             break;
17907a3148a9Sj_mayer         case EXCP_ITB_MISS:
17917a3148a9Sj_mayer             fprintf(stderr, "MMU instruction TLB miss\n");
17927a3148a9Sj_mayer             exit(1);
17937a3148a9Sj_mayer             break;
17947a3148a9Sj_mayer         case EXCP_ITB_ACV:
17957a3148a9Sj_mayer             fprintf(stderr, "MMU instruction access violation\n");
17967a3148a9Sj_mayer             exit(1);
17977a3148a9Sj_mayer             break;
17987a3148a9Sj_mayer         case EXCP_DTB_MISS_NATIVE:
17997a3148a9Sj_mayer             fprintf(stderr, "MMU data TLB miss\n");
18007a3148a9Sj_mayer             exit(1);
18017a3148a9Sj_mayer             break;
18027a3148a9Sj_mayer         case EXCP_UNALIGN:
18037a3148a9Sj_mayer             fprintf(stderr, "Unaligned access\n");
18047a3148a9Sj_mayer             exit(1);
18057a3148a9Sj_mayer             break;
18067a3148a9Sj_mayer         case EXCP_OPCDEC:
18077a3148a9Sj_mayer             fprintf(stderr, "Invalid instruction\n");
18087a3148a9Sj_mayer             exit(1);
18097a3148a9Sj_mayer             break;
18107a3148a9Sj_mayer         case EXCP_FEN:
18117a3148a9Sj_mayer             fprintf(stderr, "Floating-point not allowed\n");
18127a3148a9Sj_mayer             exit(1);
18137a3148a9Sj_mayer             break;
18147a3148a9Sj_mayer         case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
18157a3148a9Sj_mayer             fprintf(stderr, "Call to PALcode\n");
18167a3148a9Sj_mayer             call_pal(env, (trapnr >> 6) | 0x80);
18177a3148a9Sj_mayer             break;
18187a3148a9Sj_mayer         case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
18197f75ffd3Sblueswir1             fprintf(stderr, "Privileged call to PALcode\n");
18207a3148a9Sj_mayer             exit(1);
18217a3148a9Sj_mayer             break;
18227a3148a9Sj_mayer         case EXCP_DEBUG:
18237a3148a9Sj_mayer             {
18247a3148a9Sj_mayer                 int sig;
18257a3148a9Sj_mayer 
18267a3148a9Sj_mayer                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
18277a3148a9Sj_mayer                 if (sig)
18287a3148a9Sj_mayer                   {
18297a3148a9Sj_mayer                     info.si_signo = sig;
18307a3148a9Sj_mayer                     info.si_errno = 0;
18317a3148a9Sj_mayer                     info.si_code = TARGET_TRAP_BRKPT;
18327a3148a9Sj_mayer                     queue_signal(info.si_signo, &info);
18337a3148a9Sj_mayer                   }
18347a3148a9Sj_mayer             }
18357a3148a9Sj_mayer             break;
18367a3148a9Sj_mayer         default:
18377a3148a9Sj_mayer             printf ("Unhandled trap: 0x%x\n", trapnr);
18387a3148a9Sj_mayer             cpu_dump_state(env, stderr, fprintf, 0);
18397a3148a9Sj_mayer             exit (1);
18407a3148a9Sj_mayer         }
18417a3148a9Sj_mayer         process_pending_signals (env);
18427a3148a9Sj_mayer     }
18437a3148a9Sj_mayer }
18447a3148a9Sj_mayer #endif /* TARGET_ALPHA */
18457a3148a9Sj_mayer 
184631e31b8aSbellard void usage(void)
184731e31b8aSbellard {
184884f2e8efSbellard     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
1849b1f9be31Sj_mayer            "usage: qemu-" TARGET_ARCH " [-h] [-g] [-d opts] [-L path] [-s size] [-cpu model] program [arguments...]\n"
1850b346ff46Sbellard            "Linux CPU emulator (compiled for %s emulation)\n"
1851d691f669Sbellard            "\n"
1852d691f669Sbellard            "-h                print this help\n"
185374c33bedSbellard            "-g port           wait gdb connection to port\n"
1854b346ff46Sbellard            "-L path           set the elf interpreter prefix (default=%s)\n"
1855b346ff46Sbellard            "-s size           set the stack size in bytes (default=%ld)\n"
1856b1f9be31Sj_mayer            "-cpu model        select CPU (-cpu ? for list)\n"
1857b12b6a18Sths            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
185854936004Sbellard            "\n"
185954936004Sbellard            "debug options:\n"
18606f1f31c0Sbellard            "-d options   activate log (logfile=%s)\n"
1861b6741956Sbellard            "-p pagesize  set the host page size to 'pagesize'\n"
1862b6741956Sbellard            "-strace      log system calls\n",
1863b346ff46Sbellard            TARGET_ARCH,
1864d691f669Sbellard            interp_prefix,
186554936004Sbellard            x86_stack_size,
186654936004Sbellard            DEBUG_LOGFILE);
186774cd30b8Sbellard     _exit(1);
186831e31b8aSbellard }
186931e31b8aSbellard 
18709de5e440Sbellard /* XXX: currently only used for async signals (see signal.c) */
1871b346ff46Sbellard CPUState *global_env;
187259faf6d6Sbellard 
1873851e67a1Sbellard /* used to free thread contexts */
1874851e67a1Sbellard TaskState *first_task_state;
18759de5e440Sbellard 
187631e31b8aSbellard int main(int argc, char **argv)
187731e31b8aSbellard {
187831e31b8aSbellard     const char *filename;
1879b1f9be31Sj_mayer     const char *cpu_model;
188001ffc75bSbellard     struct target_pt_regs regs1, *regs = &regs1;
188131e31b8aSbellard     struct image_info info1, *info = &info1;
1882851e67a1Sbellard     TaskState ts1, *ts = &ts1;
1883b346ff46Sbellard     CPUState *env;
1884586314f2Sbellard     int optind;
1885d691f669Sbellard     const char *r;
188674c33bedSbellard     int gdbstub_port = 0;
1887b12b6a18Sths     int drop_ld_preload = 0, environ_count = 0;
1888b12b6a18Sths     char **target_environ, **wrk, **dst;
188931e31b8aSbellard 
189031e31b8aSbellard     if (argc <= 1)
189131e31b8aSbellard         usage();
1892f801f97eSbellard 
1893cc38b844Sbellard     /* init debug */
1894cc38b844Sbellard     cpu_set_log_filename(DEBUG_LOGFILE);
1895cc38b844Sbellard 
1896b1f9be31Sj_mayer     cpu_model = NULL;
1897586314f2Sbellard     optind = 1;
1898d691f669Sbellard     for(;;) {
1899d691f669Sbellard         if (optind >= argc)
1900d691f669Sbellard             break;
1901d691f669Sbellard         r = argv[optind];
1902d691f669Sbellard         if (r[0] != '-')
1903d691f669Sbellard             break;
1904586314f2Sbellard         optind++;
1905d691f669Sbellard         r++;
1906d691f669Sbellard         if (!strcmp(r, "-")) {
1907d691f669Sbellard             break;
1908d691f669Sbellard         } else if (!strcmp(r, "d")) {
1909e19e89a5Sbellard             int mask;
1910e19e89a5Sbellard             CPULogItem *item;
1911e19e89a5Sbellard 
19126f1f31c0Sbellard 	    if (optind >= argc)
19136f1f31c0Sbellard 		break;
19146f1f31c0Sbellard 
19156f1f31c0Sbellard 	    r = argv[optind++];
19166f1f31c0Sbellard             mask = cpu_str_to_log_mask(r);
1917e19e89a5Sbellard             if (!mask) {
1918e19e89a5Sbellard                 printf("Log items (comma separated):\n");
1919e19e89a5Sbellard                 for(item = cpu_log_items; item->mask != 0; item++) {
1920e19e89a5Sbellard                     printf("%-10s %s\n", item->name, item->help);
1921e19e89a5Sbellard                 }
1922e19e89a5Sbellard                 exit(1);
1923e19e89a5Sbellard             }
1924e19e89a5Sbellard             cpu_set_log(mask);
1925d691f669Sbellard         } else if (!strcmp(r, "s")) {
1926d691f669Sbellard             r = argv[optind++];
1927d691f669Sbellard             x86_stack_size = strtol(r, (char **)&r, 0);
1928d691f669Sbellard             if (x86_stack_size <= 0)
1929d691f669Sbellard                 usage();
1930d691f669Sbellard             if (*r == 'M')
1931d691f669Sbellard                 x86_stack_size *= 1024 * 1024;
1932d691f669Sbellard             else if (*r == 'k' || *r == 'K')
1933d691f669Sbellard                 x86_stack_size *= 1024;
1934d691f669Sbellard         } else if (!strcmp(r, "L")) {
1935d691f669Sbellard             interp_prefix = argv[optind++];
193654936004Sbellard         } else if (!strcmp(r, "p")) {
193783fb7adfSbellard             qemu_host_page_size = atoi(argv[optind++]);
193883fb7adfSbellard             if (qemu_host_page_size == 0 ||
193983fb7adfSbellard                 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
194054936004Sbellard                 fprintf(stderr, "page size must be a power of two\n");
194154936004Sbellard                 exit(1);
194254936004Sbellard             }
19431fddef4bSbellard         } else if (!strcmp(r, "g")) {
194474c33bedSbellard             gdbstub_port = atoi(argv[optind++]);
1945c5937220Spbrook 	} else if (!strcmp(r, "r")) {
1946c5937220Spbrook 	    qemu_uname_release = argv[optind++];
1947b1f9be31Sj_mayer         } else if (!strcmp(r, "cpu")) {
1948b1f9be31Sj_mayer             cpu_model = argv[optind++];
1949b1f9be31Sj_mayer             if (strcmp(cpu_model, "?") == 0) {
1950c732abe2Sj_mayer /* XXX: implement xxx_cpu_list for targets that still miss it */
1951c732abe2Sj_mayer #if defined(cpu_list)
1952c732abe2Sj_mayer                     cpu_list(stdout, &fprintf);
1953b1f9be31Sj_mayer #endif
1954cff4cbedSths                 _exit(1);
1955b1f9be31Sj_mayer             }
1956b12b6a18Sths         } else if (!strcmp(r, "drop-ld-preload")) {
1957b12b6a18Sths             drop_ld_preload = 1;
1958b6741956Sbellard         } else if (!strcmp(r, "strace")) {
1959b6741956Sbellard             do_strace = 1;
1960c6981055Sbellard         } else
1961c6981055Sbellard         {
1962d691f669Sbellard             usage();
1963586314f2Sbellard         }
1964d691f669Sbellard     }
1965d691f669Sbellard     if (optind >= argc)
1966d691f669Sbellard         usage();
1967586314f2Sbellard     filename = argv[optind];
196831e31b8aSbellard 
196931e31b8aSbellard     /* Zero out regs */
197001ffc75bSbellard     memset(regs, 0, sizeof(struct target_pt_regs));
197131e31b8aSbellard 
197231e31b8aSbellard     /* Zero out image_info */
197331e31b8aSbellard     memset(info, 0, sizeof(struct image_info));
197431e31b8aSbellard 
197574cd30b8Sbellard     /* Scan interp_prefix dir for replacement files. */
197674cd30b8Sbellard     init_paths(interp_prefix);
197774cd30b8Sbellard 
197846027c07Sbellard     if (cpu_model == NULL) {
1979aaed909aSbellard #if defined(TARGET_I386)
198046027c07Sbellard #ifdef TARGET_X86_64
198146027c07Sbellard         cpu_model = "qemu64";
198246027c07Sbellard #else
198346027c07Sbellard         cpu_model = "qemu32";
198446027c07Sbellard #endif
1985aaed909aSbellard #elif defined(TARGET_ARM)
1986aaed909aSbellard         cpu_model = "arm926";
1987aaed909aSbellard #elif defined(TARGET_M68K)
1988aaed909aSbellard         cpu_model = "any";
1989aaed909aSbellard #elif defined(TARGET_SPARC)
1990aaed909aSbellard #ifdef TARGET_SPARC64
1991aaed909aSbellard         cpu_model = "TI UltraSparc II";
1992aaed909aSbellard #else
1993aaed909aSbellard         cpu_model = "Fujitsu MB86904";
199446027c07Sbellard #endif
1995aaed909aSbellard #elif defined(TARGET_MIPS)
1996aaed909aSbellard #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
1997aaed909aSbellard         cpu_model = "20Kc";
1998aaed909aSbellard #else
1999aaed909aSbellard         cpu_model = "24Kf";
2000aaed909aSbellard #endif
2001aaed909aSbellard #elif defined(TARGET_PPC)
2002aaed909aSbellard         cpu_model = "750";
2003aaed909aSbellard #else
2004aaed909aSbellard         cpu_model = "any";
2005aaed909aSbellard #endif
2006aaed909aSbellard     }
200783fb7adfSbellard     /* NOTE: we need to init the CPU at this stage to get
200883fb7adfSbellard        qemu_host_page_size */
2009aaed909aSbellard     env = cpu_init(cpu_model);
2010aaed909aSbellard     if (!env) {
2011aaed909aSbellard         fprintf(stderr, "Unable to find CPU definition\n");
2012aaed909aSbellard         exit(1);
2013aaed909aSbellard     }
201415338fd7Sbellard     global_env = env;
201554936004Sbellard 
2016b92c47c1Sths     if (getenv("QEMU_STRACE")) {
2017b92c47c1Sths         do_strace = 1;
2018b92c47c1Sths     }
2019b92c47c1Sths 
2020b12b6a18Sths     wrk = environ;
2021b12b6a18Sths     while (*(wrk++))
2022b12b6a18Sths         environ_count++;
2023b12b6a18Sths 
2024b12b6a18Sths     target_environ = malloc((environ_count + 1) * sizeof(char *));
2025b12b6a18Sths     if (!target_environ)
2026b12b6a18Sths         abort();
2027b12b6a18Sths     for (wrk = environ, dst = target_environ; *wrk; wrk++) {
2028b12b6a18Sths         if (drop_ld_preload && !strncmp(*wrk, "LD_PRELOAD=", 11))
2029b12b6a18Sths             continue;
2030b12b6a18Sths         *(dst++) = strdup(*wrk);
2031b12b6a18Sths     }
2032403f14efSths     *dst = NULL; /* NULL terminate target_environ */
2033b12b6a18Sths 
2034b12b6a18Sths     if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
203531e31b8aSbellard         printf("Error loading %s\n", filename);
203674cd30b8Sbellard         _exit(1);
203731e31b8aSbellard     }
203831e31b8aSbellard 
2039b12b6a18Sths     for (wrk = target_environ; *wrk; wrk++) {
2040b12b6a18Sths         free(*wrk);
2041b12b6a18Sths     }
2042b12b6a18Sths 
2043b12b6a18Sths     free(target_environ);
2044b12b6a18Sths 
20454b74fe1fSbellard     if (loglevel) {
204654936004Sbellard         page_dump(logfile);
204754936004Sbellard 
20488a4ed7efSbellard         fprintf(logfile, "start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
20498a4ed7efSbellard         fprintf(logfile, "end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
20508a4ed7efSbellard         fprintf(logfile, "start_code  0x" TARGET_ABI_FMT_lx "\n",
20513d177870Sj_mayer                 info->start_code);
20528a4ed7efSbellard         fprintf(logfile, "start_data  0x" TARGET_ABI_FMT_lx "\n",
20533d177870Sj_mayer                 info->start_data);
20548a4ed7efSbellard         fprintf(logfile, "end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
20558a4ed7efSbellard         fprintf(logfile, "start_stack 0x" TARGET_ABI_FMT_lx "\n",
20563d177870Sj_mayer                 info->start_stack);
20578a4ed7efSbellard         fprintf(logfile, "brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
20588a4ed7efSbellard         fprintf(logfile, "entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
20594b74fe1fSbellard     }
206031e31b8aSbellard 
206153a5960aSpbrook     target_set_brk(info->brk);
206231e31b8aSbellard     syscall_init();
206366fb9763Sbellard     signal_init();
206431e31b8aSbellard 
2065851e67a1Sbellard     /* build Task State */
2066851e67a1Sbellard     memset(ts, 0, sizeof(TaskState));
2067851e67a1Sbellard     env->opaque = ts;
2068851e67a1Sbellard     ts->used = 1;
2069978efd6aSpbrook     ts->info = info;
207059faf6d6Sbellard     env->user_mode_only = 1;
2071851e67a1Sbellard 
2072b346ff46Sbellard #if defined(TARGET_I386)
20732e255c6bSbellard     cpu_x86_set_cpl(env, 3);
20742e255c6bSbellard 
20753802ce26Sbellard     env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
20761bde465eSbellard     env->hflags |= HF_PE_MASK;
20771bde465eSbellard     if (env->cpuid_features & CPUID_SSE) {
20781bde465eSbellard         env->cr[4] |= CR4_OSFXSR_MASK;
20791bde465eSbellard         env->hflags |= HF_OSFXSR_MASK;
20801bde465eSbellard     }
20813802ce26Sbellard 
2082415e561fSbellard     /* flags setup : we activate the IRQs by default as in user mode */
2083415e561fSbellard     env->eflags |= IF_MASK;
2084415e561fSbellard 
20856dbad63eSbellard     /* linux register setup */
208684409ddbSj_mayer #if defined(TARGET_X86_64)
208784409ddbSj_mayer     env->regs[R_EAX] = regs->rax;
208884409ddbSj_mayer     env->regs[R_EBX] = regs->rbx;
208984409ddbSj_mayer     env->regs[R_ECX] = regs->rcx;
209084409ddbSj_mayer     env->regs[R_EDX] = regs->rdx;
209184409ddbSj_mayer     env->regs[R_ESI] = regs->rsi;
209284409ddbSj_mayer     env->regs[R_EDI] = regs->rdi;
209384409ddbSj_mayer     env->regs[R_EBP] = regs->rbp;
209484409ddbSj_mayer     env->regs[R_ESP] = regs->rsp;
209584409ddbSj_mayer     env->eip = regs->rip;
209684409ddbSj_mayer #else
20970ecfa993Sbellard     env->regs[R_EAX] = regs->eax;
20980ecfa993Sbellard     env->regs[R_EBX] = regs->ebx;
20990ecfa993Sbellard     env->regs[R_ECX] = regs->ecx;
21000ecfa993Sbellard     env->regs[R_EDX] = regs->edx;
21010ecfa993Sbellard     env->regs[R_ESI] = regs->esi;
21020ecfa993Sbellard     env->regs[R_EDI] = regs->edi;
21030ecfa993Sbellard     env->regs[R_EBP] = regs->ebp;
21040ecfa993Sbellard     env->regs[R_ESP] = regs->esp;
2105dab2ed99Sbellard     env->eip = regs->eip;
210684409ddbSj_mayer #endif
210731e31b8aSbellard 
2108f4beb510Sbellard     /* linux interrupt setup */
210953a5960aSpbrook     env->idt.base = h2g(idt_table);
2110f4beb510Sbellard     env->idt.limit = sizeof(idt_table) - 1;
2111f4beb510Sbellard     set_idt(0, 0);
2112f4beb510Sbellard     set_idt(1, 0);
2113f4beb510Sbellard     set_idt(2, 0);
2114f4beb510Sbellard     set_idt(3, 3);
2115f4beb510Sbellard     set_idt(4, 3);
2116f4beb510Sbellard     set_idt(5, 3);
2117f4beb510Sbellard     set_idt(6, 0);
2118f4beb510Sbellard     set_idt(7, 0);
2119f4beb510Sbellard     set_idt(8, 0);
2120f4beb510Sbellard     set_idt(9, 0);
2121f4beb510Sbellard     set_idt(10, 0);
2122f4beb510Sbellard     set_idt(11, 0);
2123f4beb510Sbellard     set_idt(12, 0);
2124f4beb510Sbellard     set_idt(13, 0);
2125f4beb510Sbellard     set_idt(14, 0);
2126f4beb510Sbellard     set_idt(15, 0);
2127f4beb510Sbellard     set_idt(16, 0);
2128f4beb510Sbellard     set_idt(17, 0);
2129f4beb510Sbellard     set_idt(18, 0);
2130f4beb510Sbellard     set_idt(19, 0);
2131f4beb510Sbellard     set_idt(0x80, 3);
2132f4beb510Sbellard 
21336dbad63eSbellard     /* linux segment setup */
213453a5960aSpbrook     env->gdt.base = h2g(gdt_table);
21356dbad63eSbellard     env->gdt.limit = sizeof(gdt_table) - 1;
2136f4beb510Sbellard     write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
2137f4beb510Sbellard              DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
2138f4beb510Sbellard              (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
2139f4beb510Sbellard     write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
2140f4beb510Sbellard              DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
2141f4beb510Sbellard              (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
21426dbad63eSbellard     cpu_x86_load_seg(env, R_CS, __USER_CS);
21436dbad63eSbellard     cpu_x86_load_seg(env, R_DS, __USER_DS);
21446dbad63eSbellard     cpu_x86_load_seg(env, R_ES, __USER_DS);
21456dbad63eSbellard     cpu_x86_load_seg(env, R_SS, __USER_DS);
21466dbad63eSbellard     cpu_x86_load_seg(env, R_FS, __USER_DS);
21476dbad63eSbellard     cpu_x86_load_seg(env, R_GS, __USER_DS);
214892ccca6aSbellard 
2149d6eb40f6Sths     /* This hack makes Wine work... */
2150d6eb40f6Sths     env->segs[R_FS].selector = 0;
2151b346ff46Sbellard #elif defined(TARGET_ARM)
2152b346ff46Sbellard     {
2153b346ff46Sbellard         int i;
2154b5ff1b31Sbellard         cpsr_write(env, regs->uregs[16], 0xffffffff);
2155b346ff46Sbellard         for(i = 0; i < 16; i++) {
2156b346ff46Sbellard             env->regs[i] = regs->uregs[i];
2157b346ff46Sbellard         }
2158b346ff46Sbellard     }
215993ac68bcSbellard #elif defined(TARGET_SPARC)
2160060366c5Sbellard     {
2161060366c5Sbellard         int i;
2162060366c5Sbellard 	env->pc = regs->pc;
2163060366c5Sbellard 	env->npc = regs->npc;
2164060366c5Sbellard         env->y = regs->y;
2165060366c5Sbellard         for(i = 0; i < 8; i++)
2166060366c5Sbellard             env->gregs[i] = regs->u_regs[i];
2167060366c5Sbellard         for(i = 0; i < 8; i++)
2168060366c5Sbellard             env->regwptr[i] = regs->u_regs[i + 8];
2169060366c5Sbellard     }
217067867308Sbellard #elif defined(TARGET_PPC)
217167867308Sbellard     {
217267867308Sbellard         int i;
21733fc6c082Sbellard 
21740411a972Sj_mayer #if defined(TARGET_PPC64)
21750411a972Sj_mayer #if defined(TARGET_ABI32)
21760411a972Sj_mayer         env->msr &= ~((target_ulong)1 << MSR_SF);
2177e85e7c6eSj_mayer #else
21780411a972Sj_mayer         env->msr |= (target_ulong)1 << MSR_SF;
21790411a972Sj_mayer #endif
218084409ddbSj_mayer #endif
218167867308Sbellard         env->nip = regs->nip;
218267867308Sbellard         for(i = 0; i < 32; i++) {
218367867308Sbellard             env->gpr[i] = regs->gpr[i];
218467867308Sbellard         }
218567867308Sbellard     }
2186e6e5906bSpbrook #elif defined(TARGET_M68K)
2187e6e5906bSpbrook     {
2188e6e5906bSpbrook         env->pc = regs->pc;
2189e6e5906bSpbrook         env->dregs[0] = regs->d0;
2190e6e5906bSpbrook         env->dregs[1] = regs->d1;
2191e6e5906bSpbrook         env->dregs[2] = regs->d2;
2192e6e5906bSpbrook         env->dregs[3] = regs->d3;
2193e6e5906bSpbrook         env->dregs[4] = regs->d4;
2194e6e5906bSpbrook         env->dregs[5] = regs->d5;
2195e6e5906bSpbrook         env->dregs[6] = regs->d6;
2196e6e5906bSpbrook         env->dregs[7] = regs->d7;
2197e6e5906bSpbrook         env->aregs[0] = regs->a0;
2198e6e5906bSpbrook         env->aregs[1] = regs->a1;
2199e6e5906bSpbrook         env->aregs[2] = regs->a2;
2200e6e5906bSpbrook         env->aregs[3] = regs->a3;
2201e6e5906bSpbrook         env->aregs[4] = regs->a4;
2202e6e5906bSpbrook         env->aregs[5] = regs->a5;
2203e6e5906bSpbrook         env->aregs[6] = regs->a6;
2204e6e5906bSpbrook         env->aregs[7] = regs->usp;
2205e6e5906bSpbrook         env->sr = regs->sr;
2206e6e5906bSpbrook         ts->sim_syscalls = 1;
2207e6e5906bSpbrook     }
2208048f6b4dSbellard #elif defined(TARGET_MIPS)
2209048f6b4dSbellard     {
2210048f6b4dSbellard         int i;
2211048f6b4dSbellard 
2212048f6b4dSbellard         for(i = 0; i < 32; i++) {
2213ead9360eSths             env->gpr[i][env->current_tc] = regs->regs[i];
2214048f6b4dSbellard         }
2215ead9360eSths         env->PC[env->current_tc] = regs->cp0_epc;
2216048f6b4dSbellard     }
2217fdf9b3e8Sbellard #elif defined(TARGET_SH4)
2218fdf9b3e8Sbellard     {
2219fdf9b3e8Sbellard         int i;
2220fdf9b3e8Sbellard 
2221fdf9b3e8Sbellard         for(i = 0; i < 16; i++) {
2222fdf9b3e8Sbellard             env->gregs[i] = regs->regs[i];
2223fdf9b3e8Sbellard         }
2224fdf9b3e8Sbellard         env->pc = regs->pc;
2225fdf9b3e8Sbellard     }
22267a3148a9Sj_mayer #elif defined(TARGET_ALPHA)
22277a3148a9Sj_mayer     {
22287a3148a9Sj_mayer         int i;
22297a3148a9Sj_mayer 
22307a3148a9Sj_mayer         for(i = 0; i < 28; i++) {
2231992f48a0Sblueswir1             env->ir[i] = ((abi_ulong *)regs)[i];
22327a3148a9Sj_mayer         }
22337a3148a9Sj_mayer         env->ipr[IPR_USP] = regs->usp;
22347a3148a9Sj_mayer         env->ir[30] = regs->usp;
22357a3148a9Sj_mayer         env->pc = regs->pc;
22367a3148a9Sj_mayer         env->unique = regs->unique;
22377a3148a9Sj_mayer     }
223848733d19Sths #elif defined(TARGET_CRIS)
223948733d19Sths     {
224048733d19Sths 	    env->regs[0] = regs->r0;
224148733d19Sths 	    env->regs[1] = regs->r1;
224248733d19Sths 	    env->regs[2] = regs->r2;
224348733d19Sths 	    env->regs[3] = regs->r3;
224448733d19Sths 	    env->regs[4] = regs->r4;
224548733d19Sths 	    env->regs[5] = regs->r5;
224648733d19Sths 	    env->regs[6] = regs->r6;
224748733d19Sths 	    env->regs[7] = regs->r7;
224848733d19Sths 	    env->regs[8] = regs->r8;
224948733d19Sths 	    env->regs[9] = regs->r9;
225048733d19Sths 	    env->regs[10] = regs->r10;
225148733d19Sths 	    env->regs[11] = regs->r11;
225248733d19Sths 	    env->regs[12] = regs->r12;
225348733d19Sths 	    env->regs[13] = regs->r13;
225448733d19Sths 	    env->regs[14] = info->start_stack;
225548733d19Sths 	    env->regs[15] = regs->acr;
225648733d19Sths 	    env->pc = regs->erp;
225748733d19Sths     }
2258b346ff46Sbellard #else
2259b346ff46Sbellard #error unsupported target CPU
2260b346ff46Sbellard #endif
226131e31b8aSbellard 
2262a87295e8Spbrook #if defined(TARGET_ARM) || defined(TARGET_M68K)
2263a87295e8Spbrook     ts->stack_base = info->start_stack;
2264a87295e8Spbrook     ts->heap_base = info->brk;
2265a87295e8Spbrook     /* This will be filled in on the first SYS_HEAPINFO call.  */
2266a87295e8Spbrook     ts->heap_limit = 0;
2267a87295e8Spbrook #endif
2268a87295e8Spbrook 
226974c33bedSbellard     if (gdbstub_port) {
227074c33bedSbellard         gdbserver_start (gdbstub_port);
22711fddef4bSbellard         gdb_handlesig(env, 0);
22721fddef4bSbellard     }
22731b6b029eSbellard     cpu_loop(env);
22741b6b029eSbellard     /* never exits */
227531e31b8aSbellard     return 0;
227631e31b8aSbellard }
2277