Statistics
| Branch: | Revision:

root / bsd-user / main.c @ 753d11f2

History | View | Annotate | Download (35 kB)

1 84778508 blueswir1
/*
2 84778508 blueswir1
 *  qemu user main
3 84778508 blueswir1
 *
4 84778508 blueswir1
 *  Copyright (c) 2003-2008 Fabrice Bellard
5 84778508 blueswir1
 *
6 84778508 blueswir1
 *  This program is free software; you can redistribute it and/or modify
7 84778508 blueswir1
 *  it under the terms of the GNU General Public License as published by
8 84778508 blueswir1
 *  the Free Software Foundation; either version 2 of the License, or
9 84778508 blueswir1
 *  (at your option) any later version.
10 84778508 blueswir1
 *
11 84778508 blueswir1
 *  This program is distributed in the hope that it will be useful,
12 84778508 blueswir1
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 84778508 blueswir1
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 84778508 blueswir1
 *  GNU General Public License for more details.
15 84778508 blueswir1
 *
16 84778508 blueswir1
 *  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 84778508 blueswir1
 */
19 84778508 blueswir1
#include <stdlib.h>
20 84778508 blueswir1
#include <stdio.h>
21 84778508 blueswir1
#include <stdarg.h>
22 84778508 blueswir1
#include <string.h>
23 84778508 blueswir1
#include <errno.h>
24 84778508 blueswir1
#include <unistd.h>
25 84778508 blueswir1
#include <machine/trap.h>
26 31fc12df blueswir1
#include <sys/types.h>
27 31fc12df blueswir1
#include <sys/mman.h>
28 84778508 blueswir1
29 84778508 blueswir1
#include "qemu.h"
30 84778508 blueswir1
#include "qemu-common.h"
31 84778508 blueswir1
/* For tb_lock */
32 2b41f10e Blue Swirl
#include "cpu.h"
33 9002ec79 Richard Henderson
#include "tcg.h"
34 2ae144c9 Blue Swirl
#include "qemu-timer.h"
35 fc0d96b4 Blue Swirl
#include "envlist.h"
36 fc0d96b4 Blue Swirl
37 84778508 blueswir1
#define DEBUG_LOGFILE "/tmp/qemu.log"
38 84778508 blueswir1
39 1b530a6d aurel32
int singlestep;
40 2fa5d9ba Blue Swirl
#if defined(CONFIG_USE_GUEST_BASE)
41 2fa5d9ba Blue Swirl
unsigned long mmap_min_addr;
42 2fa5d9ba Blue Swirl
unsigned long guest_base;
43 2fa5d9ba Blue Swirl
int have_guest_base;
44 2fa5d9ba Blue Swirl
#endif
45 1b530a6d aurel32
46 7ee2822c Paolo Bonzini
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
47 84778508 blueswir1
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
48 84778508 blueswir1
extern char **environ;
49 78cfb07f Juergen Lock
enum BSDType bsd_type;
50 84778508 blueswir1
51 84778508 blueswir1
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
52 84778508 blueswir1
   we allocate a bigger stack. Need a better solution, for example
53 84778508 blueswir1
   by remapping the process stack directly at the right place */
54 84778508 blueswir1
unsigned long x86_stack_size = 512 * 1024;
55 84778508 blueswir1
56 84778508 blueswir1
void gemu_log(const char *fmt, ...)
57 84778508 blueswir1
{
58 84778508 blueswir1
    va_list ap;
59 84778508 blueswir1
60 84778508 blueswir1
    va_start(ap, fmt);
61 84778508 blueswir1
    vfprintf(stderr, fmt, ap);
62 84778508 blueswir1
    va_end(ap);
63 84778508 blueswir1
}
64 9399f095 blueswir1
65 31fc12df blueswir1
#if defined(TARGET_I386)
66 31fc12df blueswir1
int cpu_get_pic_interrupt(CPUState *env)
67 31fc12df blueswir1
{
68 31fc12df blueswir1
    return -1;
69 31fc12df blueswir1
}
70 31fc12df blueswir1
#endif
71 31fc12df blueswir1
72 9399f095 blueswir1
/* These are no-ops because we are not threadsafe.  */
73 9399f095 blueswir1
static inline void cpu_exec_start(CPUState *env)
74 9399f095 blueswir1
{
75 9399f095 blueswir1
}
76 9399f095 blueswir1
77 9399f095 blueswir1
static inline void cpu_exec_end(CPUState *env)
78 9399f095 blueswir1
{
79 9399f095 blueswir1
}
80 9399f095 blueswir1
81 9399f095 blueswir1
static inline void start_exclusive(void)
82 9399f095 blueswir1
{
83 9399f095 blueswir1
}
84 9399f095 blueswir1
85 9399f095 blueswir1
static inline void end_exclusive(void)
86 9399f095 blueswir1
{
87 9399f095 blueswir1
}
88 9399f095 blueswir1
89 9399f095 blueswir1
void fork_start(void)
90 9399f095 blueswir1
{
91 9399f095 blueswir1
}
92 9399f095 blueswir1
93 9399f095 blueswir1
void fork_end(int child)
94 9399f095 blueswir1
{
95 9399f095 blueswir1
    if (child) {
96 9399f095 blueswir1
        gdbserver_fork(thread_env);
97 9399f095 blueswir1
    }
98 9399f095 blueswir1
}
99 9399f095 blueswir1
100 9399f095 blueswir1
void cpu_list_lock(void)
101 9399f095 blueswir1
{
102 9399f095 blueswir1
}
103 9399f095 blueswir1
104 9399f095 blueswir1
void cpu_list_unlock(void)
105 9399f095 blueswir1
{
106 9399f095 blueswir1
}
107 9399f095 blueswir1
108 31fc12df blueswir1
#ifdef TARGET_I386
109 31fc12df blueswir1
/***********************************************************/
110 31fc12df blueswir1
/* CPUX86 core interface */
111 31fc12df blueswir1
112 31fc12df blueswir1
void cpu_smm_update(CPUState *env)
113 31fc12df blueswir1
{
114 31fc12df blueswir1
}
115 31fc12df blueswir1
116 31fc12df blueswir1
uint64_t cpu_get_tsc(CPUX86State *env)
117 31fc12df blueswir1
{
118 31fc12df blueswir1
    return cpu_get_real_ticks();
119 31fc12df blueswir1
}
120 31fc12df blueswir1
121 31fc12df blueswir1
static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
122 31fc12df blueswir1
                     int flags)
123 31fc12df blueswir1
{
124 31fc12df blueswir1
    unsigned int e1, e2;
125 31fc12df blueswir1
    uint32_t *p;
126 31fc12df blueswir1
    e1 = (addr << 16) | (limit & 0xffff);
127 31fc12df blueswir1
    e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
128 31fc12df blueswir1
    e2 |= flags;
129 31fc12df blueswir1
    p = ptr;
130 31fc12df blueswir1
    p[0] = tswap32(e1);
131 31fc12df blueswir1
    p[1] = tswap32(e2);
132 31fc12df blueswir1
}
133 31fc12df blueswir1
134 31fc12df blueswir1
static uint64_t *idt_table;
135 31fc12df blueswir1
#ifdef TARGET_X86_64
136 31fc12df blueswir1
static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
137 31fc12df blueswir1
                       uint64_t addr, unsigned int sel)
138 31fc12df blueswir1
{
139 31fc12df blueswir1
    uint32_t *p, e1, e2;
140 31fc12df blueswir1
    e1 = (addr & 0xffff) | (sel << 16);
141 31fc12df blueswir1
    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
142 31fc12df blueswir1
    p = ptr;
143 31fc12df blueswir1
    p[0] = tswap32(e1);
144 31fc12df blueswir1
    p[1] = tswap32(e2);
145 31fc12df blueswir1
    p[2] = tswap32(addr >> 32);
146 31fc12df blueswir1
    p[3] = 0;
147 31fc12df blueswir1
}
148 31fc12df blueswir1
/* only dpl matters as we do only user space emulation */
149 31fc12df blueswir1
static void set_idt(int n, unsigned int dpl)
150 31fc12df blueswir1
{
151 31fc12df blueswir1
    set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
152 31fc12df blueswir1
}
153 31fc12df blueswir1
#else
154 31fc12df blueswir1
static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
155 31fc12df blueswir1
                     uint32_t addr, unsigned int sel)
156 31fc12df blueswir1
{
157 31fc12df blueswir1
    uint32_t *p, e1, e2;
158 31fc12df blueswir1
    e1 = (addr & 0xffff) | (sel << 16);
159 31fc12df blueswir1
    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
160 31fc12df blueswir1
    p = ptr;
161 31fc12df blueswir1
    p[0] = tswap32(e1);
162 31fc12df blueswir1
    p[1] = tswap32(e2);
163 31fc12df blueswir1
}
164 31fc12df blueswir1
165 31fc12df blueswir1
/* only dpl matters as we do only user space emulation */
166 31fc12df blueswir1
static void set_idt(int n, unsigned int dpl)
167 31fc12df blueswir1
{
168 31fc12df blueswir1
    set_gate(idt_table + n, 0, dpl, 0, 0);
169 31fc12df blueswir1
}
170 31fc12df blueswir1
#endif
171 31fc12df blueswir1
172 78cfb07f Juergen Lock
void cpu_loop(CPUX86State *env)
173 31fc12df blueswir1
{
174 31fc12df blueswir1
    int trapnr;
175 31fc12df blueswir1
    abi_ulong pc;
176 31fc12df blueswir1
    //target_siginfo_t info;
177 31fc12df blueswir1
178 31fc12df blueswir1
    for(;;) {
179 31fc12df blueswir1
        trapnr = cpu_x86_exec(env);
180 31fc12df blueswir1
        switch(trapnr) {
181 31fc12df blueswir1
        case 0x80:
182 31fc12df blueswir1
            /* syscall from int $0x80 */
183 78cfb07f Juergen Lock
            if (bsd_type == target_freebsd) {
184 78cfb07f Juergen Lock
                abi_ulong params = (abi_ulong) env->regs[R_ESP] +
185 78cfb07f Juergen Lock
                    sizeof(int32_t);
186 78cfb07f Juergen Lock
                int32_t syscall_nr = env->regs[R_EAX];
187 78cfb07f Juergen Lock
                int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
188 78cfb07f Juergen Lock
189 78cfb07f Juergen Lock
                if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
190 78cfb07f Juergen Lock
                    get_user_s32(syscall_nr, params);
191 78cfb07f Juergen Lock
                    params += sizeof(int32_t);
192 78cfb07f Juergen Lock
                } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
193 78cfb07f Juergen Lock
                    get_user_s32(syscall_nr, params);
194 78cfb07f Juergen Lock
                    params += sizeof(int64_t);
195 78cfb07f Juergen Lock
                }
196 78cfb07f Juergen Lock
                get_user_s32(arg1, params);
197 78cfb07f Juergen Lock
                params += sizeof(int32_t);
198 78cfb07f Juergen Lock
                get_user_s32(arg2, params);
199 78cfb07f Juergen Lock
                params += sizeof(int32_t);
200 78cfb07f Juergen Lock
                get_user_s32(arg3, params);
201 78cfb07f Juergen Lock
                params += sizeof(int32_t);
202 78cfb07f Juergen Lock
                get_user_s32(arg4, params);
203 78cfb07f Juergen Lock
                params += sizeof(int32_t);
204 78cfb07f Juergen Lock
                get_user_s32(arg5, params);
205 78cfb07f Juergen Lock
                params += sizeof(int32_t);
206 78cfb07f Juergen Lock
                get_user_s32(arg6, params);
207 78cfb07f Juergen Lock
                params += sizeof(int32_t);
208 78cfb07f Juergen Lock
                get_user_s32(arg7, params);
209 78cfb07f Juergen Lock
                params += sizeof(int32_t);
210 78cfb07f Juergen Lock
                get_user_s32(arg8, params);
211 78cfb07f Juergen Lock
                env->regs[R_EAX] = do_freebsd_syscall(env,
212 78cfb07f Juergen Lock
                                                      syscall_nr,
213 78cfb07f Juergen Lock
                                                      arg1,
214 78cfb07f Juergen Lock
                                                      arg2,
215 78cfb07f Juergen Lock
                                                      arg3,
216 78cfb07f Juergen Lock
                                                      arg4,
217 78cfb07f Juergen Lock
                                                      arg5,
218 78cfb07f Juergen Lock
                                                      arg6,
219 78cfb07f Juergen Lock
                                                      arg7,
220 78cfb07f Juergen Lock
                                                      arg8);
221 78cfb07f Juergen Lock
            } else { //if (bsd_type == target_openbsd)
222 78cfb07f Juergen Lock
                env->regs[R_EAX] = do_openbsd_syscall(env,
223 78cfb07f Juergen Lock
                                                      env->regs[R_EAX],
224 78cfb07f Juergen Lock
                                                      env->regs[R_EBX],
225 78cfb07f Juergen Lock
                                                      env->regs[R_ECX],
226 78cfb07f Juergen Lock
                                                      env->regs[R_EDX],
227 78cfb07f Juergen Lock
                                                      env->regs[R_ESI],
228 78cfb07f Juergen Lock
                                                      env->regs[R_EDI],
229 78cfb07f Juergen Lock
                                                      env->regs[R_EBP]);
230 78cfb07f Juergen Lock
            }
231 78cfb07f Juergen Lock
            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
232 78cfb07f Juergen Lock
                env->regs[R_EAX] = -env->regs[R_EAX];
233 78cfb07f Juergen Lock
                env->eflags |= CC_C;
234 78cfb07f Juergen Lock
            } else {
235 78cfb07f Juergen Lock
                env->eflags &= ~CC_C;
236 78cfb07f Juergen Lock
            }
237 31fc12df blueswir1
            break;
238 31fc12df blueswir1
#ifndef TARGET_ABI32
239 31fc12df blueswir1
        case EXCP_SYSCALL:
240 5ba18547 Stefan Weil
            /* syscall from syscall instruction */
241 78cfb07f Juergen Lock
            if (bsd_type == target_freebsd)
242 78cfb07f Juergen Lock
                env->regs[R_EAX] = do_freebsd_syscall(env,
243 78cfb07f Juergen Lock
                                                      env->regs[R_EAX],
244 78cfb07f Juergen Lock
                                                      env->regs[R_EDI],
245 78cfb07f Juergen Lock
                                                      env->regs[R_ESI],
246 78cfb07f Juergen Lock
                                                      env->regs[R_EDX],
247 78cfb07f Juergen Lock
                                                      env->regs[R_ECX],
248 78cfb07f Juergen Lock
                                                      env->regs[8],
249 78cfb07f Juergen Lock
                                                      env->regs[9], 0, 0);
250 78cfb07f Juergen Lock
            else { //if (bsd_type == target_openbsd)
251 78cfb07f Juergen Lock
                env->regs[R_EAX] = do_openbsd_syscall(env,
252 78cfb07f Juergen Lock
                                                      env->regs[R_EAX],
253 78cfb07f Juergen Lock
                                                      env->regs[R_EDI],
254 78cfb07f Juergen Lock
                                                      env->regs[R_ESI],
255 78cfb07f Juergen Lock
                                                      env->regs[R_EDX],
256 78cfb07f Juergen Lock
                                                      env->regs[10],
257 78cfb07f Juergen Lock
                                                      env->regs[8],
258 78cfb07f Juergen Lock
                                                      env->regs[9]);
259 78cfb07f Juergen Lock
            }
260 31fc12df blueswir1
            env->eip = env->exception_next_eip;
261 78cfb07f Juergen Lock
            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
262 78cfb07f Juergen Lock
                env->regs[R_EAX] = -env->regs[R_EAX];
263 78cfb07f Juergen Lock
                env->eflags |= CC_C;
264 78cfb07f Juergen Lock
            } else {
265 78cfb07f Juergen Lock
                env->eflags &= ~CC_C;
266 78cfb07f Juergen Lock
            }
267 31fc12df blueswir1
            break;
268 31fc12df blueswir1
#endif
269 31fc12df blueswir1
#if 0
270 31fc12df blueswir1
        case EXCP0B_NOSEG:
271 31fc12df blueswir1
        case EXCP0C_STACK:
272 31fc12df blueswir1
            info.si_signo = SIGBUS;
273 31fc12df blueswir1
            info.si_errno = 0;
274 31fc12df blueswir1
            info.si_code = TARGET_SI_KERNEL;
275 31fc12df blueswir1
            info._sifields._sigfault._addr = 0;
276 31fc12df blueswir1
            queue_signal(env, info.si_signo, &info);
277 31fc12df blueswir1
            break;
278 31fc12df blueswir1
        case EXCP0D_GPF:
279 31fc12df blueswir1
            /* XXX: potential problem if ABI32 */
280 31fc12df blueswir1
#ifndef TARGET_X86_64
281 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
282 31fc12df blueswir1
                handle_vm86_fault(env);
283 31fc12df blueswir1
            } else
284 31fc12df blueswir1
#endif
285 31fc12df blueswir1
            {
286 31fc12df blueswir1
                info.si_signo = SIGSEGV;
287 31fc12df blueswir1
                info.si_errno = 0;
288 31fc12df blueswir1
                info.si_code = TARGET_SI_KERNEL;
289 31fc12df blueswir1
                info._sifields._sigfault._addr = 0;
290 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
291 31fc12df blueswir1
            }
292 31fc12df blueswir1
            break;
293 31fc12df blueswir1
        case EXCP0E_PAGE:
294 31fc12df blueswir1
            info.si_signo = SIGSEGV;
295 31fc12df blueswir1
            info.si_errno = 0;
296 31fc12df blueswir1
            if (!(env->error_code & 1))
297 31fc12df blueswir1
                info.si_code = TARGET_SEGV_MAPERR;
298 31fc12df blueswir1
            else
299 31fc12df blueswir1
                info.si_code = TARGET_SEGV_ACCERR;
300 31fc12df blueswir1
            info._sifields._sigfault._addr = env->cr[2];
301 31fc12df blueswir1
            queue_signal(env, info.si_signo, &info);
302 31fc12df blueswir1
            break;
303 31fc12df blueswir1
        case EXCP00_DIVZ:
304 31fc12df blueswir1
#ifndef TARGET_X86_64
305 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
306 31fc12df blueswir1
                handle_vm86_trap(env, trapnr);
307 31fc12df blueswir1
            } else
308 31fc12df blueswir1
#endif
309 31fc12df blueswir1
            {
310 31fc12df blueswir1
                /* division by zero */
311 31fc12df blueswir1
                info.si_signo = SIGFPE;
312 31fc12df blueswir1
                info.si_errno = 0;
313 31fc12df blueswir1
                info.si_code = TARGET_FPE_INTDIV;
314 31fc12df blueswir1
                info._sifields._sigfault._addr = env->eip;
315 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
316 31fc12df blueswir1
            }
317 31fc12df blueswir1
            break;
318 31fc12df blueswir1
        case EXCP01_DB:
319 31fc12df blueswir1
        case EXCP03_INT3:
320 31fc12df blueswir1
#ifndef TARGET_X86_64
321 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
322 31fc12df blueswir1
                handle_vm86_trap(env, trapnr);
323 31fc12df blueswir1
            } else
324 31fc12df blueswir1
#endif
325 31fc12df blueswir1
            {
326 31fc12df blueswir1
                info.si_signo = SIGTRAP;
327 31fc12df blueswir1
                info.si_errno = 0;
328 31fc12df blueswir1
                if (trapnr == EXCP01_DB) {
329 31fc12df blueswir1
                    info.si_code = TARGET_TRAP_BRKPT;
330 31fc12df blueswir1
                    info._sifields._sigfault._addr = env->eip;
331 31fc12df blueswir1
                } else {
332 31fc12df blueswir1
                    info.si_code = TARGET_SI_KERNEL;
333 31fc12df blueswir1
                    info._sifields._sigfault._addr = 0;
334 31fc12df blueswir1
                }
335 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
336 31fc12df blueswir1
            }
337 31fc12df blueswir1
            break;
338 31fc12df blueswir1
        case EXCP04_INTO:
339 31fc12df blueswir1
        case EXCP05_BOUND:
340 31fc12df blueswir1
#ifndef TARGET_X86_64
341 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
342 31fc12df blueswir1
                handle_vm86_trap(env, trapnr);
343 31fc12df blueswir1
            } else
344 31fc12df blueswir1
#endif
345 31fc12df blueswir1
            {
346 31fc12df blueswir1
                info.si_signo = SIGSEGV;
347 31fc12df blueswir1
                info.si_errno = 0;
348 31fc12df blueswir1
                info.si_code = TARGET_SI_KERNEL;
349 31fc12df blueswir1
                info._sifields._sigfault._addr = 0;
350 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
351 31fc12df blueswir1
            }
352 31fc12df blueswir1
            break;
353 31fc12df blueswir1
        case EXCP06_ILLOP:
354 31fc12df blueswir1
            info.si_signo = SIGILL;
355 31fc12df blueswir1
            info.si_errno = 0;
356 31fc12df blueswir1
            info.si_code = TARGET_ILL_ILLOPN;
357 31fc12df blueswir1
            info._sifields._sigfault._addr = env->eip;
358 31fc12df blueswir1
            queue_signal(env, info.si_signo, &info);
359 31fc12df blueswir1
            break;
360 31fc12df blueswir1
#endif
361 31fc12df blueswir1
        case EXCP_INTERRUPT:
362 31fc12df blueswir1
            /* just indicate that signals should be handled asap */
363 31fc12df blueswir1
            break;
364 31fc12df blueswir1
#if 0
365 31fc12df blueswir1
        case EXCP_DEBUG:
366 31fc12df blueswir1
            {
367 31fc12df blueswir1
                int sig;
368 31fc12df blueswir1

369 31fc12df blueswir1
                sig = gdb_handlesig (env, TARGET_SIGTRAP);
370 31fc12df blueswir1
                if (sig)
371 31fc12df blueswir1
                  {
372 31fc12df blueswir1
                    info.si_signo = sig;
373 31fc12df blueswir1
                    info.si_errno = 0;
374 31fc12df blueswir1
                    info.si_code = TARGET_TRAP_BRKPT;
375 31fc12df blueswir1
                    queue_signal(env, info.si_signo, &info);
376 31fc12df blueswir1
                  }
377 31fc12df blueswir1
            }
378 31fc12df blueswir1
            break;
379 31fc12df blueswir1
#endif
380 31fc12df blueswir1
        default:
381 31fc12df blueswir1
            pc = env->segs[R_CS].base + env->eip;
382 31fc12df blueswir1
            fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
383 31fc12df blueswir1
                    (long)pc, trapnr);
384 31fc12df blueswir1
            abort();
385 31fc12df blueswir1
        }
386 31fc12df blueswir1
        process_pending_signals(env);
387 31fc12df blueswir1
    }
388 31fc12df blueswir1
}
389 31fc12df blueswir1
#endif
390 31fc12df blueswir1
391 84778508 blueswir1
#ifdef TARGET_SPARC
392 84778508 blueswir1
#define SPARC64_STACK_BIAS 2047
393 84778508 blueswir1
394 84778508 blueswir1
//#define DEBUG_WIN
395 84778508 blueswir1
/* WARNING: dealing with register windows _is_ complicated. More info
396 84778508 blueswir1
   can be found at http://www.sics.se/~psm/sparcstack.html */
397 84778508 blueswir1
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
398 84778508 blueswir1
{
399 84778508 blueswir1
    index = (index + cwp * 16) % (16 * env->nwindows);
400 84778508 blueswir1
    /* wrap handling : if cwp is on the last window, then we use the
401 84778508 blueswir1
       registers 'after' the end */
402 84778508 blueswir1
    if (index < 8 && env->cwp == env->nwindows - 1)
403 84778508 blueswir1
        index += 16 * env->nwindows;
404 84778508 blueswir1
    return index;
405 84778508 blueswir1
}
406 84778508 blueswir1
407 84778508 blueswir1
/* save the register window 'cwp1' */
408 84778508 blueswir1
static inline void save_window_offset(CPUSPARCState *env, int cwp1)
409 84778508 blueswir1
{
410 84778508 blueswir1
    unsigned int i;
411 84778508 blueswir1
    abi_ulong sp_ptr;
412 84778508 blueswir1
413 84778508 blueswir1
    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
414 84778508 blueswir1
#ifdef TARGET_SPARC64
415 84778508 blueswir1
    if (sp_ptr & 3)
416 84778508 blueswir1
        sp_ptr += SPARC64_STACK_BIAS;
417 84778508 blueswir1
#endif
418 84778508 blueswir1
#if defined(DEBUG_WIN)
419 84778508 blueswir1
    printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
420 84778508 blueswir1
           sp_ptr, cwp1);
421 84778508 blueswir1
#endif
422 84778508 blueswir1
    for(i = 0; i < 16; i++) {
423 84778508 blueswir1
        /* FIXME - what to do if put_user() fails? */
424 84778508 blueswir1
        put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
425 84778508 blueswir1
        sp_ptr += sizeof(abi_ulong);
426 84778508 blueswir1
    }
427 84778508 blueswir1
}
428 84778508 blueswir1
429 84778508 blueswir1
static void save_window(CPUSPARCState *env)
430 84778508 blueswir1
{
431 84778508 blueswir1
#ifndef TARGET_SPARC64
432 84778508 blueswir1
    unsigned int new_wim;
433 84778508 blueswir1
    new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
434 84778508 blueswir1
        ((1LL << env->nwindows) - 1);
435 84778508 blueswir1
    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
436 84778508 blueswir1
    env->wim = new_wim;
437 84778508 blueswir1
#else
438 84778508 blueswir1
    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
439 84778508 blueswir1
    env->cansave++;
440 84778508 blueswir1
    env->canrestore--;
441 84778508 blueswir1
#endif
442 84778508 blueswir1
}
443 84778508 blueswir1
444 84778508 blueswir1
static void restore_window(CPUSPARCState *env)
445 84778508 blueswir1
{
446 84778508 blueswir1
#ifndef TARGET_SPARC64
447 84778508 blueswir1
    unsigned int new_wim;
448 84778508 blueswir1
#endif
449 84778508 blueswir1
    unsigned int i, cwp1;
450 84778508 blueswir1
    abi_ulong sp_ptr;
451 84778508 blueswir1
452 84778508 blueswir1
#ifndef TARGET_SPARC64
453 84778508 blueswir1
    new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
454 84778508 blueswir1
        ((1LL << env->nwindows) - 1);
455 84778508 blueswir1
#endif
456 84778508 blueswir1
457 84778508 blueswir1
    /* restore the invalid window */
458 84778508 blueswir1
    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
459 84778508 blueswir1
    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
460 84778508 blueswir1
#ifdef TARGET_SPARC64
461 84778508 blueswir1
    if (sp_ptr & 3)
462 84778508 blueswir1
        sp_ptr += SPARC64_STACK_BIAS;
463 84778508 blueswir1
#endif
464 84778508 blueswir1
#if defined(DEBUG_WIN)
465 84778508 blueswir1
    printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
466 84778508 blueswir1
           sp_ptr, cwp1);
467 84778508 blueswir1
#endif
468 84778508 blueswir1
    for(i = 0; i < 16; i++) {
469 84778508 blueswir1
        /* FIXME - what to do if get_user() fails? */
470 84778508 blueswir1
        get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
471 84778508 blueswir1
        sp_ptr += sizeof(abi_ulong);
472 84778508 blueswir1
    }
473 84778508 blueswir1
#ifdef TARGET_SPARC64
474 84778508 blueswir1
    env->canrestore++;
475 84778508 blueswir1
    if (env->cleanwin < env->nwindows - 1)
476 84778508 blueswir1
        env->cleanwin++;
477 84778508 blueswir1
    env->cansave--;
478 84778508 blueswir1
#else
479 84778508 blueswir1
    env->wim = new_wim;
480 84778508 blueswir1
#endif
481 84778508 blueswir1
}
482 84778508 blueswir1
483 84778508 blueswir1
static void flush_windows(CPUSPARCState *env)
484 84778508 blueswir1
{
485 84778508 blueswir1
    int offset, cwp1;
486 84778508 blueswir1
487 84778508 blueswir1
    offset = 1;
488 84778508 blueswir1
    for(;;) {
489 84778508 blueswir1
        /* if restore would invoke restore_window(), then we can stop */
490 84778508 blueswir1
        cwp1 = cpu_cwp_inc(env, env->cwp + offset);
491 84778508 blueswir1
#ifndef TARGET_SPARC64
492 84778508 blueswir1
        if (env->wim & (1 << cwp1))
493 84778508 blueswir1
            break;
494 84778508 blueswir1
#else
495 84778508 blueswir1
        if (env->canrestore == 0)
496 84778508 blueswir1
            break;
497 84778508 blueswir1
        env->cansave++;
498 84778508 blueswir1
        env->canrestore--;
499 84778508 blueswir1
#endif
500 84778508 blueswir1
        save_window_offset(env, cwp1);
501 84778508 blueswir1
        offset++;
502 84778508 blueswir1
    }
503 84778508 blueswir1
    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
504 84778508 blueswir1
#ifndef TARGET_SPARC64
505 84778508 blueswir1
    /* set wim so that restore will reload the registers */
506 84778508 blueswir1
    env->wim = 1 << cwp1;
507 84778508 blueswir1
#endif
508 84778508 blueswir1
#if defined(DEBUG_WIN)
509 84778508 blueswir1
    printf("flush_windows: nb=%d\n", offset - 1);
510 84778508 blueswir1
#endif
511 84778508 blueswir1
}
512 84778508 blueswir1
513 78cfb07f Juergen Lock
void cpu_loop(CPUSPARCState *env)
514 84778508 blueswir1
{
515 84778508 blueswir1
    int trapnr, ret, syscall_nr;
516 84778508 blueswir1
    //target_siginfo_t info;
517 84778508 blueswir1
518 84778508 blueswir1
    while (1) {
519 84778508 blueswir1
        trapnr = cpu_sparc_exec (env);
520 84778508 blueswir1
521 84778508 blueswir1
        switch (trapnr) {
522 77b9435f blueswir1
#ifndef TARGET_SPARC64
523 77b9435f blueswir1
        case 0x80:
524 77b9435f blueswir1
#else
525 78cfb07f Juergen Lock
        /* FreeBSD uses 0x141 for syscalls too */
526 78cfb07f Juergen Lock
        case 0x141:
527 78cfb07f Juergen Lock
            if (bsd_type != target_freebsd)
528 78cfb07f Juergen Lock
                goto badtrap;
529 84778508 blueswir1
        case 0x100:
530 77b9435f blueswir1
#endif
531 84778508 blueswir1
            syscall_nr = env->gregs[1];
532 84778508 blueswir1
            if (bsd_type == target_freebsd)
533 84778508 blueswir1
                ret = do_freebsd_syscall(env, syscall_nr,
534 84778508 blueswir1
                                         env->regwptr[0], env->regwptr[1],
535 84778508 blueswir1
                                         env->regwptr[2], env->regwptr[3],
536 78cfb07f Juergen Lock
                                         env->regwptr[4], env->regwptr[5], 0, 0);
537 84778508 blueswir1
            else if (bsd_type == target_netbsd)
538 84778508 blueswir1
                ret = do_netbsd_syscall(env, syscall_nr,
539 84778508 blueswir1
                                        env->regwptr[0], env->regwptr[1],
540 84778508 blueswir1
                                        env->regwptr[2], env->regwptr[3],
541 84778508 blueswir1
                                        env->regwptr[4], env->regwptr[5]);
542 cdba95bd blueswir1
            else { //if (bsd_type == target_openbsd)
543 cdba95bd blueswir1
#if defined(TARGET_SPARC64)
544 cdba95bd blueswir1
                syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
545 cdba95bd blueswir1
                                TARGET_OPENBSD_SYSCALL_G2RFLAG);
546 cdba95bd blueswir1
#endif
547 84778508 blueswir1
                ret = do_openbsd_syscall(env, syscall_nr,
548 84778508 blueswir1
                                         env->regwptr[0], env->regwptr[1],
549 84778508 blueswir1
                                         env->regwptr[2], env->regwptr[3],
550 84778508 blueswir1
                                         env->regwptr[4], env->regwptr[5]);
551 cdba95bd blueswir1
            }
552 84778508 blueswir1
            if ((unsigned int)ret >= (unsigned int)(-515)) {
553 78cfb07f Juergen Lock
                ret = -ret;
554 84778508 blueswir1
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
555 84778508 blueswir1
                env->xcc |= PSR_CARRY;
556 84778508 blueswir1
#else
557 84778508 blueswir1
                env->psr |= PSR_CARRY;
558 84778508 blueswir1
#endif
559 84778508 blueswir1
            } else {
560 84778508 blueswir1
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
561 84778508 blueswir1
                env->xcc &= ~PSR_CARRY;
562 84778508 blueswir1
#else
563 84778508 blueswir1
                env->psr &= ~PSR_CARRY;
564 84778508 blueswir1
#endif
565 84778508 blueswir1
            }
566 84778508 blueswir1
            env->regwptr[0] = ret;
567 84778508 blueswir1
            /* next instruction */
568 cdba95bd blueswir1
#if defined(TARGET_SPARC64)
569 cdba95bd blueswir1
            if (bsd_type == target_openbsd &&
570 cdba95bd blueswir1
                env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
571 84778508 blueswir1
                env->pc = env->gregs[2];
572 84778508 blueswir1
                env->npc = env->pc + 4;
573 cdba95bd blueswir1
            } else if (bsd_type == target_openbsd &&
574 cdba95bd blueswir1
                       env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
575 84778508 blueswir1
                env->pc = env->gregs[7];
576 84778508 blueswir1
                env->npc = env->pc + 4;
577 84778508 blueswir1
            } else {
578 84778508 blueswir1
                env->pc = env->npc;
579 84778508 blueswir1
                env->npc = env->npc + 4;
580 84778508 blueswir1
            }
581 84778508 blueswir1
#else
582 84778508 blueswir1
            env->pc = env->npc;
583 84778508 blueswir1
            env->npc = env->npc + 4;
584 84778508 blueswir1
#endif
585 84778508 blueswir1
            break;
586 84778508 blueswir1
        case 0x83: /* flush windows */
587 84778508 blueswir1
#ifdef TARGET_ABI32
588 84778508 blueswir1
        case 0x103:
589 84778508 blueswir1
#endif
590 84778508 blueswir1
            flush_windows(env);
591 84778508 blueswir1
            /* next instruction */
592 84778508 blueswir1
            env->pc = env->npc;
593 84778508 blueswir1
            env->npc = env->npc + 4;
594 84778508 blueswir1
            break;
595 84778508 blueswir1
#ifndef TARGET_SPARC64
596 84778508 blueswir1
        case TT_WIN_OVF: /* window overflow */
597 84778508 blueswir1
            save_window(env);
598 84778508 blueswir1
            break;
599 84778508 blueswir1
        case TT_WIN_UNF: /* window underflow */
600 84778508 blueswir1
            restore_window(env);
601 84778508 blueswir1
            break;
602 84778508 blueswir1
        case TT_TFAULT:
603 84778508 blueswir1
        case TT_DFAULT:
604 84778508 blueswir1
#if 0
605 84778508 blueswir1
            {
606 84778508 blueswir1
                info.si_signo = SIGSEGV;
607 84778508 blueswir1
                info.si_errno = 0;
608 84778508 blueswir1
                /* XXX: check env->error_code */
609 84778508 blueswir1
                info.si_code = TARGET_SEGV_MAPERR;
610 84778508 blueswir1
                info._sifields._sigfault._addr = env->mmuregs[4];
611 84778508 blueswir1
                queue_signal(env, info.si_signo, &info);
612 84778508 blueswir1
            }
613 84778508 blueswir1
#endif
614 84778508 blueswir1
            break;
615 84778508 blueswir1
#else
616 84778508 blueswir1
        case TT_SPILL: /* window overflow */
617 84778508 blueswir1
            save_window(env);
618 84778508 blueswir1
            break;
619 84778508 blueswir1
        case TT_FILL: /* window underflow */
620 84778508 blueswir1
            restore_window(env);
621 84778508 blueswir1
            break;
622 84778508 blueswir1
        case TT_TFAULT:
623 84778508 blueswir1
        case TT_DFAULT:
624 84778508 blueswir1
#if 0
625 84778508 blueswir1
            {
626 84778508 blueswir1
                info.si_signo = SIGSEGV;
627 84778508 blueswir1
                info.si_errno = 0;
628 84778508 blueswir1
                /* XXX: check env->error_code */
629 84778508 blueswir1
                info.si_code = TARGET_SEGV_MAPERR;
630 84778508 blueswir1
                if (trapnr == TT_DFAULT)
631 84778508 blueswir1
                    info._sifields._sigfault._addr = env->dmmuregs[4];
632 84778508 blueswir1
                else
633 84778508 blueswir1
                    info._sifields._sigfault._addr = env->tsptr->tpc;
634 84778508 blueswir1
                //queue_signal(env, info.si_signo, &info);
635 84778508 blueswir1
            }
636 84778508 blueswir1
#endif
637 84778508 blueswir1
            break;
638 84778508 blueswir1
#endif
639 84778508 blueswir1
        case EXCP_INTERRUPT:
640 84778508 blueswir1
            /* just indicate that signals should be handled asap */
641 84778508 blueswir1
            break;
642 84778508 blueswir1
        case EXCP_DEBUG:
643 84778508 blueswir1
            {
644 84778508 blueswir1
                int sig;
645 84778508 blueswir1
646 84778508 blueswir1
                sig = gdb_handlesig (env, TARGET_SIGTRAP);
647 84778508 blueswir1
#if 0
648 84778508 blueswir1
                if (sig)
649 84778508 blueswir1
                  {
650 84778508 blueswir1
                    info.si_signo = sig;
651 84778508 blueswir1
                    info.si_errno = 0;
652 84778508 blueswir1
                    info.si_code = TARGET_TRAP_BRKPT;
653 84778508 blueswir1
                    //queue_signal(env, info.si_signo, &info);
654 84778508 blueswir1
                  }
655 84778508 blueswir1
#endif
656 84778508 blueswir1
            }
657 84778508 blueswir1
            break;
658 84778508 blueswir1
        default:
659 78cfb07f Juergen Lock
#ifdef TARGET_SPARC64
660 78cfb07f Juergen Lock
        badtrap:
661 78cfb07f Juergen Lock
#endif
662 84778508 blueswir1
            printf ("Unhandled trap: 0x%x\n", trapnr);
663 84778508 blueswir1
            cpu_dump_state(env, stderr, fprintf, 0);
664 84778508 blueswir1
            exit (1);
665 84778508 blueswir1
        }
666 84778508 blueswir1
        process_pending_signals (env);
667 84778508 blueswir1
    }
668 84778508 blueswir1
}
669 84778508 blueswir1
670 84778508 blueswir1
#endif
671 84778508 blueswir1
672 84778508 blueswir1
static void usage(void)
673 84778508 blueswir1
{
674 84778508 blueswir1
    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
675 84778508 blueswir1
           "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
676 84778508 blueswir1
           "BSD CPU emulator (compiled for %s emulation)\n"
677 84778508 blueswir1
           "\n"
678 84778508 blueswir1
           "Standard options:\n"
679 84778508 blueswir1
           "-h                print this help\n"
680 84778508 blueswir1
           "-g port           wait gdb connection to port\n"
681 84778508 blueswir1
           "-L path           set the elf interpreter prefix (default=%s)\n"
682 84778508 blueswir1
           "-s size           set the stack size in bytes (default=%ld)\n"
683 84778508 blueswir1
           "-cpu model        select CPU (-cpu ? for list)\n"
684 84778508 blueswir1
           "-drop-ld-preload  drop LD_PRELOAD for target process\n"
685 fc0d96b4 Blue Swirl
           "-E var=value      sets/modifies targets environment variable(s)\n"
686 fc0d96b4 Blue Swirl
           "-U var            unsets targets environment variable(s)\n"
687 2fa5d9ba Blue Swirl
#if defined(CONFIG_USE_GUEST_BASE)
688 2fa5d9ba Blue Swirl
           "-B address        set guest_base address to address\n"
689 2fa5d9ba Blue Swirl
#endif
690 84778508 blueswir1
           "-bsd type         select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
691 84778508 blueswir1
           "\n"
692 84778508 blueswir1
           "Debug options:\n"
693 c235d738 Matthew Fernandez
           "-d options   activate log (default logfile=%s)\n"
694 c235d738 Matthew Fernandez
           "-D logfile   override default logfile location\n"
695 84778508 blueswir1
           "-p pagesize  set the host page size to 'pagesize'\n"
696 1b530a6d aurel32
           "-singlestep  always run in singlestep mode\n"
697 84778508 blueswir1
           "-strace      log system calls\n"
698 84778508 blueswir1
           "\n"
699 84778508 blueswir1
           "Environment variables:\n"
700 84778508 blueswir1
           "QEMU_STRACE       Print system calls and arguments similar to the\n"
701 84778508 blueswir1
           "                  'strace' program.  Enable by setting to any value.\n"
702 fc0d96b4 Blue Swirl
           "You can use -E and -U options to set/unset environment variables\n"
703 fc0d96b4 Blue Swirl
           "for target process.  It is possible to provide several variables\n"
704 fc0d96b4 Blue Swirl
           "by repeating the option.  For example:\n"
705 fc0d96b4 Blue Swirl
           "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
706 fc0d96b4 Blue Swirl
           "Note that if you provide several changes to single variable\n"
707 fc0d96b4 Blue Swirl
           "last change will stay in effect.\n"
708 84778508 blueswir1
           ,
709 84778508 blueswir1
           TARGET_ARCH,
710 84778508 blueswir1
           interp_prefix,
711 84778508 blueswir1
           x86_stack_size,
712 84778508 blueswir1
           DEBUG_LOGFILE);
713 2d18e637 blueswir1
    exit(1);
714 84778508 blueswir1
}
715 84778508 blueswir1
716 84778508 blueswir1
THREAD CPUState *thread_env;
717 84778508 blueswir1
718 84778508 blueswir1
/* Assumes contents are already zeroed.  */
719 84778508 blueswir1
void init_task_state(TaskState *ts)
720 84778508 blueswir1
{
721 84778508 blueswir1
    int i;
722 84778508 blueswir1
723 84778508 blueswir1
    ts->used = 1;
724 84778508 blueswir1
    ts->first_free = ts->sigqueue_table;
725 84778508 blueswir1
    for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
726 84778508 blueswir1
        ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
727 84778508 blueswir1
    }
728 84778508 blueswir1
    ts->sigqueue_table[i].next = NULL;
729 84778508 blueswir1
}
730 84778508 blueswir1
731 84778508 blueswir1
int main(int argc, char **argv)
732 84778508 blueswir1
{
733 84778508 blueswir1
    const char *filename;
734 84778508 blueswir1
    const char *cpu_model;
735 c235d738 Matthew Fernandez
    const char *log_file = DEBUG_LOGFILE;
736 c235d738 Matthew Fernandez
    const char *log_mask = NULL;
737 84778508 blueswir1
    struct target_pt_regs regs1, *regs = &regs1;
738 84778508 blueswir1
    struct image_info info1, *info = &info1;
739 84778508 blueswir1
    TaskState ts1, *ts = &ts1;
740 84778508 blueswir1
    CPUState *env;
741 84778508 blueswir1
    int optind;
742 84778508 blueswir1
    const char *r;
743 84778508 blueswir1
    int gdbstub_port = 0;
744 fc0d96b4 Blue Swirl
    char **target_environ, **wrk;
745 fc0d96b4 Blue Swirl
    envlist_t *envlist = NULL;
746 78cfb07f Juergen Lock
    bsd_type = target_openbsd;
747 84778508 blueswir1
748 84778508 blueswir1
    if (argc <= 1)
749 84778508 blueswir1
        usage();
750 84778508 blueswir1
751 fc0d96b4 Blue Swirl
    if ((envlist = envlist_create()) == NULL) {
752 fc0d96b4 Blue Swirl
        (void) fprintf(stderr, "Unable to allocate envlist\n");
753 fc0d96b4 Blue Swirl
        exit(1);
754 fc0d96b4 Blue Swirl
    }
755 fc0d96b4 Blue Swirl
756 fc0d96b4 Blue Swirl
    /* add current environment into the list */
757 fc0d96b4 Blue Swirl
    for (wrk = environ; *wrk != NULL; wrk++) {
758 fc0d96b4 Blue Swirl
        (void) envlist_setenv(envlist, *wrk);
759 fc0d96b4 Blue Swirl
    }
760 fc0d96b4 Blue Swirl
761 84778508 blueswir1
    cpu_model = NULL;
762 0c62de2f Juergen Lock
#if defined(cpudef_setup)
763 0c62de2f Juergen Lock
    cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
764 0c62de2f Juergen Lock
#endif
765 0c62de2f Juergen Lock
766 84778508 blueswir1
    optind = 1;
767 84778508 blueswir1
    for(;;) {
768 84778508 blueswir1
        if (optind >= argc)
769 84778508 blueswir1
            break;
770 84778508 blueswir1
        r = argv[optind];
771 84778508 blueswir1
        if (r[0] != '-')
772 84778508 blueswir1
            break;
773 84778508 blueswir1
        optind++;
774 84778508 blueswir1
        r++;
775 84778508 blueswir1
        if (!strcmp(r, "-")) {
776 84778508 blueswir1
            break;
777 84778508 blueswir1
        } else if (!strcmp(r, "d")) {
778 c235d738 Matthew Fernandez
            if (optind >= argc) {
779 84778508 blueswir1
                break;
780 84778508 blueswir1
            }
781 c235d738 Matthew Fernandez
            log_mask = argv[optind++];
782 c235d738 Matthew Fernandez
        } else if (!strcmp(r, "D")) {
783 c235d738 Matthew Fernandez
            if (optind >= argc) {
784 c235d738 Matthew Fernandez
                break;
785 c235d738 Matthew Fernandez
            }
786 c235d738 Matthew Fernandez
            log_file = argv[optind++];
787 fc0d96b4 Blue Swirl
        } else if (!strcmp(r, "E")) {
788 fc0d96b4 Blue Swirl
            r = argv[optind++];
789 fc0d96b4 Blue Swirl
            if (envlist_setenv(envlist, r) != 0)
790 fc0d96b4 Blue Swirl
                usage();
791 f66724c9 Stefan Weil
        } else if (!strcmp(r, "ignore-environment")) {
792 f66724c9 Stefan Weil
            envlist_free(envlist);
793 f66724c9 Stefan Weil
            if ((envlist = envlist_create()) == NULL) {
794 f66724c9 Stefan Weil
                (void) fprintf(stderr, "Unable to allocate envlist\n");
795 f66724c9 Stefan Weil
                exit(1);
796 f66724c9 Stefan Weil
            }
797 fc0d96b4 Blue Swirl
        } else if (!strcmp(r, "U")) {
798 fc0d96b4 Blue Swirl
            r = argv[optind++];
799 fc0d96b4 Blue Swirl
            if (envlist_unsetenv(envlist, r) != 0)
800 fc0d96b4 Blue Swirl
                usage();
801 84778508 blueswir1
        } else if (!strcmp(r, "s")) {
802 84778508 blueswir1
            r = argv[optind++];
803 84778508 blueswir1
            x86_stack_size = strtol(r, (char **)&r, 0);
804 84778508 blueswir1
            if (x86_stack_size <= 0)
805 84778508 blueswir1
                usage();
806 84778508 blueswir1
            if (*r == 'M')
807 84778508 blueswir1
                x86_stack_size *= 1024 * 1024;
808 84778508 blueswir1
            else if (*r == 'k' || *r == 'K')
809 84778508 blueswir1
                x86_stack_size *= 1024;
810 84778508 blueswir1
        } else if (!strcmp(r, "L")) {
811 84778508 blueswir1
            interp_prefix = argv[optind++];
812 84778508 blueswir1
        } else if (!strcmp(r, "p")) {
813 84778508 blueswir1
            qemu_host_page_size = atoi(argv[optind++]);
814 84778508 blueswir1
            if (qemu_host_page_size == 0 ||
815 84778508 blueswir1
                (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
816 84778508 blueswir1
                fprintf(stderr, "page size must be a power of two\n");
817 84778508 blueswir1
                exit(1);
818 84778508 blueswir1
            }
819 84778508 blueswir1
        } else if (!strcmp(r, "g")) {
820 84778508 blueswir1
            gdbstub_port = atoi(argv[optind++]);
821 84778508 blueswir1
        } else if (!strcmp(r, "r")) {
822 84778508 blueswir1
            qemu_uname_release = argv[optind++];
823 84778508 blueswir1
        } else if (!strcmp(r, "cpu")) {
824 84778508 blueswir1
            cpu_model = argv[optind++];
825 84778508 blueswir1
            if (strcmp(cpu_model, "?") == 0) {
826 84778508 blueswir1
/* XXX: implement xxx_cpu_list for targets that still miss it */
827 84778508 blueswir1
#if defined(cpu_list)
828 84778508 blueswir1
                    cpu_list(stdout, &fprintf);
829 84778508 blueswir1
#endif
830 2d18e637 blueswir1
                exit(1);
831 84778508 blueswir1
            }
832 2fa5d9ba Blue Swirl
#if defined(CONFIG_USE_GUEST_BASE)
833 2fa5d9ba Blue Swirl
        } else if (!strcmp(r, "B")) {
834 2fa5d9ba Blue Swirl
           guest_base = strtol(argv[optind++], NULL, 0);
835 2fa5d9ba Blue Swirl
           have_guest_base = 1;
836 2fa5d9ba Blue Swirl
#endif
837 84778508 blueswir1
        } else if (!strcmp(r, "drop-ld-preload")) {
838 fc0d96b4 Blue Swirl
            (void) envlist_unsetenv(envlist, "LD_PRELOAD");
839 84778508 blueswir1
        } else if (!strcmp(r, "bsd")) {
840 84778508 blueswir1
            if (!strcasecmp(argv[optind], "freebsd")) {
841 84778508 blueswir1
                bsd_type = target_freebsd;
842 84778508 blueswir1
            } else if (!strcasecmp(argv[optind], "netbsd")) {
843 84778508 blueswir1
                bsd_type = target_netbsd;
844 84778508 blueswir1
            } else if (!strcasecmp(argv[optind], "openbsd")) {
845 84778508 blueswir1
                bsd_type = target_openbsd;
846 84778508 blueswir1
            } else {
847 84778508 blueswir1
                usage();
848 84778508 blueswir1
            }
849 84778508 blueswir1
            optind++;
850 1b530a6d aurel32
        } else if (!strcmp(r, "singlestep")) {
851 1b530a6d aurel32
            singlestep = 1;
852 84778508 blueswir1
        } else if (!strcmp(r, "strace")) {
853 84778508 blueswir1
            do_strace = 1;
854 84778508 blueswir1
        } else
855 84778508 blueswir1
        {
856 84778508 blueswir1
            usage();
857 84778508 blueswir1
        }
858 84778508 blueswir1
    }
859 84778508 blueswir1
860 c235d738 Matthew Fernandez
    /* init debug */
861 c235d738 Matthew Fernandez
    cpu_set_log_filename(log_file);
862 c235d738 Matthew Fernandez
    if (log_mask) {
863 c235d738 Matthew Fernandez
        int mask;
864 c235d738 Matthew Fernandez
        const CPULogItem *item;
865 c235d738 Matthew Fernandez
866 1dfdcaa8 Edgar E. Iglesias
        mask = cpu_str_to_log_mask(log_mask);
867 c235d738 Matthew Fernandez
        if (!mask) {
868 c235d738 Matthew Fernandez
            printf("Log items (comma separated):\n");
869 c235d738 Matthew Fernandez
            for (item = cpu_log_items; item->mask != 0; item++) {
870 c235d738 Matthew Fernandez
                printf("%-10s %s\n", item->name, item->help);
871 c235d738 Matthew Fernandez
            }
872 c235d738 Matthew Fernandez
            exit(1);
873 c235d738 Matthew Fernandez
        }
874 c235d738 Matthew Fernandez
        cpu_set_log(mask);
875 c235d738 Matthew Fernandez
    }
876 c235d738 Matthew Fernandez
877 4b5dfd82 Peter Maydell
    if (optind >= argc) {
878 4b5dfd82 Peter Maydell
        usage();
879 4b5dfd82 Peter Maydell
    }
880 4b5dfd82 Peter Maydell
    filename = argv[optind];
881 4b5dfd82 Peter Maydell
882 84778508 blueswir1
    /* Zero out regs */
883 84778508 blueswir1
    memset(regs, 0, sizeof(struct target_pt_regs));
884 84778508 blueswir1
885 84778508 blueswir1
    /* Zero out image_info */
886 84778508 blueswir1
    memset(info, 0, sizeof(struct image_info));
887 84778508 blueswir1
888 84778508 blueswir1
    /* Scan interp_prefix dir for replacement files. */
889 84778508 blueswir1
    init_paths(interp_prefix);
890 84778508 blueswir1
891 84778508 blueswir1
    if (cpu_model == NULL) {
892 31fc12df blueswir1
#if defined(TARGET_I386)
893 31fc12df blueswir1
#ifdef TARGET_X86_64
894 31fc12df blueswir1
        cpu_model = "qemu64";
895 31fc12df blueswir1
#else
896 31fc12df blueswir1
        cpu_model = "qemu32";
897 31fc12df blueswir1
#endif
898 31fc12df blueswir1
#elif defined(TARGET_SPARC)
899 84778508 blueswir1
#ifdef TARGET_SPARC64
900 84778508 blueswir1
        cpu_model = "TI UltraSparc II";
901 84778508 blueswir1
#else
902 84778508 blueswir1
        cpu_model = "Fujitsu MB86904";
903 84778508 blueswir1
#endif
904 84778508 blueswir1
#else
905 84778508 blueswir1
        cpu_model = "any";
906 84778508 blueswir1
#endif
907 84778508 blueswir1
    }
908 d5ab9713 Jan Kiszka
    tcg_exec_init(0);
909 d5ab9713 Jan Kiszka
    cpu_exec_init_all();
910 84778508 blueswir1
    /* NOTE: we need to init the CPU at this stage to get
911 84778508 blueswir1
       qemu_host_page_size */
912 84778508 blueswir1
    env = cpu_init(cpu_model);
913 84778508 blueswir1
    if (!env) {
914 84778508 blueswir1
        fprintf(stderr, "Unable to find CPU definition\n");
915 84778508 blueswir1
        exit(1);
916 84778508 blueswir1
    }
917 b55a37c9 Blue Swirl
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
918 b55a37c9 Blue Swirl
    cpu_reset(env);
919 b55a37c9 Blue Swirl
#endif
920 84778508 blueswir1
    thread_env = env;
921 84778508 blueswir1
922 84778508 blueswir1
    if (getenv("QEMU_STRACE")) {
923 84778508 blueswir1
        do_strace = 1;
924 84778508 blueswir1
    }
925 84778508 blueswir1
926 fc0d96b4 Blue Swirl
    target_environ = envlist_to_environ(envlist, NULL);
927 fc0d96b4 Blue Swirl
    envlist_free(envlist);
928 fc0d96b4 Blue Swirl
929 2fa5d9ba Blue Swirl
#if defined(CONFIG_USE_GUEST_BASE)
930 2fa5d9ba Blue Swirl
    /*
931 2fa5d9ba Blue Swirl
     * Now that page sizes are configured in cpu_init() we can do
932 2fa5d9ba Blue Swirl
     * proper page alignment for guest_base.
933 2fa5d9ba Blue Swirl
     */
934 2fa5d9ba Blue Swirl
    guest_base = HOST_PAGE_ALIGN(guest_base);
935 2fa5d9ba Blue Swirl
936 2fa5d9ba Blue Swirl
    /*
937 2fa5d9ba Blue Swirl
     * Read in mmap_min_addr kernel parameter.  This value is used
938 2fa5d9ba Blue Swirl
     * When loading the ELF image to determine whether guest_base
939 2fa5d9ba Blue Swirl
     * is needed.
940 2fa5d9ba Blue Swirl
     *
941 2fa5d9ba Blue Swirl
     * When user has explicitly set the quest base, we skip this
942 2fa5d9ba Blue Swirl
     * test.
943 2fa5d9ba Blue Swirl
     */
944 2fa5d9ba Blue Swirl
    if (!have_guest_base) {
945 2fa5d9ba Blue Swirl
        FILE *fp;
946 2fa5d9ba Blue Swirl
947 2fa5d9ba Blue Swirl
        if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
948 2fa5d9ba Blue Swirl
            unsigned long tmp;
949 2fa5d9ba Blue Swirl
            if (fscanf(fp, "%lu", &tmp) == 1) {
950 2fa5d9ba Blue Swirl
                mmap_min_addr = tmp;
951 2fa5d9ba Blue Swirl
                qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
952 2fa5d9ba Blue Swirl
            }
953 2fa5d9ba Blue Swirl
            fclose(fp);
954 2fa5d9ba Blue Swirl
        }
955 2fa5d9ba Blue Swirl
    }
956 2fa5d9ba Blue Swirl
#endif /* CONFIG_USE_GUEST_BASE */
957 84778508 blueswir1
958 84778508 blueswir1
    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
959 84778508 blueswir1
        printf("Error loading %s\n", filename);
960 84778508 blueswir1
        _exit(1);
961 84778508 blueswir1
    }
962 84778508 blueswir1
963 84778508 blueswir1
    for (wrk = target_environ; *wrk; wrk++) {
964 84778508 blueswir1
        free(*wrk);
965 84778508 blueswir1
    }
966 84778508 blueswir1
967 84778508 blueswir1
    free(target_environ);
968 84778508 blueswir1
969 2e77eac6 blueswir1
    if (qemu_log_enabled()) {
970 2fa5d9ba Blue Swirl
#if defined(CONFIG_USE_GUEST_BASE)
971 2fa5d9ba Blue Swirl
        qemu_log("guest_base  0x%lx\n", guest_base);
972 2fa5d9ba Blue Swirl
#endif
973 2e77eac6 blueswir1
        log_page_dump();
974 2e77eac6 blueswir1
975 2e77eac6 blueswir1
        qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
976 2e77eac6 blueswir1
        qemu_log("end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
977 2e77eac6 blueswir1
        qemu_log("start_code  0x" TARGET_ABI_FMT_lx "\n",
978 2e77eac6 blueswir1
                 info->start_code);
979 2e77eac6 blueswir1
        qemu_log("start_data  0x" TARGET_ABI_FMT_lx "\n",
980 2e77eac6 blueswir1
                 info->start_data);
981 2e77eac6 blueswir1
        qemu_log("end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
982 2e77eac6 blueswir1
        qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
983 2e77eac6 blueswir1
                 info->start_stack);
984 2e77eac6 blueswir1
        qemu_log("brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
985 2e77eac6 blueswir1
        qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
986 2e77eac6 blueswir1
    }
987 84778508 blueswir1
988 84778508 blueswir1
    target_set_brk(info->brk);
989 84778508 blueswir1
    syscall_init();
990 84778508 blueswir1
    signal_init();
991 84778508 blueswir1
992 9002ec79 Richard Henderson
#if defined(CONFIG_USE_GUEST_BASE)
993 9002ec79 Richard Henderson
    /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
994 9002ec79 Richard Henderson
       generating the prologue until now so that the prologue can take
995 9002ec79 Richard Henderson
       the real value of GUEST_BASE into account.  */
996 9002ec79 Richard Henderson
    tcg_prologue_init(&tcg_ctx);
997 9002ec79 Richard Henderson
#endif
998 9002ec79 Richard Henderson
999 84778508 blueswir1
    /* build Task State */
1000 84778508 blueswir1
    memset(ts, 0, sizeof(TaskState));
1001 84778508 blueswir1
    init_task_state(ts);
1002 84778508 blueswir1
    ts->info = info;
1003 84778508 blueswir1
    env->opaque = ts;
1004 84778508 blueswir1
1005 31fc12df blueswir1
#if defined(TARGET_I386)
1006 31fc12df blueswir1
    cpu_x86_set_cpl(env, 3);
1007 31fc12df blueswir1
1008 31fc12df blueswir1
    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
1009 31fc12df blueswir1
    env->hflags |= HF_PE_MASK;
1010 31fc12df blueswir1
    if (env->cpuid_features & CPUID_SSE) {
1011 31fc12df blueswir1
        env->cr[4] |= CR4_OSFXSR_MASK;
1012 31fc12df blueswir1
        env->hflags |= HF_OSFXSR_MASK;
1013 31fc12df blueswir1
    }
1014 31fc12df blueswir1
#ifndef TARGET_ABI32
1015 31fc12df blueswir1
    /* enable 64 bit mode if possible */
1016 31fc12df blueswir1
    if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
1017 31fc12df blueswir1
        fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
1018 31fc12df blueswir1
        exit(1);
1019 31fc12df blueswir1
    }
1020 31fc12df blueswir1
    env->cr[4] |= CR4_PAE_MASK;
1021 31fc12df blueswir1
    env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
1022 31fc12df blueswir1
    env->hflags |= HF_LMA_MASK;
1023 31fc12df blueswir1
#endif
1024 31fc12df blueswir1
1025 31fc12df blueswir1
    /* flags setup : we activate the IRQs by default as in user mode */
1026 31fc12df blueswir1
    env->eflags |= IF_MASK;
1027 31fc12df blueswir1
1028 31fc12df blueswir1
    /* linux register setup */
1029 31fc12df blueswir1
#ifndef TARGET_ABI32
1030 31fc12df blueswir1
    env->regs[R_EAX] = regs->rax;
1031 31fc12df blueswir1
    env->regs[R_EBX] = regs->rbx;
1032 31fc12df blueswir1
    env->regs[R_ECX] = regs->rcx;
1033 31fc12df blueswir1
    env->regs[R_EDX] = regs->rdx;
1034 31fc12df blueswir1
    env->regs[R_ESI] = regs->rsi;
1035 31fc12df blueswir1
    env->regs[R_EDI] = regs->rdi;
1036 31fc12df blueswir1
    env->regs[R_EBP] = regs->rbp;
1037 31fc12df blueswir1
    env->regs[R_ESP] = regs->rsp;
1038 31fc12df blueswir1
    env->eip = regs->rip;
1039 31fc12df blueswir1
#else
1040 31fc12df blueswir1
    env->regs[R_EAX] = regs->eax;
1041 31fc12df blueswir1
    env->regs[R_EBX] = regs->ebx;
1042 31fc12df blueswir1
    env->regs[R_ECX] = regs->ecx;
1043 31fc12df blueswir1
    env->regs[R_EDX] = regs->edx;
1044 31fc12df blueswir1
    env->regs[R_ESI] = regs->esi;
1045 31fc12df blueswir1
    env->regs[R_EDI] = regs->edi;
1046 31fc12df blueswir1
    env->regs[R_EBP] = regs->ebp;
1047 31fc12df blueswir1
    env->regs[R_ESP] = regs->esp;
1048 31fc12df blueswir1
    env->eip = regs->eip;
1049 31fc12df blueswir1
#endif
1050 31fc12df blueswir1
1051 31fc12df blueswir1
    /* linux interrupt setup */
1052 31fc12df blueswir1
#ifndef TARGET_ABI32
1053 31fc12df blueswir1
    env->idt.limit = 511;
1054 31fc12df blueswir1
#else
1055 31fc12df blueswir1
    env->idt.limit = 255;
1056 31fc12df blueswir1
#endif
1057 31fc12df blueswir1
    env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
1058 31fc12df blueswir1
                                PROT_READ|PROT_WRITE,
1059 31fc12df blueswir1
                                MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1060 31fc12df blueswir1
    idt_table = g2h(env->idt.base);
1061 31fc12df blueswir1
    set_idt(0, 0);
1062 31fc12df blueswir1
    set_idt(1, 0);
1063 31fc12df blueswir1
    set_idt(2, 0);
1064 31fc12df blueswir1
    set_idt(3, 3);
1065 31fc12df blueswir1
    set_idt(4, 3);
1066 31fc12df blueswir1
    set_idt(5, 0);
1067 31fc12df blueswir1
    set_idt(6, 0);
1068 31fc12df blueswir1
    set_idt(7, 0);
1069 31fc12df blueswir1
    set_idt(8, 0);
1070 31fc12df blueswir1
    set_idt(9, 0);
1071 31fc12df blueswir1
    set_idt(10, 0);
1072 31fc12df blueswir1
    set_idt(11, 0);
1073 31fc12df blueswir1
    set_idt(12, 0);
1074 31fc12df blueswir1
    set_idt(13, 0);
1075 31fc12df blueswir1
    set_idt(14, 0);
1076 31fc12df blueswir1
    set_idt(15, 0);
1077 31fc12df blueswir1
    set_idt(16, 0);
1078 31fc12df blueswir1
    set_idt(17, 0);
1079 31fc12df blueswir1
    set_idt(18, 0);
1080 31fc12df blueswir1
    set_idt(19, 0);
1081 31fc12df blueswir1
    set_idt(0x80, 3);
1082 31fc12df blueswir1
1083 31fc12df blueswir1
    /* linux segment setup */
1084 31fc12df blueswir1
    {
1085 31fc12df blueswir1
        uint64_t *gdt_table;
1086 31fc12df blueswir1
        env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
1087 31fc12df blueswir1
                                    PROT_READ|PROT_WRITE,
1088 31fc12df blueswir1
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1089 31fc12df blueswir1
        env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
1090 31fc12df blueswir1
        gdt_table = g2h(env->gdt.base);
1091 31fc12df blueswir1
#ifdef TARGET_ABI32
1092 31fc12df blueswir1
        write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
1093 31fc12df blueswir1
                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
1094 31fc12df blueswir1
                 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
1095 31fc12df blueswir1
#else
1096 31fc12df blueswir1
        /* 64 bit code segment */
1097 31fc12df blueswir1
        write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
1098 31fc12df blueswir1
                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
1099 31fc12df blueswir1
                 DESC_L_MASK |
1100 31fc12df blueswir1
                 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
1101 31fc12df blueswir1
#endif
1102 31fc12df blueswir1
        write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
1103 31fc12df blueswir1
                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
1104 31fc12df blueswir1
                 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
1105 31fc12df blueswir1
    }
1106 31fc12df blueswir1
1107 31fc12df blueswir1
    cpu_x86_load_seg(env, R_CS, __USER_CS);
1108 31fc12df blueswir1
    cpu_x86_load_seg(env, R_SS, __USER_DS);
1109 31fc12df blueswir1
#ifdef TARGET_ABI32
1110 31fc12df blueswir1
    cpu_x86_load_seg(env, R_DS, __USER_DS);
1111 31fc12df blueswir1
    cpu_x86_load_seg(env, R_ES, __USER_DS);
1112 31fc12df blueswir1
    cpu_x86_load_seg(env, R_FS, __USER_DS);
1113 31fc12df blueswir1
    cpu_x86_load_seg(env, R_GS, __USER_DS);
1114 31fc12df blueswir1
    /* This hack makes Wine work... */
1115 31fc12df blueswir1
    env->segs[R_FS].selector = 0;
1116 31fc12df blueswir1
#else
1117 31fc12df blueswir1
    cpu_x86_load_seg(env, R_DS, 0);
1118 31fc12df blueswir1
    cpu_x86_load_seg(env, R_ES, 0);
1119 31fc12df blueswir1
    cpu_x86_load_seg(env, R_FS, 0);
1120 31fc12df blueswir1
    cpu_x86_load_seg(env, R_GS, 0);
1121 31fc12df blueswir1
#endif
1122 31fc12df blueswir1
#elif defined(TARGET_SPARC)
1123 84778508 blueswir1
    {
1124 84778508 blueswir1
        int i;
1125 84778508 blueswir1
        env->pc = regs->pc;
1126 84778508 blueswir1
        env->npc = regs->npc;
1127 84778508 blueswir1
        env->y = regs->y;
1128 84778508 blueswir1
        for(i = 0; i < 8; i++)
1129 84778508 blueswir1
            env->gregs[i] = regs->u_regs[i];
1130 84778508 blueswir1
        for(i = 0; i < 8; i++)
1131 84778508 blueswir1
            env->regwptr[i] = regs->u_regs[i + 8];
1132 84778508 blueswir1
    }
1133 84778508 blueswir1
#else
1134 84778508 blueswir1
#error unsupported target CPU
1135 84778508 blueswir1
#endif
1136 84778508 blueswir1
1137 84778508 blueswir1
    if (gdbstub_port) {
1138 84778508 blueswir1
        gdbserver_start (gdbstub_port);
1139 84778508 blueswir1
        gdb_handlesig(env, 0);
1140 84778508 blueswir1
    }
1141 78cfb07f Juergen Lock
    cpu_loop(env);
1142 84778508 blueswir1
    /* never exits */
1143 84778508 blueswir1
    return 0;
1144 84778508 blueswir1
}