1 #ifndef _PPC64_PAGE_H
2 #define _PPC64_PAGE_H
3
4 /*
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
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 #include <linux/config.h>
14
15 /* PAGE_SHIFT determines the page size */
16 #define PAGE_SHIFT 12
17 #ifndef __ASSEMBLY__
18 #define PAGE_SIZE (1UL << PAGE_SHIFT)
19 #else
20 # define PAGE_SIZE (1 << PAGE_SHIFT)
21 #endif
22 #define PAGE_MASK (~(PAGE_SIZE-1))
23 #define PAGE_OFFSET_MASK (PAGE_SIZE-1)
24
25 #define SID_SHIFT 28
26 #define SID_MASK 0xfffffffff
27 #define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK)
28
29 /* Define an illegal instr to trap on the bug.
30 * We don't use 0 because that marks the end of a function
31 * in the ELF ABI. That's "Boo Boo" in case you wonder...
32 */
33 #define BUG_OPCODE .long 0x00b00b00 /* For asm */
34 #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
35
36 #ifdef __KERNEL__
37 #ifndef __ASSEMBLY__
38 #include <asm/naca.h>
39 #include <asm/systemcfg.h>
40
41 #define STRICT_MM_TYPECHECKS
42
43 #define REGION_SIZE 4UL
44 #define OFFSET_SIZE 60UL
45 #define REGION_SHIFT 60UL
46 #define OFFSET_SHIFT 0UL
47 #define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
48 #define REGION_STRIDE (1UL << REGION_SHIFT)
49
50 #ifdef ___powerpc64__
51 typedef union ppc64_va {
52 struct {
53 unsigned long off : OFFSET_SIZE; /* intra-region offset */
54 unsigned long reg : REGION_SIZE; /* region number */
55 } f;
56 unsigned long l;
57 void *p;
58 } ppc64_va;
59 #endif /* ___powerpc64__ */
60
clear_page(void * addr)61 static __inline__ void clear_page(void *addr)
62 {
63 unsigned long lines, line_size;
64
65 line_size = systemcfg->dCacheL1LineSize;
66 lines = naca->dCacheL1LinesPerPage;
67
68 __asm__ __volatile__(
69 " mtctr %1\n\
70 1: dcbz 0,%0\n\
71 add %0,%0,%3\n\
72 bdnz+ 1b"
73 : "=r" (addr)
74 : "r" (lines), "0" (addr), "r" (line_size)
75 : "ctr", "memory");
76 }
77
78 extern void copy_page(void *to, void *from);
79 struct page;
80 extern void clear_user_page(void *page, unsigned long vaddr);
81 extern void copy_user_page(void *to, void *from, unsigned long vaddr);
82
83 #ifdef STRICT_MM_TYPECHECKS
84 /*
85 * These are used to make use of C type-checking.
86 * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b.
87 */
88 typedef struct { unsigned long pte; } pte_t;
89 typedef struct { unsigned int pmd; } pmd_t;
90 typedef struct { unsigned int pgd; } pgd_t;
91 typedef struct { unsigned long pgprot; } pgprot_t;
92
93 #define pte_val(x) ((x).pte)
94 #define pmd_val(x) ((x).pmd)
95 #define pgd_val(x) ((x).pgd)
96 #define pgprot_val(x) ((x).pgprot)
97
98 #define __pte(x) ((pte_t) { (x) } )
99 #define __pmd(x) ((pmd_t) { (x) } )
100 #define __pgd(x) ((pgd_t) { (x) } )
101 #define __pgprot(x) ((pgprot_t) { (x) } )
102
103 #else
104 /*
105 * .. while these make it easier on the compiler
106 */
107 typedef unsigned long pte_t;
108 typedef unsigned int pmd_t;
109 typedef unsigned int pgd_t;
110 typedef unsigned long pgprot_t;
111
112 #define pte_val(x) (x)
113 #define pmd_val(x) (x)
114 #define pgd_val(x) (x)
115 #define pgprot_val(x) (x)
116
117 #define __pte(x) (x)
118 #define __pmd(x) (x)
119 #define __pgd(x) (x)
120 #define __pgprot(x) (x)
121
122 #endif
123
124 #ifdef CONFIG_XMON
125 #include <asm/ptrace.h>
126 extern void xmon(struct pt_regs *excp);
127 #define BUG() do { \
128 printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
129 xmon(0); \
130 } while (0)
131 #else
132 #define BUG() do { \
133 printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
134 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
135 } while (0)
136 #endif
137
138 #define PAGE_BUG(page) do { BUG(); } while (0)
139
140 /* Pure 2^n version of get_order */
get_order(unsigned long size)141 static inline int get_order(unsigned long size)
142 {
143 int order;
144
145 size = (size-1) >> (PAGE_SHIFT-1);
146 order = -1;
147 do {
148 size >>= 1;
149 order++;
150 } while (size);
151 return order;
152 }
153
154 #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
155
156 #endif /* __ASSEMBLY__ */
157
158 /* align addr on a size boundry - adjust address up/down if needed */
159 #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
160 #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
161
162 /* align addr on a size boundry - adjust address up if needed */
163 #define _ALIGN(addr,size) _ALIGN_UP(addr,size)
164
165 /* to align the pointer to the (next) double word boundary */
166 #define DOUBLEWORD_ALIGN(addr) _ALIGN(addr,sizeof(unsigned long))
167
168 /* to align the pointer to the (next) page boundary */
169 #define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
170
171 #ifdef MODULE
172 #define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
173 #else
174 #define __page_aligned \
175 __attribute__((__aligned__(PAGE_SIZE), \
176 __section__(".data.page_aligned")))
177 #endif
178
179
180 /* This must match the -Ttext linker address */
181 /* Note: tophys & tovirt make assumptions about how */
182 /* KERNELBASE is defined for performance reasons. */
183 /* When KERNELBASE moves, those macros may have */
184 /* to change! */
185 #define PAGE_OFFSET 0xC000000000000000
186 #define KERNELBASE PAGE_OFFSET
187 #define VMALLOCBASE 0xD000000000000000
188 #define IOREGIONBASE 0xE000000000000000
189 #define EEHREGIONBASE 0xA000000000000000
190 #define BOLTEDBASE 0xB000000000000000
191
192 #define IO_REGION_ID (IOREGIONBASE>>REGION_SHIFT)
193 #define EEH_REGION_ID (EEHREGIONBASE>>REGION_SHIFT)
194 #define VMALLOC_REGION_ID (VMALLOCBASE>>REGION_SHIFT)
195 #define KERNEL_REGION_ID (KERNELBASE>>REGION_SHIFT)
196 #define BOLTED_REGION_ID (BOLTEDBASE>>REGION_SHIFT)
197 #define USER_REGION_ID (0UL)
198 #define REGION_ID(X) (((unsigned long)(X))>>REGION_SHIFT)
199
200 /*
201 * Define valid/invalid EA bits (for all ranges)
202 */
203 #define VALID_EA_BITS (0x000001ffffffffffUL)
204 #define INVALID_EA_BITS (~(REGION_MASK|VALID_EA_BITS))
205
206 #define IS_VALID_REGION_ID(x) \
207 (((x) == USER_REGION_ID) || ((x) >= BOLTED_REGION_ID))
208 #define IS_VALID_EA(x) \
209 ((!((x) & INVALID_EA_BITS)) && IS_VALID_REGION_ID(REGION_ID(x)))
210
211 #define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE)
212 #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT)
213
214 #define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
215
216 /* Given that physical addresses do not map 1-1 to absolute addresses, we
217 * use these macros to better specify exactly what we want to do.
218 * The only restriction on their use is that the absolute address
219 * macros cannot be used until after the LMB structure has been
220 * initialized in prom.c. -Peter
221 */
222 #define __v2p(x) ((void *) __pa(x))
223 #define __v2a(x) ((void *) phys_to_absolute(__pa(x)))
224 #define __p2a(x) ((void *) phys_to_absolute(x))
225 #define __p2v(x) ((void *) __va(x))
226 #define __a2p(x) ((void *) absolute_to_phys(x))
227 #define __a2v(x) ((void *) __va(absolute_to_phys(x)))
228
229 #define virt_to_page(kaddr) (mem_map+(__pa((unsigned long)kaddr) >> PAGE_SHIFT))
230
231 #define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
232
233 #define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
234
235 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
236 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
237
238 #endif /* __KERNEL__ */
239 #endif /* _PPC64_PAGE_H */
240