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

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

unix.superglobalmegacorp.com

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