OS/2 Version 2.0 still uses a 16-bit device driver model. In order to optimize existing device drivers for the 32-bit flat memory model, new DevHlp() functions have been added for memory management.
Since paging is used in OS/2 Version 2.0, segments no longer need to be physically contiguous in memory. Thus, when locking these segments in memory, the memory manager may need to "shuffle" pages to make them contiguous.
This shuffling can greatly increase the amount of time it takes to perform the locking. Locking of entire segments should therefore be avoided by using the new VMLock DevHlp() function, which locks only the required range of addresses within a memory object.
In previous versions of OS/2, device drivers were required to lock the user's buffers to gain context-free addressability. Since locking degrades performance and reduces available pageable system memory, new DevHlp() functions have been added to convert these addresses without the need for locking.
Device drivers can reduce the amount of selector loading by using the new flat memory model DevHlp() functions to allocate memory. All of the memory allocated by the new VMAlloc DevHlp() function can be addressed via one flat selector available to device drivers at initialization time.
Scatter/gather DMA adapters (such as the IBM SCSI adapters described in Micro Channel Architecture and SCSI) allow DMA operations on physically discontiguous pages of memory. This ability provides a significant performance advantage over contiguous DMA operations.
By using the new VMLock DevHlp() function, a device driver can specify that pages should be locked without being physically contiguous in memory. VMLock will then return the physical addresses of each page that was locked.
Address-limited devices (using 24-bit addressing) do not support memory
above 16MB. The device drivers for these products will use a new bit on
the VMLock and VMAlloc calls, which specifies that the memory
must be locked or allocated below the 16MB line.
The following are some of the new DevHlp() functions implemented in OS/2 Version 2.0:
VMAlloc is used to allocate linear and/or physical address space in memory. These allocations can exceed 64KB in size and can be either fixed, movable or swappable memory. This call can be used to map non-system memory into the current process context.
Memory allocated via VMAlloc can be freed with the VMFree DevHlp() function. VMFree is also used to remove the mappings created by VMGlobalToProcess and VMProcessToGlobal.
VMLock is used to lock a linear address range into physical memory. If the lock is needed for scatter/gather DMA, then a list of physical page addresses is returned.
VMUnlock is the counterpart of the VMLock function. It is used to unlock memory previously locked via VMLock.
The VMProcessToGlobal DevHlp() function is used to convert an address that is in the context of the current process to an address in a global context. This allows context-free addressability to the memory objects of a process.
VMGlobalToProcess can be used to map a global context address into the address space of the current process. When used for video buffers, the calling process can specify if the memory should be under screen group control. This will cause the memory to be validated or invalidated at task switch time.
VirtToLin will convert a selector:offset address into a flat 32-bit linear address.
LinToGDTSelector is used to convert a linear address to a virtual (selector:offset) address by mapping the given GDT selector to the memory region referred to by the given linear address and range.
PhysToGDTSel converts a 32-bit physical address to a GDT selector:offset pair.
FreeGDTSelector frees up a GDT selector allocated via the AllocGDTSelector DevHlp() function.
PageListToGDTSelector is used to map physical addresses to a GDT selector, setting the access byte of the descriptor to the requested type. The virtual memory needed to map the physical ranges described by the page list array must not exceed 64KB.
GetDescInfo is used to return the access byte, linear address, and size of a descriptor allocated via the AllocGDTSelector DevHlp() function.
PageListToLin is used to map physical memory pages described in an array of page list structures to a linear address.
LinToPageList is used to translate a linear address range to an array
of page list structures that describe the physical pages mapped.