Ошибка чтения 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
Любая помощь или намек от кого-либо будут оценены.