PCI mapping

I’m using a PCI-Express board which has a PCIExpress-to-PCI bridge on it. A DSP is connected to the PCI side of the bridge.

I want to access the two address ranges of the DSP (Bar 0 and Bar 1). Bar 1: no problem, Bar 0 failed (read always 0xffffffff) if using QNX 6.3.2.
If using QNX 6.1A: no problem.

Any ideas?

Can you run a test on DSP side as well? I mean just to confirm that DSP can actually see the data written through BAR1. My guess is BAR0 doesn’t work either, but you’re lucky to use some unused system memory. Simplest what I would do - make your test app even smaller and do not use pci_attach_device but try using (hard coded for start) phys addresses reported by pci utility. As you may see, pci reports base addr cb800000h and cb000000h. I think, on a PC platform with pci-bios running, pci_attach_device should not change base addresses. However, you got d4800000h and d4000000h, which is suspicious for me. I guess there might be a bug somewhere when dealing with composited 64-bit wide BARs. If I’m right, you may read config space directly (pci_read_config32) to get correct base addresses (instead of hardcoded or passed from pci utility) till QNX address this problem with pci_attach_device.

Sorry, I looked at your files again, and see that your device uses 32-bit address space (no composite 64-bit BARs). Still, I have no idea why pci utility reports different base addresses than pci_attach_device, but I think that’s the problem. I’d rather trust the pci utility.

Eduard.

Thanks for your replies.

You found differences in BAR addresses, but that’s a fault of me. I’ve played with PCI boards and restarted pci-bios while creating the attachment. Sorry.
Reading/writing in BAR1 gives no problems. I’ve checked with a JTAG ICE.
BAR0 gives problems.

I found something strange. Our PCI-Express board (Vendor ID: 104c) uses a PCI bridge of PLX (Vendor ID 10b5).
It looks like the Prefetchable Memory Base/Limit values of the bridge are wrong. These registers contain the upper 12 bits of the prefetchable address range.
Memory Base should contain the lowest address, Memory Limit the highest address of the range.

in QNX630:
bridge prefetch. range:
base: 0xd480
limit: 0xd4b0

our board (bar 0 is prefetchable):
bar0: d4800000

in QNX632:
base: 0xf7e0
limit: 0xf7b0 <-??

our board (bar 0 is prefetchable):
bar0: cb800000

The attachment includes the output of pci -v in QNX630 and QNX632.

I don’t know your real problem here, however I had problems writhing a driver in QNX where the card also used a PLX chip. Reason for this so it seemed is that the pci server has trouble finding the right address when a PLX chip is used, have u tried to find the boards manually? I.e by using the pci specs and pci_* and friend functions?

Hi mate,

Check these url’s maybre they are of any help.

community.qnx.com/sf/discussion/ … s.topc1519
community.qnx.com/sf/discussion/ … e.topc1646

Regards,
Freddy

I’ve wrote my ‘own’ attach device routine. Exept I’m also having difficulties trying to read from and write to configuration space. Well reading functions just fine but when I write words to config space and then read the same address, I get a different value. This is the information from config space: (highlighted BAR)

PCI Configuration Space:
0x905410B5 | 0x00
0x02900017 | 0x04
0x06800000 | 0x08
0x00002008 | 0x0C
0xF7800000 | 0x10
0x0000B801 | 0x14
0x0000B401 | 0x18
0xF7000000 | 0x1C
0x00000000 | 0x20
0x00000000 | 0x24

0x00000000 | 0x28
0x313310B5 | 0x2C
0x00000000 | 0x30
0x00000040 | 0x34
0x00000000 | 0x38
0x0000010B | 0x3C
PCI Configuration Space: device afhankelijke registers :
0x00000003 00804C06 00000000 00014801 | 0x40
0x00000000 00000000 00000000 00000000 | 0x50
0x00000000 00000000 00000000 00000000 | 0x60
0x00000000 00000000 00000000 00000000 | 0x70
0x00000000 00000000 00000000 00000000 | 0x80
0x00000000 00000000 00000000 00000000 | 0x90
0x00000000 00000000 00000000 00000000 | 0xA0
0x00000000 00000000 00000000 00000000 | 0xB0
0x00000000 00000000 00000000 00000000 | 0xC0
0x00000000 00000000 00000000 00000000 | 0xD0
0x00000000 00000000 00000000 00000000 | 0xE0
0x00000000 00000000 00000000 00000000 | 0xF0

and this is how I got it…

//State
inf.DeviceId = PLX_CARD_DEVICE_ID;
inf.VendorId = PLX_CARD_VENDOR_ID;

//Attach a driver to a PCI device
device_handle = pci_attach_device(NULL,PCI_SEARCH_VENDEV | PCI_INIT_ALL | PCI_INIT_IRQ,0,&inf);

//Read PCI configuration space
printf(“PCI Configuration Space:\n”);
for(i=0;i<16;i++)
{
pci_read_config(device_handle,i4,1,4,&waarde);
printf(" 0x%08X | 0x%02X\n",waarde,i
4);
}
printf(“PCI Configuration Space: device dependantregisters :\n”);
for(i=i;i<64;i=i+4)
{
i=i+3;
pci_read_config(device_handle,i–*4,1,4,&waarde);
printf(" 0x%08X",waarde);
pci_read_config(device_handle,i–4,1,4,&waarde);
printf(" %08X",waarde);
pci_read_config(device_handle,i–4,1,4,&waarde);
printf(" %08X",waarde);
pci_read_config(device_handle,i
4,1,4,&waarde);
printf(" %08X | 0x%02X\n",waarde,i
4);
}

How can I write data to config space without having to worry if everything is written wrong or incomplete? (currently using pci_write_config but doesn’t seem to work)

The posts that Freddy posted contain the requirerd information to obtain the data you are looking for… Otherwise go and check the PCI specs.

I/m sorry, maybe I wasn’t very specific. I’m trying to write to de device:

BAR: 0
BaseAddressOffset : 10
IRQOffset : 3C
Base addr value : 0xF7800000
Base addr size : 256
: MEMORY
Cpu base addr value : 0xF7800000

BAR: 1
BaseAddressOffset : 10
IRQOffset : 3C
Base addr value : 0x0000B801
Base addr size : 256
: I/O
Cpu base addr value : 0x0000B800

BAR: 2
BaseAddressOffset : 10
IRQOffset : 3C
Base addr value : 0x0000B401
Base addr size : 256
: I/O
Cpu base addr value : 0x0000B400

BAR: 3
BaseAddressOffset : 10
IRQOffset : 3C
Base addr value : 0xF7000000
Base addr size : 65536
: MEMORY
Cpu base addr value : 0xF7000000
IRQ: 0x0000000B

//inf.CpuBaseAddress[0] == 0xF7800000
                memory_handle = mmap_device_io(256,inf.CpuBaseAddress[2]);
printf("\nMemorymap handle naar BAR2 I/O: 0x%08X\n",memory_handle);

out32(memory_handle,0xFFFFFFFF);
printf("value = 0x%08X",in32(memory_handle));

these last two statements arn’t executed so I used ThreadCtl(_NTO_TCTL_IO, 0) ;
now it works fine. However I don’t know if I’m writing to system RAM or device memory???

Hi Hugo,

Please use PCI_IS_MEM of PCI_IS_IO macro’s to determine this.

And Gila and I can answer your questions in Dutch :smiley:

Solution for topic starter:
community.qnx.com/sf/go/projects … p.topc2464