Statistics
| Branch: | Revision:

root / bsd-user / main.c @ ef845c3b

History | View | Annotate | Download (30.7 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 84778508 blueswir1
#include "exec-all.h"
33 84778508 blueswir1
34 fc0d96b4 Blue Swirl
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 84778508 blueswir1
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
47 84778508 blueswir1
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
48 84778508 blueswir1
extern char **environ;
49 84778508 blueswir1
50 84778508 blueswir1
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
51 84778508 blueswir1
   we allocate a bigger stack. Need a better solution, for example
52 84778508 blueswir1
   by remapping the process stack directly at the right place */
53 84778508 blueswir1
unsigned long x86_stack_size = 512 * 1024;
54 84778508 blueswir1
55 84778508 blueswir1
void gemu_log(const char *fmt, ...)
56 84778508 blueswir1
{
57 84778508 blueswir1
    va_list ap;
58 84778508 blueswir1
59 84778508 blueswir1
    va_start(ap, fmt);
60 84778508 blueswir1
    vfprintf(stderr, fmt, ap);
61 84778508 blueswir1
    va_end(ap);
62 84778508 blueswir1
}
63 9399f095 blueswir1
64 31fc12df blueswir1
#if defined(TARGET_I386)
65 31fc12df blueswir1
int cpu_get_pic_interrupt(CPUState *env)
66 31fc12df blueswir1
{
67 31fc12df blueswir1
    return -1;
68 31fc12df blueswir1
}
69 31fc12df blueswir1
#endif
70 31fc12df blueswir1
71 9399f095 blueswir1
/* These are no-ops because we are not threadsafe.  */
72 9399f095 blueswir1
static inline void cpu_exec_start(CPUState *env)
73 9399f095 blueswir1
{
74 9399f095 blueswir1
}
75 9399f095 blueswir1
76 9399f095 blueswir1
static inline void cpu_exec_end(CPUState *env)
77 9399f095 blueswir1
{
78 9399f095 blueswir1
}
79 9399f095 blueswir1
80 9399f095 blueswir1
static inline void start_exclusive(void)
81 9399f095 blueswir1
{
82 9399f095 blueswir1
}
83 9399f095 blueswir1
84 9399f095 blueswir1
static inline void end_exclusive(void)
85 9399f095 blueswir1
{
86 9399f095 blueswir1
}
87 9399f095 blueswir1
88 9399f095 blueswir1
void fork_start(void)
89 9399f095 blueswir1
{
90 9399f095 blueswir1
}
91 9399f095 blueswir1
92 9399f095 blueswir1
void fork_end(int child)
93 9399f095 blueswir1
{
94 9399f095 blueswir1
    if (child) {
95 9399f095 blueswir1
        gdbserver_fork(thread_env);
96 9399f095 blueswir1
    }
97 9399f095 blueswir1
}
98 9399f095 blueswir1
99 9399f095 blueswir1
void cpu_list_lock(void)
100 9399f095 blueswir1
{
101 9399f095 blueswir1
}
102 9399f095 blueswir1
103 9399f095 blueswir1
void cpu_list_unlock(void)
104 9399f095 blueswir1
{
105 9399f095 blueswir1
}
106 9399f095 blueswir1
107 31fc12df blueswir1
#ifdef TARGET_I386
108 31fc12df blueswir1
/***********************************************************/
109 31fc12df blueswir1
/* CPUX86 core interface */
110 31fc12df blueswir1
111 31fc12df blueswir1
void cpu_smm_update(CPUState *env)
112 31fc12df blueswir1
{
113 31fc12df blueswir1
}
114 31fc12df blueswir1
115 31fc12df blueswir1
uint64_t cpu_get_tsc(CPUX86State *env)
116 31fc12df blueswir1
{
117 31fc12df blueswir1
    return cpu_get_real_ticks();
118 31fc12df blueswir1
}
119 31fc12df blueswir1
120 31fc12df blueswir1
static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
121 31fc12df blueswir1
                     int flags)
122 31fc12df blueswir1
{
123 31fc12df blueswir1
    unsigned int e1, e2;
124 31fc12df blueswir1
    uint32_t *p;
125 31fc12df blueswir1
    e1 = (addr << 16) | (limit & 0xffff);
126 31fc12df blueswir1
    e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
127 31fc12df blueswir1
    e2 |= flags;
128 31fc12df blueswir1
    p = ptr;
129 31fc12df blueswir1
    p[0] = tswap32(e1);
130 31fc12df blueswir1
    p[1] = tswap32(e2);
131 31fc12df blueswir1
}
132 31fc12df blueswir1
133 31fc12df blueswir1
static uint64_t *idt_table;
134 31fc12df blueswir1
#ifdef TARGET_X86_64
135 31fc12df blueswir1
static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
136 31fc12df blueswir1
                       uint64_t addr, unsigned int sel)
137 31fc12df blueswir1
{
138 31fc12df blueswir1
    uint32_t *p, e1, e2;
139 31fc12df blueswir1
    e1 = (addr & 0xffff) | (sel << 16);
140 31fc12df blueswir1
    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
141 31fc12df blueswir1
    p = ptr;
142 31fc12df blueswir1
    p[0] = tswap32(e1);
143 31fc12df blueswir1
    p[1] = tswap32(e2);
144 31fc12df blueswir1
    p[2] = tswap32(addr >> 32);
145 31fc12df blueswir1
    p[3] = 0;
146 31fc12df blueswir1
}
147 31fc12df blueswir1
/* only dpl matters as we do only user space emulation */
148 31fc12df blueswir1
static void set_idt(int n, unsigned int dpl)
149 31fc12df blueswir1
{
150 31fc12df blueswir1
    set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
151 31fc12df blueswir1
}
152 31fc12df blueswir1
#else
153 31fc12df blueswir1
static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
154 31fc12df blueswir1
                     uint32_t addr, unsigned int sel)
155 31fc12df blueswir1
{
156 31fc12df blueswir1
    uint32_t *p, e1, e2;
157 31fc12df blueswir1
    e1 = (addr & 0xffff) | (sel << 16);
158 31fc12df blueswir1
    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
159 31fc12df blueswir1
    p = ptr;
160 31fc12df blueswir1
    p[0] = tswap32(e1);
161 31fc12df blueswir1
    p[1] = tswap32(e2);
162 31fc12df blueswir1
}
163 31fc12df blueswir1
164 31fc12df blueswir1
/* only dpl matters as we do only user space emulation */
165 31fc12df blueswir1
static void set_idt(int n, unsigned int dpl)
166 31fc12df blueswir1
{
167 31fc12df blueswir1
    set_gate(idt_table + n, 0, dpl, 0, 0);
168 31fc12df blueswir1
}
169 31fc12df blueswir1
#endif
170 31fc12df blueswir1
171 31fc12df blueswir1
void cpu_loop(CPUX86State *env, enum BSDType bsd_type)
172 31fc12df blueswir1
{
173 31fc12df blueswir1
    int trapnr;
174 31fc12df blueswir1
    abi_ulong pc;
175 31fc12df blueswir1
    //target_siginfo_t info;
176 31fc12df blueswir1
177 31fc12df blueswir1
    for(;;) {
178 31fc12df blueswir1
        trapnr = cpu_x86_exec(env);
179 31fc12df blueswir1
        switch(trapnr) {
180 31fc12df blueswir1
        case 0x80:
181 31fc12df blueswir1
            /* syscall from int $0x80 */
182 31fc12df blueswir1
            env->regs[R_EAX] = do_openbsd_syscall(env,
183 31fc12df blueswir1
                                                  env->regs[R_EAX],
184 31fc12df blueswir1
                                                  env->regs[R_EBX],
185 31fc12df blueswir1
                                                  env->regs[R_ECX],
186 31fc12df blueswir1
                                                  env->regs[R_EDX],
187 31fc12df blueswir1
                                                  env->regs[R_ESI],
188 31fc12df blueswir1
                                                  env->regs[R_EDI],
189 31fc12df blueswir1
                                                  env->regs[R_EBP]);
190 31fc12df blueswir1
            break;
191 31fc12df blueswir1
#ifndef TARGET_ABI32
192 31fc12df blueswir1
        case EXCP_SYSCALL:
193 31fc12df blueswir1
            /* linux syscall from syscall intruction */
194 31fc12df blueswir1
            env->regs[R_EAX] = do_openbsd_syscall(env,
195 31fc12df blueswir1
                                                  env->regs[R_EAX],
196 31fc12df blueswir1
                                                  env->regs[R_EDI],
197 31fc12df blueswir1
                                                  env->regs[R_ESI],
198 31fc12df blueswir1
                                                  env->regs[R_EDX],
199 31fc12df blueswir1
                                                  env->regs[10],
200 31fc12df blueswir1
                                                  env->regs[8],
201 31fc12df blueswir1
                                                  env->regs[9]);
202 31fc12df blueswir1
            env->eip = env->exception_next_eip;
203 31fc12df blueswir1
            break;
204 31fc12df blueswir1
#endif
205 31fc12df blueswir1
#if 0
206 31fc12df blueswir1
        case EXCP0B_NOSEG:
207 31fc12df blueswir1
        case EXCP0C_STACK:
208 31fc12df blueswir1
            info.si_signo = SIGBUS;
209 31fc12df blueswir1
            info.si_errno = 0;
210 31fc12df blueswir1
            info.si_code = TARGET_SI_KERNEL;
211 31fc12df blueswir1
            info._sifields._sigfault._addr = 0;
212 31fc12df blueswir1
            queue_signal(env, info.si_signo, &info);
213 31fc12df blueswir1
            break;
214 31fc12df blueswir1
        case EXCP0D_GPF:
215 31fc12df blueswir1
            /* XXX: potential problem if ABI32 */
216 31fc12df blueswir1
#ifndef TARGET_X86_64
217 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
218 31fc12df blueswir1
                handle_vm86_fault(env);
219 31fc12df blueswir1
            } else
220 31fc12df blueswir1
#endif
221 31fc12df blueswir1
            {
222 31fc12df blueswir1
                info.si_signo = SIGSEGV;
223 31fc12df blueswir1
                info.si_errno = 0;
224 31fc12df blueswir1
                info.si_code = TARGET_SI_KERNEL;
225 31fc12df blueswir1
                info._sifields._sigfault._addr = 0;
226 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
227 31fc12df blueswir1
            }
228 31fc12df blueswir1
            break;
229 31fc12df blueswir1
        case EXCP0E_PAGE:
230 31fc12df blueswir1
            info.si_signo = SIGSEGV;
231 31fc12df blueswir1
            info.si_errno = 0;
232 31fc12df blueswir1
            if (!(env->error_code & 1))
233 31fc12df blueswir1
                info.si_code = TARGET_SEGV_MAPERR;
234 31fc12df blueswir1
            else
235 31fc12df blueswir1
                info.si_code = TARGET_SEGV_ACCERR;
236 31fc12df blueswir1
            info._sifields._sigfault._addr = env->cr[2];
237 31fc12df blueswir1
            queue_signal(env, info.si_signo, &info);
238 31fc12df blueswir1
            break;
239 31fc12df blueswir1
        case EXCP00_DIVZ:
240 31fc12df blueswir1
#ifndef TARGET_X86_64
241 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
242 31fc12df blueswir1
                handle_vm86_trap(env, trapnr);
243 31fc12df blueswir1
            } else
244 31fc12df blueswir1
#endif
245 31fc12df blueswir1
            {
246 31fc12df blueswir1
                /* division by zero */
247 31fc12df blueswir1
                info.si_signo = SIGFPE;
248 31fc12df blueswir1
                info.si_errno = 0;
249 31fc12df blueswir1
                info.si_code = TARGET_FPE_INTDIV;
250 31fc12df blueswir1
                info._sifields._sigfault._addr = env->eip;
251 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
252 31fc12df blueswir1
            }
253 31fc12df blueswir1
            break;
254 31fc12df blueswir1
        case EXCP01_DB:
255 31fc12df blueswir1
        case EXCP03_INT3:
256 31fc12df blueswir1
#ifndef TARGET_X86_64
257 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
258 31fc12df blueswir1
                handle_vm86_trap(env, trapnr);
259 31fc12df blueswir1
            } else
260 31fc12df blueswir1
#endif
261 31fc12df blueswir1
            {
262 31fc12df blueswir1
                info.si_signo = SIGTRAP;
263 31fc12df blueswir1
                info.si_errno = 0;
264 31fc12df blueswir1
                if (trapnr == EXCP01_DB) {
265 31fc12df blueswir1
                    info.si_code = TARGET_TRAP_BRKPT;
266 31fc12df blueswir1
                    info._sifields._sigfault._addr = env->eip;
267 31fc12df blueswir1
                } else {
268 31fc12df blueswir1
                    info.si_code = TARGET_SI_KERNEL;
269 31fc12df blueswir1
                    info._sifields._sigfault._addr = 0;
270 31fc12df blueswir1
                }
271 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
272 31fc12df blueswir1
            }
273 31fc12df blueswir1
            break;
274 31fc12df blueswir1
        case EXCP04_INTO:
275 31fc12df blueswir1
        case EXCP05_BOUND:
276 31fc12df blueswir1
#ifndef TARGET_X86_64
277 31fc12df blueswir1
            if (env->eflags & VM_MASK) {
278 31fc12df blueswir1
                handle_vm86_trap(env, trapnr);
279 31fc12df blueswir1
            } else
280 31fc12df blueswir1
#endif
281 31fc12df blueswir1
            {
282 31fc12df blueswir1
                info.si_signo = SIGSEGV;
283 31fc12df blueswir1
                info.si_errno = 0;
284 31fc12df blueswir1
                info.si_code = TARGET_SI_KERNEL;
285 31fc12df blueswir1
                info._sifields._sigfault._addr = 0;
286 31fc12df blueswir1
                queue_signal(env, info.si_signo, &info);
287 31fc12df blueswir1
            }
288 31fc12df blueswir1
            break;
289 31fc12df blueswir1
        case EXCP06_ILLOP:
290 31fc12df blueswir1
            info.si_signo = SIGILL;
291 31fc12df blueswir1
            info.si_errno = 0;
292 31fc12df blueswir1
            info.si_code = TARGET_ILL_ILLOPN;
293 31fc12df blueswir1
            info._sifields._sigfault._addr = env->eip;
294 31fc12df blueswir1
            queue_signal(env, info.si_signo, &info);
295 31fc12df blueswir1
            break;
296 31fc12df blueswir1
#endif
297 31fc12df blueswir1
        case EXCP_INTERRUPT:
298 31fc12df blueswir1
            /* just indicate that signals should be handled asap */
299 31fc12df blueswir1
            break;
300 31fc12df blueswir1
#if 0
301 31fc12df blueswir1
        case EXCP_DEBUG:
302 31fc12df blueswir1
            {
303 31fc12df blueswir1
                int sig;
304 31fc12df blueswir1

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