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