Memory mapping PCI memory region to user space

Wyse, Chris chris.wyse at
Fri Mar 24 01:21:05 EST 2006

I'm trying to map a PCI memory region 1 into user space from my driver
(PPC440GX, Linux 2.6.10).  Here's the mmap routine of the driver that
I'm using:
int phob_mmap(struct file *filp, struct vm_area_struct *vma)
    struct phob_file *fptr = filp->private_data;
    struct phob_struct *dev = fptr->dev;
    struct phob_region *rptr = &dev->region[1];
    phys_addr_t physAddr;

    physAddr = rptr->address + PPC44x_PCIMEM_PAGE;
    if (io_remap_page_range(vma, vma->vm_start,
        return -EAGAIN;

Am I using the correct routine to do this?
When I use this routine, the pfn_pte (pgtable.h): 
#define pfn_pte(pfn, prot)      __pte(((pfn) << PAGE_SHIFT) |
macro shifted out the high order bits of the pfn, which I didn't think
was correct, so I changed it to:

#define pfn_pte(pfn, prot)      __pte((((unsigned long long) (pfn)) <<
PAGE_SHIFT) | pgprot_val(prot))
For reference, the call stack up to the pfn_pte macro is:
After changing the macro, the value seems to be saved properly, and the
TLB gets updated properly when I get a TLB miss.  However, when if I try
to write to the PCI from user space, I get an error from do_wp_page()
stating that it is a bogus pfn.  If I try to read from user space, the
processor goes out to lunch and I need to reboot.
Am I missing something obvious?  Anyone have any ideas on how to do this
and/or ways to debug it?

Chris Wyse
Member of Technical Staff
Embedded Technologies
860-749-1556 office
860-978-0849 cell
413-778-9101 fax <> 

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Linuxppc-embedded mailing list