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