From: Rod Pemberton on

"James Harris" <james.harris.1(a)googlemail.com> wrote in message
news:c4553c99-386e-48cf-ad21-441759ea75ec(a)x27g2000yqb.googlegroups.com...
> On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote:
>
> ...
>
> > > Some interesting things have come out that I didn't know. For example,
> > > there are only two fundamental descriptor forms, one for blocks of
> > > memory and one for points in memory. The blocks of memory descriptor
> > > form includes all the memory segment types plus some System types -
> > > those for LDT and TSS blocks. And the points of memory are all gates.
> > > Simple!
> >
> > I think that Intel manuals also refer to two types of descriptors, but
> > call them "segment" and "gate" descriptors (or it was in earlier
> > documents, I didn't check that recently). I would also suggest that
> > your terminology choice is bad even for your own memorizing.
>
> That there are basically only two forms of descriptor is is one of
> those pieces of information that once you know it it seems obvious.
> Where I've seen them in the Intel manuals, however, they refer to many
> types.
>

Well, my notes are in fixed-width font ASCII art. (i.e., if the columns
don't align in your text editor, it's not a fixed-width font.) I had to
clean it up a bit to post. And, I just created the system/gate one...


descriptor dw 0 limit 15:0
dw 0 base 15:0
db 0 base 23:16
db 0 type
db 0 flags, limit 19:16 (nybble each)
db 0 base 31:24

flags
+---+---+---+---+---+---+---+---+
| G |B/D| 0 |Avl| Reserved |
+-+-+-+-+-+-+-+-+---+---+---+---+
| | | | |
| | | | +-- ignored
| | | +------------ can be 0 or 1
| | +---------------- must be 0
| +-------------------- 0=default 16-bit, 1=default 32-bit
+------------------------ 0=byte granular, 1=page granular

type for code/data
+---+---+---+---+---+---+---+---+
| P | DPL |T=1|C/D|E/C|W/R| A |
+-+-+---+---+-+-+-+-+-+-+-+-+-+-+
| | | | | | |
| | | | | | +- 0=not accessed, 1=accessed
| | | | | +----- data: 0=read, 1=>read/write
| | | | | code: must be 1 (readable)
| | | | +--------- data: 0=expand-up, 1=expand-down
| | | | code: must be 0 (non-conforming)
| | | +------------- 0=data, 1=code
| | +----------------- T=1 for code/data
| +----------------------- must equal caller's CPL
+----------------------------- 0=absent, 1=present

type for system/gate
+---+---+---+---+---+---+---+---+
| P | DPL |T=0| SEGMENT |
+-+-+---+---+-+-+---+-+-+---+---+
| | | |
| | | +--------- one of sixteen types (*)
| | +----------------- T=0 for system/gate
| +----------------------- must equal caller's CPL
+----------------------------- 0=absent, 1=present


(*) segment type
0000 reserved
0001 16-bit TSS (inactive) - paired with 0011
0010 ldt
0011 16-bit TSS (busy) - paired with 0001
0100 16-bit call gate
0101 16-bit/32-bit task gate
0110 16-bit interrupt gate
0111 16-bit trap gate
1000 reserved
1001 32-bit TSS (inactive) - paired with 1011
1010 reserved
1011 32-bit TSS (busy) - paired with 1001
1100 32-bit call gate
1101 reserved
1110 32-bit interrupt gate
1111 32-bit trap gate



Rod Pemberton


From: Stargazer on
On Jun 26, 4:08 pm, James Harris <james.harri...(a)googlemail.com>
wrote:
> On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote:
>
> ...
>
> > > Some interesting things have come out that I didn't know. For example,
> > > there are only two fundamental descriptor forms, one for blocks of
> > > memory and one for points in memory. The blocks of memory descriptor
> > > form includes all the memory segment types plus some System types -
> > > those for LDT and TSS blocks. And the points of memory are all gates.
> > > Simple!
>
> > I think that Intel manuals also refer to two types of descriptors, but
> > call them "segment" and "gate" descriptors (or it was in earlier
> > documents, I didn't check that recently). I would also suggest that
> > your terminology choice is bad even for your own memorizing.
>
> That there are basically only two forms of descriptor is is one of
> those pieces of information that once you know it it seems obvious.
> Where I've seen them in the Intel manuals, however, they refer to many
> types.
>
>
>
>
>
> > First, the architecture definition also refers to two types of
> > descriptors, but calls them with different name; you must have some
> > good reason to suggest a different pair of names which would require
> > you then remember both pairs and correspondence between them in order
> > to look up things in specs.
>
> > Second, if you wanted to ease remembering you ought to choose more
> > "talkative" (not even descriptive names) - names that would remind you
> > the things as they are. "Blocks" have too many options to mix up
> > (besides segments, MTRR-defined ranges may be refered as "blocks";
> > pages or page tables may be thought of as "blocks", etc.) Everything
> > in your "blocks" group is a segment except for LDT, so "segments" or
> > "segments and tables" may be a better replacement name. "Points" are
> > better hinting, but apparently not in a way that you assumed, or at
> > least your definition of "points" is misleading: it's not "points in
> > memory", but "system entry points"! As such "points" may be more
> > descriptive than "gates".
>
> Isn't an LDT a segment? Maybe it isn't. I haven't checked.

LDTs have common properties with segments in the same way as GDT has:
they are "blocks" or "ranges" of memory that reference appropriate
registers before (optionally) passing through page-level translation.

LDTs are not segments in other aspects: they don't have "default",
"granularity", "expansion direction" etc. attributes and you can't set
up LDTR load for arbitraty CPL as you can with segments (LLDT is CPL0-
only instruction).

> > No (64-bit data belongs to a different architecture), but I think you
> > should add 16-bit specifications.
>
> That's a surprise! Aren't the 16-bit forms needed only on the 80286?
> Again, I haven't checked. They are listed in the type codes. I think
> that's enough. To add breakdowns of them as well would cause
> confusion.

16-bit forms are valid for any 16-bit or 32-bit code, so they may be
used. You must actually load at least CS and SS with 16-bit segment
attributes before switching to real mode from protected mode (as Mike
reminded) because in real mode segment loads do *not* alter G/D
attributes, and real-mode code breaks when running with 32-bit CS and
SS defaults.

Daniel
From: s_dubrovich on
On Jun 26, 8:08 am, James Harris <james.harri...(a)googlemail.com>
wrote:
> On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote:
>
> ...
>
> > > Some interesting things have come out that I didn't know. For example,
> > > there are only two fundamental descriptor forms, one for blocks of
> > > memory and one for points in memory. The blocks of memory descriptor
> > > form includes all the memory segment types plus some System types -
> > > those for LDT and TSS blocks. And the points of memory are all gates.
> > > Simple!
>
> > I think that Intel manuals also refer to two types of descriptors, but
> > call them "segment" and "gate" descriptors (or it was in earlier
> > documents, I didn't check that recently). I would also suggest that
> > your terminology choice is bad even for your own memorizing.
>
> That there are basically only two forms of descriptor is is one of
> those pieces of information that once you know it it seems obvious.
> Where I've seen them in the Intel manuals, however, they refer to many
> types.
>
> > First, the architecture definition also refers to two types of
> > descriptors, but calls them with different name; you must have some
> > good reason to suggest a different pair of names which would require
> > you then remember both pairs and correspondence between them in order
> > to look up things in specs.
>
> > Second, if you wanted to ease remembering you ought to choose more
> > "talkative" (not even descriptive names) - names that would remind you
> > the things as they are. "Blocks" have too many options to mix up
> > (besides segments, MTRR-defined ranges may be refered as "blocks";
> > pages or page tables may be thought of as "blocks", etc.) Everything
> > in your "blocks" group is a segment except for LDT, so "segments" or
> > "segments and tables" may be a better replacement name. "Points" are
> > better hinting, but apparently not in a way that you assumed, or at
> > least your definition of "points" is misleading: it's not "points in
> > memory", but "system entry points"! As such "points" may be more
> > descriptive than "gates".
>
> Isn't an LDT a segment? Maybe it isn't. I haven't checked.

Yes, ia486, 5.2.5 Descriptor Table Base Registers. The GDTR & IDTR
hold 32-bit base addresses for tables in the linear address space,
which should be aligned to 16 byte boundry...

(But the LDT) is identified using a 16-bit segment selector held in
the LDTR register.

>
> I take your point about names. I don't want to call the first type
> "segment descriptors" as the term segment has a lot of baggage and
> means specific things to many people. I want the reader to see the
> first descriptor type as identifying a block/range/region/space of
> memory and contrast that with the second type which identifies a
> single location, not a range. I think that aids remembering because it
> highlights *why* they are different.
>
> Any term has baggage but I agree that "block" is not good. I've
> changed it to "range." Maybe that's a bit better?
>
> > > As ever, corrections welcome.
>
> > One thing that comes to mind is regarding limits. Unless Intel added a
> > special treatment for 0-limited segments recently, the limit for 4K-
> > granular segments is 2**12-1 .. 2**32-1, not 0 .. 2**32-1.
>
> Thanks. I've corrected it.
>
> > > Also, I've included only 32-bit data.
> > > Should I add 64-bit data to it or will that overload it with too much
> > > information?
>
> > No (64-bit data belongs to a different architecture), but I think you
> > should add 16-bit specifications.
>
> That's a surprise! Aren't the 16-bit forms needed only on the 80286?
> Again, I haven't checked. They are listed in the type codes. I think
> that's enough. To add breakdowns of them as well would cause
> confusion.
>
> James- Hide quoted text -
>

Thanks for your post, it reminded me to review and edit.. oh, circa
ia486, in case of descrepancy..

I prefer bit field kinds of descriptions, it seems alittle more
concrete to me then, so, my ref. ..

;;---------------------------------------------------------60
;; File: DESC_HHH.NSM By: s_dubrovich(a)yahoo.com
;; ?(C): COPYLEFT
;; Last: 26-Jun-10 03:31:40 PM
;; Init: 24-May-09 09:10:22 AM
;; Vers: 1r1
;; Goal: Definitions
;; Note: edited into general reference.
;;---------------------------------------------------------60
;; Segment_Selector - is the value held in a segment
;; register of the type 'index' to Segment_Descriptor in
;; a list of descriptors whose list base is in the GDT or
;; LDT. A bit field in the Segment Selector Value tells
;; which table (bit 2). (bits 0,1 indicate CPL, or RPL
;; privilege level.) The remaining bits 3..15 conveniently
;; scale by 8, as each index increments by 8, the length
;; of a descriptor in the Table. So, align tables.
;; SSEL_VAL dw bbbb bbbb bbbb b,b`Tbl,bb`PLvl
;;---------------------------------------------------------60
;; P DPL S TYP Masks are bit Positions not Values.
P_msk equ 10000000b ; Present Bit, set, else exception
DPL_msk equ 01100000b ; 0 highest, 3 lowest
Sys_msk equ 00010000b ; Set=Code/Data, clr=System
TYP_msk equ 00001111b ; see below

;; G SZ O A limit19 Masks are bit Positions not Values.
Gran_msk equ 10000000b ; set is 4K, clr is db
D_SZ_msk equ 01000000b ; set is 32bit, clr=16bit
O_msk equ 00100000b ; obit clr
AVL_msk equ 00010000b ; software tag
Lim19_msk equ 00001111b ;

;; Segment_Descriptor - an entry in either a GDT or LDT.
;;
STRUC Dsc_ ;; obit is undefined, clear bit.
.lim15 resw 1 ;; Limit 0..15
.base15 resw 1 ;; Base 0..15
.base23 resb 1 ;; Base 16..23
.PDPLSTYP resb 1 ;; MSB`Present[1],DPL[2],Sys[1],Type[4]
.GSZAlim19 resb 1 ;; MSB`Gran.[1],Sz[1],obit[1],Avail[1],
;; lim16..19[4-bits]
.base31 resb 1 ;; Base 24..31
ENDSTRUC

;; Call Gate Descriptor has two main functions: 1. define
;; entry point of a procedure, 2. specify the privilege
;; level required to enter the procedure. (B)

STRUC GateDsc_ ;; -= Call Gate Descriptor =-
.gateOffsLo resw 1 ;; Offset 0..15
.gateSelector resw 1 ;; Target's Selector of Procedure's
;; Code Segment Descriptor.
.gateSScpycnt resb 1 ;; 0..4 bits -> 0..31 Count of DWords
;; to copy from caller's stack
;; bits 5..7 set to zero.
.gPDPLSTYP resb 1 ;; MSB`Present[1],DPL[2],Sys[1](0b),
;; Type[4](1100b)
.gateOffsHi resw 1 ;; Offset 16..31
ENDSTRUC

;; Both Task Gates and TSS descriptors are provided to
;; satisfy three common needs... ref. 7-7 i486
;; Task Gate Descriptor has three main functions: 1. The need
;; to have only one Busy bit (semaphore). Because the Busy
;; bit is stored in the TSS descriptor, each task should
;; have only one such descriptor. There may, however, be
;; several task gates which select a single TSS descriptor.
;; 2. The need to provide selective access to tasks. Task
;; Gates fill this need, because they can reside in an LDT
;; and can have a DPL which is different from the TSS
;; Descriptor's DPL. A procedure which does not have suf-
;; ficient privilege to use the TSS descriptor in the GDT
;; (which usually has a DPL of 0) can still call another
;; task if it has access to a task gate in its LDT. With
;; task gates, the operating system can limit task switch-
;; ing to specific tasks. 3. The need for an interrupt or
;; exception to cause a task switch. Task Gates may also
;; reside in the IDT, which allows interrupts and execptions
;; to cause task switching. When an interrupt or exception
;; supplies a vector to a task gate, the i486 processor
;; switches to the indicated task.

STRUC TaskGDsc_ ;; -= Task Gate Descriptor =-
.TgateRsrv1 resw 1 ;; -reserved
.TSS_Selector resw 1 ;; TSS's Segment Selector
.TgateRsvr2 resb 1 ;; -reserved 0..7
.tskPDPLSTYP resb 1 ;; MSB`Present[1],DPL[2],Sys[1](0b),
;; Type[4](0101b)
.TgateRsvr3 resw 1 ;; -reserved
ENDSTRUC

;; An Interrupt Gate or Trap Gate indirectly references a
;; procedure which runs in the context of the currently
;; executing task. The selector of the gate points to an
;; executable-segment descriptor in either the GDT or current
;; LDT. The offset field of the gate descriptor points to
;; the beginning of the exception or interrupt handling
;; procedure. ** The difference between an interrupt gate
;; and a trap gate is its effect on the IF flag. An
;; interrupt which uses an interrupt gate clears the IF flag,
;; which prevents other interrupts from interfering with the
;; current interrupt handler. A subsequent IRET instruction
;; restores the IF flag to the value in the saved contents
;; of the EFLAGS register on the stack. An interrupt through
;; a trap gate does not change the IF flag.

;; -= Interrupt Gate =-

STRUC IntGDsc_ ;; -= Interrupt Gate Descriptor =-
.IgOffsLo resw 1 ;; Offset 0..15
.iTSS_Selector resw 1 ;; Segment Selector
.IgateRsvr2 resb 1 ;; -reserved 0..4, 5..7 set to 0
.iPDPLSTYP resb 1 ;; MSB`Present[1],DPL[2],Sys[1](0b),
;; Type[4](0101b)
.IgOffsHi resw 1 ;; Offset 16..31
ENDSTRUC

;; -= Trap Gate =-

STRUC TrapGDsc_ ;; -= Trap Gate Descriptor =-
.TrpgOffsLo resw 1 ;; Offset 0..15
.tTSS_Selector resw 1 ;; Segment Selector
.trpgateRsvr2 resb 1 ;; -reserved 0..4, 5..7 set to 0
.tPDPLSTYP resb 1 ;; MSB`Present[1],DPL[2],Sys[1](0b),
;; Type[4](0101b)
.TrpgOffsHi resw 1 ;; Offset 16..31
ENDSTRUC

;; -= Descriptor Types =-
;;---------------------------------------------------------60
;; .CODE. .--------- 1==Segment Present .else. exception
;; |..------- DPL: Descriptor Priv. Lvl, Hi`0..3'Lowest
;; |||.------ 1==Code/Data .else. 0==System
;; ||||
;; |||| .---- 1==Code
;; |||| |.--- Conforming
;; |||| ||.-- Read Enable (as for Constants in CS)
;; TYPES: PPlS TCRA- Accessed -(A)
;; - - - - - - - - - - - - - - - -
;; .DATA. .--------- 1==Segment Present .else. exception
;; |..------- DPL: Descriptor Priv. Lvl, Hi`0..3'Lowest
;; |||.------ 1==Code/Data .else. 0==System
;; ||||
;; |||| .---- 0==Data
;; |||| |.--- Expand Down
;; |||| ||.-- Write Enable
;; TYPES: PPlS TEWA- Accessed -(A)
;;
;; 93h - 1001 0011b | Pres, Ring0, C/D, Data.RW.Accessed
;; 9Ah - 1001 1010b | Pres, Ring0, C/D, Code.Readable
;; 92h - 1001 0010b | Pres, Ring0, C/D, Data writeable
;; = = = = = = = = = = = = = = = =
;; .SYST. .--------- 1==Segment Present .else. exception
;; |..------- DPL: Descriptor Priv. Lvl, Hi`0..3'Lowest
;; |||.------ 1==Code/Data .else. 0==System
;; ||||
;; TYPES: PPlS TYPE- *see sys_typ_list
;;
;; 89h - 1000 1001b | Pres, Ring0, Sys, 32-bit TSS
;;
;; sys_typ_list:
;; 0 = Reserved | 8 = Reserved
;; 1 = Avail 286 TSS | 9 = Avail 386/486 TSS
;; 2 = LDT | A = Reserved
;; 3 = Busy 286 TSS | B = Busy 386/486 TSS
;; 4 = 286 Call Gate | C = 386/486 Call Gate
;; 5 = 286/386 Task Gate | D = Reserved
;; 6 = 286 Int Gate | E = 386/486 Int Gate
;; 7 = 286 Trap Gate | F = 386/486 Trap Gate
;;---------------------------------------------------------60
;; GDT Holds: Code/Data_Descr, LDT_descr, TSS_Descr, ...
;; LDT Task Specific: code, data, stack, task_gate, call_gate.
;; IDT ISR_Tbl: trap_gate, task_gate, int_gate. (call gate is
;; not allowed in IVT.)
;; So the four Gate Types are: Call Gate (6-5), Task Gate
;; (7-7), Trap Gate (9-2), and Interrupt Gate (9-2) of i486.
;;---------------------------------------------------------60
;; (A) Type Characteristics for .CODE. & .DATA.
;; (less present & privilege level high order 3 bits)
;;
;; bbb1 0000b data,expand=up,non-writable
;; bbb1 0010b data,expand=up,writable
;; bbb1 0100b data,expand=down,non-writable
;; bbb1 0110b data,expand=down,writable
;; bbb1 1000b code,non-conforming,non-readable
;; bbb1 1010b code,non-conforming,readable
;; bbb1 1100b code,conforming,non-readable
;; bbb1 1111b code,conforming,readable
;;
;; Examples of .PDPLSTYP
;; 93h - 1001 0011b | Pres, Ring0, C/D,Data.RW.Accessed
;; 9Ah - 1001 1010b | Pres, Ring0, C/D,Code.Readable
;; 92h - 1001 0010b | Pres, Ring0, C/D,Data writeable
;; 89h - 1000 1001b | Pres, Ring0, Sys,32-bit TSS
;;---------------------------------------------------------60
;; ref. Fig.6-5,6-6 i486
;; (B) Call Gate Descriptors are used by CALL and JMP
;; instructions in the same manner as code segment
;; descriptors. When the hardware recognizes the target
;; is a Gate, the operation of the instruction is deter-
;; mined by the Call Gate contents. The Selector and
;; offset fields of a gate form a pointer to the entry
;; point of a procedure. A Call Gate guarantees that all
;; control transfers to other segments go to a valid
;; entry point, rather than to the middle of a procedure
;; (or worse, to the middle of an instruction). The
;; operand of the control transfer instruction is not the
;; true segment selector and offset within the segment of
;; the procedure's entry point. The offset (the Effective
;; Address indicated in the instruction) is not used.
;; Instead, the segment selector points to a Gate
;; Descriptor whose Offset field indicates the true
;; offset of the entry point, and whose Selector field
;; indicates the Code Segment Descriptor that provides
;; the Base for the Entry point's effective address.
;; - See Fig. 6-6 pg 6-12 i486. -
;;---------------------------------------------------------60
;; -= eo desc_hhh.nsm =-
;;---------------------------------------------------------60

So, for descriptor classification, I see .code. & .data. vs
..system., and classification of system types into TSS vs Gates of;
Task, Call and Interrupts (interrupts vs traps).

For me, classification this way leaves enough detail without being
overbearing.

For me, further generalisation to 'range' vs 'point' looses abit too
much detail.

My 2-cents worth for comparison,

Steve
First  |  Prev  | 
Pages: 1 2
Prev: what timer?
Next: the general server is not sufficient