Ошибка чтения PCI на QNX для PowerPC

Моя команда разрабатывает плату MPC8313 PowerPC Dev Board, и мы пытаемся написать сетевой драйвер.

Сетевая карта - это карта PCIe, подключенная к мосту PCIe-PCI (PI7C9X111SL).

Утилита pci обнаруживает карту и может читать и записывать конфигурационное пространство PCI.

Проблема в том, что мы пытаемся читать из памяти PCI. Любое чтение, выполненное на карте, возвращает все единицы (0xffffffff). Читает и записывает в конфигурационное пространство работу без заминок.

Мой вопрос: есть ли что-то особенное в архитектуре PowerPC, о котором я должен знать, и это могло бы вызвать это?

Мы используем pci-mpc8313 в качестве сервера pci.

Мы попробовали эту настройку в системе x86, работающей на той же версии QNX, и она, кажется, работает, так что это, вероятно, не проблема с оборудованием.

Вот пример кода того, чего я пытаюсь достичь:

#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);
    delay(20);
    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);
    delay(20);

    // 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 (
            NULL,
            // Commented because the first 128kB is what we're interested in. The rest is some flash memory
            //info.BaseAddressSize[0], // info.BaseAddressSize[0] = 0x100000
            0x20000,
            PROT_READ | PROT_WRITE | PROT_NOCACHE,
            MAP_SHARED | MAP_PHYS,
            PCI_MEM_ADDR(info.CpuBaseAddress[0])
        )) == 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;

}

Система с прямым порядком байтов, но адрес, который я пытаюсь прочитать, - это адрес 0x0 на чипе, поэтому проблем быть не должно. Кроме того, порядок байтов info.CpuBaseAddress[0] уже включен в официальном драйвере QNX для pci (проверено дважды, чтобы быть уверенным).

Вот паста системного журнала: https://pastebin.com/bpAp77Kt

А вот паста утилиты pci во время выполнения кода: https://pastebin.com/mzbcTzu7

Любая помощь или намек от кого-либо будут оценены.

0 ответов

Другие вопросы по тегам