PCI Busses and POSIX memory shares

Dear fellow QNX 4.x users

I am working on an embedded pentium board with a PC/104+ PCI bus.

I have a PCI DSP peripheral board I am trying to access which has both a
standard configuration space for memory (PCI BAR0), the same footprint in IO
space (BAR1), and also shared DPSRAM in BAR2.

I can access the configuration space using the PCI_CONFIG functions in C,
but now I need to access the space designated by BAR2. I am pretty sure
either the PCI BIOS or QNX has preconfigured BAR2, but I am unsure.

There is a nonzero value in the BAR2 address vector, and the address is
alligned apropriately to a 32KB block, appropriate for the on board 32KB
DPSRAM. When I try to open a share to it, I can create the share, but when I
try to read it with a pointer pointed within that address space, the
application process gets terminated with some sort of read violation
(SIGSEGV). (I can have my cake, but can’t eat it.)

I have it opened for physical memory with:


if(retval = _CA_PCI_Read_Config_DWord(
bus_num, dev_func_num,
offsetof(struct _pci_config_regs,Base_Address_Regs[2]),
1, (char *)&address2 ) != PCI_SUCCESS)
{
printf(“Error reading PCI BAR 2 address %x\n”,retval);
return -1;
}/if/

/*




*/

if( (seg2 = shm_open(“Physical”,O_RDWR,0777)) == -1)
{
printf(“Error shared memory open, PCI BAR 2:\n %s\n”,
strerror(errno));
return -1;
}
else if( (PCI_OVERLAY_DPSRAM_PREALLIGNED =
mmap( 0, 65536, PROT_READ|PROT_WRITE, MAP_SHARED, seg2,
PCI_MEM_ADDR(address2) & ~0xFFF )) == (void *)-1 )
{
printf(“Error shared memory maping, PCI BAR 2:\n %s\n”,
strerror(errno));
return -1;
}
else
{
PCI_OVERLAY_DPSRAM = PCI_OVERLAY_DPSRAM_PREALLIGNED

  • (PCI_MEM_ADDR(address2)& 0xFFFF);
    };



    I’d appreciate it if someone could help me eat my cake. :slight_smile:

Thanks,

Steve

Steve Groves <sgroves@interadlimited.com> wrote:

Dear fellow QNX 4.x users

I haven’t done careful reading – and this might be ok…

if( (seg2 = shm_open(“Physical”,O_RDWR,0777)) == -1)
{
printf(“Error shared memory open, PCI BAR 2:\n %s\n”,
strerror(errno));
return -1;
}
else if( (PCI_OVERLAY_DPSRAM_PREALLIGNED =
mmap( 0, 65536, PROT_READ|PROT_WRITE, MAP_SHARED, seg2,
PCI_MEM_ADDR(address2) & ~0xFFF )) == (void *)-1 )
^^^

Three Fs

{
printf(“Error shared memory maping, PCI BAR 2:\n %s\n”,
strerror(errno));
return -1;
}
else
{
PCI_OVERLAY_DPSRAM = PCI_OVERLAY_DPSRAM_PREALLIGNED

  • (PCI_MEM_ADDR(address2)& 0xFFFF);
    ^^^^

Four Fs.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

I see the inconsistancy, and that was a problem I just corrected. I can
access the memory from the function which openned and mapped the PCI access
now, but I can’t access it using another function in the same process
without it being killed with a SIGSEGV. Let me repeat what I have now, with
corrections. I should note again that the block I want to access is actually
32k wide DPSRAM I am not counting on being 2^x boundary-aligned (although it
seems to always be in the target peripheral).

/* Globals:*/
long address = 0x0L;
long address2 = 0x0L;
volatile long __far *PCI_OVERLAY_DPSRAM_PREALLIGNED = 0x0L;
volatile long __far *PCI_OVERLAY_DPSRAM = 0x0L;
volatile long __far DPSRAMPTR = 0x0L;
/


/
int setup_pci(){
unsigned pci_index = 0;
int retval;
unsigned static seg2;
/
… other irrelevent or mundane declarations … /


/

*/

if(retval = _CA_PCI_Read_Config_DWord(
bus_num, dev_func_num,
offsetof( struct _pci_config_regs,Base_Address_Regs[2]),
1, (char *)&address2 ) != PCI_SUCCESS)
{
printf(“Error reading PCI BAR 2 address %x\n”,retval);
return -1;
}/if/

printf(“DPSRAM address: 0x%08X\n”,address2);
if (!PCI_IS_MEM(address2))
{
printf(“Error: PCI Base Address Register 2 is not preconfigured as
memory- mapped.\nMay be incorrect PCI device.\n”);
return -1;
}
else
{

/*

*/


if((int )PCI_OVERLAY_DPSRAM_PREALLIGNED != 0)
{
printf( “Attempting to unmap previous DPSRAM address: 0x%08X \n”,
(int )PCI_OVERLAY_DPSRAM_PREALLIGNED);
if( munmap((void *)PCI_OVERLAY_DPSRAM_PREALLIGNED,65536)== -1)
printf( “Failed:\n %s\n”, strerror(errno));
}
else
printf(“No previous shared PCI DPSRAM openings.\n”);


if( (seg2 = shm_open(“Physical”,O_RDWR,0777)) == -1)
{
printf(“Error shared memory open, PCI BAR 2:\n %s\n”,
strerror(errno));
return -1;
}
else if( (PCI_OVERLAY_DPSRAM_PREALLIGNED =
mmap( 0, 65536, PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_SHARED,
seg2, PCI_MEM_ADDR(address2) & ~0xFFFF )) == (void
*)-1 )
{
printf(“Error shared memory maping, PCI BAR 2:\n %s\n”,
strerror(errno));
return -1;
}
else
{
PCI_OVERLAY_DPSRAM = (void
*)((int )PCI_OVERLAY_DPSRAM_PREALLIGNED

  • (PCI_MEM_ADDR(address2) & 0xFFFF));
    };

printf( “DPSRAM shared memory 64kb block address: 0x%08X\n”,
(int )PCI_OVERLAY_DPSRAM_PREALLIGNED);
printf( “DPSRAM shared memory address: 0x%08X\n”,
(int )PCI_OVERLAY_DPSRAM);
}

/*

(successful memory read tests)

*/

}


pointer_setup_function()
{

/* …*/

*(int )&DPSRAMPTR = offset_value_function() +
(int )PCI_OVERLAY_DPSRAM;
/
assume DPSRAM is inside of the overlay segment */
}

pci_reading_function()
{
/* … */

l = *(DPSRAMPTR++);

/* … */
}


Thank you,

Steve