Statistics
| Branch: | Revision:

root / linux-user / main.c @ 367e86e8

History | View | Annotate | Download (7.7 kB)

1 31e31b8a bellard
/*
2 31e31b8a bellard
 *  emu main
3 31e31b8a bellard
 * 
4 31e31b8a bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 31e31b8a bellard
 *
6 31e31b8a bellard
 *  This program is free software; you can redistribute it and/or modify
7 31e31b8a bellard
 *  it under the terms of the GNU General Public License as published by
8 31e31b8a bellard
 *  the Free Software Foundation; either version 2 of the License, or
9 31e31b8a bellard
 *  (at your option) any later version.
10 31e31b8a bellard
 *
11 31e31b8a bellard
 *  This program is distributed in the hope that it will be useful,
12 31e31b8a bellard
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 31e31b8a bellard
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 31e31b8a bellard
 *  GNU General Public License for more details.
15 31e31b8a bellard
 *
16 31e31b8a bellard
 *  You should have received a copy of the GNU General Public License
17 31e31b8a bellard
 *  along with this program; if not, write to the Free Software
18 31e31b8a bellard
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 31e31b8a bellard
 */
20 31e31b8a bellard
#include <stdlib.h>
21 31e31b8a bellard
#include <stdio.h>
22 31e31b8a bellard
#include <stdarg.h>
23 31e31b8a bellard
#include <errno.h>
24 31e31b8a bellard
25 31e31b8a bellard
#include "gemu.h"
26 31e31b8a bellard
27 31e31b8a bellard
#include "i386/hsw_interp.h"
28 31e31b8a bellard
29 31e31b8a bellard
unsigned long x86_stack_size;
30 31e31b8a bellard
unsigned long stktop;
31 31e31b8a bellard
32 31e31b8a bellard
void gemu_log(const char *fmt, ...)
33 31e31b8a bellard
{
34 31e31b8a bellard
    va_list ap;
35 31e31b8a bellard
36 31e31b8a bellard
    va_start(ap, fmt);
37 31e31b8a bellard
    vfprintf(stderr, fmt, ap);
38 31e31b8a bellard
    va_end(ap);
39 31e31b8a bellard
}
40 31e31b8a bellard
41 31e31b8a bellard
/* virtual x86 CPU stuff */
42 31e31b8a bellard
43 31e31b8a bellard
extern int invoke_code16(Interp_ENV *, int, int);
44 31e31b8a bellard
extern int invoke_code32(Interp_ENV *, int);
45 31e31b8a bellard
extern char *e_print_cpuemu_regs(ENVPARAMS, int is32);
46 31e31b8a bellard
extern char *e_emu_disasm(ENVPARAMS, unsigned char *org, int is32);
47 31e31b8a bellard
extern void init_npu(void);
48 31e31b8a bellard
49 31e31b8a bellard
Interp_ENV env_global;
50 31e31b8a bellard
Interp_ENV *envp_global;
51 31e31b8a bellard
52 31e31b8a bellard
QWORD EMUtime = 0;
53 31e31b8a bellard
54 31e31b8a bellard
int CEmuStat = 0;
55 31e31b8a bellard
56 31e31b8a bellard
long instr_count;
57 31e31b8a bellard
58 31e31b8a bellard
/* who will initialize this? */
59 31e31b8a bellard
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
60 31e31b8a bellard
61 31e31b8a bellard
/* debug flag, 0=disable 1..9=level */
62 31e31b8a bellard
int d_emu = 0;
63 31e31b8a bellard
64 31e31b8a bellard
unsigned long CRs[5] =
65 31e31b8a bellard
{
66 31e31b8a bellard
        0x00000013,        /* valid bits: 0xe005003f */
67 31e31b8a bellard
        0x00000000,        /* invalid */
68 31e31b8a bellard
        0x00000000,
69 31e31b8a bellard
        0x00000000,
70 31e31b8a bellard
        0x00000000
71 31e31b8a bellard
};
72 31e31b8a bellard
73 31e31b8a bellard
/*
74 31e31b8a bellard
 * DR0-3 = linear address of breakpoint 0-3
75 31e31b8a bellard
 * DR4=5 = reserved
76 31e31b8a bellard
 * DR6        b0-b3 = BP active
77 31e31b8a bellard
 *        b13   = BD
78 31e31b8a bellard
 *        b14   = BS
79 31e31b8a bellard
 *        b15   = BT
80 31e31b8a bellard
 * DR7        b0-b1 = G:L bp#0
81 31e31b8a bellard
 *        b2-b3 = G:L bp#1
82 31e31b8a bellard
 *        b4-b5 = G:L bp#2
83 31e31b8a bellard
 *        b6-b7 = G:L bp#3
84 31e31b8a bellard
 *        b8-b9 = GE:LE
85 31e31b8a bellard
 *        b13   = GD
86 31e31b8a bellard
 *        b16-19= LLRW bp#0        LL=00(1),01(2),11(4)
87 31e31b8a bellard
 *        b20-23= LLRW bp#1        RW=00(x),01(w),11(rw)
88 31e31b8a bellard
 *        b24-27= LLRW bp#2
89 31e31b8a bellard
 *        b28-31= LLRW bp#3
90 31e31b8a bellard
 */
91 31e31b8a bellard
unsigned long DRs[8] =
92 31e31b8a bellard
{
93 31e31b8a bellard
        0x00000000,
94 31e31b8a bellard
        0x00000000,
95 31e31b8a bellard
        0x00000000,
96 31e31b8a bellard
        0x00000000,
97 31e31b8a bellard
        0xffff1ff0,
98 31e31b8a bellard
        0x00000400,
99 31e31b8a bellard
        0xffff1ff0,
100 31e31b8a bellard
        0x00000400
101 31e31b8a bellard
};
102 31e31b8a bellard
103 31e31b8a bellard
unsigned long TRs[2] =
104 31e31b8a bellard
{
105 31e31b8a bellard
        0x00000000,
106 31e31b8a bellard
        0x00000000
107 31e31b8a bellard
};
108 31e31b8a bellard
109 31e31b8a bellard
void FatalAppExit(UINT wAction, LPCSTR lpText)
110 31e31b8a bellard
{
111 31e31b8a bellard
    fprintf(stderr, "Fatal error '%s' in CPU\n", lpText);
112 31e31b8a bellard
    exit(1);
113 31e31b8a bellard
}
114 31e31b8a bellard
115 31e31b8a bellard
int e_debug_check(unsigned char *PC)
116 31e31b8a bellard
{
117 31e31b8a bellard
    register unsigned long d7 = DRs[7];
118 31e31b8a bellard
119 31e31b8a bellard
    if (d7&0x03) {
120 31e31b8a bellard
        if (d7&0x30000) return 0;        /* only execute(00) bkp */
121 31e31b8a bellard
        if ((long)PC==DRs[0]) {
122 31e31b8a bellard
            e_printf("DBRK: DR0 hit at %p\n",PC);
123 31e31b8a bellard
            DRs[6] |= 1;
124 31e31b8a bellard
            return 1;
125 31e31b8a bellard
        }
126 31e31b8a bellard
    }
127 31e31b8a bellard
    if (d7&0x0c) {
128 31e31b8a bellard
        if (d7&0x300000) return 0;
129 31e31b8a bellard
        if ((long)PC==DRs[1]) {
130 31e31b8a bellard
            e_printf("DBRK: DR1 hit at %p\n",PC);
131 31e31b8a bellard
            DRs[6] |= 2;
132 31e31b8a bellard
            return 1;
133 31e31b8a bellard
        }
134 31e31b8a bellard
    }
135 31e31b8a bellard
    if (d7&0x30) {
136 31e31b8a bellard
        if (d7&0x3000000) return 0;
137 31e31b8a bellard
        if ((long)PC==DRs[2]) {
138 31e31b8a bellard
            e_printf("DBRK: DR2 hit at %p\n",PC);
139 31e31b8a bellard
            DRs[6] |= 4;
140 31e31b8a bellard
            return 1;
141 31e31b8a bellard
        }
142 31e31b8a bellard
    }
143 31e31b8a bellard
    if (d7&0xc0) {
144 31e31b8a bellard
        if (d7&0x30000000) return 0;
145 31e31b8a bellard
        if ((long)PC==DRs[3]) {
146 31e31b8a bellard
            e_printf("DBRK: DR3 hit at %p\n",PC);
147 31e31b8a bellard
            DRs[6] |= 8;
148 31e31b8a bellard
            return 1;
149 31e31b8a bellard
        }
150 31e31b8a bellard
    }
151 31e31b8a bellard
    return 0;
152 31e31b8a bellard
}
153 31e31b8a bellard
154 31e31b8a bellard
/* Debug stuff */
155 31e31b8a bellard
void logstr(unsigned long mask, const char *fmt,...) 
156 31e31b8a bellard
{
157 31e31b8a bellard
    va_list ap;
158 31e31b8a bellard
159 31e31b8a bellard
    va_start(ap, fmt);
160 31e31b8a bellard
    vfprintf(stderr, fmt, ap);
161 31e31b8a bellard
    va_end(ap);
162 31e31b8a bellard
}
163 31e31b8a bellard
164 31e31b8a bellard
/* unconditional message into debug log and stderr */
165 31e31b8a bellard
#undef error
166 31e31b8a bellard
void error(const char *fmt, ...)
167 31e31b8a bellard
{
168 31e31b8a bellard
    va_list ap;
169 31e31b8a bellard
170 31e31b8a bellard
    va_start(ap, fmt);
171 31e31b8a bellard
    vfprintf(stderr, fmt, ap);
172 31e31b8a bellard
    va_end(ap);
173 31e31b8a bellard
    exit(1);
174 31e31b8a bellard
}
175 31e31b8a bellard
176 31e31b8a bellard
int PortIO(DWORD port, DWORD value, UINT size, BOOL is_write)
177 31e31b8a bellard
{
178 31e31b8a bellard
    fprintf(stderr, "IO: %s port=0x%lx value=0x%lx size=%d",
179 31e31b8a bellard
            is_write ? "write" : "read", port, value, size);
180 31e31b8a bellard
    return value;
181 31e31b8a bellard
}
182 31e31b8a bellard
183 31e31b8a bellard
void LogProcName(WORD wSel, WORD wOff, WORD wAction)
184 31e31b8a bellard
{
185 31e31b8a bellard
186 31e31b8a bellard
}
187 31e31b8a bellard
188 31e31b8a bellard
void INT_handler(int num, void *env)
189 31e31b8a bellard
{
190 31e31b8a bellard
  fprintf(stderr, "EM86: int %d\n", num);
191 31e31b8a bellard
}
192 31e31b8a bellard
193 31e31b8a bellard
/***********************************************************/
194 367e86e8 bellard
/* new CPU core */
195 367e86e8 bellard
196 367e86e8 bellard
void port_outb(int addr, int val)
197 367e86e8 bellard
{
198 367e86e8 bellard
    fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
199 367e86e8 bellard
}
200 367e86e8 bellard
201 367e86e8 bellard
void port_outw(int addr, int val)
202 367e86e8 bellard
{
203 367e86e8 bellard
    fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
204 367e86e8 bellard
}
205 367e86e8 bellard
206 367e86e8 bellard
void port_outl(int addr, int val)
207 367e86e8 bellard
{
208 367e86e8 bellard
    fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
209 367e86e8 bellard
}
210 367e86e8 bellard
211 367e86e8 bellard
int port_inb(int addr)
212 367e86e8 bellard
{
213 367e86e8 bellard
    fprintf(stderr, "inb: port=0x%04x\n", addr);
214 367e86e8 bellard
    return 0;
215 367e86e8 bellard
}
216 367e86e8 bellard
217 367e86e8 bellard
int port_inw(int addr)
218 367e86e8 bellard
{
219 367e86e8 bellard
    fprintf(stderr, "inw: port=0x%04x\n", addr);
220 367e86e8 bellard
    return 0;
221 367e86e8 bellard
}
222 367e86e8 bellard
223 367e86e8 bellard
int port_inl(int addr)
224 367e86e8 bellard
{
225 367e86e8 bellard
    fprintf(stderr, "inl: port=0x%04x\n", addr);
226 367e86e8 bellard
    return 0;
227 367e86e8 bellard
}
228 367e86e8 bellard
229 31e31b8a bellard
230 31e31b8a bellard
/* XXX: currently we use LDT entries */
231 31e31b8a bellard
#define __USER_CS        (0x23|4)
232 31e31b8a bellard
#define __USER_DS        (0x2B|4)
233 31e31b8a bellard
234 31e31b8a bellard
void usage(void)
235 31e31b8a bellard
{
236 31e31b8a bellard
    printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
237 31e31b8a bellard
           "usage: gemu program [arguments...]\n"
238 31e31b8a bellard
           "Linux x86 emulator\n"
239 31e31b8a bellard
           );
240 31e31b8a bellard
    exit(1);
241 31e31b8a bellard
}
242 31e31b8a bellard
243 31e31b8a bellard
int main(int argc, char **argv)
244 31e31b8a bellard
{
245 31e31b8a bellard
    const char *filename;
246 01ffc75b bellard
    struct target_pt_regs regs1, *regs = &regs1;
247 31e31b8a bellard
    struct image_info info1, *info = &info1;
248 31e31b8a bellard
    Interp_ENV *env;
249 31e31b8a bellard
250 31e31b8a bellard
    if (argc <= 1)
251 31e31b8a bellard
        usage();
252 31e31b8a bellard
    
253 31e31b8a bellard
    filename = argv[1];
254 31e31b8a bellard
255 31e31b8a bellard
    /* Zero out regs */
256 01ffc75b bellard
    memset(regs, 0, sizeof(struct target_pt_regs));
257 31e31b8a bellard
258 31e31b8a bellard
    /* Zero out image_info */
259 31e31b8a bellard
    memset(info, 0, sizeof(struct image_info));
260 31e31b8a bellard
261 01ffc75b bellard
    if(elf_exec(filename, argv+1, environ, regs, info) != 0) {
262 31e31b8a bellard
        printf("Error loading %s\n", filename);
263 31e31b8a bellard
        exit(1);
264 31e31b8a bellard
    }
265 31e31b8a bellard
    
266 31e31b8a bellard
#if 0
267 31e31b8a bellard
    printf("start_brk   0x%08lx\n" , info->start_brk);
268 31e31b8a bellard
    printf("end_code    0x%08lx\n" , info->end_code);
269 31e31b8a bellard
    printf("start_code  0x%08lx\n" , info->start_code);
270 31e31b8a bellard
    printf("end_data    0x%08lx\n" , info->end_data);
271 31e31b8a bellard
    printf("start_stack 0x%08lx\n" , info->start_stack);
272 31e31b8a bellard
    printf("brk         0x%08lx\n" , info->brk);
273 31e31b8a bellard
    printf("esp         0x%08lx\n" , regs->esp);
274 31e31b8a bellard
    printf("eip         0x%08lx\n" , regs->eip);
275 31e31b8a bellard
#endif
276 31e31b8a bellard
277 31e31b8a bellard
    target_set_brk((char *)info->brk);
278 31e31b8a bellard
    syscall_init();
279 31e31b8a bellard
280 31e31b8a bellard
    env = &env_global;
281 31e31b8a bellard
    envp_global = env;
282 31e31b8a bellard
    memset(env, 0, sizeof(Interp_ENV));
283 31e31b8a bellard
284 31e31b8a bellard
    env->rax.e   = regs->eax;
285 31e31b8a bellard
    env->rbx.e   = regs->ebx;
286 31e31b8a bellard
    env->rcx.e   = regs->ecx;
287 31e31b8a bellard
    env->rdx.e   = regs->edx;
288 31e31b8a bellard
    env->rsi.esi = regs->esi;
289 31e31b8a bellard
    env->rdi.edi = regs->edi;
290 31e31b8a bellard
    env->rbp.ebp = regs->ebp;
291 31e31b8a bellard
    env->rsp.esp = regs->esp;
292 31e31b8a bellard
    env->cs.cs   = __USER_CS;
293 31e31b8a bellard
    env->ds.ds   = __USER_DS;
294 31e31b8a bellard
    env->es.es   = __USER_DS;
295 31e31b8a bellard
    env->ss.ss   = __USER_DS;
296 31e31b8a bellard
    env->fs.fs   = __USER_DS;
297 31e31b8a bellard
    env->gs.gs   = __USER_DS;
298 31e31b8a bellard
    env->trans_addr = regs->eip;
299 31e31b8a bellard
300 31e31b8a bellard
    LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
301 31e31b8a bellard
    LDT[__USER_CS >> 3].dwSelLimit = 0xfffff;
302 31e31b8a bellard
    LDT[__USER_CS >> 3].lpSelBase = NULL;
303 31e31b8a bellard
304 31e31b8a bellard
    LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
305 31e31b8a bellard
    LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
306 31e31b8a bellard
    LDT[__USER_DS >> 3].lpSelBase = NULL;
307 31e31b8a bellard
    init_npu();
308 367e86e8 bellard
    build_decode_tables();
309 31e31b8a bellard
310 31e31b8a bellard
    for(;;) {
311 31e31b8a bellard
        int err;
312 31e31b8a bellard
        uint8_t *pc;
313 31e31b8a bellard
314 31e31b8a bellard
        err = invoke_code32(env, -1);
315 31e31b8a bellard
        env->trans_addr = env->return_addr;
316 31e31b8a bellard
        pc = env->seg_regs[0] + env->trans_addr;
317 31e31b8a bellard
        switch(err) {
318 31e31b8a bellard
        case EXCP0D_GPF:
319 31e31b8a bellard
            if (pc[0] == 0xcd && pc[1] == 0x80) {
320 31e31b8a bellard
                /* syscall */
321 31e31b8a bellard
                env->trans_addr += 2;
322 31e31b8a bellard
                env->rax.e = do_syscall(env->rax.e, 
323 31e31b8a bellard
                                        env->rbx.e,
324 31e31b8a bellard
                                        env->rcx.e,
325 31e31b8a bellard
                                        env->rdx.e,
326 31e31b8a bellard
                                        env->rsi.esi,
327 31e31b8a bellard
                                        env->rdi.edi,
328 31e31b8a bellard
                                        env->rbp.ebp);
329 31e31b8a bellard
            } else {
330 31e31b8a bellard
                goto trap_error;
331 31e31b8a bellard
            }
332 31e31b8a bellard
            break;
333 31e31b8a bellard
        default:
334 31e31b8a bellard
        trap_error:
335 31e31b8a bellard
            fprintf(stderr, "GEMU: Unknown error %d, aborting\n", err);
336 5147f5aa bellard
#ifndef NO_TRACE_MSGS
337 31e31b8a bellard
            d_emu = 9;
338 31e31b8a bellard
            fprintf(stderr, "%s\n%s\n",
339 31e31b8a bellard
                    e_print_cpuemu_regs(env, 1), 
340 31e31b8a bellard
                    e_emu_disasm(env,pc,1));
341 5147f5aa bellard
#endif
342 31e31b8a bellard
            abort();
343 31e31b8a bellard
        }
344 31e31b8a bellard
    }
345 31e31b8a bellard
    return 0;
346 31e31b8a bellard
}