SCO OpenServer


phystokv, kvtophys -- convert virtual and physical addresses


#include <sys/param.h>
#include <sys/types.h>

caddr_t phystokv(paddr_t paddr); paddr_t kvtophys(caddr_t vaddr);


The phystokv( ) macro converts a physical address to a kernel virtual address. The kvtophys( ) macro converts a kernel virtual address to a physical address.


physical address

kernel virtual address

Return values

phystokv( ) returns a kernel virtual address; kvtophys( ) returns a physical address.

If kvtophys( ) is given a virtual address that does not map to a physical address, the kernel panics with the following message:

   svirtophys - Page not present


These macros are used when a driver needs to share memory addresses with adapter hardware. External hardware may only access memory by using the physical address; driver access to the same memory must use the virtual address.

phystokv( ) and kvtophys( ) are not the inverse of each other, because many virtual addresses may map to the same physical address. kvtophys( ) uses the page tables while phystokv( ) relies on the kernel having physical memory mapped directly in a portion of its address space, applying a simple offset to obtain the virtual address.

Up to 512MB of the kernel's virtual address space is devoted to a mapping of physical memory. With smaller memory configurations, this allows for a simple conversion between physical addresses and kernel virtual addresses. With very large physical memory configurations, however, the kernel may not have enough virtual space to map all of the physical memory. When this happens, phystokv( ) operates only on the memory that happens to be mapped. The standard driver interfaces (such as the I/O entry point routines and the memory allocation functions) handle this condition for the driver.

Drivers that need to translate between physical addresses and kernel virtual addresses should call the sptalloc(D3oddi) function to explicitly assign a kernel virtual address to the physical memory before calling phystokv( ) to ensure that the results will be valid for all memory configurations.

The result of these macros should always be cast to an explicit type. There is no compile-time parameter type checking for the phystokv( ) and kvtophys( ) macros and the return value of these macros has the same type as the parameter. If the parameter is not of a suitable type (such as if the parameter is a short * or int *), and the result is not type cast, these macros silently return the wrong value.

Context and synchronization

All contexts.

Hardware applicability


Version applicability

phystokv, kvtophys
oddi: 2, 2mp, 3, 3mp, 4, 4mp, 5, 5mp, 6, 6mp

ptok, ktop
oddi: 1

Differences between versions

ptok( ) and ktov( ) are the XENIX macros used to convert between physical and virtual addresses. ptok( ) is the equivalent of phystokv( ) and ktov( ) is the equivalent of kvtophys( ). The syntax is:
   caddr_t ptok(paddr_t paddr);
   paddr_t ktop(caddr_t vaddr);
All drivers written for SCO OpenServer should use the phystokv( ) and kvtophys( ) macros instead.

Beginning with ODDI version 4 (SCO OpenServer Release 5.0.4), compile-time parameter type checking is enforced and these macros return a pointer type. Drivers that specify the types as documented above should work correctly in either case, but some drivers that have depended on the lax typing may have problems beginning with SCO OpenServer Release 5.0.4.

ODDI version 4 (SCO OpenServer Release 5.0.4) modified the behavior of phystokv( ) so that many drivers that are built on SCO OpenServer Release 5.0.4 cannot run on SCO OpenServer 5 Release 5.0.2 and earlier releases. SCO OpenServer Release 5.0.5 corrects this problem. Customers who want to develop drivers on SCO OpenServer Release 5.0.4 and later versions that can run on earlier releases of the operating system should preceed the #include line for the sys/immu.h header file with the following:

   #define ODDI3_COMPAT

SVR5 compatibility

The phystokv( ) function is not supported in any current DDI versions. For DDI version 7 and earlier versions, the vtop(D3) function is similar to the kvtophys( ) macro. paddr is not visable to DDI 8 drivers, so direct conversion between physical and virtual addresses is not possible.

For DDI drivers, physical requirements for allocated memory are specified through a physreq(D4) structure, which is used with memory allocation functions such as kmem_alloc_physreq(D3) and msgphysreq(D3str).



``Memory allocation'' in HDK Technical Reference

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 5 HDK - June 2005