NAME | SYNOPSIS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | Allowed Calling Contexts | EXAMPLES | ATTRIBUTES
#include <dki/dki.h>KnError svPhysAlloc(KnPhMemChunk * chunk, KnPhMemAlign * align);
typedef struct { PhAddr paddr; PhSize psize; VmAddr vaddr; } KnPhMemChunk; typedef struct { PhAddr alignment; PhAddr floating; } KnPhMemAlign;
DKI
Provides special purpose physical memory allocation.
In order to satisfy all physical memory constraints imposed by the different I/O buses, mainly for DMA purposes, the DKI provides an interface to allocate and free special purpose physical memory that satisfies the given constraints.
Typically, different I/O buses may impose different constraints on the memory used by their devices for Direct Memory Access, such as alignement, specific boundary crossing, maximum size, or specific locations within the physical memory space.
svPhysAlloc allocates an amount of contiguous physical memory that satisfies the required constraints. The chunk argument points to the KnPhMemChunk structure. The psize field is an input argument specifying the size in bytes of the memory to be allocated. The paddr field is an input/output argument specifying the physical start address of the allocated memory chunk.
The vaddr field is not used by svPhysAlloc .
The align argument points to the KnPhMemAlign structure.
The KnPhMemAlign structure specifies the constraints on the memory chunk being allocated.
The alignment field is a mask which specifies constraints on the start address of the memory chunk being allocated. A bit set within alignment specifies that the corresponding bit within the start address may take any value, i.e. there are no specific constraints on that bit. A bit cleared within alignment specifies that the corresponding bit within the start address must take the same value as the corresponding bit of the paddr field. This mask allows the caller to specify an alignment for the start of the allocated memory, by zeroing the required number of least significant bits. By resetting the required number of most significant bits, the caller may also indicate which part of the physical space the memory should be allocated to.
The floating field is a mask which indicates which bits of the returned address can vary while walking through the allocated memory for the required size. In other words, bits cleared in the mask must be constant for all addresses in the range of the allocated memory. This mask may be used to specify that the amount of memory allocated must not span across a given address boundary.
Note that the align argument may be set to NULL specifying that there are no constraints on the memory chunks allocated. In case of success, the starting address of the allocated memory is returned in the paddr field and the function returns K_OK . The returned address is aligned on a page boundary and is therefore suitably aligned to be used subsequently in mapping services. The size of effectively allocated memory is rounded up to the next page boundary.
On failure, an error code is returned as follows:
There is no contiguous physical memory which satisfies the requirements specified by both significant and floating arguments.
The size argument is equal to zero.
svPhysFree releases physical memory previously allocated with svPhysAlloc .
The chunk argument points to the KnPhMemChunk structure which specifies the physical chunk start addresses and the chunk size.
The psize field must have the value previously specified in svPhysAlloc . The paddr field must have the value previously returned by svPhysAlloc .
Typically, a driver uses the same KnPhMemChunk structure for the svPhysAlloc and svPhysFree calls and the structure fields are not modified by the driver once svPhysAlloc has been done.
The following table specifies the contexts in which a caller is allowed to invoke each service.
Services | Base level | DKI thread | Interrupt | Blocking |
svPhysAlloc | + | + | - | + |
svPhysFree | + | + | - | + |
As an example, to allocate a 16KB contiguous memory region in the first Megabyte of physical space, that is aligned on a 4KB address, which does not span a 64KB boundary, the call should look like:
KnPhMemChunk chunk; KnPhMemAlign align; chunk.psize = 0x00004000; /* psize = 16KB */ align.alignment = 0x000ff000; /* alignment = (1024KB-1) & ~(4KB-1) */ align.floating = 0x0000ffff; /* floating = 64KB-1 */ res = svPhysAlloc(&chunk, &align);
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
NAME | SYNOPSIS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | Allowed Calling Contexts | EXAMPLES | ATTRIBUTES