Skip navigation.
Home
The QNX Community Portal

View topic - allocate DMA cache help

allocate DMA cache help

QNX Application portings.

allocate DMA cache help

Postby stjosue » Wed Mar 29, 2006 12:37 am

Hi, averyone

I´m porting device driver for vxworks to qnx 6.30.

i've found this function "cacheDmaMalloc" and in linux use this function "kmem_cache_create" for do it same, below are the description of this functions, can you tell me what is the function equivalent or how can the same functionality on qnx?

---------------------------------------------------------------------------------
NAME
cacheDmaMalloc( ) - allocate a cache-safe buffer for DMA devices and drivers

SYNOPSIS

void * cacheDmaMalloc
(
size_t bytes /* number of bytes to allocate */
)
DESCRIPTION
This routine returns a pointer to a section of memory that will not experience any cache coherency problems. Function pointers in the CACHE_FUNCS structure provide access to DMA support routines.


RETURNS
A pointer to the cache-safe buffer, or NULL.


---------------------------------------------------------------------------------

----------------------------------------------------------------------------------
Name
kmem_cache_create -- Create a cache.
Synopsis

kmem_cache_t * kmem_cache_create (const char * name, size_t size, size_t offset, unsigned long flags, void (*ctor) (void*, kmem_cache_t *, unsigned long), void (*dtor) (void*, kmem_cache_t *, unsigned long));

Arguments

name
A string which is used in /proc/slabinfo to identify this cache.

size
The size of objects to be created in this cache.

offset
The offset to use within the page.

flags
SLAB flags

ctor
A constructor for the objects.

dtor
A destructor for the objects.

Description
Returns a ptr to the cache on success, NULL on failure. Cannot be called within a int, but can be interrupted. The ctor is run when new pages are allocated by the cache and the dtor is run before the pages are handed back. The flags are

SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) to catch references to uninitialised memory.

SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check for buffer overruns.

SLAB_NO_REAP - Don't automatically reap this cache when we're under memory pressure.

SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware cacheline. This can be beneficial if you're counting cycles as closely as davem.

----------------------------------------------------------------------------------




thanks!!!

and i´m sorry if my english is bad, i'm learning yet.
stjosue
Active Member
 
Posts: 45
Joined: Mon Mar 06, 2006 6:33 pm

Re: allocate DMA cache help

Postby rgallen » Wed Mar 29, 2006 2:30 am

stjosue wrote:Hi, averyone

I´m porting device driver for vxworks to qnx 6.30.

i've found this function "cacheDmaMalloc" and in linux use this function "kmem_cache_create" for do it same, below are the description of this functions, can you tell me what is the function equivalent or how can the same functionality on qnx?

Here's how to do it with Posix (QNX is Posix compliant):

addr = mmap( 0,
XXXX,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

Where XXXX is the amount of physically contiguous uncached memory required.

Now, since QNX uses virtual memory, "addr" is a virtual address which is fine for accessing the memory from your program, but if this is to be used with DMA, then the device performing the DMA will need the physical address.

So (anticipating your next question), in order to translate "addr" to a physical address, you need to call, mem_offset() which is a proprietary QNX call (there is a Posix function for this - posix_mem_offset(), but it is currently unimplemented in QNX).

Here is how you use mem_offset() to translate "addr" into a physical address (so that you can program the DMA):

...
uint32_t offset;

mem_offset(addr, NOFD, 1, &offset, 0) ;

Following this call, offset contains the physical address of the memory "pointed to" by "addr".

You can now reference the memory area in your program via "addr" and program DMA operations using "offset".
rgallen
QNX Master
 
Posts: 671
Joined: Thu Jul 11, 2002 6:48 pm

RE: Re: allocate DMA cache help

Postby stjosue » Wed Mar 29, 2006 4:54 pm

thanks rgallen.

Thanks. I was read something of that but was not safe if that were the answer, thanks for confirmme!
stjosue
Active Member
 
Posts: 45
Joined: Mon Mar 06, 2006 6:33 pm

Postby bjchip » Tue May 02, 2006 3:54 am

For most primitive DMA controllers that is only half the addressing answer. If it is even that much.

Do we then take the phys address we get from mem_offset() and transform it somehow to get the page that the DMA controller demands to go with the offset? And do we not have to actually transform that offset to match the expectations of the DMA controller? I am muddling through this very process myself now, and I am not a happy camper.

respectfully
BJ
bjchip
Active Member
 
Posts: 46
Joined: Wed Nov 26, 2003 10:20 pm

Postby rgallen » Tue May 02, 2006 4:40 am

bjchip wrote:For most primitive DMA controllers that is only half the addressing answer. If it is even that much.

Do we then take the phys address we get from mem_offset() and transform it somehow to get the page that the DMA controller demands to go with the offset? And do we not have to actually transform that offset to match the expectations of the DMA controller?


Sounds like your refering to an old 8237. They aren't that difficult. Just make sure that when you mmap() you "or in" MAP_BELOW16M and MAP_NOX64K.

The following two macros will get you the page and offset.

DMA_PAGE(paddr) ((uint8_t)((paddr >> 16) & 0xff))
DMA_OFFSET(paddr) ((uint16_t)(paddr & 0xffff))

bjchip wrote: I am muddling through this very process myself now, and I am not a happy camper.


Well there's your problem. Coding while camping sucks (generator noise, flaky satellite internet connection, bears, squirrels, etc.).
rgallen
QNX Master
 
Posts: 671
Joined: Thu Jul 11, 2002 6:48 pm

Postby bjchip » Wed May 03, 2006 2:26 am

Thanks... I REALLY needed those Macros because I couldn't relate the prehistoric documentation on the web and lack of a "segment" concept in neutrino to the 8237 which is indeed the target of my efforts. Unable to be certain of the format of the phys_addr I have been indulging in archaeology while I am camping out here :-)

That should be all - Thanks again

BJ
bjchip
Active Member
 
Posts: 46
Joined: Wed Nov 26, 2003 10:20 pm

Postby rgallen » Wed May 03, 2006 4:22 am

bjchip wrote:Thanks... I REALLY needed those Macros because I couldn't relate the prehistoric documentation on the web and lack of a "segment" concept in neutrino to the 8237 which is indeed the target of my efforts. Unable to be certain of the format of the phys_addr I have been indulging in archaeology while I am camping out here :-)

That should be all - Thanks again

BJ


No problem; although, since I predate the "prehistoric" documentation, and I remember when segments were so integral to QNX that there was a "QNX C" language extension for referencing off of them, your making me feel old :-)
rgallen
QNX Master
 
Posts: 671
Joined: Thu Jul 11, 2002 6:48 pm


Return to Porting

Who is online

Users browsing this forum: No registered users and 0 guests

cron