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

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

unix.superglobalmegacorp.com

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