Task switching

The 80386 schedules and executes tasks based on a priority set by
the operating system. To do this, the 80386 uses a Task Register
(TR) in which it keeps a selector and a descriptor for the running
task's task state segment (TSS). The TR has both a visible and an
invisible portion. The visible and changeable portion can be read
and modified by instructions. The invisible portion is maintained
by the processor to correspond to the changeable portion and
cannot be read by any instruction.

Two instructions (STR - Store Task Register, and LTR - Load Task
Register) read and modify the changeable portion of the TR. Both
instructions take one operand which is a 16-bit selector.

The privileged instruction LTR loads the TR with the selector
operand that must select a TSS descriptor in the GDT (global
descriptor table). Generally, LTR gives an initial value to the
TR during system initialization. After that, the contents of TR
are changed by task switch operations.

──────────────────────────────────────────────────────────────────

A task gate descriptor gives an indirect, protected reference to
a TSS. The 80386 uses task gates, in addition to TSS descriptors,
to satisfy 3 needs:

■ Because the busy-bit is stored in the TSS descriptor, each
task should have only one such descriptor. However, there
may be several task gates that select the single TSS
descriptor.
■ With task gates, systems software can limit the right to
cause task switches to specific tasks.
■ Task gates may also reside in the IDT, so it is possible for
interrupts and exceptions to cause task switching.


──────────────────────────────────────────────────────────────────

To switch tasks, the operating system issues a JMP or CALL
instruction whose operand is a selector for the TSS or the task
gate of the new task.

1. The 80386 first checks that the current task is allowed to
switch to the designated task. Data access privilege rules
appply in the cases of JMP or CALL instructions. The DPL of the
TSS descriptor or task gate must be less than or equal to the
maximum of CPL or the RPL of the gate selector.

2. Next, the TSS descriptor is checked to see if it is marked
present and has a valid limit. A detected error up to this
point occurs in the context of the outgoing task. Errors are
restartable and can be handled in a way that makes its
applications transparent.

3. The processor next executes the JMP TSS instruction by first
storing its current registers in the current TSS. The EIP is
loaded with the address of the instruction after the one that
caused the task switch.

4. The processor then loads the TR with the selector specified in
the JMP instruction. It marks the incoming task's TSS
descriptor as busy and sets the TS bit (task switched) of the
MSW register. Because it now has the new TSS, the 80386 loads
its registers with the values in this new TSS. Execution
continues at the instruction pointed to by the new task's
instruction pointer. Any errors detected in this step occur in
the context of the incoming task.

──────────────────────────────────────────────────────────────────

To an exception handler, it appears as if the first instruction of
the new task has not yet executed. Exception handlers that field
task-switch exceptions in the incoming task should be cautious
about taking action that might load the selector causing the
exception. Unless the handler first examines the selector and
fixes any potential problems, such an action may well cause
another exception.

Every task switch sets the TS bit in the MSW (low 16 bits of CR0).
The TS flag is helpful when using a coprocessor such as the
numeric coprocessor. The TS bit signals that the context of the
coprocessor may not correspond to the current 80386 task.

To resume execution of the old task, the operating system issues a
JMP instruction to the old task's TSS. The process repeats with
the storing of current registers, loading of new registers, and
continuing execution.

The privilege level at which execution restarts in the incoming
task is not restricted by the privilege level of the outgoing
task. The tasks are isolated by their separate address spaces, and
TSSs and privilege access rules are used to prevent improper
access to a TSS. Thus, no special privilege rules are needed to
constrain the relations between the CPLs of the individual tasks.
The new task simply begins executing at the privilege level
indicated by the RPL of the CS selector value that is loaded from
the TSS.

──────────────────────────────────────────────────────────────────

JMP, CALL, IRET, interrupts and exceptions are all ordinary
mechanisms that can be used when a task switch is not required.
Either the type of descriptor reference or the NT (nested task) in
the flags register distinguishes between the standard mechanism
and the variant that causes a task switch.