DMA of user buffer

I am porting a driver to RTP and need to DMA user buffers.

  • Is it possible to get a physical address from a malloc’d buffer under
    RTP?
  • How can I lock it down to make it DMA safe?

This can be done at the application level if it’s possible rather than in
the resource manager. The resource manager then gets the physical
address of the buffer to DMA.

I really must use malloc if possible… mmap will break cross-platform
compatibility for our applications.

Thanks in advance.

Dan.

Yes you can do all of this. You will want to use mmap() to allocate
the DMA safe buffers. You can get details of this in the help to mmap().
Once you have it mmap’d you can use mem_offset to get the physical address.

chris


Daniel S. Chivers <dchivers@systran.com> wrote:

I am porting a driver to RTP and need to DMA user buffers.

  • Is it possible to get a physical address from a malloc’d buffer under
    RTP?
  • How can I lock it down to make it DMA safe?

This can be done at the application level if it’s possible rather than in
the resource manager. The resource manager then gets the physical
address of the buffer to DMA.

I really must use malloc if possible… mmap will break cross-platform
compatibility for our applications.

Thanks in advance.

Dan.

cdm@qnx.com > “The faster I go, the behinder I get.”

Chris McKillop – Lewis Carroll –
Software Engineer, QSSL
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

OK, this makes sense.

But is there a way to build a scatter-gather list of a currently existing
buffer?

Dan.


In article <9tf7ns$np9$2@nntp.qnx.com>, “Chris McKillop” <cdm@qnx.com>
wrote:


Yes you can do all of this. You will want to use mmap() to allocate the
DMA safe buffers. You can get details of this in the help to mmap().
Once you have it mmap’d you can use mem_offset to get the physical
address.
chris



Daniel S. Chivers <> dchivers@systran.com> > wrote:
I am porting a driver to RTP and need to DMA user buffers. * Is it
possible to get a physical address from a malloc’d buffer under RTP?

  • How can I lock it down to make it DMA safe? This can be done at the
    application level if it’s possible rather than in the resource manager.
    The resource manager then gets the physical address of the buffer to
    DMA.
    I really must use malloc if possible… mmap will break cross-platform
    compatibility for our applications.
    Thanks in advance.
    Dan.

Daniel S. Chivers <dchivers@systran.com> wrote:

OK, this makes sense.

But is there a way to build a scatter-gather list of a currently existing
buffer?

'spozedly you can use mphys() on each 4k page of your malloc’d buffer to
get the physical equivalent. A little bird told me this one day, so it
may or may not be “official” and YMMV. :slight_smile:

-RK

In article <9tf7ns$np9$> 2@nntp.qnx.com> >, “Chris McKillop” <> cdm@qnx.com
wrote:



Yes you can do all of this. You will want to use mmap() to allocate the
DMA safe buffers. You can get details of this in the help to mmap().
Once you have it mmap’d you can use mem_offset to get the physical
address.
chris



Daniel S. Chivers <> dchivers@systran.com> > wrote:
I am porting a driver to RTP and need to DMA user buffers. * Is it
possible to get a physical address from a malloc’d buffer under RTP?

  • How can I lock it down to make it DMA safe? This can be done at the
    application level if it’s possible rather than in the resource manager.
    The resource manager then gets the physical address of the buffer to
    DMA.
    I really must use malloc if possible… mmap will break cross-platform
    compatibility for our applications.
    Thanks in advance.
    Dan.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at www.parse.com
Email my initials at parse dot com.

In article <9ttrf8$mf9$1@inn.qnx.com>, “Unknown” <nospam93@parse.com>
wrote:

But is there a way to build a scatter-gather list of a currently
existing buffer?
'spozedly you can use mphys() on each 4k page of your malloc’d buffer to
get the physical equivalent. A little bird told me this one day, so it
may or may not be “official” and YMMV. > :slight_smile: > -RK

Yes, this is the idea of scatter-gather when the system uses a page size
of 4k. However, there is no way to tell how much of the buffer is on the
first page. It is not likely that the first 4k of the buffer is on one
page (ie. the buffer is probably not page aligned).
Also, the buffer must be locked down per page so it isn’t swapped out.

Without “official” scatter-gather list support in the OS… there isn’t
really a way to accomplish this.

Dan.

Daniel S. Chivers <dchivers@systran.com> wrote:

In article <9ttrf8$mf9$> 1@inn.qnx.com> >, “Unknown” <> nospam93@parse.com
wrote:

But is there a way to build a scatter-gather list of a currently
existing buffer?
'spozedly you can use mphys() on each 4k page of your malloc’d buffer to
get the physical equivalent. A little bird told me this one day, so it
may or may not be “official” and YMMV. > :slight_smile: > -RK

Yes, this is the idea of scatter-gather when the system uses a page size
of 4k. However, there is no way to tell how much of the buffer is on the
first page. It is not likely that the first 4k of the buffer is on one
page (ie. the buffer is probably not page aligned).
Also, the buffer must be locked down per page so it isn’t swapped out.

Without “official” scatter-gather list support in the OS… there isn’t
really a way to accomplish this.

Huh? Why does it matter where the buffer begins? The offset from the
beginning of the 4k page is the same in physical as it is in virtual.
For example, if I have a 2k data area that straddles two virtual pages, say
from 0x77770C00 to 0x77771400, you do an mphys() on the 0x77770000 page
to get the starting physical address of the first page, and then an mphys()
on the 0x77771000 page to get the starting physical address of the second
page. Let’s say this gives you 0x12340000 and 0x43210000. Then, you’d
feed your DMA controller 0x12340C00 through 0x12340FFF as the first
scatter/gather list, and 0x43210000 through 0x432103FF as the second
scatter/gather list element…

Locking down is accomplished “by default” now because paging is turn off :slight_smile:

Or did I misunderstand your point?

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at www.parse.com
Email my initials at parse dot com.

“Daniel S. Chivers” <dchivers@systran.com> wrote in message
news:9u097t$aif$1@inn.qnx.com

In article <9ttrf8$mf9$> 1@inn.qnx.com> >, “Unknown” <> nospam93@parse.com
wrote:

But is there a way to build a scatter-gather list of a currently
existing buffer?
'spozedly you can use mphys() on each 4k page of your malloc’d buffer to
get the physical equivalent. A little bird told me this one day, so it
may or may not be “official” and YMMV. > :slight_smile: > -RK

Yes, this is the idea of scatter-gather when the system uses a page size
of 4k. However, there is no way to tell how much of the buffer is on the
first page. It is not likely that the first 4k of the buffer is on one
page (ie. the buffer is probably not page aligned).
Also, the buffer must be locked down per page so it isn’t swapped out.

Without “official” scatter-gather list support in the OS…

I object to the “…” :wink: There is an official and portable (POSIX) way to
do this
and it’s via mmap.

Doing it via malloc is non standard and non portable and is IMHO a
hack.

there isn’t
really a way to accomplish this.

Dan.

Huh? Why does it matter where the buffer begins? The offset from the
beginning of the 4k page is the same in physical as it is in virtual.

I didn’t think to assume this, but I’m sure this is the case.

Locking down is accomplished “by default” now because paging is turn
off

You mean swapping (virtual memory) (paging is the translation from virtual to
physical memory addresses by the CPU). I can see that turning off
swapping will lock things down assuming the OS’s memory manager never
moves memory around.

But yes, your method works as long as the memory manager isn’t swapping
or relocating memory.

-Dan.

Daniel S. Chivers <dchivers@systran.com> wrote:

Huh? Why does it matter where the buffer begins? The offset from the
beginning of the 4k page is the same in physical as it is in virtual.

I didn’t think to assume this, but I’m sure this is the case.

:slight_smile:
It makes things a lot simpler (and doable!)

Locking down is accomplished “by default” now because paging is turn
off

You mean swapping (virtual memory) (paging is the translation from virtual to

Depends which systems you were weened on as a kid, I guess.
VAX/VMS had “paging to disk” :slight_smile: But yes, we are talking about VM.

physical memory addresses by the CPU). I can see that turning off
swapping will lock things down assuming the OS’s memory manager never
moves memory around.

But yes, your method works as long as the memory manager isn’t swapping
or relocating memory.

-Dan.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at www.parse.com
Email my initials at parse dot com.

Daniel S. Chivers <dchivers@systran.com> wrote:
: I am porting a driver to RTP and need to DMA user buffers.
: I really must use malloc if possible… mmap will break cross-platform
: compatibility for our applications.

I think the thing that people have been trying to impress on you is
DMA-safe memory could (depending on the device involved) have a number
of restrictions upon it, and hence should be allocated via mmap(),
which lets you pass in such flags as NOX64K and BELOW16M and MAP_PHYS.
Normal malloc() memory itself comes from mmap(MAP_ANON, NO_FD) with no
such flags specified; in fact it will by preference come from potentially
unsafe DMA memory (so as to leave the more stringent areas available
for those that explicitly request it). This may or may not be an
issue depending on the device/controller involved, but if possible
you should play it safe and allocate your buffers with mmap().
As mentioned, use mem_offset() to get the physical address (if you
have specified MAP_PHYS it will be a single contiguous, region otherwise
ou’ll need to handle discontiguous ranges); the other routine you’re
after is mlock()/mlockall(), but this is the default for memory under QNX.