SCO OpenServer


sptalloc -- allocate temporary memory or map a device's memory


#include <sys/sysmacros.h>
#include <sys/immu.h>

caddr_t sptalloc(pgcnt_t pages, int mode, pfn_t base, memflags_t flag);

uint VM_SLEEP(uint pri);


The sptalloc( ) function is used to obtain temporary memory for use by device drivers, or to map a device into memory for memory mapped I/O. Memory is obtained from the system's virtual memory pool. When the driver has finished with the memory, it should call the sptfree(D3oddi) function to release the memory segment.

The VM_SLEEP( ) macro is used to set the sleep priority at which the process will sleep waiting for memory to be addressed.


specifies the number of requested pages to be allocated or mapped in.

page descriptor table entry mask. Possible values (defined in <sys/immu.h>) are:

Must always be present for driver use. PG_P causes the ``page present bit'' to be set in the page table entry. The CPU uses the page present bit to differentiate between pages that have to be faulted in and pages that are already there.

Disables the cache when accessing the memory area.

Makes the segment usable for either reading or writing. If this flag is not ORed into mode, then the segment is read-only. This flag only has meaning when used with PG_US to indicate if a user can access the segment for both reading and writing. (Kernel processes can read or write any present page whether write access is ``permitted'' or not.)

Allows user access to the memory obtained when ORed with other values. Memory is for a kernel process only if PG_US is omitted. If selected, any user process can access the page. You should logically OR PG_US with PG_RW if write permission is required; without PG_RW, the page is read-only. To use this capability, a driver must pass the return value from sptalloc( ) back to the user process for it to be able to access the memory, but this does not limit its use to that process.

set to 0 (zero) to allocate free kernel memory, or set to the physical page frame number of the address to be mapped.

bit mask set using the following values (defined in <sys/immu.h>):

The memory allocated must be within the 16MB of memory, required for some ISA devices.

Causes immediate return if memory is not available. However, if only one page is being requested and memory is not available, sptalloc( ) ignores NOSLEEP and sleeps until memory is available. When sleeping is requested, that is the NOSLEEP flag is not set, sptalloc( ) sleeps with a priority of 0 (zero) and is not affected by signals.

Sleep until virtual memory can be allocated. Without this flag set, sptalloc( ) sleeps until physical memory is available. Use the VM_SLEEP macro to set the sleep priority.

Priority at which to block when waiting for virtual memory to be available. pri is always ORed with PCATCH so the process can be awakened by a signal. See sleep(D3oddi) for more information about sleep priorities.

Return values

The sptalloc( ) function returns the kernel virtual address of the memory that is allocated. This memory can be used by any kernel or driver routine.

NULL is returned if memory cannot be allocated or map space is not available.


The memory allocated is virtually contiguous but not physically contiguous and is never paged or swapped out. It is available until it is explicitly freed with sptfree( ).

The most common way to call sptalloc( ) is as follows:

   ptr=sptalloc(pages, PG_P, 0, NOSLEEP);
The following call sets up memory-mapped I/O for an imaginary device being installed at physical address 0xB8000:
   ptr=sptalloc(1, PG_P | PG_PCD, btoc(0xB8000), NOSLEEP);
Note that the base argument passed is the page frame number of the physical memory to map. The btoc(D3oddi) macro is used to convert from a physical address to a page frame number.

The following call illustrates how to use sptalloc( ) to allocate virtual memory. This call is set up to try again if the allocation is not successful, which might happen if the process is interrupted by a signal.

   while (!(xx = (my_t *)sptalloc(btoc(sizeof(my_t)),
   	PG_P | PG_RW, 0, VM_SLEEP(PZERO))))

A mapping performed with vasbind(D3oddi) creates a region of memory shared only between the kernel and a specific user process. sptalloc( ), however, can create a mapping that is accessible by the kernel and all processes that know the virtual address returned from sptalloc( ), which is the address at which the memory can be accessed.

Context and synchronization

If the NOSLEEP flag is set and more than 1 page is requested
Non-blockable, user or blockable context.

all other cases
User or blockable context.

Hardware applicability


The PG_PCD mode utilizes the cache disable bit which is available only on 486-class processors and later.

Version applicability

oddi: 1, 2, 2mp, 3, 3mp, 4, 4mp, 5, 5mp, 6, 6mp

Differences between versions

In ODDI versions 3 and earlier, the syntax is:
   caddr_t sptalloc(int pages, int mode, pfn_t base, int flag);
The VM_SLEEP macro is not supported for ODDI versions 3 and earlier.

SVR5 DDI compatibility

The sptalloc( ) function is not supported for DDI drivers. For DDI 7 and earlier versions, use the physmap(D3) function to map device memory. For DDI 8 and later versions, use the devmem_mapin(D3) function for this purpose. DDI drivers use the kmem_alloc(D3) and related functions for all memory allocation.

See ``Memory allocation'' in HDK Technical Reference for information about the memory allocation facilities and ``Memory-mapped I/O'' in HDK Technical Reference for information about the memory-mapped I/O facilities available to DDI drivers.


btoc(D3oddi), memget(D3oddi), sptfree(D3oddi), vas(D3oddi), vasbind(D3oddi)

``Memory allocation'' in HDK Technical Reference
``Memory-mapped I/O'' in HDK Technical Reference

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