V86 - virtual 8086 environment

On the 80386+, 8086 applications and operating systems can run in
protected mode as part of a virtual task (V86) that takes advantage
of the hardware support of multitasking offered by protected mode.

The V86 task forms a "virtual machine" that consists of the 80386
hardware and systems software. The software controls the V86
external interfacing, the interrupts and I/O. The hardware provides
the TSS (task state segment) containing the virtual registers (a
virtual memory space that is the task's first megabyte of the
linear address space) and executes the instructions that deal with
the registers and address space.

──────────────────────────────────────────────────────────────────
Virtual 8086 mode addressing
The 80386 executes V86 mode when the VM (virtual mode) flag is
set in the EFLAGS register. The processor tests the VM flag when
decoding instructions to determine which instructions are
sensitive to IOPL, and when loading segment registers to determine
if it is to use 8086-style address formation.

All 80386 registers are accessible to V86, including the segment
registers FS and GS, but subject to protected mode limitations.
V86 code also may use non-privileged 80386 instructions, including
LSS, LFS, LGS, bit scan, double-shift, byte set on condition,
long-displacement conditional jumps, move with sign/zero
extension, and a generalized multiply.


──────────────────────────────────────────────────────────────────
Address formation
When in V86 mode, the 80386 does not interpret 8086 selectors by
referring to descriptors; it forms linear addresses as if it were
an 8086. The selector is shifted left by 4 bits to form the 20-bit
base address. The effective address is extended with 4 high-order
zeros and added to the base address. Range is 0-10FFEFh.

V86 tasks actually generate 32-bit linear addresses. However, if
the value of the 32-bit address exceeds 65535 (0FFFFh), an
exception is generated (12: stack exception, or 13: general
protection exception).


──────────────────────────────────────────────────────────────────
Virtual 86 task
A virtual 8086 task must be represented by an 80386 task state
segment (TSS), which the 80386 uses to execute the 8086 program
before it returns to protected mode to execute the 80386 tasks.
The V86 task consists of two parts:
- the 8086 program to be executed, and
- 80386 code that serves as the virtual machine monitor

The V86 monitor is actually 80386 protected mode code that
executes at privilege level zero and consists mainly of
initialization and exception handling procedures. The monitor, as
with any other 80386 program, uses executable segment descriptors
that must exist in the GDT or in the task's LDT. The monitor may
also need data segment descriptors to allow it to examine the
interrupt vector table or other parts of the 8086 program that are
in the first megabyte of address space.

Operating system services can be left as part of the 8086 code or
emulated in the V86 monitor. Regardless how V86 is implemented,
note that different V86 tasks can use different 8086 operating
systems, which opens choices available to systems programmers.

Paging is not required for a single V86 task but is useful in
order to do the following:

■ Redirect or trap references to memory-mapped I/O devices.
■ Share 8086 operating system code or ROM code common to
several 8086 programs that may be executing simultaneously.
■ Create a virtual address space larger than the physical
address space.
■ Create multiple V86 tasks, in which each task must map the
lower megabyte of linear addresses to different physical
locations.
■ Emulate the megabyte wrap of the 8086.


The 80386 does not refer to descriptors while executing 8086
programs, so it does not use the protection mechanisms offered by
descriptors. A couple of approaches can be used to protect the
systems software in a V86 task from the 8086 program. The software
designer may choose to use the U/S bit of the page table entries
to protect the virtual machine monitor and other systems software
that is in each V86 task's task space. When the 80386 is in V86
mode, the current privilege level is 3 (CPL=3), which means that
the 8086 program has only user privileges. If the virtual machine
monitor's pages have supervisor privileges, they cannot be
accessed by the 8086 program.
Another way to protect the V86 system from a V86 application is to
reserve the first megabyte and 64K of each task's linear address
space for the 8086 program. The 8086 tasks cannot generate
addresses outside that range.


──────────────────────────────────────────────────────────────────
Sensitive instructions in V86 mode
Refer to IOPL-sensitive instructions.


──────────────────────────────────────────────────────────────────
Virtual mode input/output
Some 8086 programs are designed to operate on a single-task system
and use I/O devices directly. These programs are disruptive when
running in a multitasking environment. Instead of direct control,
system designers may take other approaches. The method chosen to
control the I/O depends on whether the I/O ports are memory-mapped
or I/O-mapped. Some options for control are to

■ selectively trap and then emulate references that a task
makes to specifie I/O ports
■ trap or redirect references to memory-mapped I/O addresses
■ emulate the 8086 operating system as an 80386 program and
require it to do I/O via software interrupts to the
operating system (trap all attempts to do I/O directly)

I/O-mapped input/output in the V86 differs from protected mode in
one way. The protection mechanism does not consult IOPL when it
executes the IN,INS,OUT, and OUTS instructions; only the I/O
Permission Bit Map controls whether the V86 tasks execute these
I/O instructions. The I/O Permission Bit Map traps I/O
instructions selectively, depending on the I/O address to which
they refer. Because each task has its own I/O Permission Bit Map,
the addresses trapped for one task may be different for those
trapped for others.

Each task that executes memory-mapped I/O must have a page (or
several pages) for the memory-mapped address space. The V86
monitor can control the memory-mapped I/O by

■ causing a monitor trap, which forces a page fault on the
memory-mapped page (read-only pages will trap writes and
not-present pages will trap both reads and writes), or
■ assigning the memory-mapped page to appropriate physical
addresses

Intervening for each I/O may be excessive for some kinds of I/O
devices. In this case, a page fault can intervene on the first I/O
operation. The the monitor can make sure that the task has
exclusive access to the device and can change the page status to
present and read/write, which allows subsequent I/O to proceed at
full speed.