DMA-able memory for a PCI-card

Hello everybody.

Which way is the best to allocate DMA-able memory for a PCI-card?

Thanks.

Tobias

Tobias <t.nothdurft@tu-bs.de> wrote:

Hello everybody.

Which way is the best to allocate DMA-able memory for a PCI-card?

Check the docs for mmap(), one of the examples shows how to do
this.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Is this the right way?

  • create a shared-memory-object with shm_open()
  • change the object-size with ftruncate() or shm_ctl()
  • map the SHM with mmap()
  • translate the adress with mem_offset

Could i now transfer the translated address to the PCI-card, so that the
card can read out the mapped memory?

Tobias

“David Gibbs” <dagibbs@qnx.com> schrieb im Newsbeitrag
news:cvnp1a$2qb$3@inn.qnx.com

Tobias <> t.nothdurft@tu-bs.de> > wrote:
Hello everybody.

Which way is the best to allocate DMA-able memory for a PCI-card?

Check the docs for mmap(), one of the examples shows how to do
this.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Tobias <t.nothdurft@tu-bs.de> wrote:

Is this the right way?

  • create a shared-memory-object with shm_open()
  • change the object-size with ftruncate() or shm_ctl()
  • map the SHM with mmap()
  • translate the adress with mem_offset

That will not work with ftruncate(), as it does not allocate physically
contiguous RAM.

With the right shm_ctl() flags, it could work.

Unless you want this area shared with other proceses – in which case
you need to go through the shm_open() and shm_ctl() dance, the examples
of mmap() use (just above the Returns section) say:

To allocate a DMA buffer for a bus-mastering PCI network card:
/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

And, then as you say, mem_offset() to get the physical address.

If you are on non-x86, you will also have to worry about PCI - CPU
address translations. Check the docs for pci_attach_device(),
particularly the CpuBmstrTranslation field.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

THX for answering so fast. I’m only working on x86.

Another problem is, that the to the card transferred address has to be
16-byte-aligned, and i’ve found no clean solution (like using memalign() )
yet. :neutral_face:

Tobias

“David Gibbs” <dagibbs@qnx.com> schrieb im Newsbeitrag
news:d2uloj$204$2@inn.qnx.com

Tobias <> t.nothdurft@tu-bs.de> > wrote:
Is this the right way?

  • create a shared-memory-object with shm_open()
  • change the object-size with ftruncate() or shm_ctl()
  • map the SHM with mmap()
  • translate the adress with mem_offset

That will not work with ftruncate(), as it does not allocate physically
contiguous RAM.

With the right shm_ctl() flags, it could work.

Unless you want this area shared with other proceses – in which case
you need to go through the shm_open() and shm_ctl() dance, the examples
of mmap() use (just above the Returns section) say:

To allocate a DMA buffer for a bus-mastering PCI network card:
/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

And, then as you say, mem_offset() to get the physical address.

If you are on non-x86, you will also have to worry about PCI - CPU
address translations. Check the docs for pci_attach_device(),
particularly the CpuBmstrTranslation field.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Tobias <t.nothdurft@tu-bs.de> wrote:

THX for answering so fast. I’m only working on x86.

Another problem is, that the to the card transferred address has to be
16-byte-aligned, and i’ve found no clean solution (like using memalign() )
yet. > :neutral_face:

The memory you get will be 4K page aligned. As long as you keep your
offset 16-byte-aligned, I think that 4K-page aligned should give you
16-byte-aligned, too. :wink:

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Ok, that’s nice! :astonished:)

Many Thanks.

“David Gibbs” <dagibbs@qnx.com> schrieb im Newsbeitrag
news:d31173$o5c$1@inn.qnx.com

Tobias <> t.nothdurft@tu-bs.de> > wrote:
THX for answering so fast. I’m only working on x86.

Another problem is, that the to the card transferred address has to be
16-byte-aligned, and i’ve found no clean solution (like using
memalign() )
yet. > :neutral_face:

The memory you get will be 4K page aligned. As long as you keep your
offset 16-byte-aligned, I think that 4K-page aligned should give you
16-byte-aligned, too. > :wink:

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com