2005-11-11 06:25:24 +03:00
# ifndef _ASM_POWERPC_PAGE_H
# define _ASM_POWERPC_PAGE_H
/*
* Copyright ( C ) 2001 , 2005 IBM Corporation .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# ifdef __KERNEL__
# include <linux/config.h>
# include <asm/asm-compat.h>
/*
* On PPC32 page size is 4 K . For PPC64 we support either 4 K or 64 K software
* page size . When using 64 K pages however , whether we are really supporting
* 64 K pages in HW or not is irrelevant to those definitions .
*/
# ifdef CONFIG_PPC_64K_PAGES
# define PAGE_SHIFT 16
# else
# define PAGE_SHIFT 12
# endif
# define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
# define __HAVE_ARCH_GATE_AREA 1
/*
* Subtle : ( 1 < < PAGE_SHIFT ) is an int , not an unsigned long . So if we
* assign PAGE_MASK to a larger type it gets extended the way we want
* ( i . e . with 1 s in the high bits )
*/
# define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
2005-12-05 19:24:33 +03:00
/*
* KERNELBASE is the virtual address of the start of the kernel , it ' s often
* the same as PAGE_OFFSET , but _might not be_ .
*
* The kdump dump kernel is one example where KERNELBASE ! = PAGE_OFFSET .
*
* To get a physical address from a virtual one you subtract PAGE_OFFSET ,
* _not_ KERNELBASE .
*
* If you want to know something ' s offset from the start of the kernel you
* should subtract KERNELBASE .
*
* If you want to test if something ' s a kernel address , use is_kernel_addr ( ) .
*/
2005-12-04 10:39:23 +03:00
# ifdef CONFIG_CRASH_DUMP
/* Kdump kernel runs at 32 MB, change at your peril. */
# define PHYSICAL_START 0x2000000
# else
# define PHYSICAL_START 0x0
# endif
2005-11-11 06:25:24 +03:00
# define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START)
2005-12-04 10:39:23 +03:00
# define KERNELBASE (PAGE_OFFSET + PHYSICAL_START)
2005-11-11 06:25:24 +03:00
# ifdef CONFIG_DISCONTIGMEM
# define page_to_pfn(page) discontigmem_page_to_pfn(page)
# define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
# define pfn_valid(pfn) discontigmem_pfn_valid(pfn)
# endif
# ifdef CONFIG_FLATMEM
# define pfn_to_page(pfn) (mem_map + (pfn))
# define page_to_pfn(page) ((unsigned long)((page) - mem_map))
# define pfn_valid(pfn) ((pfn) < max_mapnr)
# endif
# define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
# define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
# define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
2005-12-05 19:24:33 +03:00
# define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))
2005-11-11 06:25:24 +03:00
# define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
/*
* Unfortunately the PLT is in the BSS in the PPC32 ELF ABI ,
* and needs to be executable . This means the whole heap ends
* up being executable .
*/
# define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC )
# define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC )
# ifdef __powerpc64__
# include <asm/page_64.h>
# else
# include <asm/page_32.h>
# endif
/* align addr on a size boundary - adjust address up/down if needed */
# define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
# define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
/* align addr on a size boundary - adjust address up if needed */
# define _ALIGN(addr,size) _ALIGN_UP(addr,size)
/* to align the pointer to the (next) page boundary */
# define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
2005-12-04 10:39:15 +03:00
/*
* Don ' t compare things with KERNELBASE or PAGE_OFFSET to test for
* " kernelness " , use is_kernel_addr ( ) - it should do what you want .
*/
# define is_kernel_addr(x) ((x) >= PAGE_OFFSET)
2005-11-11 06:25:24 +03:00
# ifndef __ASSEMBLY__
# undef STRICT_MM_TYPECHECKS
# ifdef STRICT_MM_TYPECHECKS
/* These are used to make use of C type-checking. */
/* PTE level */
typedef struct { pte_basic_t pte ; } pte_t ;
# define pte_val(x) ((x).pte)
# define __pte(x) ((pte_t) { (x) })
/* 64k pages additionally define a bigger "real PTE" type that gathers
* the " second half " part of the PTE for pseudo 64 k pages
*/
# ifdef CONFIG_PPC_64K_PAGES
typedef struct { pte_t pte ; unsigned long hidx ; } real_pte_t ;
# else
typedef struct { pte_t pte ; } real_pte_t ;
# endif
/* PMD level */
typedef struct { unsigned long pmd ; } pmd_t ;
# define pmd_val(x) ((x).pmd)
# define __pmd(x) ((pmd_t) { (x) })
/* PUD level exusts only on 4k pages */
# ifndef CONFIG_PPC_64K_PAGES
typedef struct { unsigned long pud ; } pud_t ;
# define pud_val(x) ((x).pud)
# define __pud(x) ((pud_t) { (x) })
# endif
/* PGD level */
typedef struct { unsigned long pgd ; } pgd_t ;
# define pgd_val(x) ((x).pgd)
# define __pgd(x) ((pgd_t) { (x) })
/* Page protection bits */
typedef struct { unsigned long pgprot ; } pgprot_t ;
# define pgprot_val(x) ((x).pgprot)
# define __pgprot(x) ((pgprot_t) { (x) })
# else
/*
* . . while these make it easier on the compiler
*/
typedef pte_basic_t pte_t ;
# define pte_val(x) (x)
# define __pte(x) (x)
# ifdef CONFIG_PPC_64K_PAGES
typedef struct { pte_t pte ; unsigned long hidx ; } real_pte_t ;
# else
typedef unsigned long real_pte_t ;
# endif
typedef unsigned long pmd_t ;
# define pmd_val(x) (x)
# define __pmd(x) (x)
2006-01-11 08:27:21 +03:00
# if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_64K_PAGES)
2005-11-11 06:25:24 +03:00
typedef unsigned long pud_t ;
# define pud_val(x) (x)
# define __pud(x) (x)
# endif
typedef unsigned long pgd_t ;
# define pgd_val(x) (x)
# define pgprot_val(x) (x)
typedef unsigned long pgprot_t ;
# define __pgd(x) (x)
# define __pgprot(x) (x)
# endif
struct page ;
extern void clear_user_page ( void * page , unsigned long vaddr , struct page * pg ) ;
extern void copy_user_page ( void * to , void * from , unsigned long vaddr ,
struct page * p ) ;
extern int page_is_ram ( unsigned long pfn ) ;
# endif /* __ASSEMBLY__ */
# endif /* __KERNEL__ */
# endif /* _ASM_POWERPC_PAGE_H */