lkml.org 
[lkml]   [1998]   [Nov]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: Accessing MMIO PCI space - crossplatform
[Forwarded to linux-kernel because so many people ask...]

On Fri, Nov 13, 1998 at 10:59:56AM -0500, Chip Salzenberg wrote:
> > virt_to_phys is only useful for MMU manipulation, so maybe it shouldn't
> > be exported outside the MMU manipulation code (mostly in mm/memory.c).
>
> Oh. I'm working on a driver of little use to anyone (:-)) and I used
> virt_to_phys because it seemed the right thing to do. Could you point me
> to whatever documentation exists on proper usage of *phys* and *bus*?

linux/Documentation/IO-mapping.txt

It is a little out of date but basically right.

*bus* is addressed you pass to devices. E.g., what you'd write to a PCI
bus-mastering DMA device as its target address. These are returned by
ioremap() as well as virt_to_bus(). From C code, these should always be
accessed through readl(), writel() etc. and not as ordinary memory
references. See <asm/io.h>.

*phys* is a CPU address after MMU translation. It only appears in page
tables and things related to page tables. Even this is hidden to some
extent because pte_page(*pte) returns a *virt* address despite appearances.
See <asm/pgtable.h>.

*virt* is a kernel direct-mapped address. These are addresses you can
read and write from C, that correspond to main memory. E.g., on x86,
the *virt* address 0xc0001000 means the 4097th byte of main memory. See
<asm/page.h>.

There are other kinds of address too:

*user* addresses (such as passed to read() and write()) are
none of the above, and should always by accessed through get_user(),
put_user() etc. See <asm/uaccess.h>.

*static* addresses are the addresses of functions and variables that are
declared in source code. Because kernel code and modules are allocated
in various ways, you can't assume much about these addresses, but you
can always read and write them from kernel C code.

*vmalloc* addresses (returned by vmalloc()). These are kernel virtual
address, which you can read and write from kernel C code. But you can't
pass them to any of the virt_to_XXX macros, because they're *not* virt
addresses! See <linux/vmalloc.h>.

*fixmap* addresses are returned by fix_to_virt() (which has a misleading
name). These are like *vmalloc* addresses: you can't pass them to the
virt_to_XXX macros, so they're _not_ *virt* addresses. See
<asm/fixmap.h>.

Some people try to look up page tables to convert a *user* address or
*vmalloc* address to a *bus* address or *virt* address. This works, but
makes a number of assumptions that are incorrect and won't work when you
want to use the driver in a new way one day, or on a new architecture.

This mess will be cleaned up sometime in version 2.3. So if you want it
cleaned up, perhaps the best way is to help ensure 2.2 is ready for
release. Hint :-)

Hope this helps,
-- Jamie

ps. Do you find the above description helpful? I might try to get it
added to IO-mapping.txt if it is.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.290 / U:0.824 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site