Revision 5fafdf24 linux-user/vm86.c
b/linux-user/vm86.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* vm86 linux syscall support |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Copyright (c) 2003 Fabrice Bellard |
5 | 5 |
* |
6 | 6 |
* This program is free software; you can redistribute it and/or modify |
... | ... | |
85 | 85 |
target_v86->regs.eflags = tswap32(env->eflags); |
86 | 86 |
unlock_user_struct(target_v86, ts->target_v86, 1); |
87 | 87 |
#ifdef DEBUG_VM86 |
88 |
fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n",
|
|
88 |
fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n", |
|
89 | 89 |
env->eflags, env->segs[R_CS].selector, env->eip); |
90 | 90 |
#endif |
91 | 91 |
|
... | ... | |
123 | 123 |
static inline int set_IF(CPUX86State *env) |
124 | 124 |
{ |
125 | 125 |
TaskState *ts = env->opaque; |
126 |
|
|
126 |
|
|
127 | 127 |
ts->v86flags |= VIF_MASK; |
128 | 128 |
if (ts->v86flags & VIP_MASK) { |
129 | 129 |
return_to_32bit(env, TARGET_VM86_STI); |
... | ... | |
202 | 202 |
goto cannot_handle; |
203 | 203 |
if (is_revectored(intno, &ts->vm86plus.int_revectored)) |
204 | 204 |
goto cannot_handle; |
205 |
if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
|
|
205 |
if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff, |
|
206 | 206 |
&ts->vm86plus.int21_revectored)) |
207 | 207 |
goto cannot_handle; |
208 | 208 |
int_ptr = (uint32_t *)(intno << 2); |
... | ... | |
210 | 210 |
if ((segoffs >> 16) == TARGET_BIOSSEG) |
211 | 211 |
goto cannot_handle; |
212 | 212 |
#if defined(DEBUG_VM86) |
213 |
fprintf(logfile, "VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",
|
|
213 |
fprintf(logfile, "VM86: emulating int 0x%x. CS:IP=%04x:%04x\n", |
|
214 | 214 |
intno, segoffs >> 16, segoffs & 0xffff); |
215 | 215 |
#endif |
216 | 216 |
/* save old state */ |
... | ... | |
264 | 264 |
csp = (uint8_t *)(env->segs[R_CS].selector << 4); |
265 | 265 |
ip = env->eip & 0xffff; |
266 | 266 |
pc = csp + ip; |
267 |
|
|
267 |
|
|
268 | 268 |
ssp = (uint8_t *)(env->segs[R_SS].selector << 4); |
269 | 269 |
sp = env->regs[R_ESP] & 0xffff; |
270 | 270 |
|
... | ... | |
330 | 330 |
ADD16(ip, 1); |
331 | 331 |
env->eip = ip; |
332 | 332 |
if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) { |
333 |
if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >>
|
|
333 |
if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >> |
|
334 | 334 |
(intno &7)) & 1) { |
335 | 335 |
return_to_32bit(env, TARGET_VM86_INTx + (intno << 8)); |
336 | 336 |
return; |
... | ... | |
362 | 362 |
return; |
363 | 363 |
} |
364 | 364 |
VM86_FAULT_RETURN; |
365 |
|
|
365 |
|
|
366 | 366 |
case 0xfa: /* cli */ |
367 | 367 |
env->eip = ip; |
368 | 368 |
clear_IF(env); |
369 | 369 |
VM86_FAULT_RETURN; |
370 |
|
|
370 |
|
|
371 | 371 |
case 0xfb: /* sti */ |
372 | 372 |
env->eip = ip; |
373 | 373 |
if (set_IF(env)) |
... | ... | |
386 | 386 |
TaskState *ts = env->opaque; |
387 | 387 |
struct target_vm86plus_struct * target_v86; |
388 | 388 |
int ret; |
389 |
|
|
389 |
|
|
390 | 390 |
switch (subfunction) { |
391 | 391 |
case TARGET_VM86_REQUEST_IRQ: |
392 | 392 |
case TARGET_VM86_FREE_IRQ: |
... | ... | |
427 | 427 |
lock_user_struct(target_v86, vm86_addr, 1); |
428 | 428 |
/* build vm86 CPU state */ |
429 | 429 |
ts->v86flags = tswap32(target_v86->regs.eflags); |
430 |
env->eflags = (env->eflags & ~SAFE_MASK) |
|
|
430 |
env->eflags = (env->eflags & ~SAFE_MASK) | |
|
431 | 431 |
(tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK; |
432 | 432 |
|
433 | 433 |
ts->vm86plus.cpu_type = tswapl(target_v86->cpu_type); |
... | ... | |
462 | 462 |
cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs)); |
463 | 463 |
ret = tswap32(target_v86->regs.eax); /* eax will be restored at |
464 | 464 |
the end of the syscall */ |
465 |
memcpy(&ts->vm86plus.int_revectored,
|
|
465 |
memcpy(&ts->vm86plus.int_revectored, |
|
466 | 466 |
&target_v86->int_revectored, 32); |
467 |
memcpy(&ts->vm86plus.int21_revectored,
|
|
467 |
memcpy(&ts->vm86plus.int21_revectored, |
|
468 | 468 |
&target_v86->int21_revectored, 32); |
469 | 469 |
ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags); |
470 |
memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
|
|
470 |
memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab, |
|
471 | 471 |
target_v86->vm86plus.vm86dbg_intxxtab, 32); |
472 | 472 |
unlock_user_struct(target_v86, vm86_addr, 0); |
473 |
|
|
473 |
|
|
474 | 474 |
#ifdef DEBUG_VM86 |
475 |
fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n",
|
|
475 |
fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", |
|
476 | 476 |
env->segs[R_CS].selector, env->eip); |
477 | 477 |
#endif |
478 | 478 |
/* now the virtual CPU is ready for vm86 execution ! */ |
Also available in: Unified diff