Jump to content

DevHelp_PageListToLin

From EDM2
Revision as of 05:38, 11 May 2025 by Martini (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This service maps physical memory pages described in an array of _PageList structures to a linear address. The size of the linear mapping must not exceed 64KB.

Syntax

C

USHORT APIENTRY DevHelp_PageListToLin(ULONG Size,
                                      LIN   pPageList,
                                      PLIN  LinearAddr)

Assembler

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 array of PageList_s
                             ;     structures.
MOV   DL,DevHlp_PageListToLin

CALL  [Device_Help]

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;

Parameters

C

Size (ULONG)
Count of bytes to be mapped; sum of the pl_cb fields in the PageList array.
pPageList (LIN)
Flat pointer to array of PageList_s structures.
LinearAddr (PLIN)
Linear address pointer to be returned.

Each PageList_s structure describes a single physically contiguous subregion of the physical memory to be mapped. The format of the PageList_s structure is:

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

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

Assembler

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 array of PageList_s
                             ;     structures.

Return Code

C

Success Indicator: 0 if region could be mapped. Linear address returned.

Possible errors:

              Region could not be mapped.
              ERROR_INVALID_PARAMETER  (87)

Assembler

   'C' Clear if region could be mapped.
       EAX = Linear address.

   'C' Set if region could not be mapped.
       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, the first byte within the returned linear range 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 function 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 other DevHlp services, the linear mapping might be discontiguous. Linear addresses can be mapped to physical addresses only on a page-granular basis. Therefore, if the PageList contains physical addresses and sizes that do not directly correspond to page boundaries, the linear mapping will necessarily contain holes, which 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

PageListToLin maps the 600 hex bytes in PageList entry 1 to the start of the linear range. However, because the underlying hardware only supports mapping integral pages, the range 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 linear range will correspond to the beginning of the first physical page described in PageList entry 2. The data for PageList entry number 2 then follows. The offsets from the starting linear address are mapped as follows:

 100h - 6FFh:   Data for PageList entry 1.  
 700h - FFFh:   Unrequested remainder of the physical page of entry 1.
1000h - 14FFh:  Unrequested beginning of the physical page of entry 2.
1500h - 16FFh:  Data for PageList entry 2.

The first byte in the linear mapping 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, are mapped contiguously from that point.

The starting linear address of subsequent PageList entries can be computed by rounding up the linear address of the end of the previous entry to a page boundary, and then adding on the low-order 12 bits of the physical address of the target PageList entry.

The linear mapping produced by this function is valid only until the caller yields the CPU, or until it issues another call to PageListToLin or PhysToVirt. PageListToLin also invalidates any outstanding PhysToVirt mappings.

Example Code

C

#include  "dhcalls.h"

USHORT APIENTRY DevHelp_PageListToLin(ULONG Size,
                                      LIN   pPageList,
                                      PLIN  LinearAddr)

Related Functions