Annotation of qemu/linux-user/main.c, revision 1.1.1.6

1.1       root        1: /*
                      2:  *  qemu user main
1.1.1.6 ! root        3:  *
        !             4:  *  Copyright (c) 2003-2008 Fabrice Bellard
1.1       root        5:  *
                      6:  *  This program is free software; you can redistribute it and/or modify
                      7:  *  it under the terms of the GNU General Public License as published by
                      8:  *  the Free Software Foundation; either version 2 of the License, or
                      9:  *  (at your option) any later version.
                     10:  *
                     11:  *  This program is distributed in the hope that it will be useful,
                     12:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:  *  GNU General Public License for more details.
                     15:  *
                     16:  *  You should have received a copy of the GNU General Public License
                     17:  *  along with this program; if not, write to the Free Software
                     18:  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     19:  */
                     20: #include <stdlib.h>
                     21: #include <stdio.h>
                     22: #include <stdarg.h>
                     23: #include <string.h>
                     24: #include <errno.h>
                     25: #include <unistd.h>
                     26: 
                     27: #include "qemu.h"
                     28: 
                     29: #define DEBUG_LOGFILE "/tmp/qemu.log"
                     30: 
                     31: static const char *interp_prefix = CONFIG_QEMU_PREFIX;
1.1.1.4   root       32: const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
1.1       root       33: 
                     34: #if defined(__i386__) && !defined(CONFIG_STATIC)
                     35: /* Force usage of an ELF interpreter even if it is an ELF shared
                     36:    object ! */
                     37: const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
                     38: #endif
                     39: 
                     40: /* for recent libc, we add these dummy symbols which are not declared
                     41:    when generating a linked object (bug in ld ?) */
                     42: #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC)
1.1.1.6 ! root       43: asm(".globl __preinit_array_start\n"
        !            44:     ".globl __preinit_array_end\n"
        !            45:     ".globl __init_array_start\n"
        !            46:     ".globl __init_array_end\n"
        !            47:     ".globl __fini_array_start\n"
        !            48:     ".globl __fini_array_end\n"
        !            49:     ".section \".rodata\"\n"
        !            50:     "__preinit_array_start:\n"
        !            51:     "__preinit_array_end:\n"
        !            52:     "__init_array_start:\n"
        !            53:     "__init_array_end:\n"
        !            54:     "__fini_array_start:\n"
        !            55:     "__fini_array_end:\n"
        !            56:     ".long 0\n");
1.1       root       57: #endif
                     58: 
                     59: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
                     60:    we allocate a bigger stack. Need a better solution, for example
                     61:    by remapping the process stack directly at the right place */
                     62: unsigned long x86_stack_size = 512 * 1024;
                     63: 
                     64: void gemu_log(const char *fmt, ...)
                     65: {
                     66:     va_list ap;
                     67: 
                     68:     va_start(ap, fmt);
                     69:     vfprintf(stderr, fmt, ap);
                     70:     va_end(ap);
                     71: }
                     72: 
                     73: void cpu_outb(CPUState *env, int addr, int val)
                     74: {
                     75:     fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
                     76: }
                     77: 
                     78: void cpu_outw(CPUState *env, int addr, int val)
                     79: {
                     80:     fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
                     81: }
                     82: 
                     83: void cpu_outl(CPUState *env, int addr, int val)
                     84: {
                     85:     fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
                     86: }
                     87: 
                     88: int cpu_inb(CPUState *env, int addr)
                     89: {
                     90:     fprintf(stderr, "inb: port=0x%04x\n", addr);
                     91:     return 0;
                     92: }
                     93: 
                     94: int cpu_inw(CPUState *env, int addr)
                     95: {
                     96:     fprintf(stderr, "inw: port=0x%04x\n", addr);
                     97:     return 0;
                     98: }
                     99: 
                    100: int cpu_inl(CPUState *env, int addr)
                    101: {
                    102:     fprintf(stderr, "inl: port=0x%04x\n", addr);
                    103:     return 0;
                    104: }
                    105: 
                    106: int cpu_get_pic_interrupt(CPUState *env)
                    107: {
                    108:     return -1;
                    109: }
                    110: 
                    111: /* timers for rdtsc */
                    112: 
1.1.1.4   root      113: #if 0
1.1       root      114: 
                    115: static uint64_t emu_time;
                    116: 
                    117: int64_t cpu_get_real_ticks(void)
                    118: {
                    119:     return emu_time++;
                    120: }
                    121: 
                    122: #endif
                    123: 
                    124: #ifdef TARGET_I386
                    125: /***********************************************************/
                    126: /* CPUX86 core interface */
                    127: 
1.1.1.5   root      128: void cpu_smm_update(CPUState *env)
                    129: {
                    130: }
                    131: 
1.1       root      132: uint64_t cpu_get_tsc(CPUX86State *env)
                    133: {
                    134:     return cpu_get_real_ticks();
                    135: }
                    136: 
1.1.1.6 ! root      137: static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
1.1       root      138:                      int flags)
                    139: {
                    140:     unsigned int e1, e2;
1.1.1.3   root      141:     uint32_t *p;
1.1       root      142:     e1 = (addr << 16) | (limit & 0xffff);
                    143:     e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
                    144:     e2 |= flags;
1.1.1.3   root      145:     p = ptr;
                    146:     p[0] = tswapl(e1);
                    147:     p[1] = tswapl(e2);
1.1       root      148: }
                    149: 
1.1.1.6 ! root      150: #if TARGET_X86_64
        !           151: uint64_t idt_table[512];
        !           152: 
        !           153: static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
        !           154:                        uint64_t addr, unsigned int sel)
1.1       root      155: {
1.1.1.6 ! root      156:     uint32_t *p, e1, e2;
1.1       root      157:     e1 = (addr & 0xffff) | (sel << 16);
                    158:     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
1.1.1.3   root      159:     p = ptr;
1.1.1.6 ! root      160:     p[0] = tswap32(e1);
        !           161:     p[1] = tswap32(e2);
        !           162:     p[2] = tswap32(addr >> 32);
        !           163:     p[3] = 0;
1.1       root      164: }
1.1.1.6 ! root      165: /* only dpl matters as we do only user space emulation */
        !           166: static void set_idt(int n, unsigned int dpl)
        !           167: {
        !           168:     set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
        !           169: }
        !           170: #else
1.1       root      171: uint64_t idt_table[256];
                    172: 
1.1.1.6 ! root      173: static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
        !           174:                      uint32_t addr, unsigned int sel)
        !           175: {
        !           176:     uint32_t *p, e1, e2;
        !           177:     e1 = (addr & 0xffff) | (sel << 16);
        !           178:     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
        !           179:     p = ptr;
        !           180:     p[0] = tswap32(e1);
        !           181:     p[1] = tswap32(e2);
        !           182: }
        !           183: 
1.1       root      184: /* only dpl matters as we do only user space emulation */
                    185: static void set_idt(int n, unsigned int dpl)
                    186: {
                    187:     set_gate(idt_table + n, 0, dpl, 0, 0);
                    188: }
1.1.1.6 ! root      189: #endif
1.1       root      190: 
                    191: void cpu_loop(CPUX86State *env)
                    192: {
                    193:     int trapnr;
1.1.1.6 ! root      194:     abi_ulong pc;
1.1       root      195:     target_siginfo_t info;
                    196: 
                    197:     for(;;) {
                    198:         trapnr = cpu_x86_exec(env);
                    199:         switch(trapnr) {
                    200:         case 0x80:
1.1.1.6 ! root      201:             /* linux syscall from int $0x80 */
        !           202:             env->regs[R_EAX] = do_syscall(env,
        !           203:                                           env->regs[R_EAX],
1.1       root      204:                                           env->regs[R_EBX],
                    205:                                           env->regs[R_ECX],
                    206:                                           env->regs[R_EDX],
                    207:                                           env->regs[R_ESI],
                    208:                                           env->regs[R_EDI],
                    209:                                           env->regs[R_EBP]);
                    210:             break;
1.1.1.6 ! root      211: #ifndef TARGET_ABI32
        !           212:         case EXCP_SYSCALL:
        !           213:             /* linux syscall from syscall intruction */
        !           214:             env->regs[R_EAX] = do_syscall(env,
        !           215:                                           env->regs[R_EAX],
        !           216:                                           env->regs[R_EDI],
        !           217:                                           env->regs[R_ESI],
        !           218:                                           env->regs[R_EDX],
        !           219:                                           env->regs[10],
        !           220:                                           env->regs[8],
        !           221:                                           env->regs[9]);
        !           222:             env->eip = env->exception_next_eip;
        !           223:             break;
        !           224: #endif
1.1       root      225:         case EXCP0B_NOSEG:
                    226:         case EXCP0C_STACK:
                    227:             info.si_signo = SIGBUS;
                    228:             info.si_errno = 0;
                    229:             info.si_code = TARGET_SI_KERNEL;
                    230:             info._sifields._sigfault._addr = 0;
                    231:             queue_signal(info.si_signo, &info);
                    232:             break;
                    233:         case EXCP0D_GPF:
1.1.1.6 ! root      234:             /* XXX: potential problem if ABI32 */
        !           235: #ifndef TARGET_X86_64
1.1       root      236:             if (env->eflags & VM_MASK) {
                    237:                 handle_vm86_fault(env);
1.1.1.6 ! root      238:             } else
        !           239: #endif
        !           240:             {
1.1       root      241:                 info.si_signo = SIGSEGV;
                    242:                 info.si_errno = 0;
                    243:                 info.si_code = TARGET_SI_KERNEL;
                    244:                 info._sifields._sigfault._addr = 0;
                    245:                 queue_signal(info.si_signo, &info);
                    246:             }
                    247:             break;
                    248:         case EXCP0E_PAGE:
                    249:             info.si_signo = SIGSEGV;
                    250:             info.si_errno = 0;
                    251:             if (!(env->error_code & 1))
                    252:                 info.si_code = TARGET_SEGV_MAPERR;
                    253:             else
                    254:                 info.si_code = TARGET_SEGV_ACCERR;
                    255:             info._sifields._sigfault._addr = env->cr[2];
                    256:             queue_signal(info.si_signo, &info);
                    257:             break;
                    258:         case EXCP00_DIVZ:
1.1.1.6 ! root      259: #ifndef TARGET_X86_64
1.1       root      260:             if (env->eflags & VM_MASK) {
                    261:                 handle_vm86_trap(env, trapnr);
1.1.1.6 ! root      262:             } else
        !           263: #endif
        !           264:             {
1.1       root      265:                 /* division by zero */
                    266:                 info.si_signo = SIGFPE;
                    267:                 info.si_errno = 0;
                    268:                 info.si_code = TARGET_FPE_INTDIV;
                    269:                 info._sifields._sigfault._addr = env->eip;
                    270:                 queue_signal(info.si_signo, &info);
                    271:             }
                    272:             break;
                    273:         case EXCP01_SSTP:
                    274:         case EXCP03_INT3:
1.1.1.6 ! root      275: #ifndef TARGET_X86_64
1.1       root      276:             if (env->eflags & VM_MASK) {
                    277:                 handle_vm86_trap(env, trapnr);
1.1.1.6 ! root      278:             } else
        !           279: #endif
        !           280:             {
1.1       root      281:                 info.si_signo = SIGTRAP;
                    282:                 info.si_errno = 0;
                    283:                 if (trapnr == EXCP01_SSTP) {
                    284:                     info.si_code = TARGET_TRAP_BRKPT;
                    285:                     info._sifields._sigfault._addr = env->eip;
                    286:                 } else {
                    287:                     info.si_code = TARGET_SI_KERNEL;
                    288:                     info._sifields._sigfault._addr = 0;
                    289:                 }
                    290:                 queue_signal(info.si_signo, &info);
                    291:             }
                    292:             break;
                    293:         case EXCP04_INTO:
                    294:         case EXCP05_BOUND:
1.1.1.6 ! root      295: #ifndef TARGET_X86_64
1.1       root      296:             if (env->eflags & VM_MASK) {
                    297:                 handle_vm86_trap(env, trapnr);
1.1.1.6 ! root      298:             } else
        !           299: #endif
        !           300:             {
1.1       root      301:                 info.si_signo = SIGSEGV;
                    302:                 info.si_errno = 0;
                    303:                 info.si_code = TARGET_SI_KERNEL;
                    304:                 info._sifields._sigfault._addr = 0;
                    305:                 queue_signal(info.si_signo, &info);
                    306:             }
                    307:             break;
                    308:         case EXCP06_ILLOP:
                    309:             info.si_signo = SIGILL;
                    310:             info.si_errno = 0;
                    311:             info.si_code = TARGET_ILL_ILLOPN;
                    312:             info._sifields._sigfault._addr = env->eip;
                    313:             queue_signal(info.si_signo, &info);
                    314:             break;
                    315:         case EXCP_INTERRUPT:
                    316:             /* just indicate that signals should be handled asap */
                    317:             break;
                    318:         case EXCP_DEBUG:
                    319:             {
                    320:                 int sig;
                    321: 
                    322:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                    323:                 if (sig)
                    324:                   {
                    325:                     info.si_signo = sig;
                    326:                     info.si_errno = 0;
                    327:                     info.si_code = TARGET_TRAP_BRKPT;
                    328:                     queue_signal(info.si_signo, &info);
                    329:                   }
                    330:             }
                    331:             break;
                    332:         default:
                    333:             pc = env->segs[R_CS].base + env->eip;
1.1.1.6 ! root      334:             fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
1.1       root      335:                     (long)pc, trapnr);
                    336:             abort();
                    337:         }
                    338:         process_pending_signals(env);
                    339:     }
                    340: }
                    341: #endif
                    342: 
                    343: #ifdef TARGET_ARM
                    344: 
                    345: /* XXX: find a better solution */
1.1.1.6 ! root      346: extern void tb_invalidate_page_range(abi_ulong start, abi_ulong end);
1.1       root      347: 
1.1.1.6 ! root      348: static void arm_cache_flush(abi_ulong start, abi_ulong last)
1.1       root      349: {
1.1.1.6 ! root      350:     abi_ulong addr, last1;
1.1       root      351: 
                    352:     if (last < start)
                    353:         return;
                    354:     addr = start;
                    355:     for(;;) {
                    356:         last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1;
                    357:         if (last1 > last)
                    358:             last1 = last;
                    359:         tb_invalidate_page_range(addr, last1 + 1);
                    360:         if (last1 == last)
                    361:             break;
                    362:         addr = last1 + 1;
                    363:     }
                    364: }
                    365: 
                    366: void cpu_loop(CPUARMState *env)
                    367: {
                    368:     int trapnr;
                    369:     unsigned int n, insn;
                    370:     target_siginfo_t info;
1.1.1.2   root      371:     uint32_t addr;
1.1.1.6 ! root      372: 
1.1       root      373:     for(;;) {
                    374:         trapnr = cpu_arm_exec(env);
                    375:         switch(trapnr) {
                    376:         case EXCP_UDEF:
                    377:             {
                    378:                 TaskState *ts = env->opaque;
                    379:                 uint32_t opcode;
                    380: 
                    381:                 /* we handle the FPU emulation here, as Linux */
                    382:                 /* we get the opcode */
1.1.1.6 ! root      383:                 /* FIXME - what to do if get_user() fails? */
        !           384:                 get_user_u32(opcode, env->regs[15]);
        !           385: 
1.1.1.3   root      386:                 if (EmulateAll(opcode, &ts->fpa, env) == 0) {
1.1       root      387:                     info.si_signo = SIGILL;
                    388:                     info.si_errno = 0;
                    389:                     info.si_code = TARGET_ILL_ILLOPN;
                    390:                     info._sifields._sigfault._addr = env->regs[15];
                    391:                     queue_signal(info.si_signo, &info);
                    392:                 } else {
                    393:                     /* increment PC */
                    394:                     env->regs[15] += 4;
                    395:                 }
                    396:             }
                    397:             break;
                    398:         case EXCP_SWI:
1.1.1.3   root      399:         case EXCP_BKPT:
1.1       root      400:             {
1.1.1.3   root      401:                 env->eabi = 1;
1.1       root      402:                 /* system call */
1.1.1.3   root      403:                 if (trapnr == EXCP_BKPT) {
                    404:                     if (env->thumb) {
1.1.1.6 ! root      405:                         /* FIXME - what to do if get_user() fails? */
        !           406:                         get_user_u16(insn, env->regs[15]);
1.1.1.3   root      407:                         n = insn & 0xff;
                    408:                         env->regs[15] += 2;
                    409:                     } else {
1.1.1.6 ! root      410:                         /* FIXME - what to do if get_user() fails? */
        !           411:                         get_user_u32(insn, env->regs[15]);
1.1.1.3   root      412:                         n = (insn & 0xf) | ((insn >> 4) & 0xff0);
                    413:                         env->regs[15] += 4;
                    414:                     }
1.1       root      415:                 } else {
1.1.1.3   root      416:                     if (env->thumb) {
1.1.1.6 ! root      417:                         /* FIXME - what to do if get_user() fails? */
        !           418:                         get_user_u16(insn, env->regs[15] - 2);
1.1.1.3   root      419:                         n = insn & 0xff;
                    420:                     } else {
1.1.1.6 ! root      421:                         /* FIXME - what to do if get_user() fails? */
        !           422:                         get_user_u32(insn, env->regs[15] - 4);
1.1.1.3   root      423:                         n = insn & 0xffffff;
                    424:                     }
1.1       root      425:                 }
                    426: 
                    427:                 if (n == ARM_NR_cacheflush) {
                    428:                     arm_cache_flush(env->regs[0], env->regs[1]);
                    429:                 } else if (n == ARM_NR_semihosting
                    430:                            || n == ARM_NR_thumb_semihosting) {
                    431:                     env->regs[0] = do_arm_semihosting (env);
1.1.1.3   root      432:                 } else if (n == 0 || n >= ARM_SYSCALL_BASE
1.1       root      433:                            || (env->thumb && n == ARM_THUMB_SYSCALL)) {
                    434:                     /* linux syscall */
1.1.1.3   root      435:                     if (env->thumb || n == 0) {
1.1       root      436:                         n = env->regs[7];
                    437:                     } else {
                    438:                         n -= ARM_SYSCALL_BASE;
1.1.1.3   root      439:                         env->eabi = 0;
1.1       root      440:                     }
1.1.1.6 ! root      441:                     env->regs[0] = do_syscall(env,
        !           442:                                               n,
1.1       root      443:                                               env->regs[0],
                    444:                                               env->regs[1],
                    445:                                               env->regs[2],
                    446:                                               env->regs[3],
                    447:                                               env->regs[4],
                    448:                                               env->regs[5]);
                    449:                 } else {
                    450:                     goto error;
                    451:                 }
                    452:             }
                    453:             break;
                    454:         case EXCP_INTERRUPT:
                    455:             /* just indicate that signals should be handled asap */
                    456:             break;
                    457:         case EXCP_PREFETCH_ABORT:
1.1.1.2   root      458:             addr = env->cp15.c6_data;
                    459:             goto do_segv;
1.1       root      460:         case EXCP_DATA_ABORT:
1.1.1.2   root      461:             addr = env->cp15.c6_insn;
                    462:             goto do_segv;
                    463:         do_segv:
1.1       root      464:             {
                    465:                 info.si_signo = SIGSEGV;
                    466:                 info.si_errno = 0;
                    467:                 /* XXX: check env->error_code */
                    468:                 info.si_code = TARGET_SEGV_MAPERR;
1.1.1.2   root      469:                 info._sifields._sigfault._addr = addr;
1.1       root      470:                 queue_signal(info.si_signo, &info);
                    471:             }
                    472:             break;
                    473:         case EXCP_DEBUG:
                    474:             {
                    475:                 int sig;
                    476: 
                    477:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                    478:                 if (sig)
                    479:                   {
                    480:                     info.si_signo = sig;
                    481:                     info.si_errno = 0;
                    482:                     info.si_code = TARGET_TRAP_BRKPT;
                    483:                     queue_signal(info.si_signo, &info);
                    484:                   }
                    485:             }
                    486:             break;
                    487:         default:
                    488:         error:
1.1.1.6 ! root      489:             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1.1       root      490:                     trapnr);
                    491:             cpu_dump_state(env, stderr, fprintf, 0);
                    492:             abort();
                    493:         }
                    494:         process_pending_signals(env);
                    495:     }
                    496: }
                    497: 
                    498: #endif
                    499: 
                    500: #ifdef TARGET_SPARC
                    501: 
                    502: //#define DEBUG_WIN
                    503: 
                    504: /* WARNING: dealing with register windows _is_ complicated. More info
                    505:    can be found at http://www.sics.se/~psm/sparcstack.html */
                    506: static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
                    507: {
                    508:     index = (index + cwp * 16) & (16 * NWINDOWS - 1);
                    509:     /* wrap handling : if cwp is on the last window, then we use the
                    510:        registers 'after' the end */
                    511:     if (index < 8 && env->cwp == (NWINDOWS - 1))
                    512:         index += (16 * NWINDOWS);
                    513:     return index;
                    514: }
                    515: 
                    516: /* save the register window 'cwp1' */
                    517: static inline void save_window_offset(CPUSPARCState *env, int cwp1)
                    518: {
                    519:     unsigned int i;
1.1.1.6 ! root      520:     abi_ulong sp_ptr;
        !           521: 
1.1.1.3   root      522:     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1.1       root      523: #if defined(DEBUG_WIN)
1.1.1.6 ! root      524:     printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
1.1       root      525:            (int)sp_ptr, cwp1);
                    526: #endif
                    527:     for(i = 0; i < 16; i++) {
1.1.1.6 ! root      528:         /* FIXME - what to do if put_user() fails? */
        !           529:         put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
        !           530:         sp_ptr += sizeof(abi_ulong);
1.1       root      531:     }
                    532: }
                    533: 
                    534: static void save_window(CPUSPARCState *env)
                    535: {
1.1.1.4   root      536: #ifndef TARGET_SPARC64
1.1       root      537:     unsigned int new_wim;
                    538:     new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &
                    539:         ((1LL << NWINDOWS) - 1);
                    540:     save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
                    541:     env->wim = new_wim;
1.1.1.4   root      542: #else
                    543:     save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
                    544:     env->cansave++;
                    545:     env->canrestore--;
                    546: #endif
1.1       root      547: }
                    548: 
                    549: static void restore_window(CPUSPARCState *env)
                    550: {
                    551:     unsigned int new_wim, i, cwp1;
1.1.1.6 ! root      552:     abi_ulong sp_ptr;
        !           553: 
1.1       root      554:     new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
                    555:         ((1LL << NWINDOWS) - 1);
1.1.1.6 ! root      556: 
1.1       root      557:     /* restore the invalid window */
                    558:     cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
1.1.1.3   root      559:     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1.1       root      560: #if defined(DEBUG_WIN)
1.1.1.6 ! root      561:     printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
1.1       root      562:            (int)sp_ptr, cwp1);
                    563: #endif
                    564:     for(i = 0; i < 16; i++) {
1.1.1.6 ! root      565:         /* FIXME - what to do if get_user() fails? */
        !           566:         get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
        !           567:         sp_ptr += sizeof(abi_ulong);
1.1       root      568:     }
                    569:     env->wim = new_wim;
1.1.1.4   root      570: #ifdef TARGET_SPARC64
                    571:     env->canrestore++;
                    572:     if (env->cleanwin < NWINDOWS - 1)
                    573:        env->cleanwin++;
                    574:     env->cansave--;
                    575: #endif
1.1       root      576: }
                    577: 
                    578: static void flush_windows(CPUSPARCState *env)
                    579: {
                    580:     int offset, cwp1;
                    581: 
                    582:     offset = 1;
                    583:     for(;;) {
                    584:         /* if restore would invoke restore_window(), then we can stop */
                    585:         cwp1 = (env->cwp + offset) & (NWINDOWS - 1);
                    586:         if (env->wim & (1 << cwp1))
                    587:             break;
                    588:         save_window_offset(env, cwp1);
                    589:         offset++;
                    590:     }
                    591:     /* set wim so that restore will reload the registers */
                    592:     cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
                    593:     env->wim = 1 << cwp1;
                    594: #if defined(DEBUG_WIN)
                    595:     printf("flush_windows: nb=%d\n", offset - 1);
                    596: #endif
                    597: }
                    598: 
                    599: void cpu_loop (CPUSPARCState *env)
                    600: {
                    601:     int trapnr, ret;
                    602:     target_siginfo_t info;
1.1.1.6 ! root      603: 
1.1       root      604:     while (1) {
                    605:         trapnr = cpu_sparc_exec (env);
1.1.1.6 ! root      606: 
1.1       root      607:         switch (trapnr) {
1.1.1.4   root      608: #ifndef TARGET_SPARC64
1.1.1.6 ! root      609:         case 0x88:
1.1       root      610:         case 0x90:
1.1.1.4   root      611: #else
1.1.1.6 ! root      612:         case 0x110:
1.1.1.4   root      613:         case 0x16d:
                    614: #endif
1.1       root      615:             ret = do_syscall (env, env->gregs[1],
1.1.1.6 ! root      616:                               env->regwptr[0], env->regwptr[1],
        !           617:                               env->regwptr[2], env->regwptr[3],
1.1       root      618:                               env->regwptr[4], env->regwptr[5]);
                    619:             if ((unsigned int)ret >= (unsigned int)(-515)) {
1.1.1.6 ! root      620: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1.1.1.5   root      621:                 env->xcc |= PSR_CARRY;
                    622: #else
1.1       root      623:                 env->psr |= PSR_CARRY;
1.1.1.5   root      624: #endif
1.1       root      625:                 ret = -ret;
                    626:             } else {
1.1.1.6 ! root      627: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1.1.1.5   root      628:                 env->xcc &= ~PSR_CARRY;
                    629: #else
1.1       root      630:                 env->psr &= ~PSR_CARRY;
1.1.1.5   root      631: #endif
1.1       root      632:             }
                    633:             env->regwptr[0] = ret;
                    634:             /* next instruction */
                    635:             env->pc = env->npc;
                    636:             env->npc = env->npc + 4;
                    637:             break;
                    638:         case 0x83: /* flush windows */
1.1.1.6 ! root      639: #ifdef TARGET_ABI32
        !           640:         case 0x103:
        !           641: #endif
1.1       root      642:             flush_windows(env);
                    643:             /* next instruction */
                    644:             env->pc = env->npc;
                    645:             env->npc = env->npc + 4;
                    646:             break;
                    647: #ifndef TARGET_SPARC64
                    648:         case TT_WIN_OVF: /* window overflow */
                    649:             save_window(env);
                    650:             break;
                    651:         case TT_WIN_UNF: /* window underflow */
                    652:             restore_window(env);
                    653:             break;
                    654:         case TT_TFAULT:
                    655:         case TT_DFAULT:
                    656:             {
                    657:                 info.si_signo = SIGSEGV;
                    658:                 info.si_errno = 0;
                    659:                 /* XXX: check env->error_code */
                    660:                 info.si_code = TARGET_SEGV_MAPERR;
                    661:                 info._sifields._sigfault._addr = env->mmuregs[4];
                    662:                 queue_signal(info.si_signo, &info);
                    663:             }
                    664:             break;
                    665: #else
1.1.1.4   root      666:         case TT_SPILL: /* window overflow */
                    667:             save_window(env);
                    668:             break;
                    669:         case TT_FILL: /* window underflow */
                    670:             restore_window(env);
                    671:             break;
1.1.1.6 ! root      672:         case TT_TFAULT:
        !           673:         case TT_DFAULT:
        !           674:             {
        !           675:                 info.si_signo = SIGSEGV;
        !           676:                 info.si_errno = 0;
        !           677:                 /* XXX: check env->error_code */
        !           678:                 info.si_code = TARGET_SEGV_MAPERR;
        !           679:                 if (trapnr == TT_DFAULT)
        !           680:                     info._sifields._sigfault._addr = env->dmmuregs[4];
        !           681:                 else
        !           682:                     info._sifields._sigfault._addr = env->tpc[env->tl];
        !           683:                 queue_signal(info.si_signo, &info);
        !           684:             }
        !           685:             break;
        !           686: #ifndef TARGET_ABI32
        !           687:         case 0x16e:
        !           688:             flush_windows(env);
        !           689:             sparc64_get_context(env);
        !           690:             break;
        !           691:         case 0x16f:
        !           692:             flush_windows(env);
        !           693:             sparc64_set_context(env);
        !           694:             break;
        !           695: #endif
1.1       root      696: #endif
1.1.1.4   root      697:         case EXCP_INTERRUPT:
                    698:             /* just indicate that signals should be handled asap */
                    699:             break;
1.1       root      700:         case EXCP_DEBUG:
                    701:             {
                    702:                 int sig;
                    703: 
                    704:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                    705:                 if (sig)
                    706:                   {
                    707:                     info.si_signo = sig;
                    708:                     info.si_errno = 0;
                    709:                     info.si_code = TARGET_TRAP_BRKPT;
                    710:                     queue_signal(info.si_signo, &info);
                    711:                   }
                    712:             }
                    713:             break;
                    714:         default:
                    715:             printf ("Unhandled trap: 0x%x\n", trapnr);
                    716:             cpu_dump_state(env, stderr, fprintf, 0);
                    717:             exit (1);
                    718:         }
                    719:         process_pending_signals (env);
                    720:     }
                    721: }
                    722: 
                    723: #endif
                    724: 
                    725: #ifdef TARGET_PPC
                    726: static inline uint64_t cpu_ppc_get_tb (CPUState *env)
                    727: {
                    728:     /* TO FIX */
                    729:     return 0;
                    730: }
1.1.1.6 ! root      731: 
1.1       root      732: uint32_t cpu_ppc_load_tbl (CPUState *env)
                    733: {
                    734:     return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
                    735: }
1.1.1.6 ! root      736: 
1.1       root      737: uint32_t cpu_ppc_load_tbu (CPUState *env)
                    738: {
                    739:     return cpu_ppc_get_tb(env) >> 32;
                    740: }
1.1.1.6 ! root      741: 
        !           742: uint32_t cpu_ppc_load_atbl (CPUState *env)
1.1       root      743: {
1.1.1.6 ! root      744:     return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
1.1       root      745: }
                    746: 
1.1.1.6 ! root      747: uint32_t cpu_ppc_load_atbu (CPUState *env)
1.1       root      748: {
1.1.1.6 ! root      749:     return cpu_ppc_get_tb(env) >> 32;
1.1       root      750: }
1.1.1.6 ! root      751: 
        !           752: uint32_t cpu_ppc601_load_rtcu (CPUState *env)
        !           753: __attribute__ (( alias ("cpu_ppc_load_tbu") ));
        !           754: 
        !           755: uint32_t cpu_ppc601_load_rtcl (CPUState *env)
1.1       root      756: {
1.1.1.6 ! root      757:     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
1.1       root      758: }
1.1.1.6 ! root      759: 
        !           760: /* XXX: to be fixed */
        !           761: int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
1.1       root      762: {
                    763:     return -1;
                    764: }
1.1.1.6 ! root      765: 
        !           766: int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
1.1       root      767: {
1.1.1.6 ! root      768:     return -1;
1.1       root      769: }
1.1.1.6 ! root      770: 
        !           771: #define EXCP_DUMP(env, fmt, args...)                                         \
        !           772: do {                                                                          \
        !           773:     fprintf(stderr, fmt , ##args);                                            \
        !           774:     cpu_dump_state(env, stderr, fprintf, 0);                                  \
        !           775:     if (loglevel != 0) {                                                      \
        !           776:         fprintf(logfile, fmt , ##args);                                       \
        !           777:         cpu_dump_state(env, logfile, fprintf, 0);                             \
        !           778:     }                                                                         \
        !           779: } while (0)
        !           780: 
1.1       root      781: void cpu_loop(CPUPPCState *env)
                    782: {
                    783:     target_siginfo_t info;
                    784:     int trapnr;
                    785:     uint32_t ret;
1.1.1.6 ! root      786: 
1.1       root      787:     for(;;) {
                    788:         trapnr = cpu_ppc_exec(env);
                    789:         switch(trapnr) {
1.1.1.6 ! root      790:         case POWERPC_EXCP_NONE:
        !           791:             /* Just go on */
1.1       root      792:             break;
1.1.1.6 ! root      793:         case POWERPC_EXCP_CRITICAL: /* Critical input                        */
        !           794:             cpu_abort(env, "Critical interrupt while in user mode. "
        !           795:                       "Aborting\n");
        !           796:             break;
        !           797:         case POWERPC_EXCP_MCHECK:   /* Machine check exception               */
        !           798:             cpu_abort(env, "Machine check exception while in user mode. "
        !           799:                       "Aborting\n");
        !           800:             break;
        !           801:         case POWERPC_EXCP_DSI:      /* Data storage exception                */
        !           802:             EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
        !           803:                       env->spr[SPR_DAR]);
        !           804:             /* XXX: check this. Seems bugged */
1.1       root      805:             switch (env->error_code & 0xFF000000) {
                    806:             case 0x40000000:
                    807:                 info.si_signo = TARGET_SIGSEGV;
                    808:                 info.si_errno = 0;
                    809:                 info.si_code = TARGET_SEGV_MAPERR;
                    810:                 break;
                    811:             case 0x04000000:
                    812:                 info.si_signo = TARGET_SIGILL;
                    813:                 info.si_errno = 0;
                    814:                 info.si_code = TARGET_ILL_ILLADR;
                    815:                 break;
                    816:             case 0x08000000:
                    817:                 info.si_signo = TARGET_SIGSEGV;
                    818:                 info.si_errno = 0;
                    819:                 info.si_code = TARGET_SEGV_ACCERR;
                    820:                 break;
                    821:             default:
                    822:                 /* Let's send a regular segfault... */
1.1.1.6 ! root      823:                 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
        !           824:                           env->error_code);
1.1       root      825:                 info.si_signo = TARGET_SIGSEGV;
                    826:                 info.si_errno = 0;
                    827:                 info.si_code = TARGET_SEGV_MAPERR;
                    828:                 break;
                    829:             }
                    830:             info._sifields._sigfault._addr = env->nip;
                    831:             queue_signal(info.si_signo, &info);
                    832:             break;
1.1.1.6 ! root      833:         case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
        !           834:             EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
        !           835:                       env->spr[SPR_SRR0]);
        !           836:             /* XXX: check this */
1.1       root      837:             switch (env->error_code & 0xFF000000) {
                    838:             case 0x40000000:
                    839:                 info.si_signo = TARGET_SIGSEGV;
                    840:             info.si_errno = 0;
                    841:                 info.si_code = TARGET_SEGV_MAPERR;
                    842:                 break;
                    843:             case 0x10000000:
                    844:             case 0x08000000:
                    845:                 info.si_signo = TARGET_SIGSEGV;
                    846:                 info.si_errno = 0;
                    847:                 info.si_code = TARGET_SEGV_ACCERR;
                    848:                 break;
                    849:             default:
                    850:                 /* Let's send a regular segfault... */
1.1.1.6 ! root      851:                 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
        !           852:                           env->error_code);
1.1       root      853:                 info.si_signo = TARGET_SIGSEGV;
                    854:                 info.si_errno = 0;
                    855:                 info.si_code = TARGET_SEGV_MAPERR;
                    856:                 break;
                    857:             }
                    858:             info._sifields._sigfault._addr = env->nip - 4;
                    859:             queue_signal(info.si_signo, &info);
                    860:             break;
1.1.1.6 ! root      861:         case POWERPC_EXCP_EXTERNAL: /* External input                        */
        !           862:             cpu_abort(env, "External interrupt while in user mode. "
        !           863:                       "Aborting\n");
        !           864:             break;
        !           865:         case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */
        !           866:             EXCP_DUMP(env, "Unaligned memory access\n");
        !           867:             /* XXX: check this */
1.1       root      868:             info.si_signo = TARGET_SIGBUS;
                    869:             info.si_errno = 0;
                    870:             info.si_code = TARGET_BUS_ADRALN;
                    871:             info._sifields._sigfault._addr = env->nip - 4;
                    872:             queue_signal(info.si_signo, &info);
                    873:             break;
1.1.1.6 ! root      874:         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
        !           875:             /* XXX: check this */
1.1       root      876:             switch (env->error_code & ~0xF) {
1.1.1.6 ! root      877:             case POWERPC_EXCP_FP:
        !           878:                 EXCP_DUMP(env, "Floating point program exception\n");
1.1       root      879:                 info.si_signo = TARGET_SIGFPE;
                    880:                 info.si_errno = 0;
                    881:                 switch (env->error_code & 0xF) {
1.1.1.6 ! root      882:                 case POWERPC_EXCP_FP_OX:
1.1       root      883:                     info.si_code = TARGET_FPE_FLTOVF;
                    884:                     break;
1.1.1.6 ! root      885:                 case POWERPC_EXCP_FP_UX:
1.1       root      886:                     info.si_code = TARGET_FPE_FLTUND;
                    887:                     break;
1.1.1.6 ! root      888:                 case POWERPC_EXCP_FP_ZX:
        !           889:                 case POWERPC_EXCP_FP_VXZDZ:
1.1       root      890:                     info.si_code = TARGET_FPE_FLTDIV;
                    891:                     break;
1.1.1.6 ! root      892:                 case POWERPC_EXCP_FP_XX:
1.1       root      893:                     info.si_code = TARGET_FPE_FLTRES;
                    894:                     break;
1.1.1.6 ! root      895:                 case POWERPC_EXCP_FP_VXSOFT:
1.1       root      896:                     info.si_code = TARGET_FPE_FLTINV;
                    897:                     break;
1.1.1.6 ! root      898:                 case POWERPC_EXCP_FP_VXSNAN:
        !           899:                 case POWERPC_EXCP_FP_VXISI:
        !           900:                 case POWERPC_EXCP_FP_VXIDI:
        !           901:                 case POWERPC_EXCP_FP_VXIMZ:
        !           902:                 case POWERPC_EXCP_FP_VXVC:
        !           903:                 case POWERPC_EXCP_FP_VXSQRT:
        !           904:                 case POWERPC_EXCP_FP_VXCVI:
1.1       root      905:                     info.si_code = TARGET_FPE_FLTSUB;
                    906:                     break;
                    907:                 default:
1.1.1.6 ! root      908:                     EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
        !           909:                               env->error_code);
        !           910:                     break;
1.1       root      911:                 }
1.1.1.6 ! root      912:                 break;
        !           913:             case POWERPC_EXCP_INVAL:
        !           914:                 EXCP_DUMP(env, "Invalid instruction\n");
1.1       root      915:                 info.si_signo = TARGET_SIGILL;
                    916:                 info.si_errno = 0;
                    917:                 switch (env->error_code & 0xF) {
1.1.1.6 ! root      918:                 case POWERPC_EXCP_INVAL_INVAL:
1.1       root      919:                     info.si_code = TARGET_ILL_ILLOPC;
                    920:                     break;
1.1.1.6 ! root      921:                 case POWERPC_EXCP_INVAL_LSWX:
        !           922:                     info.si_code = TARGET_ILL_ILLOPN;
1.1       root      923:                     break;
1.1.1.6 ! root      924:                 case POWERPC_EXCP_INVAL_SPR:
1.1       root      925:                     info.si_code = TARGET_ILL_PRVREG;
                    926:                     break;
1.1.1.6 ! root      927:                 case POWERPC_EXCP_INVAL_FP:
1.1       root      928:                     info.si_code = TARGET_ILL_COPROC;
                    929:                     break;
                    930:                 default:
1.1.1.6 ! root      931:                     EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
        !           932:                               env->error_code & 0xF);
1.1       root      933:                     info.si_code = TARGET_ILL_ILLADR;
                    934:                     break;
                    935:                 }
                    936:                 break;
1.1.1.6 ! root      937:             case POWERPC_EXCP_PRIV:
        !           938:                 EXCP_DUMP(env, "Privilege violation\n");
1.1       root      939:                 info.si_signo = TARGET_SIGILL;
                    940:                 info.si_errno = 0;
                    941:                 switch (env->error_code & 0xF) {
1.1.1.6 ! root      942:                 case POWERPC_EXCP_PRIV_OPC:
1.1       root      943:                     info.si_code = TARGET_ILL_PRVOPC;
                    944:                     break;
1.1.1.6 ! root      945:                 case POWERPC_EXCP_PRIV_REG:
1.1       root      946:                     info.si_code = TARGET_ILL_PRVREG;
1.1.1.6 ! root      947:                     break;
1.1       root      948:                 default:
1.1.1.6 ! root      949:                     EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
        !           950:                               env->error_code & 0xF);
1.1       root      951:                     info.si_code = TARGET_ILL_PRVOPC;
                    952:                     break;
                    953:                 }
                    954:                 break;
1.1.1.6 ! root      955:             case POWERPC_EXCP_TRAP:
        !           956:                 cpu_abort(env, "Tried to call a TRAP\n");
        !           957:                 break;
1.1       root      958:             default:
                    959:                 /* Should not happen ! */
1.1.1.6 ! root      960:                 cpu_abort(env, "Unknown program exception (%02x)\n",
        !           961:                           env->error_code);
        !           962:                 break;
1.1       root      963:             }
                    964:             info._sifields._sigfault._addr = env->nip - 4;
                    965:             queue_signal(info.si_signo, &info);
                    966:             break;
1.1.1.6 ! root      967:         case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
        !           968:             EXCP_DUMP(env, "No floating point allowed\n");
1.1       root      969:             info.si_signo = TARGET_SIGILL;
                    970:             info.si_errno = 0;
                    971:             info.si_code = TARGET_ILL_COPROC;
                    972:             info._sifields._sigfault._addr = env->nip - 4;
                    973:             queue_signal(info.si_signo, &info);
                    974:             break;
1.1.1.6 ! root      975:         case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
        !           976:             cpu_abort(env, "Syscall exception while in user mode. "
        !           977:                       "Aborting\n");
1.1       root      978:             break;
1.1.1.6 ! root      979:         case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */
        !           980:             EXCP_DUMP(env, "No APU instruction allowed\n");
        !           981:             info.si_signo = TARGET_SIGILL;
        !           982:             info.si_errno = 0;
        !           983:             info.si_code = TARGET_ILL_COPROC;
        !           984:             info._sifields._sigfault._addr = env->nip - 4;
        !           985:             queue_signal(info.si_signo, &info);
1.1       root      986:             break;
1.1.1.6 ! root      987:         case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
        !           988:             cpu_abort(env, "Decrementer interrupt while in user mode. "
        !           989:                       "Aborting\n");
        !           990:             break;
        !           991:         case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */
        !           992:             cpu_abort(env, "Fix interval timer interrupt while in user mode. "
        !           993:                       "Aborting\n");
        !           994:             break;
        !           995:         case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */
        !           996:             cpu_abort(env, "Watchdog timer interrupt while in user mode. "
        !           997:                       "Aborting\n");
        !           998:             break;
        !           999:         case POWERPC_EXCP_DTLB:     /* Data TLB error                        */
        !          1000:             cpu_abort(env, "Data TLB exception while in user mode. "
        !          1001:                       "Aborting\n");
        !          1002:             break;
        !          1003:         case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */
        !          1004:             cpu_abort(env, "Instruction TLB exception while in user mode. "
        !          1005:                       "Aborting\n");
1.1       root     1006:             break;
1.1.1.6 ! root     1007:         case POWERPC_EXCP_DEBUG:    /* Debug interrupt                       */
        !          1008:             /* XXX: check this */
1.1       root     1009:             {
                   1010:                 int sig;
                   1011: 
1.1.1.6 ! root     1012:                 sig = gdb_handlesig(env, TARGET_SIGTRAP);
        !          1013:                 if (sig) {
1.1       root     1014:                     info.si_signo = sig;
                   1015:                     info.si_errno = 0;
                   1016:                     info.si_code = TARGET_TRAP_BRKPT;
                   1017:                     queue_signal(info.si_signo, &info);
                   1018:                   }
                   1019:             }
                   1020:             break;
1.1.1.6 ! root     1021:         case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
        !          1022:             EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
        !          1023:             info.si_signo = TARGET_SIGILL;
        !          1024:             info.si_errno = 0;
        !          1025:             info.si_code = TARGET_ILL_COPROC;
        !          1026:             info._sifields._sigfault._addr = env->nip - 4;
        !          1027:             queue_signal(info.si_signo, &info);
        !          1028:             break;
        !          1029:         case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
        !          1030:             cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
        !          1031:             break;
        !          1032:         case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */
        !          1033:             cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
        !          1034:             break;
        !          1035:         case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */
        !          1036:             cpu_abort(env, "Performance monitor exception not handled\n");
        !          1037:             break;
        !          1038:         case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */
        !          1039:             cpu_abort(env, "Doorbell interrupt while in user mode. "
        !          1040:                        "Aborting\n");
        !          1041:             break;
        !          1042:         case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */
        !          1043:             cpu_abort(env, "Doorbell critical interrupt while in user mode. "
        !          1044:                       "Aborting\n");
        !          1045:             break;
        !          1046:         case POWERPC_EXCP_RESET:    /* System reset exception                */
        !          1047:             cpu_abort(env, "Reset interrupt while in user mode. "
        !          1048:                       "Aborting\n");
        !          1049:             break;
        !          1050:         case POWERPC_EXCP_DSEG:     /* Data segment exception                */
        !          1051:             cpu_abort(env, "Data segment exception while in user mode. "
        !          1052:                       "Aborting\n");
        !          1053:             break;
        !          1054:         case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */
        !          1055:             cpu_abort(env, "Instruction segment exception "
        !          1056:                       "while in user mode. Aborting\n");
        !          1057:             break;
        !          1058:         /* PowerPC 64 with hypervisor mode support */
        !          1059:         case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */
        !          1060:             cpu_abort(env, "Hypervisor decrementer interrupt "
        !          1061:                       "while in user mode. Aborting\n");
        !          1062:             break;
        !          1063:         case POWERPC_EXCP_TRACE:    /* Trace exception                       */
        !          1064:             /* Nothing to do:
        !          1065:              * we use this exception to emulate step-by-step execution mode.
        !          1066:              */
        !          1067:             break;
        !          1068:         /* PowerPC 64 with hypervisor mode support */
        !          1069:         case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */
        !          1070:             cpu_abort(env, "Hypervisor data storage exception "
        !          1071:                       "while in user mode. Aborting\n");
        !          1072:             break;
        !          1073:         case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */
        !          1074:             cpu_abort(env, "Hypervisor instruction storage exception "
        !          1075:                       "while in user mode. Aborting\n");
        !          1076:             break;
        !          1077:         case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */
        !          1078:             cpu_abort(env, "Hypervisor data segment exception "
        !          1079:                       "while in user mode. Aborting\n");
        !          1080:             break;
        !          1081:         case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */
        !          1082:             cpu_abort(env, "Hypervisor instruction segment exception "
        !          1083:                       "while in user mode. Aborting\n");
        !          1084:             break;
        !          1085:         case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */
        !          1086:             EXCP_DUMP(env, "No Altivec instructions allowed\n");
        !          1087:             info.si_signo = TARGET_SIGILL;
        !          1088:             info.si_errno = 0;
        !          1089:             info.si_code = TARGET_ILL_COPROC;
        !          1090:             info._sifields._sigfault._addr = env->nip - 4;
        !          1091:             queue_signal(info.si_signo, &info);
        !          1092:             break;
        !          1093:         case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
        !          1094:             cpu_abort(env, "Programable interval timer interrupt "
        !          1095:                       "while in user mode. Aborting\n");
        !          1096:             break;
        !          1097:         case POWERPC_EXCP_IO:       /* IO error exception                    */
        !          1098:             cpu_abort(env, "IO error exception while in user mode. "
        !          1099:                       "Aborting\n");
        !          1100:             break;
        !          1101:         case POWERPC_EXCP_RUNM:     /* Run mode exception                    */
        !          1102:             cpu_abort(env, "Run mode exception while in user mode. "
        !          1103:                       "Aborting\n");
        !          1104:             break;
        !          1105:         case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */
        !          1106:             cpu_abort(env, "Emulation trap exception not handled\n");
        !          1107:             break;
        !          1108:         case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */
        !          1109:             cpu_abort(env, "Instruction fetch TLB exception "
        !          1110:                       "while in user-mode. Aborting");
        !          1111:             break;
        !          1112:         case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */
        !          1113:             cpu_abort(env, "Data load TLB exception while in user-mode. "
        !          1114:                       "Aborting");
        !          1115:             break;
        !          1116:         case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */
        !          1117:             cpu_abort(env, "Data store TLB exception while in user-mode. "
        !          1118:                       "Aborting");
        !          1119:             break;
        !          1120:         case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */
        !          1121:             cpu_abort(env, "Floating-point assist exception not handled\n");
        !          1122:             break;
        !          1123:         case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */
        !          1124:             cpu_abort(env, "Instruction address breakpoint exception "
        !          1125:                       "not handled\n");
        !          1126:             break;
        !          1127:         case POWERPC_EXCP_SMI:      /* System management interrupt           */
        !          1128:             cpu_abort(env, "System management interrupt while in user mode. "
        !          1129:                       "Aborting\n");
        !          1130:             break;
        !          1131:         case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */
        !          1132:             cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
        !          1133:                       "Aborting\n");
        !          1134:             break;
        !          1135:         case POWERPC_EXCP_PERFM:   /* Embedded performance monitor IRQ      */
        !          1136:             cpu_abort(env, "Performance monitor exception not handled\n");
        !          1137:             break;
        !          1138:         case POWERPC_EXCP_VPUA:     /* Vector assist exception               */
        !          1139:             cpu_abort(env, "Vector assist exception not handled\n");
        !          1140:             break;
        !          1141:         case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */
        !          1142:             cpu_abort(env, "Soft patch exception not handled\n");
        !          1143:             break;
        !          1144:         case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */
        !          1145:             cpu_abort(env, "Maintenance exception while in user mode. "
        !          1146:                       "Aborting\n");
        !          1147:             break;
        !          1148:         case POWERPC_EXCP_STOP:     /* stop translation                      */
        !          1149:             /* We did invalidate the instruction cache. Go on */
        !          1150:             break;
        !          1151:         case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */
        !          1152:             /* We just stopped because of a branch. Go on */
        !          1153:             break;
        !          1154:         case POWERPC_EXCP_SYSCALL_USER:
        !          1155:             /* system call in user-mode emulation */
        !          1156:             /* WARNING:
        !          1157:              * PPC ABI uses overflow flag in cr0 to signal an error
        !          1158:              * in syscalls.
        !          1159:              */
        !          1160: #if 0
        !          1161:             printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
        !          1162:                    env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
        !          1163: #endif
        !          1164:             env->crf[0] &= ~0x1;
        !          1165:             ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
        !          1166:                              env->gpr[5], env->gpr[6], env->gpr[7],
        !          1167:                              env->gpr[8]);
        !          1168:             if (ret > (uint32_t)(-515)) {
        !          1169:                 env->crf[0] |= 0x1;
        !          1170:                 ret = -ret;
1.1       root     1171:             }
1.1.1.6 ! root     1172:             env->gpr[3] = ret;
        !          1173: #if 0
        !          1174:             printf("syscall returned 0x%08x (%d)\n", ret, ret);
        !          1175: #endif
        !          1176:             break;
        !          1177:         case EXCP_INTERRUPT:
        !          1178:             /* just indicate that signals should be handled asap */
        !          1179:             break;
        !          1180:         default:
        !          1181:             cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
        !          1182:             break;
1.1       root     1183:         }
                   1184:         process_pending_signals(env);
                   1185:     }
                   1186: }
                   1187: #endif
                   1188: 
1.1.1.2   root     1189: #ifdef TARGET_MIPS
                   1190: 
                   1191: #define MIPS_SYS(name, args) args,
                   1192: 
                   1193: static const uint8_t mips_syscall_args[] = {
                   1194:        MIPS_SYS(sys_syscall    , 0)    /* 4000 */
                   1195:        MIPS_SYS(sys_exit       , 1)
                   1196:        MIPS_SYS(sys_fork       , 0)
                   1197:        MIPS_SYS(sys_read       , 3)
                   1198:        MIPS_SYS(sys_write      , 3)
                   1199:        MIPS_SYS(sys_open       , 3)    /* 4005 */
                   1200:        MIPS_SYS(sys_close      , 1)
                   1201:        MIPS_SYS(sys_waitpid    , 3)
                   1202:        MIPS_SYS(sys_creat      , 2)
                   1203:        MIPS_SYS(sys_link       , 2)
                   1204:        MIPS_SYS(sys_unlink     , 1)    /* 4010 */
                   1205:        MIPS_SYS(sys_execve     , 0)
                   1206:        MIPS_SYS(sys_chdir      , 1)
                   1207:        MIPS_SYS(sys_time       , 1)
                   1208:        MIPS_SYS(sys_mknod      , 3)
                   1209:        MIPS_SYS(sys_chmod      , 2)    /* 4015 */
                   1210:        MIPS_SYS(sys_lchown     , 3)
                   1211:        MIPS_SYS(sys_ni_syscall , 0)
                   1212:        MIPS_SYS(sys_ni_syscall , 0)    /* was sys_stat */
                   1213:        MIPS_SYS(sys_lseek      , 3)
                   1214:        MIPS_SYS(sys_getpid     , 0)    /* 4020 */
                   1215:        MIPS_SYS(sys_mount      , 5)
                   1216:        MIPS_SYS(sys_oldumount  , 1)
                   1217:        MIPS_SYS(sys_setuid     , 1)
                   1218:        MIPS_SYS(sys_getuid     , 0)
                   1219:        MIPS_SYS(sys_stime      , 1)    /* 4025 */
                   1220:        MIPS_SYS(sys_ptrace     , 4)
                   1221:        MIPS_SYS(sys_alarm      , 1)
                   1222:        MIPS_SYS(sys_ni_syscall , 0)    /* was sys_fstat */
                   1223:        MIPS_SYS(sys_pause      , 0)
                   1224:        MIPS_SYS(sys_utime      , 2)    /* 4030 */
                   1225:        MIPS_SYS(sys_ni_syscall , 0)
                   1226:        MIPS_SYS(sys_ni_syscall , 0)
                   1227:        MIPS_SYS(sys_access     , 2)
                   1228:        MIPS_SYS(sys_nice       , 1)
                   1229:        MIPS_SYS(sys_ni_syscall , 0)    /* 4035 */
                   1230:        MIPS_SYS(sys_sync       , 0)
                   1231:        MIPS_SYS(sys_kill       , 2)
                   1232:        MIPS_SYS(sys_rename     , 2)
                   1233:        MIPS_SYS(sys_mkdir      , 2)
                   1234:        MIPS_SYS(sys_rmdir      , 1)    /* 4040 */
                   1235:        MIPS_SYS(sys_dup                , 1)
                   1236:        MIPS_SYS(sys_pipe       , 0)
                   1237:        MIPS_SYS(sys_times      , 1)
                   1238:        MIPS_SYS(sys_ni_syscall , 0)
                   1239:        MIPS_SYS(sys_brk                , 1)    /* 4045 */
                   1240:        MIPS_SYS(sys_setgid     , 1)
                   1241:        MIPS_SYS(sys_getgid     , 0)
                   1242:        MIPS_SYS(sys_ni_syscall , 0)    /* was signal(2) */
                   1243:        MIPS_SYS(sys_geteuid    , 0)
                   1244:        MIPS_SYS(sys_getegid    , 0)    /* 4050 */
                   1245:        MIPS_SYS(sys_acct       , 0)
                   1246:        MIPS_SYS(sys_umount     , 2)
                   1247:        MIPS_SYS(sys_ni_syscall , 0)
                   1248:        MIPS_SYS(sys_ioctl      , 3)
                   1249:        MIPS_SYS(sys_fcntl      , 3)    /* 4055 */
                   1250:        MIPS_SYS(sys_ni_syscall , 2)
                   1251:        MIPS_SYS(sys_setpgid    , 2)
                   1252:        MIPS_SYS(sys_ni_syscall , 0)
                   1253:        MIPS_SYS(sys_olduname   , 1)
                   1254:        MIPS_SYS(sys_umask      , 1)    /* 4060 */
                   1255:        MIPS_SYS(sys_chroot     , 1)
                   1256:        MIPS_SYS(sys_ustat      , 2)
                   1257:        MIPS_SYS(sys_dup2       , 2)
                   1258:        MIPS_SYS(sys_getppid    , 0)
                   1259:        MIPS_SYS(sys_getpgrp    , 0)    /* 4065 */
                   1260:        MIPS_SYS(sys_setsid     , 0)
                   1261:        MIPS_SYS(sys_sigaction  , 3)
                   1262:        MIPS_SYS(sys_sgetmask   , 0)
                   1263:        MIPS_SYS(sys_ssetmask   , 1)
                   1264:        MIPS_SYS(sys_setreuid   , 2)    /* 4070 */
                   1265:        MIPS_SYS(sys_setregid   , 2)
                   1266:        MIPS_SYS(sys_sigsuspend , 0)
                   1267:        MIPS_SYS(sys_sigpending , 1)
                   1268:        MIPS_SYS(sys_sethostname        , 2)
                   1269:        MIPS_SYS(sys_setrlimit  , 2)    /* 4075 */
                   1270:        MIPS_SYS(sys_getrlimit  , 2)
                   1271:        MIPS_SYS(sys_getrusage  , 2)
                   1272:        MIPS_SYS(sys_gettimeofday, 2)
                   1273:        MIPS_SYS(sys_settimeofday, 2)
                   1274:        MIPS_SYS(sys_getgroups  , 2)    /* 4080 */
                   1275:        MIPS_SYS(sys_setgroups  , 2)
                   1276:        MIPS_SYS(sys_ni_syscall , 0)    /* old_select */
                   1277:        MIPS_SYS(sys_symlink    , 2)
                   1278:        MIPS_SYS(sys_ni_syscall , 0)    /* was sys_lstat */
                   1279:        MIPS_SYS(sys_readlink   , 3)    /* 4085 */
                   1280:        MIPS_SYS(sys_uselib     , 1)
                   1281:        MIPS_SYS(sys_swapon     , 2)
                   1282:        MIPS_SYS(sys_reboot     , 3)
                   1283:        MIPS_SYS(old_readdir    , 3)
                   1284:        MIPS_SYS(old_mmap       , 6)    /* 4090 */
                   1285:        MIPS_SYS(sys_munmap     , 2)
                   1286:        MIPS_SYS(sys_truncate   , 2)
                   1287:        MIPS_SYS(sys_ftruncate  , 2)
                   1288:        MIPS_SYS(sys_fchmod     , 2)
                   1289:        MIPS_SYS(sys_fchown     , 3)    /* 4095 */
                   1290:        MIPS_SYS(sys_getpriority        , 2)
                   1291:        MIPS_SYS(sys_setpriority        , 3)
                   1292:        MIPS_SYS(sys_ni_syscall , 0)
                   1293:        MIPS_SYS(sys_statfs     , 2)
                   1294:        MIPS_SYS(sys_fstatfs    , 2)    /* 4100 */
                   1295:        MIPS_SYS(sys_ni_syscall , 0)    /* was ioperm(2) */
                   1296:        MIPS_SYS(sys_socketcall , 2)
                   1297:        MIPS_SYS(sys_syslog     , 3)
                   1298:        MIPS_SYS(sys_setitimer  , 3)
                   1299:        MIPS_SYS(sys_getitimer  , 2)    /* 4105 */
                   1300:        MIPS_SYS(sys_newstat    , 2)
                   1301:        MIPS_SYS(sys_newlstat   , 2)
                   1302:        MIPS_SYS(sys_newfstat   , 2)
                   1303:        MIPS_SYS(sys_uname      , 1)
                   1304:        MIPS_SYS(sys_ni_syscall , 0)    /* 4110 was iopl(2) */
                   1305:        MIPS_SYS(sys_vhangup    , 0)
                   1306:        MIPS_SYS(sys_ni_syscall , 0)    /* was sys_idle() */
                   1307:        MIPS_SYS(sys_ni_syscall , 0)    /* was sys_vm86 */
                   1308:        MIPS_SYS(sys_wait4      , 4)
                   1309:        MIPS_SYS(sys_swapoff    , 1)    /* 4115 */
                   1310:        MIPS_SYS(sys_sysinfo    , 1)
                   1311:        MIPS_SYS(sys_ipc                , 6)
                   1312:        MIPS_SYS(sys_fsync      , 1)
                   1313:        MIPS_SYS(sys_sigreturn  , 0)
                   1314:        MIPS_SYS(sys_clone      , 0)    /* 4120 */
                   1315:        MIPS_SYS(sys_setdomainname, 2)
                   1316:        MIPS_SYS(sys_newuname   , 1)
                   1317:        MIPS_SYS(sys_ni_syscall , 0)    /* sys_modify_ldt */
                   1318:        MIPS_SYS(sys_adjtimex   , 1)
                   1319:        MIPS_SYS(sys_mprotect   , 3)    /* 4125 */
                   1320:        MIPS_SYS(sys_sigprocmask        , 3)
                   1321:        MIPS_SYS(sys_ni_syscall , 0)    /* was create_module */
                   1322:        MIPS_SYS(sys_init_module        , 5)
                   1323:        MIPS_SYS(sys_delete_module, 1)
                   1324:        MIPS_SYS(sys_ni_syscall , 0)    /* 4130 was get_kernel_syms */
                   1325:        MIPS_SYS(sys_quotactl   , 0)
                   1326:        MIPS_SYS(sys_getpgid    , 1)
                   1327:        MIPS_SYS(sys_fchdir     , 1)
                   1328:        MIPS_SYS(sys_bdflush    , 2)
                   1329:        MIPS_SYS(sys_sysfs      , 3)    /* 4135 */
                   1330:        MIPS_SYS(sys_personality        , 1)
                   1331:        MIPS_SYS(sys_ni_syscall , 0)    /* for afs_syscall */
                   1332:        MIPS_SYS(sys_setfsuid   , 1)
                   1333:        MIPS_SYS(sys_setfsgid   , 1)
                   1334:        MIPS_SYS(sys_llseek     , 5)    /* 4140 */
                   1335:        MIPS_SYS(sys_getdents   , 3)
                   1336:        MIPS_SYS(sys_select     , 5)
                   1337:        MIPS_SYS(sys_flock      , 2)
                   1338:        MIPS_SYS(sys_msync      , 3)
                   1339:        MIPS_SYS(sys_readv      , 3)    /* 4145 */
                   1340:        MIPS_SYS(sys_writev     , 3)
                   1341:        MIPS_SYS(sys_cacheflush , 3)
                   1342:        MIPS_SYS(sys_cachectl   , 3)
                   1343:        MIPS_SYS(sys_sysmips    , 4)
                   1344:        MIPS_SYS(sys_ni_syscall , 0)    /* 4150 */
                   1345:        MIPS_SYS(sys_getsid     , 1)
                   1346:        MIPS_SYS(sys_fdatasync  , 0)
                   1347:        MIPS_SYS(sys_sysctl     , 1)
                   1348:        MIPS_SYS(sys_mlock      , 2)
                   1349:        MIPS_SYS(sys_munlock    , 2)    /* 4155 */
                   1350:        MIPS_SYS(sys_mlockall   , 1)
                   1351:        MIPS_SYS(sys_munlockall , 0)
                   1352:        MIPS_SYS(sys_sched_setparam, 2)
                   1353:        MIPS_SYS(sys_sched_getparam, 2)
                   1354:        MIPS_SYS(sys_sched_setscheduler, 3)     /* 4160 */
                   1355:        MIPS_SYS(sys_sched_getscheduler, 1)
                   1356:        MIPS_SYS(sys_sched_yield        , 0)
                   1357:        MIPS_SYS(sys_sched_get_priority_max, 1)
                   1358:        MIPS_SYS(sys_sched_get_priority_min, 1)
                   1359:        MIPS_SYS(sys_sched_rr_get_interval, 2)  /* 4165 */
                   1360:        MIPS_SYS(sys_nanosleep, 2)
                   1361:        MIPS_SYS(sys_mremap     , 4)
                   1362:        MIPS_SYS(sys_accept     , 3)
                   1363:        MIPS_SYS(sys_bind       , 3)
                   1364:        MIPS_SYS(sys_connect    , 3)    /* 4170 */
                   1365:        MIPS_SYS(sys_getpeername        , 3)
                   1366:        MIPS_SYS(sys_getsockname        , 3)
                   1367:        MIPS_SYS(sys_getsockopt , 5)
                   1368:        MIPS_SYS(sys_listen     , 2)
                   1369:        MIPS_SYS(sys_recv       , 4)    /* 4175 */
                   1370:        MIPS_SYS(sys_recvfrom   , 6)
                   1371:        MIPS_SYS(sys_recvmsg    , 3)
                   1372:        MIPS_SYS(sys_send       , 4)
                   1373:        MIPS_SYS(sys_sendmsg    , 3)
                   1374:        MIPS_SYS(sys_sendto     , 6)    /* 4180 */
                   1375:        MIPS_SYS(sys_setsockopt , 5)
                   1376:        MIPS_SYS(sys_shutdown   , 2)
                   1377:        MIPS_SYS(sys_socket     , 3)
                   1378:        MIPS_SYS(sys_socketpair , 4)
                   1379:        MIPS_SYS(sys_setresuid  , 3)    /* 4185 */
                   1380:        MIPS_SYS(sys_getresuid  , 3)
                   1381:        MIPS_SYS(sys_ni_syscall , 0)    /* was sys_query_module */
                   1382:        MIPS_SYS(sys_poll       , 3)
                   1383:        MIPS_SYS(sys_nfsservctl , 3)
                   1384:        MIPS_SYS(sys_setresgid  , 3)    /* 4190 */
                   1385:        MIPS_SYS(sys_getresgid  , 3)
                   1386:        MIPS_SYS(sys_prctl      , 5)
                   1387:        MIPS_SYS(sys_rt_sigreturn, 0)
                   1388:        MIPS_SYS(sys_rt_sigaction, 4)
                   1389:        MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
                   1390:        MIPS_SYS(sys_rt_sigpending, 2)
                   1391:        MIPS_SYS(sys_rt_sigtimedwait, 4)
                   1392:        MIPS_SYS(sys_rt_sigqueueinfo, 3)
                   1393:        MIPS_SYS(sys_rt_sigsuspend, 0)
                   1394:        MIPS_SYS(sys_pread64    , 6)    /* 4200 */
                   1395:        MIPS_SYS(sys_pwrite64   , 6)
                   1396:        MIPS_SYS(sys_chown      , 3)
                   1397:        MIPS_SYS(sys_getcwd     , 2)
                   1398:        MIPS_SYS(sys_capget     , 2)
                   1399:        MIPS_SYS(sys_capset     , 2)    /* 4205 */
                   1400:        MIPS_SYS(sys_sigaltstack        , 0)
                   1401:        MIPS_SYS(sys_sendfile   , 4)
                   1402:        MIPS_SYS(sys_ni_syscall , 0)
                   1403:        MIPS_SYS(sys_ni_syscall , 0)
                   1404:        MIPS_SYS(sys_mmap2      , 6)    /* 4210 */
                   1405:        MIPS_SYS(sys_truncate64 , 4)
                   1406:        MIPS_SYS(sys_ftruncate64        , 4)
                   1407:        MIPS_SYS(sys_stat64     , 2)
                   1408:        MIPS_SYS(sys_lstat64    , 2)
                   1409:        MIPS_SYS(sys_fstat64    , 2)    /* 4215 */
                   1410:        MIPS_SYS(sys_pivot_root , 2)
                   1411:        MIPS_SYS(sys_mincore    , 3)
                   1412:        MIPS_SYS(sys_madvise    , 3)
                   1413:        MIPS_SYS(sys_getdents64 , 3)
                   1414:        MIPS_SYS(sys_fcntl64    , 3)    /* 4220 */
                   1415:        MIPS_SYS(sys_ni_syscall , 0)
                   1416:        MIPS_SYS(sys_gettid     , 0)
                   1417:        MIPS_SYS(sys_readahead  , 5)
                   1418:        MIPS_SYS(sys_setxattr   , 5)
                   1419:        MIPS_SYS(sys_lsetxattr  , 5)    /* 4225 */
                   1420:        MIPS_SYS(sys_fsetxattr  , 5)
                   1421:        MIPS_SYS(sys_getxattr   , 4)
                   1422:        MIPS_SYS(sys_lgetxattr  , 4)
                   1423:        MIPS_SYS(sys_fgetxattr  , 4)
                   1424:        MIPS_SYS(sys_listxattr  , 3)    /* 4230 */
                   1425:        MIPS_SYS(sys_llistxattr , 3)
                   1426:        MIPS_SYS(sys_flistxattr , 3)
                   1427:        MIPS_SYS(sys_removexattr        , 2)
                   1428:        MIPS_SYS(sys_lremovexattr, 2)
                   1429:        MIPS_SYS(sys_fremovexattr, 2)   /* 4235 */
                   1430:        MIPS_SYS(sys_tkill      , 2)
                   1431:        MIPS_SYS(sys_sendfile64 , 5)
                   1432:        MIPS_SYS(sys_futex      , 2)
                   1433:        MIPS_SYS(sys_sched_setaffinity, 3)
                   1434:        MIPS_SYS(sys_sched_getaffinity, 3)      /* 4240 */
                   1435:        MIPS_SYS(sys_io_setup   , 2)
                   1436:        MIPS_SYS(sys_io_destroy , 1)
                   1437:        MIPS_SYS(sys_io_getevents, 5)
                   1438:        MIPS_SYS(sys_io_submit  , 3)
                   1439:        MIPS_SYS(sys_io_cancel  , 3)    /* 4245 */
                   1440:        MIPS_SYS(sys_exit_group , 1)
                   1441:        MIPS_SYS(sys_lookup_dcookie, 3)
                   1442:        MIPS_SYS(sys_epoll_create, 1)
                   1443:        MIPS_SYS(sys_epoll_ctl  , 4)
                   1444:        MIPS_SYS(sys_epoll_wait , 3)    /* 4250 */
                   1445:        MIPS_SYS(sys_remap_file_pages, 5)
                   1446:        MIPS_SYS(sys_set_tid_address, 1)
                   1447:        MIPS_SYS(sys_restart_syscall, 0)
                   1448:        MIPS_SYS(sys_fadvise64_64, 7)
                   1449:        MIPS_SYS(sys_statfs64   , 3)    /* 4255 */
                   1450:        MIPS_SYS(sys_fstatfs64  , 2)
                   1451:        MIPS_SYS(sys_timer_create, 3)
                   1452:        MIPS_SYS(sys_timer_settime, 4)
                   1453:        MIPS_SYS(sys_timer_gettime, 2)
                   1454:        MIPS_SYS(sys_timer_getoverrun, 1)       /* 4260 */
                   1455:        MIPS_SYS(sys_timer_delete, 1)
                   1456:        MIPS_SYS(sys_clock_settime, 2)
                   1457:        MIPS_SYS(sys_clock_gettime, 2)
                   1458:        MIPS_SYS(sys_clock_getres, 2)
                   1459:        MIPS_SYS(sys_clock_nanosleep, 4)        /* 4265 */
                   1460:        MIPS_SYS(sys_tgkill     , 3)
                   1461:        MIPS_SYS(sys_utimes     , 2)
                   1462:        MIPS_SYS(sys_mbind      , 4)
                   1463:        MIPS_SYS(sys_ni_syscall , 0)    /* sys_get_mempolicy */
                   1464:        MIPS_SYS(sys_ni_syscall , 0)    /* 4270 sys_set_mempolicy */
                   1465:        MIPS_SYS(sys_mq_open    , 4)
                   1466:        MIPS_SYS(sys_mq_unlink  , 1)
                   1467:        MIPS_SYS(sys_mq_timedsend, 5)
                   1468:        MIPS_SYS(sys_mq_timedreceive, 5)
                   1469:        MIPS_SYS(sys_mq_notify  , 2)    /* 4275 */
                   1470:        MIPS_SYS(sys_mq_getsetattr, 3)
                   1471:        MIPS_SYS(sys_ni_syscall , 0)    /* sys_vserver */
                   1472:        MIPS_SYS(sys_waitid     , 4)
                   1473:        MIPS_SYS(sys_ni_syscall , 0)    /* available, was setaltroot */
                   1474:        MIPS_SYS(sys_add_key    , 5)
1.1.1.6 ! root     1475:        MIPS_SYS(sys_request_key, 4)
1.1.1.2   root     1476:        MIPS_SYS(sys_keyctl     , 5)
1.1.1.6 ! root     1477:        MIPS_SYS(sys_set_thread_area, 1)
        !          1478:        MIPS_SYS(sys_inotify_init, 0)
        !          1479:        MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
        !          1480:        MIPS_SYS(sys_inotify_rm_watch, 2)
        !          1481:        MIPS_SYS(sys_migrate_pages, 4)
        !          1482:        MIPS_SYS(sys_openat, 4)
        !          1483:        MIPS_SYS(sys_mkdirat, 3)
        !          1484:        MIPS_SYS(sys_mknodat, 4)        /* 4290 */
        !          1485:        MIPS_SYS(sys_fchownat, 5)
        !          1486:        MIPS_SYS(sys_futimesat, 3)
        !          1487:        MIPS_SYS(sys_fstatat64, 4)
        !          1488:        MIPS_SYS(sys_unlinkat, 3)
        !          1489:        MIPS_SYS(sys_renameat, 4)       /* 4295 */
        !          1490:        MIPS_SYS(sys_linkat, 5)
        !          1491:        MIPS_SYS(sys_symlinkat, 3)
        !          1492:        MIPS_SYS(sys_readlinkat, 4)
        !          1493:        MIPS_SYS(sys_fchmodat, 3)
        !          1494:        MIPS_SYS(sys_faccessat, 3)      /* 4300 */
        !          1495:        MIPS_SYS(sys_pselect6, 6)
        !          1496:        MIPS_SYS(sys_ppoll, 5)
        !          1497:        MIPS_SYS(sys_unshare, 1)
        !          1498:        MIPS_SYS(sys_splice, 4)
        !          1499:        MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
        !          1500:        MIPS_SYS(sys_tee, 4)
        !          1501:        MIPS_SYS(sys_vmsplice, 4)
        !          1502:        MIPS_SYS(sys_move_pages, 6)
        !          1503:        MIPS_SYS(sys_set_robust_list, 2)
        !          1504:        MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
        !          1505:        MIPS_SYS(sys_kexec_load, 4)
        !          1506:        MIPS_SYS(sys_getcpu, 3)
        !          1507:        MIPS_SYS(sys_epoll_pwait, 6)
        !          1508:        MIPS_SYS(sys_ioprio_set, 3)
        !          1509:        MIPS_SYS(sys_ioprio_get, 2)
1.1.1.2   root     1510: };
                   1511: 
                   1512: #undef MIPS_SYS
                   1513: 
                   1514: void cpu_loop(CPUMIPSState *env)
                   1515: {
                   1516:     target_siginfo_t info;
1.1.1.6 ! root     1517:     int trapnr, ret;
1.1.1.2   root     1518:     unsigned int syscall_num;
                   1519: 
                   1520:     for(;;) {
                   1521:         trapnr = cpu_mips_exec(env);
                   1522:         switch(trapnr) {
                   1523:         case EXCP_SYSCALL:
1.1.1.6 ! root     1524:             syscall_num = env->gpr[2][env->current_tc] - 4000;
        !          1525:             env->PC[env->current_tc] += 4;
        !          1526:             if (syscall_num >= sizeof(mips_syscall_args)) {
        !          1527:                 ret = -ENOSYS;
        !          1528:             } else {
        !          1529:                 int nb_args;
        !          1530:                 abi_ulong sp_reg;
        !          1531:                 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
        !          1532: 
        !          1533:                 nb_args = mips_syscall_args[syscall_num];
        !          1534:                 sp_reg = env->gpr[29][env->current_tc];
        !          1535:                 switch (nb_args) {
        !          1536:                 /* these arguments are taken from the stack */
        !          1537:                 /* FIXME - what to do if get_user() fails? */
        !          1538:                 case 8: get_user_ual(arg8, sp_reg + 28);
        !          1539:                 case 7: get_user_ual(arg7, sp_reg + 24);
        !          1540:                 case 6: get_user_ual(arg6, sp_reg + 20);
        !          1541:                 case 5: get_user_ual(arg5, sp_reg + 16);
        !          1542:                 default:
        !          1543:                     break;
1.1.1.2   root     1544:                 }
1.1.1.6 ! root     1545:                 ret = do_syscall(env, env->gpr[2][env->current_tc],
        !          1546:                                  env->gpr[4][env->current_tc],
        !          1547:                                  env->gpr[5][env->current_tc],
        !          1548:                                  env->gpr[6][env->current_tc],
        !          1549:                                  env->gpr[7][env->current_tc],
        !          1550:                                  arg5, arg6/*, arg7, arg8*/);
        !          1551:             }
        !          1552:             if ((unsigned int)ret >= (unsigned int)(-1133)) {
        !          1553:                 env->gpr[7][env->current_tc] = 1; /* error flag */
        !          1554:                 ret = -ret;
        !          1555:             } else {
        !          1556:                 env->gpr[7][env->current_tc] = 0; /* error flag */
1.1.1.2   root     1557:             }
1.1.1.6 ! root     1558:             env->gpr[2][env->current_tc] = ret;
1.1.1.2   root     1559:             break;
1.1.1.5   root     1560:         case EXCP_TLBL:
                   1561:         case EXCP_TLBS:
1.1.1.2   root     1562:         case EXCP_CpU:
                   1563:         case EXCP_RI:
1.1.1.4   root     1564:             info.si_signo = TARGET_SIGILL;
                   1565:             info.si_errno = 0;
                   1566:             info.si_code = 0;
                   1567:             queue_signal(info.si_signo, &info);
                   1568:             break;
                   1569:         case EXCP_INTERRUPT:
                   1570:             /* just indicate that signals should be handled asap */
1.1.1.2   root     1571:             break;
1.1.1.5   root     1572:         case EXCP_DEBUG:
                   1573:             {
                   1574:                 int sig;
                   1575: 
                   1576:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                   1577:                 if (sig)
                   1578:                   {
                   1579:                     info.si_signo = sig;
                   1580:                     info.si_errno = 0;
                   1581:                     info.si_code = TARGET_TRAP_BRKPT;
                   1582:                     queue_signal(info.si_signo, &info);
                   1583:                   }
                   1584:             }
                   1585:             break;
1.1.1.2   root     1586:         default:
                   1587:             //        error:
1.1.1.6 ! root     1588:             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1.1.1.2   root     1589:                     trapnr);
                   1590:             cpu_dump_state(env, stderr, fprintf, 0);
                   1591:             abort();
                   1592:         }
                   1593:         process_pending_signals(env);
                   1594:     }
                   1595: }
                   1596: #endif
                   1597: 
1.1.1.3   root     1598: #ifdef TARGET_SH4
                   1599: void cpu_loop (CPUState *env)
                   1600: {
                   1601:     int trapnr, ret;
1.1.1.4   root     1602:     target_siginfo_t info;
1.1.1.6 ! root     1603: 
1.1.1.3   root     1604:     while (1) {
                   1605:         trapnr = cpu_sh4_exec (env);
1.1.1.6 ! root     1606: 
1.1.1.3   root     1607:         switch (trapnr) {
                   1608:         case 0x160:
1.1.1.6 ! root     1609:             ret = do_syscall(env,
        !          1610:                              env->gregs[3],
        !          1611:                              env->gregs[4],
        !          1612:                              env->gregs[5],
        !          1613:                              env->gregs[6],
        !          1614:                              env->gregs[7],
        !          1615:                              env->gregs[0],
        !          1616:                              env->gregs[1]);
1.1.1.4   root     1617:             env->gregs[0] = ret;
1.1.1.3   root     1618:             env->pc += 2;
                   1619:             break;
1.1.1.6 ! root     1620:         case EXCP_INTERRUPT:
        !          1621:             /* just indicate that signals should be handled asap */
        !          1622:             break;
        !          1623:         case EXCP_DEBUG:
        !          1624:             {
        !          1625:                 int sig;
        !          1626: 
        !          1627:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
        !          1628:                 if (sig)
        !          1629:                   {
        !          1630:                     info.si_signo = sig;
        !          1631:                     info.si_errno = 0;
        !          1632:                     info.si_code = TARGET_TRAP_BRKPT;
        !          1633:                     queue_signal(info.si_signo, &info);
        !          1634:                   }
        !          1635:             }
        !          1636:             break;
        !          1637:        case 0xa0:
        !          1638:        case 0xc0:
        !          1639:             info.si_signo = SIGSEGV;
        !          1640:             info.si_errno = 0;
        !          1641:             info.si_code = TARGET_SEGV_MAPERR;
        !          1642:             info._sifields._sigfault._addr = env->tea;
        !          1643:             queue_signal(info.si_signo, &info);
        !          1644:            break;
        !          1645: 
        !          1646:         default:
        !          1647:             printf ("Unhandled trap: 0x%x\n", trapnr);
        !          1648:             cpu_dump_state(env, stderr, fprintf, 0);
        !          1649:             exit (1);
        !          1650:         }
        !          1651:         process_pending_signals (env);
        !          1652:     }
        !          1653: }
        !          1654: #endif
        !          1655: 
        !          1656: #ifdef TARGET_CRIS
        !          1657: void cpu_loop (CPUState *env)
        !          1658: {
        !          1659:     int trapnr, ret;
        !          1660:     target_siginfo_t info;
        !          1661:     
        !          1662:     while (1) {
        !          1663:         trapnr = cpu_cris_exec (env);
        !          1664:         switch (trapnr) {
        !          1665:         case 0xaa:
        !          1666:             {
        !          1667:                 info.si_signo = SIGSEGV;
        !          1668:                 info.si_errno = 0;
        !          1669:                 /* XXX: check env->error_code */
        !          1670:                 info.si_code = TARGET_SEGV_MAPERR;
        !          1671:                 info._sifields._sigfault._addr = env->debug1;
        !          1672:                 queue_signal(info.si_signo, &info);
        !          1673:             }
        !          1674:             break;
        !          1675:         case EXCP_BREAK:
        !          1676:             ret = do_syscall(env, 
        !          1677:                              env->regs[9], 
        !          1678:                              env->regs[10], 
        !          1679:                              env->regs[11], 
        !          1680:                              env->regs[12], 
        !          1681:                              env->regs[13], 
        !          1682:                              env->pregs[7], 
        !          1683:                              env->pregs[11]);
        !          1684:             env->regs[10] = ret;
        !          1685:             env->pc += 2;
        !          1686:             break;
1.1.1.4   root     1687:         case EXCP_DEBUG:
                   1688:             {
                   1689:                 int sig;
                   1690: 
                   1691:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                   1692:                 if (sig)
                   1693:                   {
                   1694:                     info.si_signo = sig;
                   1695:                     info.si_errno = 0;
                   1696:                     info.si_code = TARGET_TRAP_BRKPT;
                   1697:                     queue_signal(info.si_signo, &info);
                   1698:                   }
                   1699:             }
                   1700:             break;
1.1.1.3   root     1701:         default:
                   1702:             printf ("Unhandled trap: 0x%x\n", trapnr);
                   1703:             cpu_dump_state(env, stderr, fprintf, 0);
                   1704:             exit (1);
                   1705:         }
                   1706:         process_pending_signals (env);
                   1707:     }
                   1708: }
                   1709: #endif
                   1710: 
1.1.1.5   root     1711: #ifdef TARGET_M68K
                   1712: 
                   1713: void cpu_loop(CPUM68KState *env)
                   1714: {
                   1715:     int trapnr;
                   1716:     unsigned int n;
                   1717:     target_siginfo_t info;
                   1718:     TaskState *ts = env->opaque;
1.1.1.6 ! root     1719: 
1.1.1.5   root     1720:     for(;;) {
                   1721:         trapnr = cpu_m68k_exec(env);
                   1722:         switch(trapnr) {
                   1723:         case EXCP_ILLEGAL:
                   1724:             {
                   1725:                 if (ts->sim_syscalls) {
                   1726:                     uint16_t nr;
                   1727:                     nr = lduw(env->pc + 2);
                   1728:                     env->pc += 4;
                   1729:                     do_m68k_simcall(env, nr);
                   1730:                 } else {
                   1731:                     goto do_sigill;
                   1732:                 }
                   1733:             }
                   1734:             break;
1.1.1.6 ! root     1735:         case EXCP_HALT_INSN:
1.1.1.5   root     1736:             /* Semihosing syscall.  */
1.1.1.6 ! root     1737:             env->pc += 4;
1.1.1.5   root     1738:             do_m68k_semihosting(env, env->dregs[0]);
                   1739:             break;
                   1740:         case EXCP_LINEA:
                   1741:         case EXCP_LINEF:
                   1742:         case EXCP_UNSUPPORTED:
                   1743:         do_sigill:
                   1744:             info.si_signo = SIGILL;
                   1745:             info.si_errno = 0;
                   1746:             info.si_code = TARGET_ILL_ILLOPN;
                   1747:             info._sifields._sigfault._addr = env->pc;
                   1748:             queue_signal(info.si_signo, &info);
                   1749:             break;
                   1750:         case EXCP_TRAP0:
                   1751:             {
                   1752:                 ts->sim_syscalls = 0;
                   1753:                 n = env->dregs[0];
                   1754:                 env->pc += 2;
1.1.1.6 ! root     1755:                 env->dregs[0] = do_syscall(env,
        !          1756:                                           n,
1.1.1.5   root     1757:                                           env->dregs[1],
                   1758:                                           env->dregs[2],
                   1759:                                           env->dregs[3],
                   1760:                                           env->dregs[4],
                   1761:                                           env->dregs[5],
                   1762:                                           env->dregs[6]);
                   1763:             }
                   1764:             break;
                   1765:         case EXCP_INTERRUPT:
                   1766:             /* just indicate that signals should be handled asap */
                   1767:             break;
                   1768:         case EXCP_ACCESS:
                   1769:             {
                   1770:                 info.si_signo = SIGSEGV;
                   1771:                 info.si_errno = 0;
                   1772:                 /* XXX: check env->error_code */
                   1773:                 info.si_code = TARGET_SEGV_MAPERR;
                   1774:                 info._sifields._sigfault._addr = env->mmu.ar;
                   1775:                 queue_signal(info.si_signo, &info);
                   1776:             }
                   1777:             break;
                   1778:         case EXCP_DEBUG:
                   1779:             {
                   1780:                 int sig;
                   1781: 
                   1782:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                   1783:                 if (sig)
                   1784:                   {
                   1785:                     info.si_signo = sig;
                   1786:                     info.si_errno = 0;
                   1787:                     info.si_code = TARGET_TRAP_BRKPT;
                   1788:                     queue_signal(info.si_signo, &info);
                   1789:                   }
                   1790:             }
                   1791:             break;
                   1792:         default:
1.1.1.6 ! root     1793:             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1.1.1.5   root     1794:                     trapnr);
                   1795:             cpu_dump_state(env, stderr, fprintf, 0);
                   1796:             abort();
                   1797:         }
                   1798:         process_pending_signals(env);
                   1799:     }
                   1800: }
                   1801: #endif /* TARGET_M68K */
                   1802: 
1.1.1.6 ! root     1803: #ifdef TARGET_ALPHA
        !          1804: void cpu_loop (CPUState *env)
        !          1805: {
        !          1806:     int trapnr;
        !          1807:     target_siginfo_t info;
        !          1808: 
        !          1809:     while (1) {
        !          1810:         trapnr = cpu_alpha_exec (env);
        !          1811: 
        !          1812:         switch (trapnr) {
        !          1813:         case EXCP_RESET:
        !          1814:             fprintf(stderr, "Reset requested. Exit\n");
        !          1815:             exit(1);
        !          1816:             break;
        !          1817:         case EXCP_MCHK:
        !          1818:             fprintf(stderr, "Machine check exception. Exit\n");
        !          1819:             exit(1);
        !          1820:             break;
        !          1821:         case EXCP_ARITH:
        !          1822:             fprintf(stderr, "Arithmetic trap.\n");
        !          1823:             exit(1);
        !          1824:             break;
        !          1825:         case EXCP_HW_INTERRUPT:
        !          1826:             fprintf(stderr, "External interrupt. Exit\n");
        !          1827:             exit(1);
        !          1828:             break;
        !          1829:         case EXCP_DFAULT:
        !          1830:             fprintf(stderr, "MMU data fault\n");
        !          1831:             exit(1);
        !          1832:             break;
        !          1833:         case EXCP_DTB_MISS_PAL:
        !          1834:             fprintf(stderr, "MMU data TLB miss in PALcode\n");
        !          1835:             exit(1);
        !          1836:             break;
        !          1837:         case EXCP_ITB_MISS:
        !          1838:             fprintf(stderr, "MMU instruction TLB miss\n");
        !          1839:             exit(1);
        !          1840:             break;
        !          1841:         case EXCP_ITB_ACV:
        !          1842:             fprintf(stderr, "MMU instruction access violation\n");
        !          1843:             exit(1);
        !          1844:             break;
        !          1845:         case EXCP_DTB_MISS_NATIVE:
        !          1846:             fprintf(stderr, "MMU data TLB miss\n");
        !          1847:             exit(1);
        !          1848:             break;
        !          1849:         case EXCP_UNALIGN:
        !          1850:             fprintf(stderr, "Unaligned access\n");
        !          1851:             exit(1);
        !          1852:             break;
        !          1853:         case EXCP_OPCDEC:
        !          1854:             fprintf(stderr, "Invalid instruction\n");
        !          1855:             exit(1);
        !          1856:             break;
        !          1857:         case EXCP_FEN:
        !          1858:             fprintf(stderr, "Floating-point not allowed\n");
        !          1859:             exit(1);
        !          1860:             break;
        !          1861:         case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
        !          1862:             fprintf(stderr, "Call to PALcode\n");
        !          1863:             call_pal(env, (trapnr >> 6) | 0x80);
        !          1864:             break;
        !          1865:         case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
        !          1866:             fprintf(stderr, "Privileged call to PALcode\n");
        !          1867:             exit(1);
        !          1868:             break;
        !          1869:         case EXCP_DEBUG:
        !          1870:             {
        !          1871:                 int sig;
        !          1872: 
        !          1873:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
        !          1874:                 if (sig)
        !          1875:                   {
        !          1876:                     info.si_signo = sig;
        !          1877:                     info.si_errno = 0;
        !          1878:                     info.si_code = TARGET_TRAP_BRKPT;
        !          1879:                     queue_signal(info.si_signo, &info);
        !          1880:                   }
        !          1881:             }
        !          1882:             break;
        !          1883:         default:
        !          1884:             printf ("Unhandled trap: 0x%x\n", trapnr);
        !          1885:             cpu_dump_state(env, stderr, fprintf, 0);
        !          1886:             exit (1);
        !          1887:         }
        !          1888:         process_pending_signals (env);
        !          1889:     }
        !          1890: }
        !          1891: #endif /* TARGET_ALPHA */
        !          1892: 
1.1       root     1893: void usage(void)
                   1894: {
1.1.1.6 ! root     1895:     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
        !          1896:            "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
1.1       root     1897:            "Linux CPU emulator (compiled for %s emulation)\n"
                   1898:            "\n"
1.1.1.6 ! root     1899:            "Standard options:\n"
        !          1900:            "-h                print this help\n"
        !          1901:            "-g port           wait gdb connection to port\n"
        !          1902:            "-L path           set the elf interpreter prefix (default=%s)\n"
        !          1903:            "-s size           set the stack size in bytes (default=%ld)\n"
        !          1904:            "-cpu model        select CPU (-cpu ? for list)\n"
        !          1905:            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
1.1       root     1906:            "\n"
1.1.1.6 ! root     1907:            "Debug options:\n"
1.1       root     1908:            "-d options   activate log (logfile=%s)\n"
1.1.1.6 ! root     1909:            "-p pagesize  set the host page size to 'pagesize'\n"
        !          1910:            "-strace      log system calls\n"
        !          1911:            "\n"
        !          1912:            "Environment variables:\n"
        !          1913:            "QEMU_STRACE       Print system calls and arguments similar to the\n"
        !          1914:            "                  'strace' program.  Enable by setting to any value.\n"
        !          1915:            ,
1.1       root     1916:            TARGET_ARCH,
1.1.1.6 ! root     1917:            interp_prefix,
1.1       root     1918:            x86_stack_size,
                   1919:            DEBUG_LOGFILE);
                   1920:     _exit(1);
                   1921: }
                   1922: 
                   1923: /* XXX: currently only used for async signals (see signal.c) */
                   1924: CPUState *global_env;
                   1925: 
                   1926: /* used to free thread contexts */
                   1927: TaskState *first_task_state;
                   1928: 
                   1929: int main(int argc, char **argv)
                   1930: {
                   1931:     const char *filename;
1.1.1.6 ! root     1932:     const char *cpu_model;
1.1       root     1933:     struct target_pt_regs regs1, *regs = &regs1;
                   1934:     struct image_info info1, *info = &info1;
                   1935:     TaskState ts1, *ts = &ts1;
                   1936:     CPUState *env;
                   1937:     int optind;
                   1938:     const char *r;
1.1.1.2   root     1939:     int gdbstub_port = 0;
1.1.1.6 ! root     1940:     int drop_ld_preload = 0, environ_count = 0;
        !          1941:     char **target_environ, **wrk, **dst;
        !          1942: 
1.1       root     1943:     if (argc <= 1)
                   1944:         usage();
                   1945: 
                   1946:     /* init debug */
                   1947:     cpu_set_log_filename(DEBUG_LOGFILE);
                   1948: 
1.1.1.6 ! root     1949:     cpu_model = NULL;
1.1       root     1950:     optind = 1;
                   1951:     for(;;) {
                   1952:         if (optind >= argc)
                   1953:             break;
                   1954:         r = argv[optind];
                   1955:         if (r[0] != '-')
                   1956:             break;
                   1957:         optind++;
                   1958:         r++;
                   1959:         if (!strcmp(r, "-")) {
                   1960:             break;
                   1961:         } else if (!strcmp(r, "d")) {
                   1962:             int mask;
                   1963:             CPULogItem *item;
                   1964: 
                   1965:            if (optind >= argc)
                   1966:                break;
1.1.1.6 ! root     1967: 
1.1       root     1968:            r = argv[optind++];
                   1969:             mask = cpu_str_to_log_mask(r);
                   1970:             if (!mask) {
                   1971:                 printf("Log items (comma separated):\n");
                   1972:                 for(item = cpu_log_items; item->mask != 0; item++) {
                   1973:                     printf("%-10s %s\n", item->name, item->help);
                   1974:                 }
                   1975:                 exit(1);
                   1976:             }
                   1977:             cpu_set_log(mask);
                   1978:         } else if (!strcmp(r, "s")) {
                   1979:             r = argv[optind++];
                   1980:             x86_stack_size = strtol(r, (char **)&r, 0);
                   1981:             if (x86_stack_size <= 0)
                   1982:                 usage();
                   1983:             if (*r == 'M')
                   1984:                 x86_stack_size *= 1024 * 1024;
                   1985:             else if (*r == 'k' || *r == 'K')
                   1986:                 x86_stack_size *= 1024;
                   1987:         } else if (!strcmp(r, "L")) {
                   1988:             interp_prefix = argv[optind++];
                   1989:         } else if (!strcmp(r, "p")) {
                   1990:             qemu_host_page_size = atoi(argv[optind++]);
                   1991:             if (qemu_host_page_size == 0 ||
                   1992:                 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
                   1993:                 fprintf(stderr, "page size must be a power of two\n");
                   1994:                 exit(1);
                   1995:             }
                   1996:         } else if (!strcmp(r, "g")) {
1.1.1.2   root     1997:             gdbstub_port = atoi(argv[optind++]);
1.1.1.4   root     1998:        } else if (!strcmp(r, "r")) {
                   1999:            qemu_uname_release = argv[optind++];
1.1.1.6 ! root     2000:         } else if (!strcmp(r, "cpu")) {
        !          2001:             cpu_model = argv[optind++];
        !          2002:             if (strcmp(cpu_model, "?") == 0) {
        !          2003: /* XXX: implement xxx_cpu_list for targets that still miss it */
        !          2004: #if defined(cpu_list)
        !          2005:                     cpu_list(stdout, &fprintf);
        !          2006: #endif
        !          2007:                 _exit(1);
        !          2008:             }
        !          2009:         } else if (!strcmp(r, "drop-ld-preload")) {
        !          2010:             drop_ld_preload = 1;
        !          2011:         } else if (!strcmp(r, "strace")) {
        !          2012:             do_strace = 1;
        !          2013:         } else
1.1       root     2014:         {
                   2015:             usage();
                   2016:         }
                   2017:     }
                   2018:     if (optind >= argc)
                   2019:         usage();
                   2020:     filename = argv[optind];
                   2021: 
                   2022:     /* Zero out regs */
                   2023:     memset(regs, 0, sizeof(struct target_pt_regs));
                   2024: 
                   2025:     /* Zero out image_info */
                   2026:     memset(info, 0, sizeof(struct image_info));
                   2027: 
                   2028:     /* Scan interp_prefix dir for replacement files. */
                   2029:     init_paths(interp_prefix);
                   2030: 
1.1.1.6 ! root     2031:     if (cpu_model == NULL) {
        !          2032: #if defined(TARGET_I386)
        !          2033: #ifdef TARGET_X86_64
        !          2034:         cpu_model = "qemu64";
        !          2035: #else
        !          2036:         cpu_model = "qemu32";
        !          2037: #endif
        !          2038: #elif defined(TARGET_ARM)
        !          2039:         cpu_model = "arm926";
        !          2040: #elif defined(TARGET_M68K)
        !          2041:         cpu_model = "any";
        !          2042: #elif defined(TARGET_SPARC)
        !          2043: #ifdef TARGET_SPARC64
        !          2044:         cpu_model = "TI UltraSparc II";
        !          2045: #else
        !          2046:         cpu_model = "Fujitsu MB86904";
        !          2047: #endif
        !          2048: #elif defined(TARGET_MIPS)
        !          2049: #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
        !          2050:         cpu_model = "20Kc";
        !          2051: #else
        !          2052:         cpu_model = "24Kf";
        !          2053: #endif
        !          2054: #elif defined(TARGET_PPC)
        !          2055: #ifdef TARGET_PPC64
        !          2056:         cpu_model = "970";
        !          2057: #else
        !          2058:         cpu_model = "750";
        !          2059: #endif
        !          2060: #else
        !          2061:         cpu_model = "any";
        !          2062: #endif
        !          2063:     }
1.1       root     2064:     /* NOTE: we need to init the CPU at this stage to get
                   2065:        qemu_host_page_size */
1.1.1.6 ! root     2066:     env = cpu_init(cpu_model);
        !          2067:     if (!env) {
        !          2068:         fprintf(stderr, "Unable to find CPU definition\n");
        !          2069:         exit(1);
        !          2070:     }
1.1.1.2   root     2071:     global_env = env;
1.1.1.6 ! root     2072: 
        !          2073:     if (getenv("QEMU_STRACE")) {
        !          2074:         do_strace = 1;
1.1       root     2075:     }
1.1.1.6 ! root     2076: 
        !          2077:     wrk = environ;
        !          2078:     while (*(wrk++))
        !          2079:         environ_count++;
        !          2080: 
        !          2081:     target_environ = malloc((environ_count + 1) * sizeof(char *));
        !          2082:     if (!target_environ)
        !          2083:         abort();
        !          2084:     for (wrk = environ, dst = target_environ; *wrk; wrk++) {
        !          2085:         if (drop_ld_preload && !strncmp(*wrk, "LD_PRELOAD=", 11))
        !          2086:             continue;
        !          2087:         *(dst++) = strdup(*wrk);
        !          2088:     }
        !          2089:     *dst = NULL; /* NULL terminate target_environ */
        !          2090: 
        !          2091:     if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
        !          2092:         printf("Error loading %s\n", filename);
        !          2093:         _exit(1);
        !          2094:     }
        !          2095: 
        !          2096:     for (wrk = target_environ; *wrk; wrk++) {
        !          2097:         free(*wrk);
        !          2098:     }
        !          2099: 
        !          2100:     free(target_environ);
        !          2101: 
1.1       root     2102:     if (loglevel) {
                   2103:         page_dump(logfile);
1.1.1.6 ! root     2104: 
        !          2105:         fprintf(logfile, "start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
        !          2106:         fprintf(logfile, "end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
        !          2107:         fprintf(logfile, "start_code  0x" TARGET_ABI_FMT_lx "\n",
        !          2108:                 info->start_code);
        !          2109:         fprintf(logfile, "start_data  0x" TARGET_ABI_FMT_lx "\n",
        !          2110:                 info->start_data);
        !          2111:         fprintf(logfile, "end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
        !          2112:         fprintf(logfile, "start_stack 0x" TARGET_ABI_FMT_lx "\n",
        !          2113:                 info->start_stack);
        !          2114:         fprintf(logfile, "brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
        !          2115:         fprintf(logfile, "entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
1.1       root     2116:     }
                   2117: 
1.1.1.3   root     2118:     target_set_brk(info->brk);
1.1       root     2119:     syscall_init();
                   2120:     signal_init();
                   2121: 
                   2122:     /* build Task State */
                   2123:     memset(ts, 0, sizeof(TaskState));
                   2124:     env->opaque = ts;
                   2125:     ts->used = 1;
1.1.1.4   root     2126:     ts->info = info;
1.1       root     2127:     env->user_mode_only = 1;
1.1.1.6 ! root     2128: 
1.1       root     2129: #if defined(TARGET_I386)
                   2130:     cpu_x86_set_cpl(env, 3);
                   2131: 
                   2132:     env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
                   2133:     env->hflags |= HF_PE_MASK;
                   2134:     if (env->cpuid_features & CPUID_SSE) {
                   2135:         env->cr[4] |= CR4_OSFXSR_MASK;
                   2136:         env->hflags |= HF_OSFXSR_MASK;
                   2137:     }
1.1.1.6 ! root     2138: #ifndef TARGET_ABI32
        !          2139:     /* enable 64 bit mode if possible */
        !          2140:     if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
        !          2141:         fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
        !          2142:         exit(1);
        !          2143:     }
        !          2144:     env->cr[4] |= CR4_PAE_MASK;
        !          2145:     env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
        !          2146:     env->hflags |= HF_LMA_MASK;
        !          2147: #endif
1.1       root     2148: 
                   2149:     /* flags setup : we activate the IRQs by default as in user mode */
                   2150:     env->eflags |= IF_MASK;
1.1.1.6 ! root     2151: 
1.1       root     2152:     /* linux register setup */
1.1.1.6 ! root     2153: #ifndef TARGET_ABI32
        !          2154:     env->regs[R_EAX] = regs->rax;
        !          2155:     env->regs[R_EBX] = regs->rbx;
        !          2156:     env->regs[R_ECX] = regs->rcx;
        !          2157:     env->regs[R_EDX] = regs->rdx;
        !          2158:     env->regs[R_ESI] = regs->rsi;
        !          2159:     env->regs[R_EDI] = regs->rdi;
        !          2160:     env->regs[R_EBP] = regs->rbp;
        !          2161:     env->regs[R_ESP] = regs->rsp;
        !          2162:     env->eip = regs->rip;
        !          2163: #else
1.1       root     2164:     env->regs[R_EAX] = regs->eax;
                   2165:     env->regs[R_EBX] = regs->ebx;
                   2166:     env->regs[R_ECX] = regs->ecx;
                   2167:     env->regs[R_EDX] = regs->edx;
                   2168:     env->regs[R_ESI] = regs->esi;
                   2169:     env->regs[R_EDI] = regs->edi;
                   2170:     env->regs[R_EBP] = regs->ebp;
                   2171:     env->regs[R_ESP] = regs->esp;
                   2172:     env->eip = regs->eip;
1.1.1.6 ! root     2173: #endif
1.1       root     2174: 
                   2175:     /* linux interrupt setup */
1.1.1.3   root     2176:     env->idt.base = h2g(idt_table);
1.1       root     2177:     env->idt.limit = sizeof(idt_table) - 1;
                   2178:     set_idt(0, 0);
                   2179:     set_idt(1, 0);
                   2180:     set_idt(2, 0);
                   2181:     set_idt(3, 3);
                   2182:     set_idt(4, 3);
                   2183:     set_idt(5, 3);
                   2184:     set_idt(6, 0);
                   2185:     set_idt(7, 0);
                   2186:     set_idt(8, 0);
                   2187:     set_idt(9, 0);
                   2188:     set_idt(10, 0);
                   2189:     set_idt(11, 0);
                   2190:     set_idt(12, 0);
                   2191:     set_idt(13, 0);
                   2192:     set_idt(14, 0);
                   2193:     set_idt(15, 0);
                   2194:     set_idt(16, 0);
                   2195:     set_idt(17, 0);
                   2196:     set_idt(18, 0);
                   2197:     set_idt(19, 0);
                   2198:     set_idt(0x80, 3);
                   2199: 
                   2200:     /* linux segment setup */
1.1.1.6 ! root     2201:     {
        !          2202:         uint64_t *gdt_table;
        !          2203:         gdt_table = qemu_mallocz(sizeof(uint64_t) * TARGET_GDT_ENTRIES);
        !          2204:         env->gdt.base = h2g((unsigned long)gdt_table);
        !          2205:         env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
        !          2206: #ifdef TARGET_ABI32
        !          2207:         write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
        !          2208:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
        !          2209:                  (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
        !          2210: #else
        !          2211:         /* 64 bit code segment */
        !          2212:         write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
        !          2213:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
        !          2214:                  DESC_L_MASK |
        !          2215:                  (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
        !          2216: #endif
        !          2217:         write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
        !          2218:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
        !          2219:                  (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
        !          2220:     }
1.1       root     2221:     cpu_x86_load_seg(env, R_CS, __USER_CS);
1.1.1.6 ! root     2222:     cpu_x86_load_seg(env, R_SS, __USER_DS);
        !          2223: #ifdef TARGET_ABI32
1.1       root     2224:     cpu_x86_load_seg(env, R_DS, __USER_DS);
                   2225:     cpu_x86_load_seg(env, R_ES, __USER_DS);
                   2226:     cpu_x86_load_seg(env, R_FS, __USER_DS);
                   2227:     cpu_x86_load_seg(env, R_GS, __USER_DS);
1.1.1.6 ! root     2228:     /* This hack makes Wine work... */
        !          2229:     env->segs[R_FS].selector = 0;
        !          2230: #else
        !          2231:     cpu_x86_load_seg(env, R_DS, 0);
        !          2232:     cpu_x86_load_seg(env, R_ES, 0);
        !          2233:     cpu_x86_load_seg(env, R_FS, 0);
        !          2234:     cpu_x86_load_seg(env, R_GS, 0);
        !          2235: #endif
1.1       root     2236: #elif defined(TARGET_ARM)
                   2237:     {
                   2238:         int i;
1.1.1.2   root     2239:         cpsr_write(env, regs->uregs[16], 0xffffffff);
1.1       root     2240:         for(i = 0; i < 16; i++) {
                   2241:             env->regs[i] = regs->uregs[i];
                   2242:         }
                   2243:     }
                   2244: #elif defined(TARGET_SPARC)
                   2245:     {
                   2246:         int i;
                   2247:        env->pc = regs->pc;
                   2248:        env->npc = regs->npc;
                   2249:         env->y = regs->y;
                   2250:         for(i = 0; i < 8; i++)
                   2251:             env->gregs[i] = regs->u_regs[i];
                   2252:         for(i = 0; i < 8; i++)
                   2253:             env->regwptr[i] = regs->u_regs[i + 8];
                   2254:     }
                   2255: #elif defined(TARGET_PPC)
                   2256:     {
                   2257:         int i;
                   2258: 
1.1.1.6 ! root     2259: #if defined(TARGET_PPC64)
        !          2260: #if defined(TARGET_ABI32)
        !          2261:         env->msr &= ~((target_ulong)1 << MSR_SF);
        !          2262: #else
        !          2263:         env->msr |= (target_ulong)1 << MSR_SF;
        !          2264: #endif
        !          2265: #endif
1.1       root     2266:         env->nip = regs->nip;
                   2267:         for(i = 0; i < 32; i++) {
                   2268:             env->gpr[i] = regs->gpr[i];
                   2269:         }
                   2270:     }
1.1.1.5   root     2271: #elif defined(TARGET_M68K)
                   2272:     {
                   2273:         env->pc = regs->pc;
                   2274:         env->dregs[0] = regs->d0;
                   2275:         env->dregs[1] = regs->d1;
                   2276:         env->dregs[2] = regs->d2;
                   2277:         env->dregs[3] = regs->d3;
                   2278:         env->dregs[4] = regs->d4;
                   2279:         env->dregs[5] = regs->d5;
                   2280:         env->dregs[6] = regs->d6;
                   2281:         env->dregs[7] = regs->d7;
                   2282:         env->aregs[0] = regs->a0;
                   2283:         env->aregs[1] = regs->a1;
                   2284:         env->aregs[2] = regs->a2;
                   2285:         env->aregs[3] = regs->a3;
                   2286:         env->aregs[4] = regs->a4;
                   2287:         env->aregs[5] = regs->a5;
                   2288:         env->aregs[6] = regs->a6;
                   2289:         env->aregs[7] = regs->usp;
                   2290:         env->sr = regs->sr;
                   2291:         ts->sim_syscalls = 1;
                   2292:     }
1.1.1.2   root     2293: #elif defined(TARGET_MIPS)
                   2294:     {
                   2295:         int i;
                   2296: 
                   2297:         for(i = 0; i < 32; i++) {
1.1.1.6 ! root     2298:             env->gpr[i][env->current_tc] = regs->regs[i];
1.1.1.2   root     2299:         }
1.1.1.6 ! root     2300:         env->PC[env->current_tc] = regs->cp0_epc;
1.1.1.2   root     2301:     }
1.1.1.3   root     2302: #elif defined(TARGET_SH4)
                   2303:     {
                   2304:         int i;
                   2305: 
                   2306:         for(i = 0; i < 16; i++) {
                   2307:             env->gregs[i] = regs->regs[i];
                   2308:         }
                   2309:         env->pc = regs->pc;
                   2310:     }
1.1.1.6 ! root     2311: #elif defined(TARGET_ALPHA)
        !          2312:     {
        !          2313:         int i;
        !          2314: 
        !          2315:         for(i = 0; i < 28; i++) {
        !          2316:             env->ir[i] = ((abi_ulong *)regs)[i];
        !          2317:         }
        !          2318:         env->ipr[IPR_USP] = regs->usp;
        !          2319:         env->ir[30] = regs->usp;
        !          2320:         env->pc = regs->pc;
        !          2321:         env->unique = regs->unique;
        !          2322:     }
        !          2323: #elif defined(TARGET_CRIS)
        !          2324:     {
        !          2325:            env->regs[0] = regs->r0;
        !          2326:            env->regs[1] = regs->r1;
        !          2327:            env->regs[2] = regs->r2;
        !          2328:            env->regs[3] = regs->r3;
        !          2329:            env->regs[4] = regs->r4;
        !          2330:            env->regs[5] = regs->r5;
        !          2331:            env->regs[6] = regs->r6;
        !          2332:            env->regs[7] = regs->r7;
        !          2333:            env->regs[8] = regs->r8;
        !          2334:            env->regs[9] = regs->r9;
        !          2335:            env->regs[10] = regs->r10;
        !          2336:            env->regs[11] = regs->r11;
        !          2337:            env->regs[12] = regs->r12;
        !          2338:            env->regs[13] = regs->r13;
        !          2339:            env->regs[14] = info->start_stack;
        !          2340:            env->regs[15] = regs->acr;      
        !          2341:            env->pc = regs->erp;
        !          2342:     }
1.1       root     2343: #else
                   2344: #error unsupported target CPU
                   2345: #endif
                   2346: 
1.1.1.6 ! root     2347: #if defined(TARGET_ARM) || defined(TARGET_M68K)
        !          2348:     ts->stack_base = info->start_stack;
        !          2349:     ts->heap_base = info->brk;
        !          2350:     /* This will be filled in on the first SYS_HEAPINFO call.  */
        !          2351:     ts->heap_limit = 0;
        !          2352: #endif
        !          2353: 
1.1.1.2   root     2354:     if (gdbstub_port) {
                   2355:         gdbserver_start (gdbstub_port);
1.1       root     2356:         gdb_handlesig(env, 0);
                   2357:     }
                   2358:     cpu_loop(env);
                   2359:     /* never exits */
                   2360:     return 0;
                   2361: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.