| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef _M68K_PAGE_H | 
|  | 2 | #define _M68K_PAGE_H | 
|  | 3 |  | 
| Geert Uytterhoeven | 42b3592 | 2007-08-22 14:01:32 -0700 | [diff] [blame] | 4 | #include <linux/const.h> | 
|  | 5 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 | /* PAGE_SHIFT determines the page size */ | 
|  | 7 | #ifndef CONFIG_SUN3 | 
|  | 8 | #define PAGE_SHIFT	(12) | 
|  | 9 | #else | 
|  | 10 | #define PAGE_SHIFT	(13) | 
|  | 11 | #endif | 
| Geert Uytterhoeven | 42b3592 | 2007-08-22 14:01:32 -0700 | [diff] [blame] | 12 | #define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 13 | #define PAGE_MASK	(~(PAGE_SIZE-1)) | 
|  | 14 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 | #include <asm/setup.h> | 
|  | 16 |  | 
|  | 17 | #if PAGE_SHIFT < 13 | 
|  | 18 | #define THREAD_SIZE (8192) | 
|  | 19 | #else | 
|  | 20 | #define THREAD_SIZE PAGE_SIZE | 
|  | 21 | #endif | 
|  | 22 |  | 
|  | 23 | #ifndef __ASSEMBLY__ | 
|  | 24 |  | 
| Geert Uytterhoeven | 4f85589 | 2007-08-22 14:01:29 -0700 | [diff] [blame] | 25 | #include <linux/compiler.h> | 
|  | 26 |  | 
| Roman Zippel | fbe9c96 | 2007-05-31 00:40:50 -0700 | [diff] [blame] | 27 | #include <asm/module.h> | 
|  | 28 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 29 | #define get_user_page(vaddr)		__get_free_page(GFP_KERNEL) | 
|  | 30 | #define free_user_page(page, addr)	free_page(addr) | 
|  | 31 |  | 
|  | 32 | /* | 
|  | 33 | * We don't need to check for alignment etc. | 
|  | 34 | */ | 
|  | 35 | #ifdef CPU_M68040_OR_M68060_ONLY | 
|  | 36 | static inline void copy_page(void *to, void *from) | 
|  | 37 | { | 
|  | 38 | unsigned long tmp; | 
|  | 39 |  | 
|  | 40 | __asm__ __volatile__("1:\t" | 
|  | 41 | ".chip 68040\n\t" | 
|  | 42 | "move16 %1@+,%0@+\n\t" | 
|  | 43 | "move16 %1@+,%0@+\n\t" | 
|  | 44 | ".chip 68k\n\t" | 
|  | 45 | "dbra  %2,1b\n\t" | 
|  | 46 | : "=a" (to), "=a" (from), "=d" (tmp) | 
|  | 47 | : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1) | 
|  | 48 | ); | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | static inline void clear_page(void *page) | 
|  | 52 | { | 
|  | 53 | unsigned long tmp; | 
|  | 54 | unsigned long *sp = page; | 
|  | 55 |  | 
|  | 56 | *sp++ = 0; | 
|  | 57 | *sp++ = 0; | 
|  | 58 | *sp++ = 0; | 
|  | 59 | *sp++ = 0; | 
|  | 60 |  | 
|  | 61 | __asm__ __volatile__("1:\t" | 
|  | 62 | ".chip 68040\n\t" | 
|  | 63 | "move16 %2@+,%0@+\n\t" | 
|  | 64 | ".chip 68k\n\t" | 
|  | 65 | "subqw  #8,%2\n\t" | 
|  | 66 | "subqw  #8,%2\n\t" | 
|  | 67 | "dbra   %1,1b\n\t" | 
|  | 68 | : "=a" (sp), "=d" (tmp) | 
|  | 69 | : "a" (page), "0" (sp), | 
|  | 70 | "1" ((PAGE_SIZE - 16) / 16 - 1)); | 
|  | 71 | } | 
|  | 72 |  | 
|  | 73 | #else | 
|  | 74 | #define clear_page(page)	memset((page), 0, PAGE_SIZE) | 
|  | 75 | #define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE) | 
|  | 76 | #endif | 
|  | 77 |  | 
|  | 78 | #define clear_user_page(addr, vaddr, page)	\ | 
|  | 79 | do {	clear_page(addr);		\ | 
|  | 80 | flush_dcache_page(page);	\ | 
|  | 81 | } while (0) | 
|  | 82 | #define copy_user_page(to, from, vaddr, page)	\ | 
|  | 83 | do {	copy_page(to, from);		\ | 
|  | 84 | flush_dcache_page(page);	\ | 
|  | 85 | } while (0) | 
|  | 86 |  | 
|  | 87 | /* | 
|  | 88 | * These are used to make use of C type-checking.. | 
|  | 89 | */ | 
|  | 90 | typedef struct { unsigned long pte; } pte_t; | 
|  | 91 | typedef struct { unsigned long pmd[16]; } pmd_t; | 
|  | 92 | typedef struct { unsigned long pgd; } pgd_t; | 
|  | 93 | typedef struct { unsigned long pgprot; } pgprot_t; | 
| Martin Schwidefsky | 2f569af | 2008-02-08 04:22:04 -0800 | [diff] [blame] | 94 | typedef struct page *pgtable_t; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 95 |  | 
|  | 96 | #define pte_val(x)	((x).pte) | 
|  | 97 | #define pmd_val(x)	((&x)->pmd[0]) | 
|  | 98 | #define pgd_val(x)	((x).pgd) | 
|  | 99 | #define pgprot_val(x)	((x).pgprot) | 
|  | 100 |  | 
|  | 101 | #define __pte(x)	((pte_t) { (x) } ) | 
|  | 102 | #define __pmd(x)	((pmd_t) { (x) } ) | 
|  | 103 | #define __pgd(x)	((pgd_t) { (x) } ) | 
|  | 104 | #define __pgprot(x)	((pgprot_t) { (x) } ) | 
|  | 105 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 106 | #endif /* !__ASSEMBLY__ */ | 
|  | 107 |  | 
|  | 108 | #include <asm/page_offset.h> | 
|  | 109 |  | 
|  | 110 | #define PAGE_OFFSET		(PAGE_OFFSET_RAW) | 
|  | 111 |  | 
|  | 112 | #ifndef __ASSEMBLY__ | 
|  | 113 |  | 
| Roman Zippel | fbe9c96 | 2007-05-31 00:40:50 -0700 | [diff] [blame] | 114 | extern unsigned long m68k_memoffset; | 
|  | 115 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 116 | #ifndef CONFIG_SUN3 | 
|  | 117 |  | 
|  | 118 | #define WANT_PAGE_VIRTUAL | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 119 |  | 
| Roman Zippel | fbe9c96 | 2007-05-31 00:40:50 -0700 | [diff] [blame] | 120 | static inline unsigned long ___pa(void *vaddr) | 
|  | 121 | { | 
|  | 122 | unsigned long paddr; | 
|  | 123 | asm ( | 
|  | 124 | "1:	addl #0,%0\n" | 
|  | 125 | m68k_fixup(%c2, 1b+2) | 
|  | 126 | : "=r" (paddr) | 
|  | 127 | : "0" (vaddr), "i" (m68k_fixup_memoffset)); | 
|  | 128 | return paddr; | 
|  | 129 | } | 
| Roman Zippel | 12d810c | 2007-05-31 00:40:54 -0700 | [diff] [blame] | 130 | #define __pa(vaddr)	___pa((void *)(vaddr)) | 
| Roman Zippel | fbe9c96 | 2007-05-31 00:40:50 -0700 | [diff] [blame] | 131 | static inline void *__va(unsigned long paddr) | 
|  | 132 | { | 
|  | 133 | void *vaddr; | 
|  | 134 | asm ( | 
|  | 135 | "1:	subl #0,%0\n" | 
|  | 136 | m68k_fixup(%c2, 1b+2) | 
|  | 137 | : "=r" (vaddr) | 
|  | 138 | : "0" (paddr), "i" (m68k_fixup_memoffset)); | 
|  | 139 | return vaddr; | 
|  | 140 | } | 
|  | 141 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 142 | #else	/* !CONFIG_SUN3 */ | 
|  | 143 | /* This #define is a horrible hack to suppress lots of warnings. --m */ | 
| Andreas Schwab | 40bb0c3 | 2005-08-24 17:36:21 +0200 | [diff] [blame] | 144 | #define __pa(x) ___pa((unsigned long)(x)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 145 | static inline unsigned long ___pa(unsigned long x) | 
|  | 146 | { | 
|  | 147 | if(x == 0) | 
|  | 148 | return 0; | 
|  | 149 | if(x >= PAGE_OFFSET) | 
|  | 150 | return (x-PAGE_OFFSET); | 
|  | 151 | else | 
|  | 152 | return (x+0x2000000); | 
|  | 153 | } | 
|  | 154 |  | 
|  | 155 | static inline void *__va(unsigned long x) | 
|  | 156 | { | 
|  | 157 | if(x == 0) | 
|  | 158 | return (void *)0; | 
|  | 159 |  | 
|  | 160 | if(x < 0x2000000) | 
|  | 161 | return (void *)(x+PAGE_OFFSET); | 
|  | 162 | else | 
|  | 163 | return (void *)(x-0x2000000); | 
|  | 164 | } | 
|  | 165 | #endif	/* CONFIG_SUN3 */ | 
|  | 166 |  | 
|  | 167 | /* | 
|  | 168 | * NOTE: virtual isn't really correct, actually it should be the offset into the | 
|  | 169 | * memory node, but we have no highmem, so that works for now. | 
|  | 170 | * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots | 
|  | 171 | * of the shifts unnecessary. | 
|  | 172 | */ | 
|  | 173 | #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT) | 
|  | 174 | #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT) | 
|  | 175 |  | 
| Roman Zippel | 12d810c | 2007-05-31 00:40:54 -0700 | [diff] [blame] | 176 | extern int m68k_virt_to_node_shift; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 177 |  | 
| Roman Zippel | 12d810c | 2007-05-31 00:40:54 -0700 | [diff] [blame] | 178 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK | 
|  | 179 | #define __virt_to_node(addr)	(&pg_data_map[0]) | 
|  | 180 | #else | 
|  | 181 | extern struct pglist_data *pg_data_table[]; | 
|  | 182 |  | 
|  | 183 | static inline __attribute_const__ int __virt_to_node_shift(void) | 
|  | 184 | { | 
|  | 185 | int shift; | 
|  | 186 |  | 
|  | 187 | asm ( | 
|  | 188 | "1:	moveq	#0,%0\n" | 
|  | 189 | m68k_fixup(%c1, 1b) | 
|  | 190 | : "=d" (shift) | 
|  | 191 | : "i" (m68k_fixup_vnode_shift)); | 
|  | 192 | return shift; | 
|  | 193 | } | 
|  | 194 |  | 
|  | 195 | #define __virt_to_node(addr)	(pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()]) | 
|  | 196 | #endif | 
|  | 197 |  | 
|  | 198 | #define virt_to_page(addr) ({						\ | 
|  | 199 | pfn_to_page(virt_to_pfn(addr));					\ | 
|  | 200 | }) | 
|  | 201 | #define page_to_virt(page) ({						\ | 
|  | 202 | pfn_to_virt(page_to_pfn(page));					\ | 
|  | 203 | }) | 
|  | 204 |  | 
|  | 205 | #define pfn_to_page(pfn) ({						\ | 
|  | 206 | unsigned long __pfn = (pfn);					\ | 
|  | 207 | struct pglist_data *pgdat;					\ | 
|  | 208 | pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn));	\ | 
|  | 209 | pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn);		\ | 
|  | 210 | }) | 
|  | 211 | #define page_to_pfn(_page) ({						\ | 
|  | 212 | struct page *__p = (_page);					\ | 
|  | 213 | struct pglist_data *pgdat;					\ | 
|  | 214 | pgdat = &pg_data_map[page_to_nid(__p)];				\ | 
|  | 215 | ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn;		\ | 
|  | 216 | }) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 217 |  | 
|  | 218 | #define virt_addr_valid(kaddr)	((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory) | 
|  | 219 | #define pfn_valid(pfn)		virt_addr_valid(pfn_to_virt(pfn)) | 
|  | 220 |  | 
|  | 221 | #endif /* __ASSEMBLY__ */ | 
|  | 222 |  | 
|  | 223 | #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \ | 
|  | 224 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 
|  | 225 |  | 
| Stephen Rothwell | fd4fd5a | 2005-09-03 15:54:30 -0700 | [diff] [blame] | 226 | #include <asm-generic/page.h> | 
|  | 227 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 228 | #endif /* _M68K_PAGE_H */ |