SCO OpenServer
sptalloc(D3oddi)
sptalloc --
allocate temporary memory or map a device's memory
Synopsis
#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);
Description
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.
Arguments
pages-
specifies the number of requested pages
to be allocated or mapped in.
mode-
page descriptor table entry mask.
Possible values (defined in <sys/immu.h>) are:
PG_P-
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.
PG_PCD-
Disables the cache when accessing the memory area.
PG_RW-
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.)
PG_US-
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.
base-
set to 0 (zero) to allocate free kernel memory,
or set to the physical page frame number
of the address to be mapped.
flag-
bit mask set using the following values (defined
in <sys/immu.h>):
DMAABLE-
The memory allocated must be within the 16MB of memory,
required for some ISA devices.
NOSLEEP-
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.
VM_SLEEPFLAG-
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.
pri-
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.
Usage
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
All
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.
References
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