I have a PPC MVME5100 with a Tundra Universe II chip on it. This chip
is a PCI to VME bridge. The nice people at VMIC have written a BSD
licensed driver for Linux for their boards which are x86 based. With a
few changes it mostly works on the PPC. So far things seem to work fine
in kernel space but there is an issue in user space with mmap. Let me
give you a quick rundown of what is going on.
After all of the initialization is done the driver allocates a 4Mb block
of memory with allocate_resource(...) and in this case it happens to be
at 0xD4000000.
The Universe registers are set up to use this area so that a read or a
write in this area actually reads or writes a specific address on the
VME bus. After doing an ioremap(0xD4000000, 0x1000) the kernel can do
readl or writel to the VME bus so the Universe chip is set up properly.
The driver's mmap function does the following:
int vme_mmap (struct file *filp, struct vm_area_struct *vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long vsize = vma->vm_end - vma->vm_start;
if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC)){
vma->vm_flags |= VM_IO;
}
vma->vm_flags |= VM_RESERVED;
return (remap_page_range(vma->vm_start, offset,
vsize, vma->vm_page_prot));
}
The user program calls a library function to do the mmap, where paddr is
passed as 0xD4000000 and size is 0x1000.
void *vme_mmap_phys (int fd, unsigned long paddr, size_t size)
{
unsigned long mapaddr, off, mapsize;
size_t ps = getpagesize ();
char *ptr;
/* Page align the memory mapping
*/
off = paddr % ps;
mapaddr = paddr - off;
mapsize = size + off;
mapsize += (mapsize % ps) ? ps - (mapsize % ps) : 0;
if (NULL == (ptr =
mmap (0, mapsize, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, mapaddr)))
return (NULL);
/* Return the pointer compenstated for offset from a page boundary
*/
return (ptr + off);
}
When the user program accesses the returned ptr using
uint8_t *ptr;
ptr = vme_master_window_map(bus_handle, window_handle, 0)
for(ii = 0; ii < NBYTES; ++ii, ++ptr)
printf("%.2x ", *ptr);
It just prints ff and there is no activity on the VME bus.
Any idea what is wrong? This supposedly works on an x86 though I do not
have hardware to verify.
Thanks,
Eric Wulf
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/