Statistics
| Branch: | Revision:

root / linux-user / main.c @ 93148aa5

History | View | Annotate | Download (118.4 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 04a6dfeb aurel32
37 3ef693a0 bellard
#define DEBUG_LOGFILE "/tmp/qemu.log"
38 586314f2 bellard
39 d088d664 aurel32
char *exec_path;
40 d088d664 aurel32
41 1b530a6d aurel32
int singlestep;
42 fc9c5412 Johannes Schauer
const char *filename;
43 fc9c5412 Johannes Schauer
const char *argv0;
44 fc9c5412 Johannes Schauer
int gdbstub_port;
45 fc9c5412 Johannes Schauer
envlist_t *envlist;
46 fc9c5412 Johannes Schauer
const char *cpu_model;
47 379f6698 Paul Brook
unsigned long mmap_min_addr;
48 14f24e14 Richard Henderson
#if defined(CONFIG_USE_GUEST_BASE)
49 379f6698 Paul Brook
unsigned long guest_base;
50 379f6698 Paul Brook
int have_guest_base;
51 68a1c816 Paul Brook
unsigned long reserved_va;
52 379f6698 Paul Brook
#endif
53 1b530a6d aurel32
54 fc9c5412 Johannes Schauer
static void usage(void);
55 fc9c5412 Johannes Schauer
56 7ee2822c Paolo Bonzini
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
57 c5937220 pbrook
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
58 586314f2 bellard
59 9de5e440 bellard
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
60 9de5e440 bellard
   we allocate a bigger stack. Need a better solution, for example
61 9de5e440 bellard
   by remapping the process stack directly at the right place */
62 703e0e89 Richard Henderson
unsigned long guest_stack_size = 8 * 1024 * 1024UL;
63 31e31b8a bellard
64 31e31b8a bellard
void gemu_log(const char *fmt, ...)
65 31e31b8a bellard
{
66 31e31b8a bellard
    va_list ap;
67 31e31b8a bellard
68 31e31b8a bellard
    va_start(ap, fmt);
69 31e31b8a bellard
    vfprintf(stderr, fmt, ap);
70 31e31b8a bellard
    va_end(ap);
71 31e31b8a bellard
}
72 31e31b8a bellard
73 8fcd3692 blueswir1
#if defined(TARGET_I386)
74 a541f297 bellard
int cpu_get_pic_interrupt(CPUState *env)
75 92ccca6a bellard
{
76 92ccca6a bellard
    return -1;
77 92ccca6a bellard
}
78 8fcd3692 blueswir1
#endif
79 92ccca6a bellard
80 28ab0e2e bellard
/* timers for rdtsc */
81 28ab0e2e bellard
82 1dce7c3c bellard
#if 0
83 28ab0e2e bellard

84 28ab0e2e bellard
static uint64_t emu_time;
85 28ab0e2e bellard

86 28ab0e2e bellard
int64_t cpu_get_real_ticks(void)
87 28ab0e2e bellard
{
88 28ab0e2e bellard
    return emu_time++;
89 28ab0e2e bellard
}
90 28ab0e2e bellard

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