Messages in this thread | | | Date | Fri, 13 Nov 1998 15:55:04 +0000 | From | Jamie Lokier <> | Subject | Re: 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/
| |