mmap problem on PPC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux