From 74bda98cb236130b1d4f84795f7fafd5c8e540a9 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Fri, 3 Aug 2012 16:49:15 +0100 Subject: [PATCH] Killed off vm86 code, no longer being used. --- headers/private/kernel/arch/x86/32/iframe.h | 32 - headers/private/kernel/arch/x86/vm86.h | 42 -- src/system/kernel/arch/x86/32/int.cpp | 1 - src/system/kernel/arch/x86/32/interrupts.S | 109 ---- src/system/kernel/arch/x86/32/vm86.cpp | 668 -------------------- src/system/kernel/arch/x86/Jamfile | 1 - src/system/kernel/arch/x86/arch_int.cpp | 9 - src/system/kernel/arch/x86/asm_offsets.cpp | 4 - 8 files changed, 866 deletions(-) delete mode 100644 headers/private/kernel/arch/x86/vm86.h delete mode 100644 src/system/kernel/arch/x86/32/vm86.cpp diff --git a/headers/private/kernel/arch/x86/32/iframe.h b/headers/private/kernel/arch/x86/32/iframe.h index 1aa51ed90a..47c423826f 100644 --- a/headers/private/kernel/arch/x86/32/iframe.h +++ b/headers/private/kernel/arch/x86/32/iframe.h @@ -37,40 +37,8 @@ struct iframe { uint32 user_ss; }; -struct vm86_iframe { - uint32 type; // iframe type - uint32 __null_gs; - uint32 __null_fs; - uint32 __null_es; - uint32 __null_ds; - uint32 edi; - uint32 esi; - uint32 ebp; - uint32 __kern_esp; - uint32 ebx; - uint32 edx; - uint32 ecx; - uint32 eax; - uint32 orig_eax; - uint32 orig_edx; - uint32 vector; - uint32 error_code; - uint32 eip; - uint16 cs, __csh; - uint32 flags; - uint32 esp; - uint16 ss, __ssh; - - /* vm86 mode specific part */ - uint16 es, __esh; - uint16 ds, __dsh; - uint16 fs, __fsh; - uint16 gs, __gsh; -}; - #define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SEG \ || ((f)->flags & 0x20000) != 0) -#define IFRAME_IS_VM86(f) (((f)->flags & 0x20000) != 0) #endif /* _KERNEL_ARCH_X86_32_IFRAME_H */ diff --git a/headers/private/kernel/arch/x86/vm86.h b/headers/private/kernel/arch/x86/vm86.h deleted file mode 100644 index 7e4692da48..0000000000 --- a/headers/private/kernel/arch/x86/vm86.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2008 Jan Klötzke - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _VM86_H -#define _VM86_H - - -#ifndef __x86_64__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define VM86_MIN_RAM_SIZE 0x1000 -#define RETURN_TO_32_INT 255 - -struct vm86_state { - struct vm86_iframe regs; - area_id bios_area; - area_id ram_area; - unsigned int if_flag : 1; -}; - -status_t x86_vm86_enter(struct vm86_iframe *frame); -void x86_vm86_return(struct vm86_iframe *frame, status_t retval); - -status_t vm86_prepare(struct vm86_state *state, unsigned int ram_size); -void vm86_cleanup(struct vm86_state *state); -status_t vm86_do_int(struct vm86_state *state, uint8 vec); - -#ifdef __cplusplus -} -#endif - -#endif -#endif - - diff --git a/src/system/kernel/arch/x86/32/int.cpp b/src/system/kernel/arch/x86/32/int.cpp index d718623538..e05305d8d8 100644 --- a/src/system/kernel/arch/x86/32/int.cpp +++ b/src/system/kernel/arch/x86/32/int.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include "interrupts.h" diff --git a/src/system/kernel/arch/x86/32/interrupts.S b/src/system/kernel/arch/x86/32/interrupts.S index ea3cd5e5a4..5fde6b901e 100644 --- a/src/system/kernel/arch/x86/32/interrupts.S +++ b/src/system/kernel/arch/x86/32/interrupts.S @@ -516,8 +516,6 @@ STATIC_FUNCTION(int_bottom): // exception. orl $0x10000, IFRAME_flags(%ebp); - testl $0x20000, IFRAME_flags(%ebp) // VM86 mode - jnz int_bottom_vm86 cmp $USER_CODE_SEG, IFRAME_cs(%ebp) // user mode je int_bottom_user @@ -583,36 +581,6 @@ STATIC_FUNCTION(int_bottom_user): FUNCTION_END(int_bottom_user) -STATIC_FUNCTION(int_bottom_vm86): - movl $KERNEL_DATA_SEG,%eax - cld - movl %eax,%ds - movl %eax,%es - - // update the thread's user time - movl %dr3, %edi // thread pointer - cli - UPDATE_THREAD_USER_TIME() - - // leave interrupts disabled -- the handler will enable them, if - // necessary - - pushl %ebp - movl IFRAME_vector(%ebp), %eax - call *gInterruptHandlerTable(, %eax, 4) - - cli // disable interrupts - - // update the thread's kernel time and return - UPDATE_THREAD_KERNEL_TIME() - - // the above will reset the in_kernel flag to 0, but we actually stay - movb $1, THREAD_in_kernel(%edi); - - POP_IFRAME_AND_RETURN() -FUNCTION_END(int_bottom_vm86) - - // test interrupt handler for performance measurements .align 16 FUNCTION(trap98): @@ -856,80 +824,3 @@ FUNCTION(x86_return_to_userland): UPDATE_THREAD_KERNEL_TIME() POP_IFRAME_AND_RETURN() FUNCTION_END(x86_return_to_userland) - - -/* status_t x86_vm86_enter(struct vm86_iframe *frame) */ -FUNCTION(x86_vm86_enter): - // save critical registers - pushf - pushl %edi - pushl %esi - pushl %ebp - pushl %ebx - push %gs - push %fs - - // get pointers - movl 32(%esp), %esi // vm86 iframe - pushl %esi // ... store iframe addr for x86_vm86_return - movl %dr3, %edi // Thread* - - // make sure eflags are in right shape - movl VM86_IFRAME_flags(%esi), %eax - andl $0x200CD5, %eax // leave ID,OF,DF,SF,ZF,AF,PF,CF flags - orl $0x20202, %eax // set VM and IF flags (+10b) - movl %eax, VM86_IFRAME_flags(%esi) - - // update kernel_stack_top and tss.esp0 - pushl THREAD_kernel_stack_top(%edi) - movl %esp, THREAD_kernel_stack_top(%edi) - pushl %esp - call x86_set_tss_and_kstack - - // go to vm86 mode - cli - UPDATE_THREAD_KERNEL_TIME() - lea 20(%esi), %esp - popa - addl $16, %esp - iret -FUNCTION_END(x86_vm86_enter) - - -/* void x86_vm86_return(struct vm86_iframe *frame, status_t retval) */ -FUNCTION(x86_vm86_return): - // set stack to where x86_vm86_enter was left - movl 8(%esp), %ebx - movl 4(%esp), %esi - cli - movl %esi, %esp - addl $VM86_IFRAME_sizeof, %esp - - // save old iframe - popl %eax // old kernel stack top - popl %edi - movl $(VM86_IFRAME_sizeof >> 2), %ecx - cld - rep movsl - - // adjust kernel_stack_top and tss.esp0 - movl %dr3, %edi - movl %eax, THREAD_kernel_stack_top(%edi) - pushl %eax - call x86_set_tss_and_kstack - addl $4, %esp - - // restore registers - movl %ebx, %eax - - // we skip %fs, as this contains the CPU dependent TLS segment - addl $4, %esp; - - pop %gs - popl %ebx - popl %ebp - popl %esi - popl %edi - popf - ret -FUNCTION_END(x86_vm86_return) diff --git a/src/system/kernel/arch/x86/32/vm86.cpp b/src/system/kernel/arch/x86/32/vm86.cpp deleted file mode 100644 index 948b701019..0000000000 --- a/src/system/kernel/arch/x86/32/vm86.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Copyright 2008 Jan Klötzke - * All rights reserved. Distributed under the terms of the MIT License. - * - * Emulation based on the Linux Real Mode Interface library. - * Copyright (C) 1998 by Josh Vanderhoof - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -//#define TRACE_VM86 -#ifdef TRACE_VM86 -# define TRACE(x...) dprintf("[vm86] " x) -# define TRACE_NP(x...) dprintf(x) -#else -# define TRACE(x...) -# define TRACE_NP(x...) -#endif - -#define CLI 0xfa -#define INB 0xec -#define INBI 0xe4 -#define INSB 0x6c -#define INSW 0x6d -#define INTn 0xcd -#define INW 0xed -#define INWI 0xe5 -#define IRET 0xcf -#define OUTB 0xee -#define OUTBI 0xe6 -#define OUTSB 0x6e -#define OUTSW 0x6f -#define OUTW 0xef -#define OUTWI 0xe7 -#define POPF 0x9d -#define PUSHF 0x9c -#define STI 0xfb - -#define I_FLAG (1u << 9) -#define DIRECTION_FLAG (1u << 10) - -#define CSEG 0x2e -#define SSEG 0x36 -#define DSEG 0x3e -#define ESEG 0x26 -#define FSEG 0x64 -#define GSEG 0x65 - - -static inline uint16 -get_int_seg(int i) -{ - return *(uint16 *)(i * 4 + 2); -} - - -static inline uint16 -get_int_off(int i) -{ - return *(uint16 *)(i * 4); -} - - -static inline void -pushw(struct vm86_iframe *regs, uint16 i) -{ - regs->esp -= 2; - *(uint16 *)(((uint32)regs->ss << 4) + regs->esp) = i; -} - - -static inline void -pushl(struct vm86_iframe *regs, uint32 i) -{ - regs->esp -= 4; - *(uint32 *)(((uint32)regs->ss << 4) + regs->esp) = i; -} - - -static inline uint16 -popw(struct vm86_iframe *regs) -{ - uint16 ret = *(uint16 *)(((uint32)regs->ss << 4) + regs->esp); - regs->esp += 2; - return ret; -} - - -static inline uint32 -popl(struct vm86_iframe *regs) -{ - uint32 ret = *(uint32 *)(((uint32)regs->ss << 4) + regs->esp); - regs->esp += 4; - return ret; -} - - -static void -em_ins(struct vm86_iframe *regs, int size) -{ - unsigned int edx, edi; - - edx = regs->edx & 0xffff; - edi = regs->edi & 0xffff; - edi += (unsigned int)regs->es << 4; - - if (regs->flags & DIRECTION_FLAG) { - if (size == 4) - asm volatile ("std; insl; cld" : "=D" (edi) : "d" (edx), "0" (edi)); - else if (size == 2) - asm volatile ("std; insw; cld" : "=D" (edi) : "d" (edx), "0" (edi)); - else - asm volatile ("std; insb; cld" : "=D" (edi) : "d" (edx), "0" (edi)); - } else { - if (size == 4) - asm volatile ("cld; insl" : "=D" (edi) : "d" (edx), "0" (edi)); - else if (size == 2) - asm volatile ("cld; insw" : "=D" (edi) : "d" (edx), "0" (edi)); - else - asm volatile ("cld; insb" : "=D" (edi) : "d" (edx), "0" (edi)); - } - - edi -= (unsigned int)regs->es << 4; - - regs->edi &= 0xffff0000; - regs->edi |= edi & 0xffff; -} - - -static void -em_rep_ins(struct vm86_iframe *regs, int size) -{ - unsigned int cx; - - cx = regs->ecx & 0xffff; - - while (cx--) - em_ins(regs, size); - - regs->ecx &= 0xffff0000; -} - - -static void -em_outs(struct vm86_iframe *regs, int size, int seg) -{ - unsigned int edx, esi, base; - - edx = regs->edx & 0xffff; - esi = regs->esi & 0xffff; - - switch (seg) { - case CSEG: base = regs->cs; break; - case SSEG: base = regs->ss; break; - case ESEG: base = regs->es; break; - case FSEG: base = regs->fs; break; - case GSEG: base = regs->gs; break; - case DSEG: - default: - base = regs->ds; - break; - } - - esi += base << 4; - - if (regs->flags & DIRECTION_FLAG) { - if (size == 4) { - asm volatile ("std; outsl; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } else if (size == 2) { - asm volatile ("std; outsw; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } else { - asm volatile ("std; outsb; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } - } else { - if (size == 4) - asm volatile ("cld; outsl" : "=S" (esi) : "d" (edx), "0" (esi)); - else if (size == 2) - asm volatile ("cld; outsw" : "=S" (esi) : "d" (edx), "0" (esi)); - else - asm volatile ("cld; outsb" : "=S" (esi) : "d" (edx), "0" (esi)); - } - - esi -= base << 4; - - regs->esi &= 0xffff0000; - regs->esi |= esi & 0xffff; -} - - -static void -em_rep_outs(struct vm86_iframe *regs, int size, int seg) -{ - unsigned int cx; - - cx = regs->ecx & 0xffff; - - while (cx--) - em_outs(regs, size, seg); - - regs->ecx &= 0xffff0000; -} - - -static inline void -em_inb(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("inb %w1, %b0" - : "=a" (regs->eax) - : "d" (port), "0" (regs->eax)); -} - - -static inline void -em_inw(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("inw %w1, %w0" - : "=a" (regs->eax) - : "d" (port), "0" (regs->eax)); -} - - -static inline void -em_inl(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("inl %w1, %0" : "=a" (regs->eax) : "d" (port)); -} - - -static inline void -em_outb(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("outb %b0, %w1" : : "a" (regs->eax), "d" (port)); -} - - -static inline void -em_outw(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("outw %w0, %w1" : : "a" (regs->eax), "d" (port)); -} - - -static inline void -em_outl(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("outl %0, %w1" : : "a" (regs->eax), "d" (port)); -} - - -static int -emulate(struct vm86_state *state) -{ - unsigned char *instruction; - struct { - unsigned char seg; - unsigned int size : 1; - unsigned int rep : 1; - } prefix = { DSEG, 0, 0 }; - int ret = 0; - - instruction = (unsigned char *)((unsigned int)state->regs.cs << 4); - instruction += state->regs.eip; - - TRACE("emulate: "); - - /* handle prefixes */ - do { - switch (*instruction) { - case 0x66: - TRACE_NP("[SIZE] "); - prefix.size = 1 - prefix.size; - state->regs.eip++; - instruction++; - break; - case 0xf3: - TRACE_NP("REP "); - prefix.rep = 1; - state->regs.eip++; - instruction++; - break; - case CSEG: - case SSEG: - case DSEG: - case ESEG: - case FSEG: - case GSEG: - TRACE_NP("SEG(0x%02x) ", *instruction); - prefix.seg = *instruction; - state->regs.eip++; - instruction++; - break; - case 0xf0: - case 0xf2: - case 0x67: - /* these prefixes are just ignored */ - TRACE_NP("IGN(0x%02x) ", *instruction); - state->regs.eip++; - instruction++; - break; - default: - ret = 1; - } - } while (!ret); - - /* handle actual instruction */ - ret = 0; - switch (*instruction) { - case INSB: - TRACE_NP("INSB"); - if (prefix.rep) - em_rep_ins(&state->regs, 1); - else - em_ins(&state->regs, 1); - state->regs.eip++; - break; - case INSW: - TRACE_NP("INSW"); - if (prefix.rep) { - if (prefix.size) - em_rep_ins(&state->regs, 4); - else - em_rep_ins(&state->regs, 2); - } else { - if (prefix.size) - em_ins(&state->regs, 4); - else - em_ins(&state->regs, 2); - } - state->regs.eip++; - break; - case OUTSB: - TRACE_NP("OUTSB"); - if (prefix.rep) - em_rep_outs(&state->regs, 1, prefix.seg); - else - em_outs(&state->regs, 1, prefix.seg); - state->regs.eip++; - break; - case OUTSW: - TRACE_NP("OUTSW"); - if (prefix.rep) { - if (prefix.size) - em_rep_outs(&state->regs, 4, prefix.seg); - else - em_rep_outs(&state->regs, 2, prefix.seg); - } else { - if (prefix.size) - em_outs(&state->regs, 4, prefix.seg); - else - em_outs(&state->regs, 2, prefix.seg); - } - state->regs.eip++; - break; - case INBI: - em_inb(&state->regs, instruction[1]); - TRACE_NP("IN al(=0x%02lx), 0x%02x", state->regs.eax & 0xff, - instruction[1]); - state->regs.eip += 2; - break; - case INWI: - if (prefix.size) { - em_inl(&state->regs, instruction[1]); - TRACE_NP("IN eax(=0x%08lx), 0x%02x", state->regs.eax, - instruction[1]); - } else { - em_inw(&state->regs, instruction[1]); - TRACE_NP("IN ax(=0x%04lx), 0x%02x", state->regs.eax & 0xffff, - instruction[1]); - } - state->regs.eip += 2; - break; - case INB: - em_inb(&state->regs, state->regs.edx); - TRACE_NP("IN al(=0x%02lx), dx(0x%04lx)", state->regs.edx & 0xff, - state->regs.edx & 0xffff); - state->regs.eip++; - break; - case INW: - if (prefix.size) { - em_inl(&state->regs, state->regs.edx); - TRACE_NP("IN eax(=0x%08lx), dx(0x%04lx)", state->regs.edx, - state->regs.edx & 0xffff); - } else { - em_inw(&state->regs, state->regs.edx); - TRACE_NP("IN ax(=0x%04lx), dx(0x%04lx)", - state->regs.edx & 0xffff, state->regs.edx & 0xffff); - } - state->regs.eip++; - break; - case OUTBI: - em_outb(&state->regs, instruction[1]); - TRACE_NP("OUT 0x%02x, al(0x%02lx)", instruction[1], - state->regs.eax & 0xff); - state->regs.eip += 2; - break; - case OUTWI: - if (prefix.size) { - em_outl(&state->regs, instruction[1]); - TRACE_NP("OUT 0x%02x, eax(0x%08lx)", instruction[1], - state->regs.eax); - } else { - em_outw(&state->regs, instruction[1]); - TRACE_NP("OUT 0x%02x, ax(0x%04lx)", instruction[1], - state->regs.eax & 0xffff); - } - state->regs.eip += 2; - break; - case OUTB: - em_outb(&state->regs, state->regs.edx); - TRACE_NP("OUT dx(0x%04lx), al(0x%02lx)", state->regs.edx & 0xffff, - state->regs.eax & 0xff); - state->regs.eip++; - break; - case OUTW: - if (prefix.size) { - em_outl(&state->regs, state->regs.edx); - TRACE_NP("OUT dx(0x%04lx), eax(0x%08lx)", - state->regs.edx & 0xffff, state->regs.eax); - } else { - em_outw(&state->regs, state->regs.edx); - TRACE_NP("OUT dx(0x%04lx), ax(0x%04lx)", - state->regs.edx & 0xffff, state->regs.eax & 0xffff); - } - state->regs.eip++; - break; - case INTn: - TRACE_NP("INT 0x%02x", instruction[1]); - if (instruction[1] == RETURN_TO_32_INT) { - ret = 1; - } else { - uint16 flags = state->regs.flags; - - /* store real IF */ - flags &= ~I_FLAG; - flags |= (uint16)state->if_flag << 9; - - pushw(&state->regs, flags); - pushw(&state->regs, state->regs.cs); - pushw(&state->regs, state->regs.eip + 2); - - state->regs.cs = get_int_seg(instruction[1]); - state->regs.eip = get_int_off(instruction[1]); - state->if_flag = 0; - } - break; - case IRET: - TRACE_NP("IRET"); - state->regs.eip = popw(&state->regs); - state->regs.cs = popw(&state->regs); - state->regs.flags = popw(&state->regs); - /* restore IF */ - state->if_flag = (state->regs.flags >> 9) & 0x01; - break; - case CLI: - TRACE_NP("CLI"); - state->if_flag = 0; - state->regs.eip++; - break; - case STI: - TRACE_NP("STI"); - state->if_flag = 1; - state->regs.eip++; - break; - case PUSHF: - { - TRACE_NP("PUSHF"); - uint32 flags = state->regs.flags; - - /* store real IF */ - flags &= ~I_FLAG; - flags |= (uint32)state->if_flag << 9; - if (prefix.size) - pushl(&state->regs, flags); - else - pushw(&state->regs, flags); - state->regs.eip++; - break; - } - case POPF: - { - TRACE_NP("POPF"); - if (prefix.size) - state->regs.flags = popl(&state->regs); - else - state->regs.flags = popw(&state->regs); - /* restore IF */ - state->if_flag = (state->regs.flags >> 9) & 0x01; - state->regs.eip++; - break; - } - default: - TRACE_NP("UNK"); - ret = -1; - } - - TRACE_NP("\n"); - return ret; -} - - -static bool -vm86_fault_callback(addr_t address, addr_t faultAddress, bool isWrite) -{ - struct iframe *frame = x86_get_user_iframe(); - - TRACE("Unhandled fault at %#" B_PRIxADDR " touching %#" B_PRIxADDR - "while %s\n", faultAddress, address, isWrite ? "writing" : "reading"); - - // we shouldn't have unhandled page faults in vm86 mode - x86_vm86_return((struct vm86_iframe *)frame, B_BAD_ADDRESS); - - // not reached - return false; -} - - -// #pragma mark - exported interface - - -/*! Prepare the thread to execute BIOS code in virtual 8086 mode. Initializes - the given \a state to default values and maps the BIOS into the teams - address space. The size of the available conventional RAM is given in - \a ramSize in bytes which should be greater or equal to VM86_MIN_RAM_SIZE. -*/ -extern "C" status_t -vm86_prepare(struct vm86_state *state, unsigned int ramSize) -{ - Team *team = thread_get_current_thread()->team; - status_t ret = B_OK; - area_id vectors; - - state->bios_area = B_ERROR; - - // create RAM area - if (ramSize < VM86_MIN_RAM_SIZE) - ramSize = VM86_MIN_RAM_SIZE; - - void *address; - virtual_address_restrictions virtualRestrictions = {}; - virtualRestrictions.address = NULL; - virtualRestrictions.address_specification = B_EXACT_ADDRESS; - physical_address_restrictions physicalRestrictions = {}; - state->ram_area = create_area_etc(team->id, "dos", ramSize, B_NO_LOCK, - B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, - &physicalRestrictions, &address); - if (state->ram_area < B_OK) { - ret = state->ram_area; - TRACE("Could not create RAM area\n"); - goto error; - } - - // copy int vectors and BIOS data area - vectors = map_physical_memory("int vectors", 0, 0x502, - B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - &address); - if (vectors < B_OK) { - ret = vectors; - TRACE("Could not copy vectors\n"); - goto error; - } - ret = user_memcpy((void *)0, address, 0x502); - *((uint32 *)0) = 0xdeadbeef; - delete_area(vectors); - if (ret != B_OK) - goto error; - - // map vga/bios area - address = (void *)0xa0000; - state->bios_area = vm_map_physical_memory(team->id, "bios", - &address, B_EXACT_ADDRESS, 0x60000, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, - (addr_t)0xa0000, false); - if (state->bios_area < B_OK) { - ret = state->bios_area; - TRACE("Could not map VGA BIOS.\n"); - goto error; - } - - return B_OK; - -error: - if (state->bios_area > B_OK) - vm_delete_area(team->id, state->bios_area, true); - if (state->ram_area > B_OK) - vm_delete_area(team->id, state->ram_area, true); - return ret; -} - - -/*! Free ressources which were allocated by vm86_prepare(). -*/ -extern "C" void -vm86_cleanup(struct vm86_state *state) -{ - Team *team = thread_get_current_thread()->team; - - if (state->bios_area > B_OK) - vm_delete_area(team->id, state->bios_area, true); - if (state->ram_area > B_OK) - vm_delete_area(team->id, state->ram_area, true); -} - - -/*! Execute a BIOS call of interrupt \a vec. The given \a state must be - initialized by vm86_prepare() before, any registers needed by the BIOS too. - - The function will return B_OK if the BIOS was called successfully, - otherwise an apropriate error code. After the call the registers are - copied back to \a state to reflect the status after the BIOS returned. - - Any buffer which is given to the BIOS function may be allocated starting - from address 0x1000 up to the allocated RAM size (see vm86_prepare()). The - area below 0x1000 is not available because it is used for the interrupt - vector table, BIOS data area and as real mode stack. -*/ -extern "C" status_t -vm86_do_int(struct vm86_state *state, uint8 vec) -{ - int8 *ip; - int emuState = 0; - Thread *thread = thread_get_current_thread(); - status_t ret; - - // prepare environment - state->regs.ss = 0x600 >> 4; - state->regs.esp = (0x1000 - 0x600); - state->regs.cs = get_int_seg(vec); - state->regs.eip = get_int_off(vec); - state->if_flag = 0; - - pushw(&state->regs, state->regs.flags); - pushw(&state->regs, 0x0000); /* CS */ - pushw(&state->regs, 0x0600); /* IP */ - - ip = (int8 *)0x600; - *ip++ = INTn; - *ip++ = RETURN_TO_32_INT; - - // execute interrupt - thread->fault_callback = &vm86_fault_callback; - do { - ret = x86_vm86_enter(&state->regs); - if (ret != B_OK) - break; - emuState = emulate(state); - } while (emuState == 0); - thread->fault_callback = NULL; - - // We might have clobbered %fs, so we need to restore the CPU dependent - // TLS context that we may have overwritten. Note that we can't simply - // restore %fs to its previous value as we might not run on the same CPU - // anymore. - x86_set_tls_context(thread); - - return emuState < 0 ? B_BAD_DATA : ret; -} - diff --git a/src/system/kernel/arch/x86/Jamfile b/src/system/kernel/arch/x86/Jamfile index ccab5f8f02..745f69b8fa 100644 --- a/src/system/kernel/arch/x86/Jamfile +++ b/src/system/kernel/arch/x86/Jamfile @@ -55,7 +55,6 @@ if $(TARGET_ARCH) = x86_64 { syscalls.cpp syscalls_asm.S thread.cpp - vm86.cpp arch_user_debugger.cpp ioapic.cpp diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index f604defdb1..c1340f1060 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include @@ -109,14 +108,6 @@ x86_unexpected_exception(iframe* frame) addr_t signalAddress = 0; int32 signalError = B_ERROR; -#ifndef __x86_64__ - if (IFRAME_IS_VM86(frame)) { - x86_vm86_return((vm86_iframe*)frame, (frame->vector == 13) ? - B_OK : B_ERROR); - // won't get here - } -#endif - switch (frame->vector) { case 0: // Divide Error Exception (#DE) type = B_DIVIDE_ERROR; diff --git a/src/system/kernel/arch/x86/asm_offsets.cpp b/src/system/kernel/arch/x86/asm_offsets.cpp index 42f7bc9a48..88082f90ce 100644 --- a/src/system/kernel/arch/x86/asm_offsets.cpp +++ b/src/system/kernel/arch/x86/asm_offsets.cpp @@ -68,10 +68,6 @@ dummy() DEFINE_OFFSET_MACRO(IFRAME, iframe, r10); #else DEFINE_OFFSET_MACRO(IFRAME, iframe, orig_eax); - - // struct vm86_iframe - DEFINE_SIZEOF_MACRO(VM86_IFRAME, vm86_iframe); - DEFINE_OFFSET_MACRO(VM86_IFRAME, vm86_iframe, flags); #endif // struct syscall_info