OK, today my troubles are with the mmap_device_memory() call.
Here’s the quick background again. Currently this code is working just fine running under QNX 6.1. I’m in the process of upgrading everything to QNX 6.3. The code in question below is trying to map a stepper card but failing. I’ve cut out parts below where it fails because those aren’t important since the code doesn’t reach that point (BTW, this code was written several years ago by someone who is no longer here).
int StepperCardMemory::Open(int CardNumber)
{
int status;
assert(CardNumber >= 1);
// close any previous connection to stepper
Close();
m_CardNumber = CardNumber;
// Connect to the PCI server, refer to [2] for details
m_PciHandle = pci_attach( 0 );
if (m_PciHandle == -1)
{
ReportError(“pci_attach”, errno);
return 0;
}
// determine if pci present, refer to [2] for details
unsigned int lastbus, version, hardware;
status = pci_present(&lastbus, &version, &hardware);
if (status != PCI_SUCCESS)
{
ReportError(“pci_present”, status);
return 0;
}
// find the first card of base class 0x0b, subclass 0x40, interface 0x00
// refer to [2] for details of this call
// refer to [1] for details of pci class numbers
// refer to [3] for details of class code provided by the 2040
// show_pci can be used to display details of all pci cards present
unsigned bus, dev_func;
status = pci_find_class(0xb4000, m_CardNumber-1, &bus, &dev_func);
if (status != PCI_SUCCESS)
{
ReportError(“pci_find_class”, status);
return 0;
}
// read the physical address of the HPI CSR data area
// refer to [2] for details of pci_read_config32
// refer to [3] for details about the data area contents
status = pci_read_config32(bus, dev_func, 0x10, 1, &m_HPI_CSR_BaseAddress);
if (status != PCI_SUCCESS)
{
ReportError(“pci_read_config32”, status);
return 0;
}
// read the physical address of the HPI control space
// refer to [2] for details of pci_read_config32
// refer to [3] for details about the data area contents
status = pci_read_config32(bus, dev_func, 0x14, 1, &m_ControlSpaceBaseAddress);
if (status != PCI_SUCCESS)
{
ReportError(“pci_read_config32”, status);
return 0;
}
// map the HPI CSR data space into this tasks logical memory space
// refer to [2] for details of mmap_device_memory
/* Original 6.1 mmap call here */
// m_pHPI_CSR = (unsigned char*)mmap_device_memory((void*)0x10000000, 4096, PROT_NOCACHE | PROT_READ | PROT_WRITE, MAP_TYPE, m_HPI_CSR_BaseAddress);
/* Updated 6.3 call here */
m_pHPI_CSR = (unsigned char*)mmap_device_memory(0, 4096, PROT_NOCACHE | PROT_READ | PROT_WRITE, 0, HPI_CSR_BaseAddress);
if (m_pHPI_CSR == MAP_FAILED)
{
m_pHPI_CSR = 0;
ReportError("mmap_device_memory", errno);
cout << "StepperCardMemory::Open() - mmap_device_memory failed with MAP_FAILED and errno " << errno << " for address " << m_HPI_CSR_BaseAddress << endl;
return 0;
}
SNIP LOTS OF CODE HERE
}
So what happens is that the call to mmap_device_memory fails with (22) EINVAL at address D7028000.
You can see the original 6.1 call with the address specified and flags set to MAP_TYPE. I took a look at the mmap_device_memory call and it should only generate EINVAL is the ‘flag’ arguments are incorrect. Since MAP_TYPE isn’t supported under 6.3 I decided to just replace it and the address with 0 and see what happened. But it still generates the EINVAL error even though I am clearly using valid flag arguments. I’m not sure why this can be unless the D7028000 address is somehow out of range for the PCI bus (I’m not a hardware expert so it could well be which is why I included it above).
I also tried several varriations on the above code such as:
m_pHPI_CSR = (unsigned char*)mmap_device_memory((void*)0x10000000, 4096, PROT_NOCACHE | PROT_READ | PROT_WRITE, MAP_FIXED, m_HPI_CSR_BaseAddress);
m_pHPI_CSR = (unsigned char*)mmap_device_memory((void*)0x10000000, 4096, PROT_NOCACHE | PROT_READ | PROT_WRITE, 0, m_HPI_CSR_BaseAddress);
m_pHPI_CSR = (unsigned char*)mmap_device_memory(0, 4096, PROT_NOCACHE | PROT_READ | PROT_WRITE, MAP_FIXED, m_HPI_CSR_BaseAddress);
but all give me the same EINVAL error.
It’s been a while since I have done anything with mmap in general (back in QNX 4.25 days) and never with mmap_device_memory so I’m really lost as to what to attempt next.
TIA,
Tim
P.S. Here are the original references from the file header referred to by [] in the comments in the routine. They mean little to me but might help someone trying to diagnose the problem.
// References:
// [1] PCI Local Bus Specification Revision 2.1
// hard copy
// - describes general PCI details.
// - Most useful part was Chapter 6 containing details of the PCI
// configuration space.
// [2] qnx library functions pci_xxxxx
// support.qnx.com/support/docs/qnx … xxxxx.html
// - describes the pci_xxxxx functions used to find a pci card and read its
// configuration area.
// - describes the mmap_device_memory and munmap_device_memory used to
// map physical to logical memory
// - describes the delay function
// [3] TI PCI2040 PCI-DSP Bridge Controller Data Manual
// scps048.pdf and hard copy
// - describes the contents of the pci memory areas mapped into the
// PC memory space
// [4] TI TMS32054x DSP Enhanced Peripherals Reference Set Volume 5
// hard copy and on Code Composer Studio CD
// - Chapter 4 describes the Enhanced Host Port Interface
// This supercedes some of the information given in [3] about the
// HPI interface.
// Also contains some info about HPI use during initial DSP reset
// [5] TI TMS320VC5410 Bootloader
// spra609a.pdf
// - contains details on how to load a program to the 5410 using HPI
// [6] TI 2040 EVM Hardware Guide Users Guide
// describes EVM card details relevent to the bootload process
// pci 2040 EVM hardware guide.pdf
// [7] TI TMS320VC5402 and TMS320UC5402 Bootloaders
// hard copy
// - contains details on how to load a program to the 5402 using HPI.
// It is not needed for the EVM board but will be required for the
// final stepper board
// [8] TI TMS32054x Assembly Language Tools Users Guide
// hard copy and on Code Composer Studio CD
// - Chapter 10 describes how to create and the format of the hex program
// file created
// [9] show_pci.c
// example neutrino program for displaying pci card details
// converted to neutrino from qnx by ZPZ 20/7/00
// [10] TI TMS320UC5402/TMS320VC5402 Digital Signal Processor Silicon Advisories SPRZ155B
// contains details of bug where HPI may lock up if both DSP and host write 1 to HINT