DMA shared memory - qnx6.21 vs qnx6.3

“Igor Kovalenko” <kovalenko@comcast.net> wrote in message
news:djp4sm$8up$1@inn.qnx.com

Hell must be freezing over. Or aboyd is writing another 3c509 driver …

Or… White Sox winning the ‘World Series’ maybe :wink:

Yes, Martin, you don’t have to fake the class code with the replaced
server (or with this new -B option I guess).

“Joe Mammone” <> hw@qnx.com> > wrote in message
news:djoogt$m8$> 1@inn.qnx.com> …
With the SP2 pci server (pci-bios) there is a ‘-B’ option, This option
causes the pci server to enumerate PCI-PCI Bridge devices. You should be
able to get access to the BaseAddress of the board with the default class
code (68000 I think).

Regards,

Joe

Martin Gagnon wrote:
So, do I have to put back the Class code to the default one ? Because it
was not working with the default class code (it was
“bridge” i think), I change it to something else (I put “Pci I/O
accelerator” I think). With the default class code, I’m was not able to
get the BaseAdress of the board, with the other ones, it’s start
working but with the problem with the DMA safe memory for the Burst
mode in QNX6.3.

Martin


On 2005-10-26, Igor Kovalenko <> kovalenko@comcast.net> > wrote:

If I remember right, PLX9054 is a non-transparent PCI-PCI bridge. I have
posted this before, but to save you the trouble, here is is again.

Compile the pcitest.c and run it with vendor and device id of your board
as parameters. Compare the output to what pci -v says. If there is
anything odd in the output (look for bad IRQ numbers, 0 for memory
ranges, etc) then replace the pci-bios with pci-bios.igor and run
pcitest again. If it fixes the problem, try running your app again.

Basically, pci-bios shipped with QNX (all versions) has a bug (or should
I say ‘feature’) that prevents it from working properly with any
non-transparent PCI bridge. Since you said your app worked with 6.21,
your problem could be with something else, but I would be very surprized
if this issue did not have a hand in it.

– igor

“Martin Gagnon” <> martin@yanos.org> > wrote in message
news:> slrndlv0s0.4d8.martin@parrot.island.com> …

On 2005-10-25, John Garvey <> jgarvey@qnx.com> > wrote:

David Bacon wrote:

I’m still confused. Why are you specifying MAP_PHYS if
you don’t want to specify a physical address?

MAP_PHYS | MAP_ANON | MAP_NOX64K is used to get DMA-safe memory.
In particular, the combination of PHYS and ANON gives you
physically contiguous memory; it is only when PHYS used in
conjunction with PRIVATE or SHARED that it means a set physical
address.


That’s exactly my case here… thanks to give this nice explanation, I
could not do better because of my “relatively poor” english skills.

I know that the MAP_NOX64K is not always needed but in my case, it’s a
lot simplier because where I specify the physical addresse on the PLX
chip, I can only put a multiple of 64K (the 16 lower bits are not
accessible).

I’ve use this kind of thing with another PCI board, based on a DSP that
have the PCI interface chip inside. That one work on both, QNX6.21 and
QNX6.3 with mmap (never try mmap64).

Now for my board with the PLX9054, I have no idea. May be the physical
address I try to give is not valid for the PLX (if qnx 6.3
mmap/mem_offset give different result than 6.21). May be QNX6.3 act
differently with the memory management unit or with the PCI bus, I
don’t
know ?

Martin.

Ok, I’ve test with the patched version of pci-bios, it’s help to make me
able to map the pci baseaddress without changing the Class code do
something else than a bridge, but change nothing to my problem. I don’t
care if I have to change the Class code in the eeproom anyway, we
already have a custom eeprom for other configs. So, if this patched
version of pci-bios only help to be able to found the pci board with
the “pci_attach” function, that doesn’t help me. Thanks anyway for
answers.

I’m still trying to found a solution, meanwhile, I’m stuck with 6.21 for
that computer. (the others in the projects are on 6.3).

Martin


On 2005-10-22, Martin Gagnon <martin@yanos.org> wrote:

Hi ,

Situation:
We made a Pci board using the PLX9054 PCI chips with a TI DSP on the
local-bus (TMS320C6103B). We start to devellop on QNX6.21 and everything
works ok. We use 2 transfert modes with that board. DMA channels of the
PLX9054 chip (PC memory to DSP memory transfers) and Burst transfert
initiated by the DSP (DSP memory to PC memory transfers) using the DSP
Dma channel).

For the first way, the PLX chip is master on both bus (PCI bus and his
localbus where is the DSP). The other way, the DSP is master for the
localbus (where the plx is slave) and the plx is master on the PCI bus.
Anyway, I don’t want to go to much in details here… I just want to give
an idea of our setup.

For both type of transfert, we reserved a shared memory with mmap using
the MAP_PHYS | MAP_ANON | MAP_NOX64K flags. I use mem_offset to give the
physical Addresses to the PLX and the DSP for their respective
source/destination memory in the PC RAM. Each block is 1M and It’s works
no problem with QNX 6.21. I made a library to access that board, I use
it on 2 different program, everything works ok.

The Problem:
I take the same program on the same computer, I run it under QNX 6.3,
the DMA channel used on the PLX work, but the Burst transfers initiated
by the DSP does’nt, I get nothing on my shared memory. I also tried to
recompile everything under 6.3, does’nt help.

The Question:
What I miss ? Is there a new function I must use in QNX 6.3 to make it
work ? Should I set something somewhere on the PCI bus registers ?

Thanks for your help.

Martin Gagnon, b.Eng.

Igor Kovalenko wrote:

Hell must be freezing over. Or aboyd is writing another 3c509 driver …

I got tired of seeing you post and took pity on you :wink:


Cheers,
Adam

QNX Software Systems
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster

Hi again…

My pci board still does’nt work on QNX6.3… So I’ve decide to give-up
and use QNX6.21 instead for that project. But now I have another problem
related with 6.21… Configuration of 2 videocard…

Now I’m stuck with 6.21… with no real (documented) support for 2
videocard. As the oposite with 6.3 with the new ‘-c’ for io-graphics
that permit to use a configuration file. (with differents examples in
the help.)

So I have to choice… Continue to try to make work our Pci card on 6.3
or try to make work the 2 videocard on 6.21. For sure I’d like to move
completely to 6.3 but for now… I’m looking for a fast solution because
the deadline become closer.


My setup:
Normal PC: P4, ASUS P4P800X mother board, 2 ATI Radeon 7500 videocard
(one AGP, the other PCI).

With 6.21 and the 2 videocard… I’ve make work partially and I got
stange behavior. I got similar result if I load the second one myself
after photon is load and when I try to load it from the rc.local with an
automatic login etc… To do so, I use io-graphics with “-I1” + the
option “-o1280” to give a X offset of 1280. The command with parameters
look like that:

/usr/photon/bin/io-graphics -g1280x1024x32 -o1280, -dldevg-radeon.so

-I1 -d0x1002,0x5159

It’s the same line that is use for the first card… exept it’s “-I0”
instead of “-I1” and there’s no “-o1280”.

After I type that line once… nothing happens… if I do it again… it’s
seems to work… the second monitor goes on and display the right things…

Now, after I tried it more… the fist video work strangely… i.e. My
program have a PtRaw with some graphics drawing, with a lot of thing
around (buttons, text field etc…) The drawing does not appear on it. I
see the window normally with the buttons, text etc… but the rectangle
where is supposed to have the drawing don’t work… If I move another
window over it… the part of the window that was over the Pt_Raw stay
drawn… In the second display… (the last one for which I io-graphics
was load) the graphics is ok… The same thing with the Help program…
for what is inside the main pane.

What’s I did wrong ? Is it possible to make it work in 6.21 properly…
with drawing fonction etc… on both display ? I did’nt try yet in 6.3
with the new options but It’s useless if I cannot make my Pci card with
Burst transfers to work properly.

Thanks again for you help…

Martin Gagnon



Martin Gagnon wrote:

Hi ,

Situation:
We made a Pci board using the PLX9054 PCI chips with a TI DSP on the
local-bus (TMS320C6103B). We start to devellop on QNX6.21 and everything
works ok. We use 2 transfert modes with that board. DMA channels of the
PLX9054 chip (PC memory to DSP memory transfers) and Burst transfert
initiated by the DSP (DSP memory to PC memory transfers) using the DSP
Dma channel).

For the first way, the PLX chip is master on both bus (PCI bus and his
localbus where is the DSP). The other way, the DSP is master for the
localbus (where the plx is slave) and the plx is master on the PCI bus.
Anyway, I don’t want to go to much in details here… I just want to give
an idea of our setup.

For both type of transfert, we reserved a shared memory with mmap using
the MAP_PHYS | MAP_ANON | MAP_NOX64K flags. I use mem_offset to give the
physical Addresses to the PLX and the DSP for their respective
source/destination memory in the PC RAM. Each block is 1M and It’s works
no problem with QNX 6.21. I made a library to access that board, I use
it on 2 different program, everything works ok.

The Problem:
I take the same program on the same computer, I run it under QNX 6.3,
the DMA channel used on the PLX work, but the Burst transfers initiated
by the DSP does’nt, I get nothing on my shared memory. I also tried to
recompile everything under 6.3, does’nt help.

The Question:
What I miss ? Is there a new function I must use in QNX 6.3 to make it
work ? Should I set something somewhere on the PCI bus registers ?

Thanks for your help.

Martin Gagnon, b.Eng.

Oky… For the video in 6.3, I made it finally work… It was not as
simple, Nothing to do with 2 video card, the 2 radeon 7500 (AGP+PCI)
never show nothing with the configuration file, but a Nvidia GF2 MX400
AGP + a radeon 7500 PCI almost work; It’s crash the whole system after
resizing a window… So I decide to try with a RAdeon Dual-Head, one of
the supported dual-head in 6.3… and it’s work fisrt try. I’m happy with
that…

But now I must use QNX6.3 to make work the dualhead videocard, I have
to make work my Pci card on 6.3. Anyway, I prefer to use 6.3 for the
imprevement in hardware support and to don’t have many systems with
different versions.

I’ll paste here a part of my Init code, may be someone will see
something…

======================================================================

struct plx9054_info {
// PCI structure
struct pci_dev_info pinfo; /* Structure that contains all
information about the PCI board.*/

// Memory info
uint32_t dma_start_addr[NUM_DMAREGION]; / Shared memory region
for DMA and Dsp
Burst*/
uint32_t dsp_dma_size[NUM_DMAREGION];
off64_t dma_start_physaddr[NUM_DMAREGION]; /* Physical Address
of shared memory
used by the
hardware for DMA
or Burst
transfers */
uint32_t dsp_mapped_addr; / PCI Mapped address to access
DSP memory (by single
read/write /
uint32_t plx_mapped_addr; / PCI mapped address to access
PLX configuration
registers.
/

// Related with PCI Interrupt…
struct sigevent plx_int_event ; /* Event Signal for PCI
Interrupt (Only used
internally by the library) /
int irq_id; /
(Only used internally by the library) */
};

board_init(uint32_t dev_id, uint8_t rev_id,
struct plx9054_info *plxinfo)
{
void *hdl;
uint32_t temp, i;

if ((temp=pci_attach(0)) < 0) {
fprintf(stderr, “Failed to access PCI Server!:”
" [%s:%d]\n",FUNCTION, LINE);
exit(EXIT_FAILURE);
}

plxinfo->pinfo.VendorId = PLX_VENDOR_ID;

if (dev_id == NULL)
plxinfo->pinfo.DeviceId = PCI_DEVICE_ID;
else
plxinfo->pinfo.DeviceId = dev_id;

for (i=0; i<6; i++) {
if ((hdl = pci_attach_device(NULL, 0, i, &plxinfo->pinfo)) == NULL) {
fprintf(stderr,
“Can not attach PCI dsp board to PCI server!:”
" [%s:%d]\n",FUNCTION, LINE);
exit(EXIT_FAILURE);
}
if (plxinfo->pinfo.Revision == rev_id) {
fprintf(stderr, “rev_id: %d, plxinfo->pinfo.Revision: %d\n”,
rev_id, plxinfo->pinfo.Revision);
if ((pci_attach_device(hdl, PCI_INIT_IRQ |
PCI_INIT_BASE0 |
PCI_INIT_BASE2,
i, &plxinfo->pinfo)) == NULL) {
fprintf(stderr,
“Can not attach PCI dsp board to PCI server!:”
" [%s:%d]\n",FUNCTION, LINE);
exit(EXIT_FAILURE);
}
goto GOT_REV_ID ;
}
}
return -1 ;
GOT_REV_ID:

/* register to kernel DMA memory region (DMA-safe memory)/
for(i=0; i<NUM_DMAREGION; i++){
if (plxinfo->dsp_dma_size _== NULL){
fprintf(stderr, "Warning, the DMA region number %d is "
“not mapped you cannot use Dsp Master "
“DMA transfer for that region.\n”,i);

} else if (dma_register_region(plxinfo, i) < 0) {
dma_unregister_region(plxinfo, i);
fprintf(stderr, “Problem with DMA region registration:”
" [%s:%d]\n”,FUNCTION, LINE);
exit(EXIT_FAILURE);
}
}




/
initializes the DSP module /
board_memmap(plxinfo); /
use mmap_device_memory() to

  • map the Pci board Memory.
    /




    return 0;
    }


    /
  • this routine registers (pins) a certain amount of memory DMA and
  • Burst transfers
    /
    static int
    dma_register_region(struct plx9054_info plxinfo, uint32_t region_number)
    {
    size_t contig_len;

    /
    maps DMA region /
    /
    ********************************************************************
  • Here, I use “region_number 0” for DMA transfers controled by the PLX
  • chip and “region_number 1” for the DSP Burst. if you refer the my
  • Original post. DMA work, Bust doesn’t work.
    **********************************************************************/
    plxinfo->dma_start_addr[region_number] =
    (uint32_t *)mmap64(0, plxinfo->dsp_dma_size[region_number],
    PROT_READ | PROT_WRITE | PROT_NOCACHE,
    MAP_PHYS | MAP_ANON | MAP_NOX64K, NOFD, 0);

    if (plxinfo->dma_start_addr[region_number] == MAP_FAILED) {
    perror(“DMA registration procedure failed”);
    return -1;
    } else {
    if (mem_offset64((uint32_t *)plxinfo->dma_start_addr[region_number],
    NOFD, 4,
    &plxinfo->dma_start_physaddr[region_number],
    &contig_len) < 0) {
    perror(“DMA virtual start addr to phys. addr. failed”);
    return -1;
    }
    }

    return 0;
    }


    ======================================================================

    On 2005-11-22, Martin Gagnon <martin@yanos.org> wrote:_

_Hi again…

My pci board still does’nt work on QNX6.3… So I’ve decide to give-up
and use QNX6.21 instead for that project. But now I have another problem
related with 6.21… Configuration of 2 videocard…

Now I’m stuck with 6.21… with no real (documented) support for 2
videocard. As the oposite with 6.3 with the new ‘-c’ for io-graphics
that permit to use a configuration file. (with differents examples in
the help.)

So I have to choice… Continue to try to make work our Pci card on 6.3
or try to make work the 2 videocard on 6.21. For sure I’d like to move
completely to 6.3 but for now… I’m looking for a fast solution because
the deadline become closer.


My setup:
Normal PC: P4, ASUS P4P800X mother board, 2 ATI Radeon 7500 videocard
(one AGP, the other PCI).

With 6.21 and the 2 videocard… I’ve make work partially and I got
stange behavior. I got similar result if I load the second one myself
after photon is load and when I try to load it from the rc.local with an
automatic login etc… To do so, I use io-graphics with “-I1” + the
option “-o1280” to give a X offset of 1280. The command with parameters
look like that:
\

/usr/photon/bin/io-graphics -g1280x1024x32 -o1280, -dldevg-radeon.so

-I1 -d0x1002,0x5159

It’s the same line that is use for the first card… exept it’s “-I0”
instead of “-I1” and there’s no “-o1280”.

After I type that line once… nothing happens… if I do it again… it’s
seems to work… the second monitor goes on and display the right things…

Now, after I tried it more… the fist video work strangely… i.e. My
program have a PtRaw with some graphics drawing, with a lot of thing
around (buttons, text field etc…) The drawing does not appear on it. I
see the window normally with the buttons, text etc… but the rectangle
where is supposed to have the drawing don’t work… If I move another
window over it… the part of the window that was over the Pt_Raw stay
drawn… In the second display… (the last one for which I io-graphics
was load) the graphics is ok… The same thing with the Help program…
for what is inside the main pane.

What’s I did wrong ? Is it possible to make it work in 6.21 properly…
with drawing fonction etc… on both display ? I did’nt try yet in 6.3
with the new options but It’s useless if I cannot make my Pci card with
Burst transfers to work properly.

Thanks again for you help…

Martin Gagnon



Martin Gagnon wrote:
Hi ,

Situation:
We made a Pci board using the PLX9054 PCI chips with a TI DSP on the
local-bus (TMS320C6103B). We start to devellop on QNX6.21 and everything
works ok. We use 2 transfert modes with that board. DMA channels of the
PLX9054 chip (PC memory to DSP memory transfers) and Burst transfert
initiated by the DSP (DSP memory to PC memory transfers) using the DSP
Dma channel).

For the first way, the PLX chip is master on both bus (PCI bus and his
localbus where is the DSP). The other way, the DSP is master for the
localbus (where the plx is slave) and the plx is master on the PCI bus.
Anyway, I don’t want to go to much in details here… I just want to give
an idea of our setup.

For both type of transfert, we reserved a shared memory with mmap using
the MAP_PHYS | MAP_ANON | MAP_NOX64K flags. I use mem_offset to give the
physical Addresses to the PLX and the DSP for their respective
source/destination memory in the PC RAM. Each block is 1M and It’s works
no problem with QNX 6.21. I made a library to access that board, I use
it on 2 different program, everything works ok.

The Problem:
I take the same program on the same computer, I run it under QNX 6.3,
the DMA channel used on the PLX work, but the Burst transfers initiated
by the DSP does’nt, I get nothing on my shared memory. I also tried to
recompile everything under 6.3, does’nt help.

The Question:
What I miss ? Is there a new function I must use in QNX 6.3 to make it
work ? Should I set something somewhere on the PCI bus registers ?

Thanks for your help.

Martin Gagnon, b.Eng._

Just wondering if you have solved your problem yet?

I don’t know if is just a typo, but in your posted code you specify a
fixed size of 4 to the mem_offset call instead of using the
plxinfo->dsp_dma_size[region_number] like the mmap call. Now if
this isn’t a typo, and your DMA size for ‘Burst’ is larger than 4
than this could potentially explain your problem.

Regards Ross

On 2005-12-21, roscoh <r.hennessy@acfr.usyd.edu-dot-au.no-spam.invalid> wrote:

Just wondering if you have solved your problem yet?

Yes, it’s solved now, I was problem on an hardware register on the PLX
that was not set right. I’m was lucky that work in QNX 6.21, it was
working because of a funny behavior and that why I’m was looking for the
problem at the wrong place. It’s was related with boundary, a mistake on
a PLX register that fixe the boundary it can accept was set to 1MB
instead of 64K, the mmap in QNX6.21 was always give me 1MB boundary
for some reason (when I specified MAP_NOX64K flag). In QNX6.3, it’s work
like it should, it garanty 64K boundary, not more. So when I discover
the misconfigured register, I change it and start to work in QNX6.3 as
well as 6.21.

I don’t know if is just a typo, but in your posted code you specify a
fixed size of 4 to the mem_offset call instead of using the
plxinfo->dsp_dma_size[region_number] like the mmap call. Now if this
isn’t a typo, and your DMA size for ‘Burst’ is larger than 4 than this
could potentially explain your problem.

Regards Ross

I don’t know why I put a fixed size of 4, it’s really what is on my
code and it’s work. It’s probably a mistake but I don’t think it change
something because the memory is contigous and mem_offset is used to get
the Physical address of the beginning of the mapped memory, so don’t
matter the size, it give me the same value. I will correct it, it’s not
look very clean…

Thanks


Martin Gagnon
NDT Technologies inc.