0
votes

Last few days onwards I am trying to develop data transfer between the host and endpoint, but I am unable to do that implementation.I have tried how to read the configure space using some calls(pci_read_long),it is successfully reading the data like vendor_id,device_id...etc.

In the configuration space BAR(base address register) is stored the memory address as well as I/O address it depends on 0th bit.coming to my problem I am reading the 10h address register, for example, let us consider the value 0XFE000000 what I am doing is to clear last four bits then complement the bits and finally add 1 to the address then the result indicates the size of the address.

my problems are:

  • whenever I am writing to particular address location(FE000000) using this pci_write_long I am facing the segmentation fault.
  • why I am facing segmentation fault while writing ? can anyone please help me to resolve this issue and is it correct calculating the size of memory(above steps).
  • about bar : Is it represent the memory base address?

coming to my code:

int  c = pci_write_long(dev,0X10,0xFFFFFFFF);//write all 1's to that location

c = pci_read_long(dev,0x10); //reading the address
printf("c = %x\n",c);

for(i=0;i<4;i++)             //clearing the last four bits
        c = c & ~(1<<i);
printf("c = %x\n",c);

c = ~c;                    // 1's complement
c =c+1;                    //add the one to that address

printf("c = %x\n",c);          // size of the address

int  ch1 = pci_write_byte(dev,c,0xf);  // i am facing the segmentation fault here
printf("ch1 = %x\n",ch1);

ch1 = pci_read_byte(dev,c);         // again i am reading the the data current location 
printf("final read = %x\n",ch1);

Is it the correct way of implementing the code or not? if it is not correct can u provide any related information or any link?

1

1 Answers

0
votes

whenever I am writing to particular address location(FE000000) using this pci_write_long I am facing the segmentation fault.

pci_write_long() is used to access the Endpoints config space. The address you are trying to access is memory mapped Endpoint's internal registers and you can simply use pointers to do it. Just mmap() the address and access it like normal buffer provided you are aware of the device's internal register structure. You can see that first write of 0xFFFFFFFF was successful because you were writing to offset 0x10 which lies in the config space. Next write which caused the segmentation fault, you are writing to offset 0xFE000000 from the config space base which is invalid. One more point, in case you are on ARM, is this memory i.e. 0xFE000000 lies withing the PCIe controllers memory range? If that is not the case, then you are accessing an invalid memory.

why I am facing segmentation fault while writing ? can anyone please help me to resolve this issue and is it correct calculating the size of memory(above steps).

Reason for crash is given above. The size calculation algorithm looks correct. You can simply match your calculated size with the BAR size mentioned in the EP's datasheet to be sure.

about bar : Is it represent the memory base address?

It represents where your Endpoint's or Device's internal registers/memory is mapped in your host address space region. You can use the same address from your host machine to access the device's internal registers as if you are accessing a local memory buffer. Just mmap() the address before accessing if your architecture has virtual memory in place.

EDIT 1 - I can see you are writing all 1's and trying to read the address. You are not string any address first which should be from your host address space. I believe there is some misunderstanding you need to clear with BAR usage.

1 - Get the BAR size. 2 - Write an host address to the BAR where you want EP's internal registers to map. (For ARM, the address should be from PCIe controllers address range. Check manual of your board) - Enable memory transaction access by writing 0x3 in command register. 3 - from your c code, do mmap() of that address 4 - Access that address now.