
; Copyright (c) Microsoft Corporation 1988-1991. All Rights Reserved.

;****************************************************************
;*                                                              *
;*      PMDEFS.INC      --  80286 Protected Mode Definitions    *
;*                                                              *
;****************************************************************
;*  Revision History:                                           *
;*                                                              *
;*   7/28/89 jimmat   Changes selectors for Wdeb386 (it now     *
;*                    needs 4, not 2)                           *
;*   3/11/89 jimmat   Added selector for TSS                    *
;*   3/09/89 jimmat   Added selectors for DynaLink call gates   *
;*  02/10/89 (GeneA): reorganized selector definitions for      *
;*      change from small model to medium model                 *
;*  12/01/88 (GeneA): added definitions for SEL_BIOSCODE and    *
;*      SEL_USERSCR                                             *
;*                                                              *
;****************************************************************
;
; -------------------------------------------------------
;                  SELECTOR FIELDS
; -------------------------------------------------------

SELECTOR_RPL    =   00000011b           ;Requested Privilege Level mask
SELECTOR_TI     =   00000100b           ;Table Indicator mask
SELECTOR_INDEX  =   0fff8h              ;Index mask

SELECTOR_PL0    =   00000000b           ;Ring 0 privilege level
SELECTOR_PL1    =   00000001b           ;Ring 1 privilege level
SELECTOR_PL2    =   00000010b           ;Ring 2 privilege level
SELECTOR_PL3    =   00000011b           ;Ring 3 privilege level

SELECTOR_PL_DX  =   SELECTOR_PL3        ;Privilege level used by DOSX

; -------------------------------------------------------
;           ACCESS RIGHTS BIT DEFINITIONS
; -------------------------------------------------------
;
; These are the access rights byte bit position definitions.

; These fields are common to all descriptors
AB_PRESENT  =   10000000b   ;segment present bit
AB_DPL0     =   00000000b   ;ring 0 DPL
AB_DPL1     =   00100000b   ;ring 1 DPL
AB_DPL2     =   01000000b   ;ring 2 DPL
AB_DPL3     =   01100000b   ;ring 3 DPL
AB_DPL      =   01100000b   ;mask for DPL field

;AB_DPL_DX   =  AB_DPL3     ;DPL used by DOSX
AB_DPL_DX   =   (SELECTOR_PL_DX shl 5)      ;DPL used by DOSX

; These fields are relevant to code and data segment descriptors
;   (non-system descriptors)
AB_DATA     =   00010000b   ;data segment
AB_CODE     =   00011000b   ;code segment
AB_STACK    =   00010100b   ;expand down (stack) segment
AB_WRITE    =   00000010b   ;writable data
AB_READ     =   00000010b   ;readable code
AB_CONFORM  =   00000100b   ;conforming code
AB_ACCESSED =   00000001b   ;segment has been accessed
AB_BIG      =   0100000000000000b ; 32 bit segment

; These fields are relevant to system descriptors
AB_INVALID  =   00000000b   ;invalid descriptor
AB_TSS      =   00000001b   ;task state segment descriptor
AB_TSS386   =   00001001b   ;task state segment descriptor 386
AB_BUSY     =   00000010b   ;busy bit for task state descriptor
AB_LDT      =   00000010b   ;local descriptor table descriptor
AB_CALLGATE =   00000100b   ;call gate descriptor
AB_TASKGATE =   00000101b   ;task gate descriptor
AB_INTRGATE =   00000110b   ;interrupt gate descriptor
AB_TRAPGATE =   00000111b   ;trap gate descriptor
AB_IGATE386 =   00001110b   ;80386 interrupt gate descriptor

; These are some common combinations of the above fields making up
; useful access rights bytes.

ARB_CODE0   =   AB_PRESENT+AB_DPL0+AB_CODE+AB_READ      ;ring 0 code segment
ARB_CODE1   =   AB_PRESENT+AB_DPL1+AB_CODE+AB_READ      ;ring 1 code segment
ARB_CODE3   =   AB_PRESENT+AB_DPL3+AB_CODE+AB_READ      ;ring 3 code segment
ARB_CODE_DX =   AB_PRESENT+AB_DPL_DX+AB_CODE+AB_READ    ;DOSX ring code segment

ARB_DATA0NP =              AB_DPL0+AB_DATA+AB_WRITE     ;illegal segment
ARB_DATA0   =   AB_PRESENT+AB_DPL0+AB_DATA+AB_WRITE     ;ring 0 read/write data
ARB_DATA1   =   AB_PRESENT+AB_DPL1+AB_DATA+AB_WRITE     ;ring 1 read/write data
ARB_DATA3   =   AB_PRESENT+AB_DPL3+AB_DATA+AB_WRITE     ;ring 3 read/write data
ARB_DATA_DX =   AB_PRESENT+AB_DPL_DX+AB_DATA+AB_WRITE   ;DOSX ring read/write data

ARB_STACK0  =   AB_PRESENT+AB_DPL0+AB_STACK+AB_WRITE    ;ring 0 stack
ARB_STACK1  =   AB_PRESENT+AB_DPL1+AB_STACK+AB_WRITE    ;ring 1 stack
ARB_STACK3  =   AB_PRESENT+AB_DPL3+AB_STACK+AB_WRITE    ;ring 3 stack
ARB_STACK_DX =  AB_PRESENT+AB_DPL_DX+AB_STACK+AB_WRITE  ;DOSX ring stack

ARB_TRAP0   =   AB_PRESENT+AB_DPL0+AB_TRAPGATE          ;ring 0 trap gate
ARB_TRAP1   =   AB_PRESENT+AB_DPL1+AB_TRAPGATE          ;ring 1 trap gate
ARB_TRAP3   =   AB_PRESENT+AB_DPL3+AB_TRAPGATE          ;ring 3 trap gate
ARB_TRAP_DX =   AB_PRESENT+AB_DPL_DX+AB_TRAPGATE        ;DOSX ring trap gate

ARB_INTR0   =   AB_PRESENT+AB_DPL0+AB_INTRGATE          ;ring 0 interrupt gate
ARB_INTR1   =   AB_PRESENT+AB_DPL1+AB_INTRGATE          ;ring 1 interrupt gate
ARB_INTR3   =   AB_PRESENT+AB_DPL3+AB_INTRGATE          ;ring 3 interrupt gate
ARB_INTR_DX =   AB_PRESENT+AB_DPL_DX+AB_INTRGATE        ;DOSX ring interrupt gate

ARB_INTR0386=   AB_PRESENT+AB_DPL0+AB_IGATE386          ;ring 0 386 int gate
ARB_INTR1386=   AB_PRESENT+AB_DPL1+AB_IGATE386          ;ring 1 386 int gate
ARB_INTR3386=   AB_PRESENT+AB_DPL3+AB_IGATE386          ;ring 3 386 int gate
ARB_INTR_DX386= AB_PRESENT+AB_DPL_DX+AB_IGATE386        ;DOSX ring 386 int gate

ARB_CALL0   =   AB_PRESENT+AB_DPL0+AB_CALLGATE          ;ring 0 call gate
ARB_CALL1   =   AB_PRESENT+AB_DPL1+AB_CALLGATE          ;ring 1 call gate
ARB_CALL3   =   AB_PRESENT+AB_DPL3+AB_CALLGATE          ;ring 3 call gate
ARB_CALL_DX =   AB_PRESENT+AB_DPL_DX+AB_CALLGATE        ;DOSX ring call gate

ARB_TSS1    =   AB_PRESENT+AB_DPL1+AB_TSS               ;ring 1 task state seg
ARB_TSS3    =   AB_PRESENT+AB_DPL3+AB_TSS               ;ring 3 task state seg
ARB_TSS_DX  =   AB_PRESENT+AB_DPL_DX+AB_TSS             ;DOSX ring task state seg

ARB_TSS1386 =   AB_PRESENT+AB_DPL1+AB_TSS386            ;ring 1 386 TSS
ARB_TSS3386 =   AB_PRESENT+AB_DPL3+AB_TSS386            ;ring 3 386 TSS
ARB_TSS_DX386 = AB_PRESENT+AB_DPL_DX+AB_TSS386          ;DOSX ring 386 TSS

ARB_LDT1    =   AB_PRESENT+AB_DPL1+AB_LDT               ;ring 1 local dscr tbl
ARB_LDT3    =   AB_PRESENT+AB_DPL3+AB_LDT               ;ring 3 local dscr tbl
ARB_LDT_DX  =   AB_PRESENT+AB_DPL_DX+AB_LDT             ;DOSX ring local dscr tbl

;--------------------------------------------------------
;       STANDARD DESCRIPTOR TABLE/RING EQUATES
;--------------------------------------------------------

; Currently DOSX is setup to run most of itself and the child app in
; ring 1.  However this may be changed by changing the following equates.

STD_DPL         =       AB_DPL_DX
STD_DATA        =       ARB_DATA_DX
STD_CODE        =       ARB_CODE_DX
STD_STACK       =       ARB_STACK_DX
STD_TRAP        =       ARB_TRAP_DX
STD_INTR        =       ARB_INTR_DX
STD_INTR386     =       ARB_INTR_DX386
STD_CALL        =       ARB_CALL_DX
STD_TSS         =       ARB_TSS_DX
STD_TSS386      =       ARB_TSS_DX386
STD_LDT         =       ARB_LDT_DX

STD_TBL         =       SELECTOR_TI
ifdef WOW
STD_RING        =       SELECTOR_PL_DX OR SELECTOR_TI
else
STD_RING        =       SELECTOR_PL_DX
endif
STD_TBL_RING    =       (STD_TBL or STD_RING)

;
; Code descriptor type for handling processor exceptions.
;
EH_CODE         =       ARB_CODE0
EH_RING         =       SELECTOR_PL0
EH_RING_MASK    =       NOT 3
EH_DATA         =       ARB_DATA0

; -------------------------------------------------------
;           DESCRIPTOR STRUCTURE DEFINITIONS
; -------------------------------------------------------

; This structure defines the layout of a segment descriptor on the '286
; These can appear in either the local descriptor table or the global
; descriptor table.  The local descriptor table descriptors also fit into
; this format, but they can only appear in the global descriptor table.

SEGDSCR     struc
cbLimit         dw      0       ;segment size limit
adrBaseLow      dw      0       ;low word of segment base address
adrBaseHigh     db      0       ;high byte of segment base address
arbSegAccess    db      0       ;access rights byte
rsvdSeg         dw      0       ;Intel reserved, must be 0
SEGDSCR     ends

SEGDSCR386      struc
cbLimit386      dw      0       ;segment size limit
adrwBaseLow386  dw      0       ;low word of segment base address
adrbBaseMid386  db      0       ;mid byte of segment base address
arbSegAccess386 db      0       ;access rights byte
cbLimitHi386    db      0       ;hi nybble of size limit
adrbBaseHi386   db      0       ;high byte of segment base address
SEGDSCR386      ends

; This structure defines the layout of gate descriptors.  These can appear
; in any of the descriptor tables.  Only Interrupt Gate, Trap Gate, and
; Task Gate descriptors can appear in the interrupt descriptor table.

GATEDSCR    struc
offDest         dw      0       ;destination function offset (not used in
                                ; task gates)
selDest         dw      0       ;destination function segment selector
cwParam         db      0       ;count of parameter words to transfer
arbGate         db      0       ;access rights byte
rsvdGate        dw      0       ;Intel reserved, must be 0
GATEDSCR    ends

; This is the structure defines the layout of a Task State Segment
; descriptor.  This can only appear in the Global Descriptor Table

TSSDSCR     struc
cbTssLimit      dw  0           ;segment size limit
adrTssBaseLow   dw  0           ;low word of segment base address
adrTssBaseHigh  db  0           ;high byte of segment base address
arbTssAccess    db  0           ;access rights byte
rsvdTss         dw  0           ;Intel reserved, must be 0
TSSDSCR     ends

; -------------------------------------------------------
;               80286 TASK STATE SEGMENT
; -------------------------------------------------------
;
; This structure describes the layout of an 80286 task state
; segment.

TSS286  struc
tss_backlink    dw  ?           ;backlink to previous task
tss_sp0         dw  ?           ;privelege level 0 stack pointer
tss_ss0         dw  ?           ;privelege level 0 stack segment
tss_sp1         dw  ?           ;privelege level 1 stack pointer
tss_ss1         dw  ?           ;privelege level 1 stack segment
tss_sp2         dw  ?           ;privelege level 2 stack pointer
tss_ss2         dw  ?           ;privelege level 2 stack segment
tss_ip          dw  ?           ;initial instruction pointer
tss_flags       dw  ?
tss_ax          dw  ?
tss_cx          dw  ?
tss_dx          dw  ?
tss_bx          dw  ?
tss_sp          dw  ?
tss_bp          dw  ?
tss_si          dw  ?
tss_di          dw  ?
tss_es          dw  ?
tss_cs          dw  ?
tss_ss          dw  ?
tss_ds          dw  ?
tss_ldt         dw  ?           ;local descriptor table for this task

TSS286  ends

; -------------------------------------------------------
;               80386 TASK STATE SEGMENT
; -------------------------------------------------------
;
; This structure describes the layout of an 80386 task state
; segment.

TSS386  struc
ts3_backlink    dw  0           ;backlink to previous task
                dw  0
ts3_esp0        dd  0           ;privelege level 0 stack pointer
ts3_ss0         dw  0           ;privelege level 0 stack segment
                dw  0
ts3_esp1        dd  0           ;privelege level 1 stack pointer
ts3_ss1         dw  0           ;privelege level 1 stack segment
                dw  0
ts3_esp2        dd  0           ;privelege level 2 stack pointer
ts3_ss2         dw  0           ;privelege level 2 stack segment
                dw  0
ts3_eip         dd  0           ;initial instruction pointer
ts3_cr3         dd  0
ts3_eflags      dd  0
ts3_eax         dd  0
ts3_ecx         dd  0
ts3_edx         dd  0
ts3_ebx         dd  0
ts3_esp         dd  0
ts3_ebp         dd  0
ts3_esi         dd  0
ts3_edi         dd  0
ts3_es          dw  0
                dw  0
ts3_cs          dw  0
                dw  0
ts3_ss          dw  0
                dw  0
ts3_ds          dw  0
                dw  0
ts3_fs          dw  0
                dw  0
ts3_gs          dw  0
                dw  0
ts3_ldt         dw  0           ;local descriptor table for this task
                dw  0
ts3_iomap       dw  0
                dw  0

TSS386  ends


; -------------------------------------------------------
;               EXCEPTION VECTORS
; -------------------------------------------------------

; These are the interrupt vector numbers for the exception
; interrupts reserved by the 80286/80386.

EXC_DIV0        =   0           ;divide error
EXC_SINGLESTEP  =   1           ;single step
EXC_NMI         =   2           ;NMI interrupt
EXC_BREAKPOINT  =   3           ;breakpoint interrupt
EXC_INTO        =   4           ;overflow interrupt
EXC_BOUND       =   5           ;bounds overflow exception
EXC_OPCODE      =   6           ;invalid opcode exception
EXC_COPROCESSOR =   7           ;processor extension not available
EXC_DOUBLE      =   8           ;double fault
EXC_XOVERRUN    =   9           ;coprocessor segment overrun
EXC_TSS         =   10          ;invalid task state segment exception
EXC_NOTPRESENT  =   11          ;segment not present exception
EXC_STACK       =   12          ;stack overrun, or stack segment not present
EXC_GP          =   13          ;general protection exception
EXC_PF          =   14          ;page fault

; -------------------------------------------------------
;           GLOBAL DESCRIPTOR DECLARATIONS
; -------------------------------------------------------
;
;   The following symbols define the segment descriptors that
;   are statically defined in the Dos Extender.
;
;   NOTE:
;   These selector definitions assume that codeview is running
;   at privelege level 0.  If codeview is running at another
;   privelege level, the RPL fields must be adjusted.
;
;   Global Descriptor Table Conventions used in the Dos Extender

SEL_NULL        = 00h           ;null selector
IFNDEF WOW
SEL_GDT         = 08h           ;read/write data segment pointing to the
                                ; global descriptor table
SEL_IDT         = 10h           ;read/write data segment pointing to the
                                ; protected mode interrupt descriptor table
SEL_RMIVT       = 18h           ;read/write data segment pointing to the
                                ; real mode interrupt vector table
SEL_PSP         = 20h           ;Dos Extender PSP
SEL_ENVIRON     = 28h           ;Dos Extender Environment
SEL_BIOSCODE    = 30h           ;points at segment F000
SEL_DXDATA      = 38h           ;Dos Extender data segment
SEL_BIOSDATA    = 40h           ;PC BIOS data segment
SEL_DXPMCODE    = 48h           ;Dos Extender extended memory code segment
SEL_DXCODE      = 50h           ;Dos Extender low memory code segment
SEL_TSS         = 58h           ;Task State Segment selector
SEL_TSS_ALIAS   = 60h           ;read/write alias to TSS
SEL_LDT         = 68h           ;LDT selector
SEL_LDT_ALIAS   = 70h           ;read/write alias to LDT

SEL_DEBUG       = 78h           ;linear 4GB segment to be used by the
                                ; debugger to access all memory

SEL_EH          = 80h           ;Ring 0 segment code for handling processor
                                ;exceptions in PMODE

; NOTE: The next 4 segment descriptors are reserved for WDEB386 debugger.

SEL_DEB386      = 088h

SEL_RESET       = 0A8h          ;call gate to code that switches to real mode
SEL_DXDATA0     = 0B0h          ;Dos Extender data segment-ring 0
SEL_DXCODE0     = 0B8h          ;Dos Extender low memory code segment-ring 0

SEL_RZIRET      = 0C0h          ;Call gate to exit from fault handler.
SEL_STACK_ALIAS = 0C8h          ;Stack alias for Ring 3 exception handlers.

if      VCPI

SEL_DXPD        = 0D0h          ;for accessing page directory.

SEL_DXPT        = 0D8h          ;for accessing page tables

SEL_VCPI        = 0E0h          ;3 selectors for vcpi server
;                 0E8h
;                 0F0h

SEL_VCPIALLMEM  = SEL_DEBUG     ;for calls to vcpi to switch from protect
                                ; mode, this is a data segment mapping 4meg
                                ; starting at linear base 0.

SEL_CALLVCPI    = 0F8h          ;call gate to ring 0 VCPI interface

SEL_DYNALINK    = 100h          ;first DynaLink call gate selector

else    ;VCPI

SEL_IRETHOOK    = 0D0h
SEL_NBPMCODE    = 0D8H          ; net bios anr handler cs
SEL_DYNALINK    = 0E0h

endif   ;VCPI


;
; Size of the GDT.
;
GDT_SIZE        = (((SEL_DYNALINK + (NUM_DYNALINK shl 3) + 8) shr 4) shl 4)
GDT_SELECTORS   = (GDT_SIZE shr 3)

ELSE
SEL_DXDATA0     = 0
SEL_DXCODE0     = 0
SEL_RZIRET      = 0
SEL_LDT         = 0
SEL_RESET       = 0
SEL_TSS         = 0

SEL_GDT         = 80h           ;read/write data segment pointing to the
                                ; global descriptor table
SEL_IDT         = 88h           ;read/write data segment pointing to the
                                ; protected mode interrupt descriptor table
SEL_RMIVT       = 90h           ;read/write data segment pointing to the
                                ; real mode interrupt vector table
SEL_PSP         = 98h           ;Dos Extender PSP
SEL_ENVIRON     = 0A0h          ;Dos Extender Environment
SEL_BIOSCODE    = 0A8h          ;points at segment F000
SEL_DXDATA      = 0B0h          ;Dos Extender data segment
SEL_BIOSDATA    = 0B8h          ;PC BIOS data segment
SEL_DXPMCODE    = 0C0h          ;Dos Extender extended memory code segment
SEL_DXCODE      = 0C8h          ;Dos Extender low memory code segment
SEL_LDT_ALIAS   = 0D0h          ;read/write alias to LDT

SEL_VDMTIB      = 0D8h          ;used by DOSX to access TIB

SEL_EH          = 0E0h          ;Ring 0 segment code for handling processor
                                ;exceptions in PMODE

; NOTE: The next 4 segment descriptors are reserved for WDEB386 debugger.

SEL_DEB386      = 0E8h

SEL_STACK_ALIAS = 0128h         ;Stack alias for Ring 3 exception handlers.

SEL_WOW_LDT     = 0130h         ; readonly LDT selector for WOW kernel

SEL_NPXHDLR     = 0138h         ; selector for NpxExceptionHandler

SEL_IRETHOOK    = 0140h
SEL_NBPMCODE    = 0148H          ; net bios anr handler cs
;
; Size of the GDT.
;
GDT_SIZE        = (SEL_NBPMCODE + 8)
GDT_SELECTORS   = (GDT_SIZE shr 3)
ENDIF

;
; Special LDT selectors.
;

SEL_DPMI_FIRST  =      0        ; first reserved DPMI LDT selector
C_DPMI_RESERVED =      10h      ; count of reserved DPMI LDT selectors
SEL_DPMI_LAST   =      (C_DPMI_RESERVED - 1) * 8
                                ; last reserved DPMI LDT selector
IFNDEF WOW
SEL_SCR0        = SEL_DPMI_LAST + 8

                                ;scratch selector 0
SEL_SCR1        = SEL_SCR0 + 8  ;scratch selector 1
SEL_USERSCR     = SEL_SCR1 + 8  ;user scratch selector. This is used for
                                ; temporary return values to user from
                                ; system and bios calls
SEL_USER_STACK  = SEL_USERSCR + 8

;SEL_USER       = SEL_DYNALINK + (NUM_DYNALINK shl 3)
;this is where the dos extender starts allocating user selectors

SEL_USER        = SEL_USER_STACK + 8

ELSE

SEL_SCR0        = SEL_NBPMCODE + 8

                                ;scratch selector 0
SEL_SCR1        = SEL_SCR0 + 8  ;scratch selector 1
SEL_USERSCR     = SEL_SCR1 + 8  ;user scratch selector. This is used for
                                ; temporary return values to user from
                                ; system and bios calls
SEL_USER_STACK  = SEL_USERSCR + 8

;SEL_USER       = SEL_DYNALINK + (NUM_DYNALINK shl 3)
;this is where the dos extender starts allocating user selectors

SEL_USER        = SEL_USER_STACK + 8
ENDIF
; -------------------------------------------------------
; -------------------------------------------------------
; -------------------------------------------------------

;****************************************************************
