explanation of __va() and __pa() macros.
Hi, My source is from 2.6 git tree. In LDD3 its said that a logical address is mapped to physical address and vice versa by the macros __va() and __pa(). In my source tree they are defined as follows: <include/asm-generic/page.h> #define __va(x) ((void *)((unsigned long) (x))) #define __pa(x) ((unsigned long) (x)) I'm not actually understanding how these "cute" looking casting is performing "address mapping". I thought address mapping involves more complex operations. cheers. aft
On Fri, Jun 22, 2012 at 2:49 PM, AFT <aftnix@gmail.com> wrote:
Hi,
My source is from 2.6 git tree. In LDD3 its said that a logical address is mapped to physical address and vice versa by the macros __va() and __pa().
In my source tree they are defined as follows:
<include/asm-generic/page.h>
#define __va(x) ((void *)((unsigned long) (x))) #define __pa(x) ((unsigned long) (x))
I'm not actually understanding how these "cute" looking casting is performing "address mapping". I thought address mapping involves more complex operations.
See the comments at the beginning of the file you quoted: /* * Generic page.h implementation, for NOMMU architectures. * This provides the dummy definitions for the memory management. */ For arch-specific code try looking, for instance, at arch/x86/include/asm/page.h . Hope this helps, Vlad
Vlad Dogaru <ddvlad@rosedu.org> writes:
On Fri, Jun 22, 2012 at 2:49 PM, AFT <aftnix@gmail.com> wrote:
Hi,
My source is from 2.6 git tree. In LDD3 its said that a logical address is mapped to physical address and vice versa by the macros __va() and __pa().
In my source tree they are defined as follows:
<include/asm-generic/page.h>
#define __va(x) ((void *)((unsigned long) (x))) #define __pa(x) ((unsigned long) (x))
I'm not actually understanding how these "cute" looking casting is performing "address mapping". I thought address mapping involves more complex operations.
See the comments at the beginning of the file you quoted:
/* * Generic page.h implementation, for NOMMU architectures. * This provides the dummy definitions for the memory management. */
For arch-specific code try looking, for instance, at arch/x86/include/asm/page.h .
Hope this helps, Vlad Hi Vlad,
Thanks for the explanation. I should lookout for embedded comments with more attention from now. cheers. aft
AFT <aftnix@gmail.com> writes:
My source is from 2.6 git tree. In LDD3 its said that a logical address is mapped to physical address and vice versa by the macros __va() and __pa().
In my source tree they are defined as follows:
<include/asm-generic/page.h>
There's an important comment in the beginning of that file: /* * Generic page.h implementation, for NOMMU architectures. * This provides the dummy definitions for the memory management. */
#define __va(x) ((void *)((unsigned long) (x))) #define __pa(x) ((unsigned long) (x))
I'm not actually understanding how these "cute" looking casting is performing "address mapping". I thought address mapping involves more complex operations.
The dummy definition is the identity mapping. You can look at the real implementations to see more complex mappings: bjorn@nemi:/usr/local/src/git/linux$ egrep '#define __(p|v)a\(' arch/*/include/asm/page.h arch/alpha/include/asm/page.h:#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) arch/alpha/include/asm/page.h:#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) arch/avr32/include/asm/page.h:#define __pa(x) PHYSADDR(x) arch/avr32/include/asm/page.h:#define __va(x) ((void *)(P1SEGADDR(x))) arch/frv/include/asm/page.h:#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) arch/frv/include/asm/page.h:#define __va(paddr) phys_to_virt((unsigned long) (paddr)) arch/h8300/include/asm/page.h:#define __pa(vaddr) virt_to_phys(vaddr) arch/h8300/include/asm/page.h:#define __va(paddr) phys_to_virt((unsigned long)paddr) arch/hexagon/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) arch/hexagon/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) arch/ia64/include/asm/page.h:#define __pa(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = 0; _v.l;}) arch/ia64/include/asm/page.h:#define __va(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.p;}) arch/m32r/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) arch/m32r/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) arch/mips/include/asm/page.h:#define __pa(x) \ arch/mips/include/asm/page.h:#define __pa(x) \ arch/mips/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) arch/mn10300/include/asm/page.h:#define __pa(x) ((unsigned long)(x)) arch/mn10300/include/asm/page.h:#define __va(x) ((void *)(unsigned long)(x)) arch/openrisc/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) arch/openrisc/include/asm/page.h:#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) arch/parisc/include/asm/page.h:#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) arch/parisc/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) arch/powerpc/include/asm/page.h:#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET)) arch/powerpc/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET) arch/powerpc/include/asm/page.h:#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START)) arch/powerpc/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START) arch/s390/include/asm/page.h:#define __pa(x) (unsigned long)(x) arch/s390/include/asm/page.h:#define __va(x) (void *)(unsigned long)(x) arch/score/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) arch/score/include/asm/page.h:#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) arch/sh/include/asm/page.h:#define __pa(x) ___pa((unsigned long)x) arch/sh/include/asm/page.h:#define __va(x) (void *)___va((unsigned long)x) arch/tile/include/asm/page.h:#define __pa(kaddr) virt_to_phys((void *)(unsigned long)(kaddr)) arch/tile/include/asm/page.h:#define __va(paddr) phys_to_virt((phys_addr_t)(paddr)) arch/um/include/asm/page.h:#define __pa(virt) to_phys((void *) (unsigned long) (virt)) arch/um/include/asm/page.h:#define __va(phys) to_virt((unsigned long) (phys)) arch/x86/include/asm/page.h:#define __pa(x) __phys_addr((unsigned long)(x)) arch/x86/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) arch/xtensa/include/asm/page.h:#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) arch/xtensa/include/asm/page.h:#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) Bjørn
Bjørn Mork <bjorn@mork.no> writes:
AFT <aftnix@gmail.com> writes:
My source is from 2.6 git tree. In LDD3 its said that a logical address is mapped to physical address and vice versa by the macros __va() and __pa().
In my source tree they are defined as follows:
<include/asm-generic/page.h>
There's an important comment in the beginning of that file:
/* * Generic page.h implementation, for NOMMU architectures. * This provides the dummy definitions for the memory management. */
#define __va(x) ((void *)((unsigned long) (x))) #define __pa(x) ((unsigned long) (x))
I'm not actually understanding how these "cute" looking casting is performing "address mapping". I thought address mapping involves more complex operations.
The dummy definition is the identity mapping. You can look at the real implementations to see more complex mappings:
bjorn@nemi:/usr/local/src/git/linux$ egrep '#define __(p|v)a\(' arch/*/include/asm/page.h arch/alpha/include/asm/page.h:#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) arch/alpha/include/asm/page.h:#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) arch/avr32/include/asm/page.h:#define __pa(x) PHYSADDR(x) arch/avr32/include/asm/page.h:#define __va(x) ((void *)(P1SEGADDR(x))) arch/frv/include/asm/page.h:#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) arch/frv/include/asm/page.h:#define __va(paddr) phys_to_virt((unsigned long) (paddr)) arch/h8300/include/asm/page.h:#define __pa(vaddr) virt_to_phys(vaddr) arch/h8300/include/asm/page.h:#define __va(paddr) phys_to_virt((unsigned long)paddr) arch/hexagon/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) arch/hexagon/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) arch/ia64/include/asm/page.h:#define __pa(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = 0; _v.l;}) arch/ia64/include/asm/page.h:#define __va(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.p;}) arch/m32r/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) arch/m32r/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) arch/mips/include/asm/page.h:#define __pa(x) \ arch/mips/include/asm/page.h:#define __pa(x) \ arch/mips/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) arch/mn10300/include/asm/page.h:#define __pa(x) ((unsigned long)(x)) arch/mn10300/include/asm/page.h:#define __va(x) ((void *)(unsigned long)(x)) arch/openrisc/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) arch/openrisc/include/asm/page.h:#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) arch/parisc/include/asm/page.h:#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) arch/parisc/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) arch/powerpc/include/asm/page.h:#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET)) arch/powerpc/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET) arch/powerpc/include/asm/page.h:#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START)) arch/powerpc/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START) arch/s390/include/asm/page.h:#define __pa(x) (unsigned long)(x) arch/s390/include/asm/page.h:#define __va(x) (void *)(unsigned long)(x) arch/score/include/asm/page.h:#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) arch/score/include/asm/page.h:#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) arch/sh/include/asm/page.h:#define __pa(x) ___pa((unsigned long)x) arch/sh/include/asm/page.h:#define __va(x) (void *)___va((unsigned long)x) arch/tile/include/asm/page.h:#define __pa(kaddr) virt_to_phys((void *)(unsigned long)(kaddr)) arch/tile/include/asm/page.h:#define __va(paddr) phys_to_virt((phys_addr_t)(paddr)) arch/um/include/asm/page.h:#define __pa(virt) to_phys((void *) (unsigned long) (virt)) arch/um/include/asm/page.h:#define __va(phys) to_virt((unsigned long) (phys)) arch/x86/include/asm/page.h:#define __pa(x) __phys_addr((unsigned long)(x)) arch/x86/include/asm/page.h:#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) arch/xtensa/include/asm/page.h:#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) arch/xtensa/include/asm/page.h:#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
Bjørn
Hi Bjorn, Thanks for the reply. cheers, aft
participants (3)
-
AFT -
Bjørn Mork -
Vlad Dogaru