DevHelp PageListToGDTSelector

From EDM2
Jump to: navigation, search

This service maps physical addresses described in an array of _PageList structures to a GDT (Global Descriptor Table) selector, setting the access byte of the descriptor to the requested type. The virtual memory needed to map the physical ranges described by the PageList array must not exceed 64KB.

Syntax

C

USHORT APIENTRY DevHelp_PageListToGDTSelector( SEL     Selector,
                                               ULONG   Size,
                                               USHORT  Access,
                                               LIN     pPageList)

Assembler

MOV   AX,Selector              ; GDT selector to map;  allocated with
                                    AllocateGDTSelector
MOV   ECX,cbSize               ; Count of bytes to be mapped;
                               ;    sum of the pl_cb fields in the PageList array
MOV   EDI,OFFSET pPageList     ; Flat pointer to an array of PageList_s
                               ;    structures to map the selector to.
MOV   DH, Access               ; Descriptor's type and privilege level
                               ; = 0  The selector is mapped as Ring 3, readable
                               ;    code with 16-bit addressing/operand size
                               ;    (286 format).
                               ; = 1 (binary 0001)  The selector is mapped as Ring
                               ;     3, writable data.
                               ; = 3 (binary 0011)  The selector is mapped as Ring
                               ;     2, IOPL, readable code with 16 bit
                               ;     addressing/operand size.
                               ; = 4 (binary 0100)  The selector is mapped as Ring
                               ;     2, IOPL, writable data.
                               ; = 5 (binary 0101)  The selector is mapped as Ring
                               ;     0, readable code with 16 bit
                               ;     addressing/operand size.
                               ; = 6 (binary 0110)  The selector is mapped as Ring
                               ;     0, writable data.
                               ; In addition, 128 (binary 10000000) can be OR'ed
                               ;     onto any of the above access values and will
                               ;     cause the selector to be mapped with 32 bit
                               ;     default addressing/operand size (the 'B' or
                               ;     'D' bit will be set in the selector).
                               ; Any other values are invalid.


MOV   DL,DevHlp_PageListToGDTSelector

CALL  [Device_Help]

_PAGELIST is the flat address of an array of _PAGELIST structures. Each _PAGELIST structure describes a single physically contiguous subregion of the physical memory to be mapped. The format of the _PAGELIST structure is:

PAGELIST struc
{
  ULONG pl_PhysAddr /* physical address of first byte in this region      */
  ULONG pl_cb       /* number of contiguous bytes starting at pl_physAddr */
}

Parameters

C

Selector (SEL)
GDT selector to map; allocated with AllocateGDTSelector.
Size (ULONG) 
Count of bytes to be mapped; sum of the pl_cb fields in the PageList array.
Access (USHORT) 
Descriptor's type and privilege level:
GDTSEL_R3CODE - The selector is mapped as ring 3, readable code with 16-bit addressing/operand size (286 format).
GDTSEL_R3DATA - (binary 0001) The selector is mapped as ring 3 writable data.
GDTSEL_R2CODE - (binary 0011) The selector is mapped as ring 2, IOPL, readable code with 16-bit addressing/operand size.
GDTSEL_R2DATA - (binary 0100) The selector is mapped as ring 2, IOPL, writable data.
GDTSEL_R0CODE - (binary 0101) The selector is mapped as ring 0, readable code with 16-bit addressing/operand size.
GDTSEL_R0DATA - (binary 0110) The selector is mapped as ring 0, writable data.
In addition, GDTSEL_ADDR32 (binary 10000000) can be OR'ed into any of the above access values and will cause the selector to be mapped with 32-bit default addressing/operand size (the 'B' or 'D' bit will be set in the selector).
Any other values are invalid.
pPageList (LIN) 
Flat pointer to an array of PageList_s structures to map the selector to.

PAGELIST is a flat address of an array of PAGELIST structures. Each PAGELIST structure describes a single physically contiguous subregion of the physical memory to be mapped. The format of the PAGELIST structure is:

Typedef struct _PAGELIST{
      ULONG PhysAddr;
      ULONG Size;
      }PAGELIST;

The sum of the pl_cb fields in the PageList array produced by this function is equal to Size.

Assembler

MOV   AX,Selector          ; GDT selector to map;  allocated with
                                    AllocateGDTSelector
MOV   ECX,cbSize           ; Count of bytes to be mapped;
                           ;    sum of the pl_cb fields in the PageList array
MOV   EDI,OFFSET pPageList ; Flat pointer to an array of PageList_s
                           ;    structures to map the selector to.
MOV   DH, Access           ; Descriptor's type and privilege level
                           ; = 0  The selector is mapped as Ring 3, readable
                           ;    code with 16-bit addressing/operand size
                           ;    (286 format).
                           ; = 1 (binary 0001)  The selector is mapped as Ring
                           ;     3, writable data.
                           ; = 3 (binary 0011)  The selector is mapped as Ring
                           ;     2, IOPL, readable code with 16 bit
                           ;     addressing/operand size.
                           ; = 4 (binary 0100)  The selector is mapped as Ring
                           ;     2, IOPL, writable data.
                           ; = 5 (binary 0101)  The selector is mapped as Ring
                           ;     0, readable code with 16 bit
                           ;     addressing/operand size.
                           ; = 6 (binary 0110)  The selector is mapped as Ring
                           ;     0, writable data.
                           ; In addition, 128 (binary 10000000) can be OR'ed
                           ;     onto any of the above access values and will
                           ;     cause the selector to be mapped with 32 bit
                           ;     default addressing/operand size (the 'B' or
                           ;     'D' bit will be set in the selector).
                           ; Any other values are invalid.


MOV   DL,DevHlp_PageListToGDTSelector

Return Code

C

Success Indicator:

0 if pages locked - Selector returned with modified RPL (Requested Privilege Level) bits.

Possible errors:

Segment unavailable
EAX = Error code - ERROR_INVALID_PARAMETER (87)

Assembler

   'C' Clear if pages locked.
       AX = Selector with the modified RPL (Requested Privilege Level) bits.

   'C' Set if segment unavailable.
       EAX = Error code -  ERROR_INVALID_PARAMETER  (87)

Remarks

The physical memory that is being mapped must be fixed or locked prior to this call. After this call, offset 0 within the selector corresponds to the first byte in the first entry in the array pointed to by pPageList. If the PageList is an unmodified return array from VMLock or LinToPageList, then the mapping returned from this call is, byte for byte, the same as the original linear range. However, if the PageList array was constructed by some other means, or is a concatenation of two or more PageList arrays returned from various other DevHlp services, the selector mapping can be discontiguous. Because linear addresses must be mapped to physical addresses on a page-granular basis, if the PageList contains physical addresses and sizes, which do not directly correspond to page boundaries, then the selector mapping will necessarily contain holes that map unrequested front, or tail ends of pages that contain requested addresses. For example, given the following two PageList entries (all numbers are in hex):

   pl_PhysAddr = 4100, pl_cb = 600
   pl_PhysAddr = 1500, pl_cb = 200

PageListToGDTSelector maps the 600 hex bytes in PageList entry 1, beginning at offset 0 within the selector. However, because the underlying hardware only supports mapping integral pages, the selector also addresses the remaining 900 hex bytes in the physical page, beginning at address 4000 (4100H + 600H + 900H = 5000H = the end of the physical page). The next addresses mapped by the selector corresponds to the beginning of the first physical page described in PageList entry 2. The data for PageList entry number 2 then follows. The offsets within the selector are mapped as follows:

   0  -  5FFH:   Data for PageList entry 1.
 600H -  EFFH:   Unrequested remainder of the physical page of entry 1.
 F00H - 13FFH:   Unrequested beginning of the physical page of entry 2.
1400H - 15FFH:   Data for PageList entry 2.

The first byte mapped by the selector corresponds to the first byte described in the first entry in the PageList array. The next n bytes, where n is the size parameter of the first PageList entry, is mapped contiguously from that point.

The offset within the selector of subsequent PageList entries can be computed by the formula O + PS - (A mod PS) + (B mod PS), where O is the offset within the selector of the byte following the end of the previous PageList entry; PS is the page size (4KB); A is the physical address of the byte following the end of the previous PageList entry; and B is the physical address of the start of the next PageList entry.

After this call has been issued for a particular selector, the addressability remains valid until the physical device driver changes its content with a subsequent call to the PageListToGDTSelector, PhysToGDTSel, PhysToGDTSelector, or LinToGDTSelector DevHelp services.

Example Code

C

#include  "dhcalls.h"

USHORT APIENTRY DevHelp_PageListToGDTSelector( SEL     Selector,
                                               ULONG   Size,
                                               USHORT  Access,
                                               LIN     pPageList)