PCI Read Error on QNX for PowerPC


My team is developping on an MPC8313 PowerPC Dev Board and we're trying to write a network driver.

The network card is a PCIe card connected to a PCIe-to-PCI bridge (PI7C9X111SL).

The pci utility detects the card and can read and write the PCI config space.

The problem is when we're trying to read from PCI memory. Any read done on the card returns all ones (0xffffffff). Reads and writes to the configuration space work without a hitch.

My question is: Is there something special about the PowerPC architecture that I should know about and that would cause that?

We're using pci-mpc8313 as the pci server.

We've tried this setup on an x86 system running the same version of QNX and it seems to be working, so this probably isn't a hardware issue.

Here's a code example of what I'm trying to achieve:

#include <stdlib.h>
#include <stdio.h>

#include <sys/mman.h>
#include <hw/pci.h>
#include <gulliver.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/neutrino.h>

#include <ppc/inout.h>

int main(int argc, char *argv[]) {
    struct pci_dev_info info;
    unsigned int bus, dev_func;
    int pci_hdl;

    ThreadCtl (_NTO_TCTL_IO, 0); // Maybe not needed, doesn't work either way
    eieio(); // Maybe not needed, doesn't work either way

    if ((pci_hdl = pci_attach (0)) < 0) {
        return -1;

    if (pci_find_device (0x1533, 0x8086, 0, &bus, &dev_func) != PCI_SUCCESS) {
        return -1;

    memset( &info, 0, sizeof( info ) );
     // Hardcoded for now.
    info.VendorId = 0x8086;
    info.DeviceId = 0x1533;
    if (pci_attach_device(NULL, PCI_INIT_ALL | PCI_INIT_IRQ | PCI_MASTER_ENABLE | PCI_INIT_ROM, 0, &info) == NULL) {
        printf( "Error: %s\n", strerror(errno) );
        return -1;

    // See if disabling and enabling memory access and bus master does anything
    uint16_t pci_cmd;
    pci_read_config16(bus, dev_func, 0x4, 1, &pci_cmd);
    pci_cmd &= ~(0x1 | 0x2 | 0x4);
    pci_write_config16(bus, dev_func, 0x4, 1, &pci_cmd);
    pci_read_config16(bus, dev_func, 0x4, 1, &pci_cmd);
    pci_cmd |= (0x1 | 0x2 | 0x4);
    pci_write_config16(bus, dev_func, 0x4, 1, &pci_cmd);

    // Let's check that, even though it is probably already correct
    if (!PCI_IS_MEM(info.CpuBaseAddress[0])){
        return -1;

    volatile uint32_t* pci_mem;
    if ((pci_mem = mmap_device_memory (
            // Commented because the first 128kB is what we're interested in. The rest is some flash memory
            //info.BaseAddressSize[0], // info.BaseAddressSize[0] = 0x100000
            MAP_SHARED | MAP_PHYS,
        )) == MAP_FAILED) {
        return -1;

    delay(200); // Let's wait just in case...

    printf("Didn't die yet\n");
    printf("CTRL: %x\n", pci_mem[0]); // reads 0xffffffff
    printf("CTRL (shadow): %x\n", pci_mem[1]); // reads 0xffffffff
    printf("Status: %x\n", pci_mem[2]); // reads 0xffffffff
    printf("CTRL_EXT: %x\n", pci_mem[3]); // reads 0xffffffff

    return 0;


The system is big endian, but the address I'm trying to read is address 0x0 on the chip, so there shouldn't be any problem. Besides, info.CpuBaseAddress[0]'s endianness is already switched up in QNX's official pci driver (checked twice to be sure).

Here's a paste of the system log: https://pastebin.com/bpAp77Kt

And here's a paste of the pci utility while running the code: https://pastebin.com/mzbcTzu7

Any help or hint from anyone would be appreciated.


0 Answers

Nobody has answered this question yet.

User contributions licensed under CC BY-SA 3.0