TASKS AND STATE TRANSITIONS
Each TSS consists of
two
parts, a static portion and a dynamic portion. The static entries are never
changed by the 80286, while the dynamic entries are changed
by
each task switch out of this task. The
static portions of this segment are the task LDT selector and the initial
SS:SP stack pointer addresses
for levels
0-2.
The modifiable or dynamic portion of the task state segment consists of all dynamically-variable and
programmer-visible processor registers, including flags, segment registers, and the instruction pointer.
It
also includes the linkage word used
to
chain nested invocations of different tasks.
The link word provides a history of which tasks invoked
others~
The link word
is
important for restart-
ing an interrupted task when the interrupt has been serviced.
Placing the back link in the TSS protects
the identity of the interrupted task from changes by the interrupt task, since the TSS
is
not writable
by the interrupt task. (In most systems only the operating system has sufficient privilege
to
create or
use a writable data segment
"alias" descriptor for the TSS.)
The stack pointer entries in the TSS for privilege levels
0-2
are static (i.e., never written during a
privilege or task switch). They define the stack to use upon entry
to
that privilege level. These stack
entries are initialized by the operating system when the task
is
created.
If
a privilege level
is
never
used,
no
stack need be allocated for it.
When entering a more privileged level, the caller's stack pointer
is
saved
on
the stack of the
new
privilege level, not in the TSS. Leaving the privilege level requires popping the caller's return address
and stack pointer off the current stack. The stack pointer
at
that time
will
be
the same
as
the initial
value loaded from the TSS upon entry
to
the privilege level.
There
is
only one stack active at any time, the one defined
by
the SS and
SP
registers. The only other
stacks that may be non-empty are those at outer (less privileged) levels that called the current level.
Stacks for inner levels must be empty, since outward (to numerically larger privilege levels) calls from
inner levels are not allowed.
.
The location of the stack pointer for an outer privilege level
will
always
be
found at the start of the
stack of the inner privilege level called by that level. That stack may be the initial stack
for this
privilege level or an outer level. Look at the start of the stack for this privilege level. The
TSS contains
the starting stack address for levels
0-2.
If
the RPL of the saved SS selector
is
the privilege level
required, then the stack pointer has been found. Otherwise,
go
to the beginning of the stack defined
by
that value and look at the saved SS:SP value there.
8.2.1 Task State Segment Descriptors
A special descriptor
is
used for task state segments. This descriptor must
be
accessible at all times;
therefore, it can appear only in the GDT. The access byte distinguishes
TSS descriptors from data or
code segment descriptors. When bits
0 through 4 of the access byte are 00001 or 00011, the descriptor
is
for a TSS.
The complete layout of a task state segment descriptor
is
shown in figure
8-2.
Like a data segment, the descriptor contains a base address and limit field. The limit must
be
at
least
002BH (43)
to
contain the minimum amount of information required for a TSS. An invalid task excep-
tion
will
occur if an attempt
is
made
to
switch
to
a task
whose
TSS descriptor limit
is
less than
43.
The
error code
will
identify the bad TSS.
8-3