Data Structures | Defines | Typedefs | Functions | Variables

cmem.h File Reference


Detailed Description

Describes the interface to the contiguous memory allocator.

The cmem user interface library wraps file system calls to an associated kernel module (cmemk.ko), which needs to be loaded in order for calls to this library to succeed.

The following is an example of installing the cmem kernel module:

/sbin/insmod cmemk.ko pools=4x30000,2x500000 phys_start=0x0 phys_end=0x3000000 

This particular command creates 2 pools. The first pool is created with 4 buffers of size 30000 bytes and the second pool is created with 2 buffers of size 500000 bytes. The CMEM pool buffers start at 0x0 and end at 0x2FFFFFF (max).

There is also support for a 2nd contiguous memory block to be specified, with all the same features supported for the 2nd block as with the 1st. This 2nd block is specified with *_1 parameters. The following example expands upon the first example above:

/sbin/insmod cmemk.ko pools=4x30000,2x500000 phys_start=0x0 phys_end=0x3000000
    pools_1=4x65536 phys_start_1=0x80000000 phys_end_1=0x80010000 

This particular command, in addition to the pools explained above, creates 1 pool (with 4 buffers of size 64KB) in a 2nd memory block which starts at 0x80000000 and ends at 0x8000FFFF (specified as "end + 1" on the insmod command).

In order to access this 2nd memory block, new APIs have been added to CMEM which allow specification of the block ID.

There are two more configuration "switches" for the cmemk.ko kernel module, which can be specified on the 'insmod' (or 'modprobe') command lines: useHeapIfPoolUnavailable=[0|1] allowOverlap=[0|1]

'useHeapIfPoolUnavailable', when set to 1, will cause pool-based allocations to fallback to a heap-based allocation if no pool buffer of sufficient size is available (the CMEM heap is described below).

'allowOverlap', when set to 1, causes cmemk.ko to not fail when it detects that a CMEM memory block location conflicts with the Linux kernel memory, and instead an informational message is printed on the console. When set to 0, cmemk.ko insertion will fail when this condition is detected. The overlap detection is fairly crude, however, checking only that the end of the kernel's memory (assigned by way of the u-boot 'bootargs' parameter "mem=##M") is not above the beginning location of a CMEM memory block. For example, on most TI processor-based systems the kernel's memory starts at 0x80000000 and ends at (0x80000000 + #M), so a CMEM block starting at 0x1000 would be detected as overlapping since the beginning location of that block is not greater than the end location of the kernel's memory. To allow this situation, cmemk.ko should be inserted using "allowOverlap=1".

Pool buffers are aligned on a module-dependent boundary, and their sizes are rounded up to this same boundary. This applies to each buffer within a pool. The total space used by an individual pool will therefore be greater than (or equal to) the exact amount requested in the installation of the module.

The poolid used in the driver calls would be 0 for the first pool and 1 for the second pool.

Pool allocations can be requested explicitly by pool number, or more generally by just a size. For size-based allocations, the pool which best fits the requested size is automatically chosen. Some CMEM APIs (newer ones) accept a blockid as a parameter, in order to specify which of the multiple blocks to operate on. For 'legacy' APIs (ones that existed before the support for multiple blocks) where a blockid is still needed, block 0 is assumed.

There is also support for a general purpose heap. In addition to the 2 pools described above, a general purpose heap block is created from which allocations of any size can be requested. Internally, allocation sizes are rounded up to a module-dependent boundary and allocation addresses are aligned either to this same boundary or to the requested alignment (whichever is greater).

The size of the heap block is the amount of CMEM memory remaining after all pool allocations. If more heap space is needed than is available after pool allocations, you must reduce the amount of CMEM memory granted to the pools.

Buffer allocation is tracked at the file descriptor level by way of a 'registration' list. The initial allocator of a buffer (the process that calls CMEM_alloc()) is automatically added to the registration list, and further processes can become registered for the same buffer by way of the CMEM_registerAlloc() API (and unregister with the CMEM_unregister() API). This registration list for each buffer allows for buffer ownership tracking and cleanup on a per-file-descriptor basis, so that when a process exits or dies without having explicitly freed/unregistered its buffers, they get automatically unregistered (and freed when no more registered file descriptors exist). Only when the last registered file descriptor frees a buffer (either explictily, or by auto-cleanup) does a buffer actually get freed back to the kernel module.

Since the CMEM interface library doesn't use the GT tracing facility, there is one configuration option available for the CMEM module to control whether the debug or release interface library is used for building the application. This config parameter is named 'debug' and is of type bool, and the default value is 'false'.

The following line is an example of enabling usage of the debug interface library: var cmem = xdc.useModule('ti.sdo.linuxutils.cmem.CMEM'); cmem.debug = true; This will enable "CMEM Debug" statements to be printed to stdout.

Go to the source code of this file.

Data Structures

struct  CMEM_AllocParams
 Parameters for CMEM_alloc(), CMEM_alloc2(), CMEM_allocPool(), CMEM_allocPool2(), CMEM_free(). More...
struct  CMEM_BlockAttrs

Defines

#define CMEM_VERSION   0x03000100U
#define CMEM_WB   0x00010000
#define CMEM_INV   0x00020000
#define CMEM_HEAP   0x00040000
#define CMEM_POOL   0x00000000
#define CMEM_CACHED   0x00080000
#define CMEM_NONCACHED   0x00000000
#define CMEM_PHYS   0x00100000
#define CMEM_IOCMAGIC   0x0000fe00
#define CMEM_IOCALLOC   1
#define CMEM_IOCALLOCHEAP   2
#define CMEM_IOCFREE   3
#define CMEM_IOCGETPHYS   4
#define CMEM_IOCGETSIZE   5
#define CMEM_IOCGETPOOL   6
#define CMEM_IOCCACHE   7
#define CMEM_IOCGETVERSION   8
#define CMEM_IOCGETBLOCK   9
#define CMEM_IOCREGUSER   10
#define CMEM_IOCGETNUMBLOCKS   11
#define CMEM_IOCCACHEWBINV   CMEM_IOCCACHE | CMEM_WB | CMEM_INV
#define CMEM_IOCCACHEWB   CMEM_IOCCACHE | CMEM_WB
#define CMEM_IOCCACHEINV   CMEM_IOCCACHE | CMEM_INV
#define CMEM_IOCALLOCCACHED   CMEM_IOCALLOC | CMEM_CACHED
#define CMEM_IOCALLOCHEAPCACHED   CMEM_IOCALLOCHEAP | CMEM_CACHED
#define CMEM_IOCFREEHEAP   CMEM_IOCFREE | CMEM_HEAP
#define CMEM_IOCFREEPHYS   CMEM_IOCFREE | CMEM_PHYS
#define CMEM_IOCFREEHEAPPHYS   CMEM_IOCFREE | CMEM_HEAP | CMEM_PHYS
#define CMEM_IOCCMDMASK   0x000000ff

Typedefs

typedef struct CMEM_AllocParams CMEM_AllocParams
 Parameters for CMEM_alloc(), CMEM_alloc2(), CMEM_allocPool(), CMEM_allocPool2(), CMEM_free().
typedef struct CMEM_BlockAttrs CMEM_BlockAttrs

Functions

int CMEM_init (void)
 Initialize the CMEM module. Must be called before other API calls.
int CMEM_getPool (size_t size)
 Find the pool that best fits a given buffer size and has a buffer available.
int CMEM_getPool2 (int blockid, size_t size)
 Find the pool in memory block blockid that best fits a given buffer size and has a buffer available.
void * CMEM_allocPool (int poolid, CMEM_AllocParams *params)
 Allocate memory from a specified pool.
void * CMEM_allocPool2 (int blockid, int poolid, CMEM_AllocParams *params)
 Allocate memory from a specified pool in a specified memory block.
void * CMEM_alloc (size_t size, CMEM_AllocParams *params)
 Allocate memory of a specified size.
void * CMEM_alloc2 (int blockid, size_t size, CMEM_AllocParams *params)
 Allocate memory of a specified size from a specified memory block.
void * CMEM_registerAlloc (unsigned long physp)
 Register shared usage of an already-allocated buffer.
int CMEM_free (void *ptr, CMEM_AllocParams *params)
 Free a buffer previously allocated with CMEM_alloc()/CMEM_allocPool().
int CMEM_unregister (void *ptr, CMEM_AllocParams *params)
 Unregister use of a buffer previously registered with CMEM_registerAlloc().
unsigned long CMEM_getPhys (void *ptr)
 Get the physical address of a contiguous buffer.
int CMEM_cacheWb (void *ptr, size_t size)
 Do a cache writeback of the block pointed to by ptr/size.
int CMEM_cacheInv (void *ptr, size_t size)
 Do a cache invalidate of the block pointed to by ptr/size.
int CMEM_cacheWbInv (void *ptr, size_t size)
 Do a cache writeback/invalidate of the block pointed to by ptr/size.
int CMEM_getVersion (void)
 Retrieve version from CMEM driver.
int CMEM_getBlock (unsigned long *pphys_base, size_t *psize)
 Retrieve memory block bounds from CMEM driver.
int CMEM_getBlockAttrs (int blockid, CMEM_BlockAttrs *pattrs)
 Retrieve extended memory block attributes from CMEM driver.
int CMEM_getNumBlocks (int *pnblocks)
 Retrieve number of blocks configured into CMEM driver.
int CMEM_exit (void)
 Finalize the CMEM module.

Variables

CMEM_AllocParams CMEM_DEFAULTPARAMS
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Copyright 2011, Texas Instruments Incorporated