Statistics
| Branch: | Revision:

root / linux-user / main.c @ 0b959cf5

History | View | Annotate | Download (132.9 kB)

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