I am using a Zynq SoC with Petalinux 2016.2 I originally accessed my AXIS Fifo by opening it with
open("/dev/mem", O_RDWR | O_SYNC)
and using mmap to access it. I could access the registers of the AXIS device and interface successfully with the device through my C application.
I then created a platform device driver, and misc device node to access the device. The device is succesfully recognized by the driver, and I then
fd = open("/dev/devname, O_RDWR | O_SYNC)
and then mmap the device again with:
info->mapped_base = mmap(0, AXIFIFO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
I can read the registers and it seems to be the correct memory region. But when I start writing to some of the registers I start getting the following error:
Unhandled fault: imprecise external abort (0x1406) at 0x36e42000
pgd = 40ab4000
[36e42000] *pgd=3bff0831, *pte=43c0075f, *ppte=43c00c7f
Bus error
At first it seemed only to be when I write to the SRR reset register, but there's still a few other places as well.
Is there something obvious I am missing? I am suspecting it's to do with specific flags relating to the way the memory is mapped and can be accessed.
I currently have my own mmap function in the device driver where I do the following operation where start and length denotes the size of the mapped region of the AXIS FIFO's registers.
vm_iomap_memory(vma, start, length)
It seems the memory was marked as cached in the vma_area_struct:
So simply:
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
before
vm_iomap_memory(vma, start, length)
did the trick.