| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 1 | #ifndef _ASM_POWERPC_PAGE_H | 
 | 2 | #define _ASM_POWERPC_PAGE_H | 
 | 3 |  | 
 | 4 | /* | 
 | 5 |  * Copyright (C) 2001,2005 IBM Corporation. | 
 | 6 |  * | 
 | 7 |  * This program is free software; you can redistribute it and/or | 
 | 8 |  * modify it under the terms of the GNU General Public License | 
 | 9 |  * as published by the Free Software Foundation; either version | 
 | 10 |  * 2 of the License, or (at your option) any later version. | 
 | 11 |  */ | 
 | 12 |  | 
 | 13 | #ifdef __KERNEL__ | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 14 | #include <asm/asm-compat.h> | 
| Michael Ellerman | 4731041 | 2006-05-17 18:00:49 +1000 | [diff] [blame] | 15 | #include <asm/kdump.h> | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 16 |  | 
 | 17 | /* | 
 | 18 |  * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software | 
 | 19 |  * page size. When using 64K pages however, whether we are really supporting | 
 | 20 |  * 64K pages in HW or not is irrelevant to those definitions. | 
 | 21 |  */ | 
 | 22 | #ifdef CONFIG_PPC_64K_PAGES | 
 | 23 | #define PAGE_SHIFT		16 | 
 | 24 | #else | 
 | 25 | #define PAGE_SHIFT		12 | 
 | 26 | #endif | 
 | 27 |  | 
 | 28 | #define PAGE_SIZE		(ASM_CONST(1) << PAGE_SHIFT) | 
 | 29 |  | 
 | 30 | /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ | 
 | 31 | #define __HAVE_ARCH_GATE_AREA		1 | 
 | 32 |  | 
 | 33 | /* | 
 | 34 |  * Subtle: (1 << PAGE_SHIFT) is an int, not an unsigned long. So if we | 
 | 35 |  * assign PAGE_MASK to a larger type it gets extended the way we want | 
 | 36 |  * (i.e. with 1s in the high bits) | 
 | 37 |  */ | 
 | 38 | #define PAGE_MASK      (~((1 << PAGE_SHIFT) - 1)) | 
 | 39 |  | 
| Michael Ellerman | b5666f7 | 2005-12-05 10:24:33 -0600 | [diff] [blame] | 40 | /* | 
 | 41 |  * KERNELBASE is the virtual address of the start of the kernel, it's often | 
 | 42 |  * the same as PAGE_OFFSET, but _might not be_. | 
 | 43 |  * | 
 | 44 |  * The kdump dump kernel is one example where KERNELBASE != PAGE_OFFSET. | 
 | 45 |  * | 
 | 46 |  * To get a physical address from a virtual one you subtract PAGE_OFFSET, | 
 | 47 |  * _not_ KERNELBASE. | 
 | 48 |  * | 
 | 49 |  * If you want to know something's offset from the start of the kernel you | 
 | 50 |  * should subtract KERNELBASE. | 
 | 51 |  * | 
 | 52 |  * If you want to test if something's a kernel address, use is_kernel_addr(). | 
 | 53 |  */ | 
| Michael Ellerman | 398ab1f | 2005-12-04 18:39:23 +1100 | [diff] [blame] | 54 |  | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 55 | #define PAGE_OFFSET     ASM_CONST(CONFIG_KERNEL_START) | 
| Michael Ellerman | 398ab1f | 2005-12-04 18:39:23 +1100 | [diff] [blame] | 56 | #define KERNELBASE      (PAGE_OFFSET + PHYSICAL_START) | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 57 |  | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 58 | #ifdef CONFIG_FLATMEM | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 59 | #define pfn_valid(pfn)		((pfn) < max_mapnr) | 
 | 60 | #endif | 
 | 61 |  | 
 | 62 | #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) | 
 | 63 | #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT) | 
 | 64 | #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT) | 
 | 65 |  | 
| Michael Ellerman | b5666f7 | 2005-12-05 10:24:33 -0600 | [diff] [blame] | 66 | #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 67 | #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) | 
 | 68 |  | 
 | 69 | /* | 
 | 70 |  * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI, | 
 | 71 |  * and needs to be executable.  This means the whole heap ends | 
 | 72 |  * up being executable. | 
 | 73 |  */ | 
 | 74 | #define VM_DATA_DEFAULT_FLAGS32	(VM_READ | VM_WRITE | VM_EXEC | \ | 
 | 75 | 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 
 | 76 |  | 
 | 77 | #define VM_DATA_DEFAULT_FLAGS64	(VM_READ | VM_WRITE | \ | 
 | 78 | 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 
 | 79 |  | 
 | 80 | #ifdef __powerpc64__ | 
 | 81 | #include <asm/page_64.h> | 
 | 82 | #else | 
 | 83 | #include <asm/page_32.h> | 
 | 84 | #endif | 
 | 85 |  | 
 | 86 | /* align addr on a size boundary - adjust address up/down if needed */ | 
 | 87 | #define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1))) | 
 | 88 | #define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1))) | 
 | 89 |  | 
 | 90 | /* align addr on a size boundary - adjust address up if needed */ | 
 | 91 | #define _ALIGN(addr,size)     _ALIGN_UP(addr,size) | 
 | 92 |  | 
 | 93 | /* to align the pointer to the (next) page boundary */ | 
 | 94 | #define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE) | 
 | 95 |  | 
| Michael Ellerman | 51fae6de | 2005-12-04 18:39:15 +1100 | [diff] [blame] | 96 | /* | 
 | 97 |  * Don't compare things with KERNELBASE or PAGE_OFFSET to test for | 
 | 98 |  * "kernelness", use is_kernel_addr() - it should do what you want. | 
 | 99 |  */ | 
 | 100 | #define is_kernel_addr(x)	((x) >= PAGE_OFFSET) | 
 | 101 |  | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 102 | #ifndef __ASSEMBLY__ | 
 | 103 |  | 
 | 104 | #undef STRICT_MM_TYPECHECKS | 
 | 105 |  | 
 | 106 | #ifdef STRICT_MM_TYPECHECKS | 
 | 107 | /* These are used to make use of C type-checking. */ | 
 | 108 |  | 
 | 109 | /* PTE level */ | 
 | 110 | typedef struct { pte_basic_t pte; } pte_t; | 
 | 111 | #define pte_val(x)	((x).pte) | 
 | 112 | #define __pte(x)	((pte_t) { (x) }) | 
 | 113 |  | 
 | 114 | /* 64k pages additionally define a bigger "real PTE" type that gathers | 
 | 115 |  * the "second half" part of the PTE for pseudo 64k pages | 
 | 116 |  */ | 
 | 117 | #ifdef CONFIG_PPC_64K_PAGES | 
 | 118 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | 
 | 119 | #else | 
 | 120 | typedef struct { pte_t pte; } real_pte_t; | 
 | 121 | #endif | 
 | 122 |  | 
 | 123 | /* PMD level */ | 
| David Gibson | d1953c8 | 2007-05-08 12:46:49 +1000 | [diff] [blame] | 124 | #ifdef CONFIG_PPC64 | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 125 | typedef struct { unsigned long pmd; } pmd_t; | 
 | 126 | #define pmd_val(x)	((x).pmd) | 
 | 127 | #define __pmd(x)	((pmd_t) { (x) }) | 
 | 128 |  | 
 | 129 | /* PUD level exusts only on 4k pages */ | 
| David Gibson | d1953c8 | 2007-05-08 12:46:49 +1000 | [diff] [blame] | 130 | #ifndef CONFIG_PPC_64K_PAGES | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 131 | typedef struct { unsigned long pud; } pud_t; | 
 | 132 | #define pud_val(x)	((x).pud) | 
 | 133 | #define __pud(x)	((pud_t) { (x) }) | 
| David Gibson | d1953c8 | 2007-05-08 12:46:49 +1000 | [diff] [blame] | 134 | #endif /* !CONFIG_PPC_64K_PAGES */ | 
 | 135 | #endif /* CONFIG_PPC64 */ | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 136 |  | 
 | 137 | /* PGD level */ | 
 | 138 | typedef struct { unsigned long pgd; } pgd_t; | 
 | 139 | #define pgd_val(x)	((x).pgd) | 
 | 140 | #define __pgd(x)	((pgd_t) { (x) }) | 
 | 141 |  | 
 | 142 | /* Page protection bits */ | 
 | 143 | typedef struct { unsigned long pgprot; } pgprot_t; | 
 | 144 | #define pgprot_val(x)	((x).pgprot) | 
 | 145 | #define __pgprot(x)	((pgprot_t) { (x) }) | 
 | 146 |  | 
 | 147 | #else | 
 | 148 |  | 
 | 149 | /* | 
 | 150 |  * .. while these make it easier on the compiler | 
 | 151 |  */ | 
 | 152 |  | 
 | 153 | typedef pte_basic_t pte_t; | 
 | 154 | #define pte_val(x)	(x) | 
 | 155 | #define __pte(x)	(x) | 
 | 156 |  | 
 | 157 | #ifdef CONFIG_PPC_64K_PAGES | 
 | 158 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | 
 | 159 | #else | 
 | 160 | typedef unsigned long real_pte_t; | 
 | 161 | #endif | 
 | 162 |  | 
 | 163 |  | 
| David Gibson | d1953c8 | 2007-05-08 12:46:49 +1000 | [diff] [blame] | 164 | #ifdef CONFIG_PPC64 | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 165 | typedef unsigned long pmd_t; | 
 | 166 | #define pmd_val(x)	(x) | 
 | 167 | #define __pmd(x)	(x) | 
 | 168 |  | 
| David Gibson | d1953c8 | 2007-05-08 12:46:49 +1000 | [diff] [blame] | 169 | #ifndef CONFIG_PPC_64K_PAGES | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 170 | typedef unsigned long pud_t; | 
 | 171 | #define pud_val(x)	(x) | 
 | 172 | #define __pud(x)	(x) | 
| David Gibson | d1953c8 | 2007-05-08 12:46:49 +1000 | [diff] [blame] | 173 | #endif /* !CONFIG_PPC_64K_PAGES */ | 
 | 174 | #endif /* CONFIG_PPC64 */ | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 175 |  | 
 | 176 | typedef unsigned long pgd_t; | 
 | 177 | #define pgd_val(x)	(x) | 
 | 178 | #define pgprot_val(x)	(x) | 
 | 179 |  | 
 | 180 | typedef unsigned long pgprot_t; | 
 | 181 | #define __pgd(x)	(x) | 
 | 182 | #define __pgprot(x)	(x) | 
 | 183 |  | 
 | 184 | #endif | 
 | 185 |  | 
 | 186 | struct page; | 
 | 187 | extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); | 
 | 188 | extern void copy_user_page(void *to, void *from, unsigned long vaddr, | 
 | 189 | 		struct page *p); | 
 | 190 | extern int page_is_ram(unsigned long pfn); | 
 | 191 |  | 
| Benjamin Herrenschmidt | a5bba93 | 2006-05-30 13:51:37 +1000 | [diff] [blame] | 192 | struct vm_area_struct; | 
| Benjamin Herrenschmidt | a5bba93 | 2006-05-30 13:51:37 +1000 | [diff] [blame] | 193 |  | 
| KAMEZAWA Hiroyuki | 659e350 | 2006-03-27 01:15:35 -0800 | [diff] [blame] | 194 | #include <asm-generic/memory_model.h> | 
| Michael Ellerman | 5cd16ee | 2005-11-11 14:25:24 +1100 | [diff] [blame] | 195 | #endif /* __ASSEMBLY__ */ | 
 | 196 |  | 
 | 197 | #endif /* __KERNEL__ */ | 
 | 198 |  | 
 | 199 | #endif /* _ASM_POWERPC_PAGE_H */ |