linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Memory mapping PCI memory region to user space
@ 2006-03-23 14:21 Wyse, Chris
  2006-03-23 15:44 ` Kumar Gala
  2006-03-23 17:04 ` David Hawkins
  0 siblings, 2 replies; 20+ messages in thread
From: Wyse, Chris @ 2006-03-23 14:21 UTC (permalink / raw)
  To: linuxppc-embedded, +linux-embedded

[-- Attachment #1: Type: text/plain, Size: 1871 bytes --]

Hi,
 
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:
 
 
staticfun
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,
                            physAddr,
                            rptr->len,
                            vma->vm_page_prot))
        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) |
pgprot_val(prot))
 
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:
 
remap_pte_range()
remap_pmd_range()
remap_pfn_range()
io_remap_page_range()
 
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?
 
Thanks.


Chris Wyse
Member of Technical Staff
Embedded Technologies
860-749-1556 office
860-978-0849 cell
413-778-9101 fax
http://www.windriver.com <http://www.windriver.com/> 
  

 

[-- Attachment #2: Type: text/html, Size: 6392 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread
* RE: Memory mapping PCI memory region to user space
@ 2006-03-23 19:52 Wyse, Chris
  2006-03-23 20:01 ` Kumar Gala
  0 siblings, 1 reply; 20+ messages in thread
From: Wyse, Chris @ 2006-03-23 19:52 UTC (permalink / raw)
  To: David Hawkins, Kumar Gala; +Cc: Linuxppc-Embedded ((E-Mail))

Hi,

Thanks for all the help.

My ideal solution would have been to use sysfs, but I didn't want to
upgrade the kernel.  Therefore, I used Dave's program as a guide for
setting the protect bits appropriately, and was able to get the driver
working.  The driver required the pfn_pte macro change specified in my
original post.  It appears to be a kernel bug on PPC processors with a
greater than 32 bit address space.


Chris Wyse
Member of Technical Staff
Embedded Technologies
860-749-1556 office
860-978-0849 cell
413-778-9101 fax
http://www.windriver.com
 =20


-----Original Message-----
From: David Hawkins [mailto:dwh@ovro.caltech.edu]=20
Sent: Thursday, March 23, 2006 12:47 PM
To: Kumar Gala
Cc: Wyse, Chris; Linuxppc-Embedded ((E-Mail))
Subject: Re: Memory mapping PCI memory region to user space

Hi Kumar,

>> When I was testing the Yosemite board as the host, I found that I=20
>> could set the endian flag on the mmapped page, which then made the=20
>> PCI device registers read as 32-bit quantities read back with the=20
>> same layout under both x86 and PPC hosts.
>=20
> Hmm, I guess I would handle this like how the reset of the kernel=20
> handle is with the io routines handling the swapping.  Not sure if=20
> there is any advantage to using the endian flag.  I guess if you have=20
> something you are treating as just memory there would be.

I haven't used the feature, I just tested it to see what it did.

The application case I thought of was this; the PCI boards I built (that
I am revising, and replacing the DSP with a PPC) have an 8MB PCI region
that I can mmap from the host. I have a test suite that runs from the
host that manipulates registers on the boards to download FPGAs etc.
When the boards are used in a real system, the onboard DSP is generally
used, and the host just talks to the DSP.

However, for the test suite, if I have a header with definitions
like:

#define CONTROL_FPGA_ENABLE   (1 << 0)
#define CONTROL_FPGA_DONE_BIT (1 << 1)

that correspond to bits in a 32-bit PCI mmapped register. Then code in
the user-space test suite that did something like

   pci_addr[CONTROL_OFFSET] |=3D CONTROL_FPGA_ENABLE;

would instead need to be re-written, eg.,

   write_le32(&pci_addr[CONTROL_OFFSET], CONTROL_FPGA_ENABLE);

to be portable.

I definitely agree that this is how kernel-level code should be written,
but user-space code ... well, if I want to reuse code already written,
setting the page endian flag and reusing the code would seem like the
way to go. (This isn't what I need to do, since my host will still be an
x86, the PPC will be a target device, but I still need to think about
the endian issues).

Now of course that I have seen the consequences of my coding, I'll be
more careful to deal with endianness more appropriately.

Its a tricky trade-off though. I could define control ioctl's that hide
all the endianness issues ... but then the driver just gets bigger. I
think the appropriate solution for the user-space test code would be to
use CPU-to-little-endian routines, and wrap the lot in a re-usable
library that the test suite links against.

> There isn't a sysfs flag for the endianness page attribute since =20
> thats a PPC book-e specific feature.  We could possible expand things

> to support it but, I've been trying to actively avoid using the 'E'
bit.

Ok, I haven't received the 8349E board that I am waiting on, so I hadn't
spotted that the PAGE_ENDIAN flag was Book E specific.

Thanks for your insight.

Cheers
Dave

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2006-03-29  2:26 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-23 14:21 Memory mapping PCI memory region to user space Wyse, Chris
2006-03-23 15:44 ` Kumar Gala
2006-03-23 17:12   ` David Hawkins
2006-03-23 17:19     ` Kumar Gala
2006-03-23 17:43       ` Mark Chambers
2006-03-23 17:54         ` David Hawkins
2006-03-23 19:55           ` Mark Chambers
2006-03-23 20:26             ` David Hawkins
2006-03-23 17:46       ` David Hawkins
2006-03-27  8:02   ` Phil Nitschke
2006-03-27 16:05     ` David Hawkins
2006-03-28  4:21       ` Phil Nitschke
2006-03-28  4:55         ` David Hawkins
2006-03-28  6:44           ` Phil Nitschke
2006-03-28 16:35             ` David Hawkins
2006-03-27 16:18     ` Kumar Gala
2006-03-29  2:26       ` Phil Nitschke
2006-03-23 17:04 ` David Hawkins
  -- strict thread matches above, loose matches on Subject: below --
2006-03-23 19:52 Wyse, Chris
2006-03-23 20:01 ` Kumar Gala

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).