Statistics
| Branch: | Revision:

root / linux-user / main.c @ ef5b2344

History | View | Annotate | Download (122.3 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 902b3d5c malc
#include "cache-utils.h"
32 2b41f10e Blue Swirl
#include "cpu.h"
33 9002ec79 Richard Henderson
#include "tcg.h"
34 29e922b6 Blue Swirl
#include "qemu-timer.h"
35 04a6dfeb aurel32
#include "envlist.h"
36 d8fd2954 Paul Brook
#include "elf.h"
37 04a6dfeb aurel32
38 3ef693a0 bellard
#define DEBUG_LOGFILE "/tmp/qemu.log"
39 586314f2 bellard
40 d088d664 aurel32
char *exec_path;
41 d088d664 aurel32
42 1b530a6d aurel32
int singlestep;
43 fc9c5412 Johannes Schauer
const char *filename;
44 fc9c5412 Johannes Schauer
const char *argv0;
45 fc9c5412 Johannes Schauer
int gdbstub_port;
46 fc9c5412 Johannes Schauer
envlist_t *envlist;
47 fc9c5412 Johannes Schauer
const char *cpu_model;
48 379f6698 Paul Brook
unsigned long mmap_min_addr;
49 14f24e14 Richard Henderson
#if defined(CONFIG_USE_GUEST_BASE)
50 379f6698 Paul Brook
unsigned long guest_base;
51 379f6698 Paul Brook
int have_guest_base;
52 288e65b9 Alexander Graf
#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
53 288e65b9 Alexander Graf
/*
54 288e65b9 Alexander Graf
 * When running 32-on-64 we should make sure we can fit all of the possible
55 288e65b9 Alexander Graf
 * guest address space into a contiguous chunk of virtual host memory.
56 288e65b9 Alexander Graf
 *
57 288e65b9 Alexander Graf
 * This way we will never overlap with our own libraries or binaries or stack
58 288e65b9 Alexander Graf
 * or anything else that QEMU maps.
59 288e65b9 Alexander Graf
 */
60 288e65b9 Alexander Graf
unsigned long reserved_va = 0xf7000000;
61 288e65b9 Alexander Graf
#else
62 68a1c816 Paul Brook
unsigned long reserved_va;
63 379f6698 Paul Brook
#endif
64 288e65b9 Alexander Graf
#endif
65 1b530a6d aurel32
66 fc9c5412 Johannes Schauer
static void usage(void);
67 fc9c5412 Johannes Schauer
68 7ee2822c Paolo Bonzini
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
69 c5937220 pbrook
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
70 586314f2 bellard
71 9de5e440 bellard
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
72 9de5e440 bellard
   we allocate a bigger stack. Need a better solution, for example
73 9de5e440 bellard
   by remapping the process stack directly at the right place */
74 703e0e89 Richard Henderson
unsigned long guest_stack_size = 8 * 1024 * 1024UL;
75 31e31b8a bellard
76 31e31b8a bellard
void gemu_log(const char *fmt, ...)
77 31e31b8a bellard
{
78 31e31b8a bellard
    va_list ap;
79 31e31b8a bellard
80 31e31b8a bellard
    va_start(ap, fmt);
81 31e31b8a bellard
    vfprintf(stderr, fmt, ap);
82 31e31b8a bellard
    va_end(ap);
83 31e31b8a bellard
}
84 31e31b8a bellard
85 8fcd3692 blueswir1
#if defined(TARGET_I386)
86 05390248 Andreas Färber
int cpu_get_pic_interrupt(CPUX86State *env)
87 92ccca6a bellard
{
88 92ccca6a bellard
    return -1;
89 92ccca6a bellard
}
90 8fcd3692 blueswir1
#endif
91 92ccca6a bellard
92 28ab0e2e bellard
/* timers for rdtsc */
93 28ab0e2e bellard
94 1dce7c3c bellard
#if 0
95 28ab0e2e bellard

96 28ab0e2e bellard
static uint64_t emu_time;
97 28ab0e2e bellard

98 28ab0e2e bellard
int64_t cpu_get_real_ticks(void)
99 28ab0e2e bellard
{
100 28ab0e2e bellard
    return emu_time++;
101 28ab0e2e bellard
}
102 28ab0e2e bellard

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