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