aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-ppc64
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-ppc64')
-rw-r--r--include/asm-ppc64/a.out.h2
-rw-r--r--include/asm-ppc64/bug.h7
-rw-r--r--include/asm-ppc64/elf.h8
-rw-r--r--include/asm-ppc64/imalloc.h24
-rw-r--r--include/asm-ppc64/mmu.h193
-rw-r--r--include/asm-ppc64/mmu_context.h82
-rw-r--r--include/asm-ppc64/page.h30
-rw-r--r--include/asm-ppc64/pgalloc.h2
-rw-r--r--include/asm-ppc64/pgtable.h156
-rw-r--r--include/asm-ppc64/signal.h33
-rw-r--r--include/asm-ppc64/spinlock.h8
-rw-r--r--include/asm-ppc64/xics.h3
12 files changed, 256 insertions, 292 deletions
diff --git a/include/asm-ppc64/a.out.h b/include/asm-ppc64/a.out.h
index 802338efcb19..3871e252a6f1 100644
--- a/include/asm-ppc64/a.out.h
+++ b/include/asm-ppc64/a.out.h
@@ -1,8 +1,6 @@
1#ifndef __PPC64_A_OUT_H__ 1#ifndef __PPC64_A_OUT_H__
2#define __PPC64_A_OUT_H__ 2#define __PPC64_A_OUT_H__
3 3
4#include <asm/ppcdebug.h>
5
6/* 4/*
7 * c 2001 PPC 64 Team, IBM Corp 5 * c 2001 PPC 64 Team, IBM Corp
8 * 6 *
diff --git a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h
index db31dd22233c..169868fa307d 100644
--- a/include/asm-ppc64/bug.h
+++ b/include/asm-ppc64/bug.h
@@ -26,6 +26,8 @@ struct bug_entry *find_bug(unsigned long bugaddr);
26 */ 26 */
27#define BUG_WARNING_TRAP 0x1000000 27#define BUG_WARNING_TRAP 0x1000000
28 28
29#ifdef CONFIG_BUG
30
29#define BUG() do { \ 31#define BUG() do { \
30 __asm__ __volatile__( \ 32 __asm__ __volatile__( \
31 "1: twi 31,0,0\n" \ 33 "1: twi 31,0,0\n" \
@@ -55,11 +57,12 @@ struct bug_entry *find_bug(unsigned long bugaddr);
55 "i" (__FILE__), "i" (__FUNCTION__)); \ 57 "i" (__FILE__), "i" (__FUNCTION__)); \
56} while (0) 58} while (0)
57 59
58#endif
59
60#define HAVE_ARCH_BUG 60#define HAVE_ARCH_BUG
61#define HAVE_ARCH_BUG_ON 61#define HAVE_ARCH_BUG_ON
62#define HAVE_ARCH_WARN_ON 62#define HAVE_ARCH_WARN_ON
63#endif
64#endif
65
63#include <asm-generic/bug.h> 66#include <asm-generic/bug.h>
64 67
65#endif 68#endif
diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
index 8457d90244fb..6c42d61bedd1 100644
--- a/include/asm-ppc64/elf.h
+++ b/include/asm-ppc64/elf.h
@@ -229,9 +229,13 @@ do { \
229 229
230/* 230/*
231 * An executable for which elf_read_implies_exec() returns TRUE will 231 * An executable for which elf_read_implies_exec() returns TRUE will
232 * have the READ_IMPLIES_EXEC personality flag set automatically. 232 * have the READ_IMPLIES_EXEC personality flag set automatically. This
233 * is only required to work around bugs in old 32bit toolchains. Since
234 * the 64bit ABI has never had these issues dont enable the workaround
235 * even if we have an executable stack.
233 */ 236 */
234#define elf_read_implies_exec(ex, exec_stk) (exec_stk != EXSTACK_DISABLE_X) 237#define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
238 (exec_stk != EXSTACK_DISABLE_X) : 0)
235 239
236#endif 240#endif
237 241
diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h
new file mode 100644
index 000000000000..3a45e918bf16
--- /dev/null
+++ b/include/asm-ppc64/imalloc.h
@@ -0,0 +1,24 @@
1#ifndef _PPC64_IMALLOC_H
2#define _PPC64_IMALLOC_H
3
4/*
5 * Define the address range of the imalloc VM area.
6 */
7#define PHBS_IO_BASE IOREGIONBASE
8#define IMALLOC_BASE (IOREGIONBASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
9#define IMALLOC_END (IOREGIONBASE + EADDR_MASK)
10
11
12/* imalloc region types */
13#define IM_REGION_UNUSED 0x1
14#define IM_REGION_SUBSET 0x2
15#define IM_REGION_EXISTS 0x4
16#define IM_REGION_OVERLAP 0x8
17#define IM_REGION_SUPERSET 0x10
18
19extern struct vm_struct * im_get_free_area(unsigned long size);
20extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
21 int region_type);
22unsigned long im_free(void *addr);
23
24#endif /* _PPC64_IMALLOC_H */
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index 188987e9d9d4..c78282a67d8e 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -15,19 +15,10 @@
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <asm/page.h> 17#include <asm/page.h>
18#include <linux/stringify.h>
19 18
20#ifndef __ASSEMBLY__ 19/*
21 20 * Segment table
22/* Time to allow for more things here */ 21 */
23typedef unsigned long mm_context_id_t;
24typedef struct {
25 mm_context_id_t id;
26#ifdef CONFIG_HUGETLB_PAGE
27 pgd_t *huge_pgdir;
28 u16 htlb_segs; /* bitmask */
29#endif
30} mm_context_t;
31 22
32#define STE_ESID_V 0x80 23#define STE_ESID_V 0x80
33#define STE_ESID_KS 0x20 24#define STE_ESID_KS 0x20
@@ -36,15 +27,48 @@ typedef struct {
36 27
37#define STE_VSID_SHIFT 12 28#define STE_VSID_SHIFT 12
38 29
39struct stab_entry { 30/* Location of cpu0's segment table */
40 unsigned long esid_data; 31#define STAB0_PAGE 0x9
41 unsigned long vsid_data; 32#define STAB0_PHYS_ADDR (STAB0_PAGE<<PAGE_SHIFT)
42}; 33#define STAB0_VIRT_ADDR (KERNELBASE+STAB0_PHYS_ADDR)
34
35/*
36 * SLB
37 */
43 38
44/* Hardware Page Table Entry */ 39#define SLB_NUM_BOLTED 3
40#define SLB_CACHE_ENTRIES 8
41
42/* Bits in the SLB ESID word */
43#define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */
44
45/* Bits in the SLB VSID word */
46#define SLB_VSID_SHIFT 12
47#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
48#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
49#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */
50#define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage 16M */
51#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */
52
53#define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C)
54#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS)
55
56/*
57 * Hash table
58 */
45 59
46#define HPTES_PER_GROUP 8 60#define HPTES_PER_GROUP 8
47 61
62/* Values for PP (assumes Ks=0, Kp=1) */
63/* pp0 will always be 0 for linux */
64#define PP_RWXX 0 /* Supervisor read/write, User none */
65#define PP_RWRX 1 /* Supervisor read/write, User read */
66#define PP_RWRW 2 /* Supervisor read/write, User read/write */
67#define PP_RXRX 3 /* Supervisor read, User read */
68
69#ifndef __ASSEMBLY__
70
71/* Hardware Page Table Entry */
48typedef struct { 72typedef struct {
49 unsigned long avpn:57; /* vsid | api == avpn */ 73 unsigned long avpn:57; /* vsid | api == avpn */
50 unsigned long : 2; /* Software use */ 74 unsigned long : 2; /* Software use */
@@ -90,14 +114,6 @@ typedef struct {
90 } dw1; 114 } dw1;
91} HPTE; 115} HPTE;
92 116
93/* Values for PP (assumes Ks=0, Kp=1) */
94/* pp0 will always be 0 for linux */
95#define PP_RWXX 0 /* Supervisor read/write, User none */
96#define PP_RWRX 1 /* Supervisor read/write, User read */
97#define PP_RWRW 2 /* Supervisor read/write, User read/write */
98#define PP_RXRX 3 /* Supervisor read, User read */
99
100
101extern HPTE * htab_address; 117extern HPTE * htab_address;
102extern unsigned long htab_hash_mask; 118extern unsigned long htab_hash_mask;
103 119
@@ -174,31 +190,70 @@ extern int __hash_page(unsigned long ea, unsigned long access,
174 190
175extern void htab_finish_init(void); 191extern void htab_finish_init(void);
176 192
193extern void hpte_init_native(void);
194extern void hpte_init_lpar(void);
195extern void hpte_init_iSeries(void);
196
197extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
198 unsigned long va, unsigned long prpn,
199 int secondary, unsigned long hpteflags,
200 int bolted, int large);
201extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
202 unsigned long prpn, int secondary,
203 unsigned long hpteflags, int bolted, int large);
204
177#endif /* __ASSEMBLY__ */ 205#endif /* __ASSEMBLY__ */
178 206
179/* 207/*
180 * Location of cpu0's segment table 208 * VSID allocation
209 *
210 * We first generate a 36-bit "proto-VSID". For kernel addresses this
211 * is equal to the ESID, for user addresses it is:
212 * (context << 15) | (esid & 0x7fff)
213 *
214 * The two forms are distinguishable because the top bit is 0 for user
215 * addresses, whereas the top two bits are 1 for kernel addresses.
216 * Proto-VSIDs with the top two bits equal to 0b10 are reserved for
217 * now.
218 *
219 * The proto-VSIDs are then scrambled into real VSIDs with the
220 * multiplicative hash:
221 *
222 * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
223 * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7
224 * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF
225 *
226 * This scramble is only well defined for proto-VSIDs below
227 * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are
228 * reserved. VSID_MULTIPLIER is prime, so in particular it is
229 * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
230 * Because the modulus is 2^n-1 we can compute it efficiently without
231 * a divide or extra multiply (see below).
232 *
233 * This scheme has several advantages over older methods:
234 *
235 * - We have VSIDs allocated for every kernel address
236 * (i.e. everything above 0xC000000000000000), except the very top
237 * segment, which simplifies several things.
238 *
239 * - We allow for 15 significant bits of ESID and 20 bits of
240 * context for user addresses. i.e. 8T (43 bits) of address space for
241 * up to 1M contexts (although the page table structure and context
242 * allocation will need changes to take advantage of this).
243 *
244 * - The scramble function gives robust scattering in the hash
245 * table (at least based on some initial results). The previous
246 * method was more susceptible to pathological cases giving excessive
247 * hash collisions.
248 */
249/*
250 * WARNING - If you change these you must make sure the asm
251 * implementations in slb_allocate (slb_low.S), do_stab_bolted
252 * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly.
253 *
254 * You'll also need to change the precomputed VSID values in head.S
255 * which are used by the iSeries firmware.
181 */ 256 */
182#define STAB0_PAGE 0x9
183#define STAB0_PHYS_ADDR (STAB0_PAGE<<PAGE_SHIFT)
184#define STAB0_VIRT_ADDR (KERNELBASE+STAB0_PHYS_ADDR)
185
186#define SLB_NUM_BOLTED 3
187#define SLB_CACHE_ENTRIES 8
188
189/* Bits in the SLB ESID word */
190#define SLB_ESID_V 0x0000000008000000 /* entry is valid */
191
192/* Bits in the SLB VSID word */
193#define SLB_VSID_SHIFT 12
194#define SLB_VSID_KS 0x0000000000000800
195#define SLB_VSID_KP 0x0000000000000400
196#define SLB_VSID_N 0x0000000000000200 /* no-execute */
197#define SLB_VSID_L 0x0000000000000100 /* largepage (4M) */
198#define SLB_VSID_C 0x0000000000000080 /* class */
199
200#define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C)
201#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS)
202 257
203#define VSID_MULTIPLIER ASM_CONST(200730139) /* 28-bit prime */ 258#define VSID_MULTIPLIER ASM_CONST(200730139) /* 28-bit prime */
204#define VSID_BITS 36 259#define VSID_BITS 36
@@ -239,4 +294,50 @@ extern void htab_finish_init(void);
239 srdi rx,rx,VSID_BITS; /* extract 2^36 bit */ \ 294 srdi rx,rx,VSID_BITS; /* extract 2^36 bit */ \
240 add rt,rt,rx 295 add rt,rt,rx
241 296
297
298#ifndef __ASSEMBLY__
299
300typedef unsigned long mm_context_id_t;
301
302typedef struct {
303 mm_context_id_t id;
304#ifdef CONFIG_HUGETLB_PAGE
305 pgd_t *huge_pgdir;
306 u16 htlb_segs; /* bitmask */
307#endif
308} mm_context_t;
309
310
311static inline unsigned long vsid_scramble(unsigned long protovsid)
312{
313#if 0
314 /* The code below is equivalent to this function for arguments
315 * < 2^VSID_BITS, which is all this should ever be called
316 * with. However gcc is not clever enough to compute the
317 * modulus (2^n-1) without a second multiply. */
318 return ((protovsid * VSID_MULTIPLIER) % VSID_MODULUS);
319#else /* 1 */
320 unsigned long x;
321
322 x = protovsid * VSID_MULTIPLIER;
323 x = (x >> VSID_BITS) + (x & VSID_MODULUS);
324 return (x + ((x+1) >> VSID_BITS)) & VSID_MODULUS;
325#endif /* 1 */
326}
327
328/* This is only valid for addresses >= KERNELBASE */
329static inline unsigned long get_kernel_vsid(unsigned long ea)
330{
331 return vsid_scramble(ea >> SID_SHIFT);
332}
333
334/* This is only valid for user addresses (which are below 2^41) */
335static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
336{
337 return vsid_scramble((context << USER_ESID_BITS)
338 | (ea >> SID_SHIFT));
339}
340
341#endif /* __ASSEMBLY */
342
242#endif /* _PPC64_MMU_H_ */ 343#endif /* _PPC64_MMU_H_ */
diff --git a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h
index c2e8e0466383..77a743402db4 100644
--- a/include/asm-ppc64/mmu_context.h
+++ b/include/asm-ppc64/mmu_context.h
@@ -84,86 +84,4 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
84 local_irq_restore(flags); 84 local_irq_restore(flags);
85} 85}
86 86
87/* VSID allocation
88 * ===============
89 *
90 * We first generate a 36-bit "proto-VSID". For kernel addresses this
91 * is equal to the ESID, for user addresses it is:
92 * (context << 15) | (esid & 0x7fff)
93 *
94 * The two forms are distinguishable because the top bit is 0 for user
95 * addresses, whereas the top two bits are 1 for kernel addresses.
96 * Proto-VSIDs with the top two bits equal to 0b10 are reserved for
97 * now.
98 *
99 * The proto-VSIDs are then scrambled into real VSIDs with the
100 * multiplicative hash:
101 *
102 * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
103 * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7
104 * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF
105 *
106 * This scramble is only well defined for proto-VSIDs below
107 * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are
108 * reserved. VSID_MULTIPLIER is prime, so in particular it is
109 * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
110 * Because the modulus is 2^n-1 we can compute it efficiently without
111 * a divide or extra multiply (see below).
112 *
113 * This scheme has several advantages over older methods:
114 *
115 * - We have VSIDs allocated for every kernel address
116 * (i.e. everything above 0xC000000000000000), except the very top
117 * segment, which simplifies several things.
118 *
119 * - We allow for 15 significant bits of ESID and 20 bits of
120 * context for user addresses. i.e. 8T (43 bits) of address space for
121 * up to 1M contexts (although the page table structure and context
122 * allocation will need changes to take advantage of this).
123 *
124 * - The scramble function gives robust scattering in the hash
125 * table (at least based on some initial results). The previous
126 * method was more susceptible to pathological cases giving excessive
127 * hash collisions.
128 */
129
130/*
131 * WARNING - If you change these you must make sure the asm
132 * implementations in slb_allocate(), do_stab_bolted and mmu.h
133 * (ASM_VSID_SCRAMBLE macro) are changed accordingly.
134 *
135 * You'll also need to change the precomputed VSID values in head.S
136 * which are used by the iSeries firmware.
137 */
138
139static inline unsigned long vsid_scramble(unsigned long protovsid)
140{
141#if 0
142 /* The code below is equivalent to this function for arguments
143 * < 2^VSID_BITS, which is all this should ever be called
144 * with. However gcc is not clever enough to compute the
145 * modulus (2^n-1) without a second multiply. */
146 return ((protovsid * VSID_MULTIPLIER) % VSID_MODULUS);
147#else /* 1 */
148 unsigned long x;
149
150 x = protovsid * VSID_MULTIPLIER;
151 x = (x >> VSID_BITS) + (x & VSID_MODULUS);
152 return (x + ((x+1) >> VSID_BITS)) & VSID_MODULUS;
153#endif /* 1 */
154}
155
156/* This is only valid for addresses >= KERNELBASE */
157static inline unsigned long get_kernel_vsid(unsigned long ea)
158{
159 return vsid_scramble(ea >> SID_SHIFT);
160}
161
162/* This is only valid for user addresses (which are below 2^41) */
163static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
164{
165 return vsid_scramble((context << USER_ESID_BITS)
166 | (ea >> SID_SHIFT));
167}
168
169#endif /* __PPC64_MMU_CONTEXT_H */ 87#endif /* __PPC64_MMU_CONTEXT_H */
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
index 20e0f19324e8..bcd21789d3b7 100644
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -23,7 +23,6 @@
23#define PAGE_SHIFT 12 23#define PAGE_SHIFT 12
24#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) 24#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
25#define PAGE_MASK (~(PAGE_SIZE-1)) 25#define PAGE_MASK (~(PAGE_SIZE-1))
26#define PAGE_OFFSET_MASK (PAGE_SIZE-1)
27 26
28#define SID_SHIFT 28 27#define SID_SHIFT 28
29#define SID_MASK 0xfffffffffUL 28#define SID_MASK 0xfffffffffUL
@@ -85,9 +84,6 @@
85/* align addr on a size boundary - adjust address up if needed */ 84/* align addr on a size boundary - adjust address up if needed */
86#define _ALIGN(addr,size) _ALIGN_UP(addr,size) 85#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
87 86
88/* to align the pointer to the (next) double word boundary */
89#define DOUBLEWORD_ALIGN(addr) _ALIGN(addr,sizeof(unsigned long))
90
91/* to align the pointer to the (next) page boundary */ 87/* to align the pointer to the (next) page boundary */
92#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) 88#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
93 89
@@ -100,7 +96,6 @@
100#define REGION_SIZE 4UL 96#define REGION_SIZE 4UL
101#define REGION_SHIFT 60UL 97#define REGION_SHIFT 60UL
102#define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT) 98#define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
103#define REGION_STRIDE (1UL << REGION_SHIFT)
104 99
105static __inline__ void clear_page(void *addr) 100static __inline__ void clear_page(void *addr)
106{ 101{
@@ -209,13 +204,13 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */
209#define VMALLOCBASE ASM_CONST(0xD000000000000000) 204#define VMALLOCBASE ASM_CONST(0xD000000000000000)
210#define IOREGIONBASE ASM_CONST(0xE000000000000000) 205#define IOREGIONBASE ASM_CONST(0xE000000000000000)
211 206
212#define IO_REGION_ID (IOREGIONBASE>>REGION_SHIFT) 207#define IO_REGION_ID (IOREGIONBASE >> REGION_SHIFT)
213#define VMALLOC_REGION_ID (VMALLOCBASE>>REGION_SHIFT) 208#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT)
214#define KERNEL_REGION_ID (KERNELBASE>>REGION_SHIFT) 209#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT)
215#define USER_REGION_ID (0UL) 210#define USER_REGION_ID (0UL)
216#define REGION_ID(X) (((unsigned long)(X))>>REGION_SHIFT) 211#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
217 212
218#define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE) 213#define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + KERNELBASE)
219#define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT) 214#define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT)
220 215
221#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) 216#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
@@ -252,10 +247,19 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */
252 247
253/* 248/*
254 * This is the default if a program doesn't have a PT_GNU_STACK 249 * This is the default if a program doesn't have a PT_GNU_STACK
255 * program header entry. 250 * program header entry. The PPC64 ELF ABI has a non executable stack
251 * stack by default, so in the absense of a PT_GNU_STACK program header
252 * we turn execute permission off.
256 */ 253 */
257#define VM_STACK_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 254#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
258 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 255 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
256
257#define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
258 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
259
260#define VM_STACK_DEFAULT_FLAGS \
261 (test_thread_flag(TIF_32BIT) ? \
262 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
259 263
260#endif /* __KERNEL__ */ 264#endif /* __KERNEL__ */
261#endif /* _PPC64_PAGE_H */ 265#endif /* _PPC64_PAGE_H */
diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h
index 16232d740173..4fc4b739b380 100644
--- a/include/asm-ppc64/pgalloc.h
+++ b/include/asm-ppc64/pgalloc.h
@@ -27,7 +27,7 @@ pgd_free(pgd_t *pgd)
27 kmem_cache_free(zero_cache, pgd); 27 kmem_cache_free(zero_cache, pgd);
28} 28}
29 29
30#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) 30#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD)
31 31
32static inline pmd_t * 32static inline pmd_t *
33pmd_alloc_one(struct mm_struct *mm, unsigned long addr) 33pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
index a26120517c54..264c4f7993be 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -1,8 +1,6 @@
1#ifndef _PPC64_PGTABLE_H 1#ifndef _PPC64_PGTABLE_H
2#define _PPC64_PGTABLE_H 2#define _PPC64_PGTABLE_H
3 3
4#include <asm-generic/4level-fixup.h>
5
6/* 4/*
7 * This file contains the functions and defines necessary to modify and use 5 * This file contains the functions and defines necessary to modify and use
8 * the ppc64 hashed page table. 6 * the ppc64 hashed page table.
@@ -17,15 +15,7 @@
17#include <asm/tlbflush.h> 15#include <asm/tlbflush.h>
18#endif /* __ASSEMBLY__ */ 16#endif /* __ASSEMBLY__ */
19 17
20/* PMD_SHIFT determines what a second-level page table entry can map */ 18#include <asm-generic/pgtable-nopud.h>
21#define PMD_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3)
22#define PMD_SIZE (1UL << PMD_SHIFT)
23#define PMD_MASK (~(PMD_SIZE-1))
24
25/* PGDIR_SHIFT determines what a third-level page table entry can map */
26#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3) + (PAGE_SHIFT - 2))
27#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
28#define PGDIR_MASK (~(PGDIR_SIZE-1))
29 19
30/* 20/*
31 * Entries per page directory level. The PTE level must use a 64b record 21 * Entries per page directory level. The PTE level must use a 64b record
@@ -40,40 +30,30 @@
40#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) 30#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
41#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) 31#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
42 32
43#define USER_PTRS_PER_PGD (1024) 33/* PMD_SHIFT determines what a second-level page table entry can map */
44#define FIRST_USER_ADDRESS 0 34#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
35#define PMD_SIZE (1UL << PMD_SHIFT)
36#define PMD_MASK (~(PMD_SIZE-1))
45 37
46#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ 38/* PGDIR_SHIFT determines what a third-level page table entry can map */
47 PGD_INDEX_SIZE + PAGE_SHIFT) 39#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
40#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
41#define PGDIR_MASK (~(PGDIR_SIZE-1))
42
43#define FIRST_USER_ADDRESS 0
48 44
49/* 45/*
50 * Size of EA range mapped by our pagetables. 46 * Size of EA range mapped by our pagetables.
51 */ 47 */
52#define PGTABLE_EA_BITS 41 48#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
53#define PGTABLE_EA_MASK ((1UL<<PGTABLE_EA_BITS)-1) 49 PGD_INDEX_SIZE + PAGE_SHIFT)
50#define EADDR_MASK ((1UL << EADDR_SIZE) - 1)
54 51
55/* 52/*
56 * Define the address range of the vmalloc VM area. 53 * Define the address range of the vmalloc VM area.
57 */ 54 */
58#define VMALLOC_START (0xD000000000000000ul) 55#define VMALLOC_START (0xD000000000000000ul)
59#define VMALLOC_END (VMALLOC_START + PGTABLE_EA_MASK) 56#define VMALLOC_END (VMALLOC_START + EADDR_MASK)
60
61/*
62 * Define the address range of the imalloc VM area.
63 * (used for ioremap)
64 */
65#define IMALLOC_START (ioremap_bot)
66#define IMALLOC_VMADDR(x) ((unsigned long)(x))
67#define PHBS_IO_BASE (0xE000000000000000ul) /* Reserve 2 gigs for PHBs */
68#define IMALLOC_BASE (0xE000000080000000ul)
69#define IMALLOC_END (IMALLOC_BASE + PGTABLE_EA_MASK)
70
71/*
72 * Define the user address range
73 */
74#define USER_START (0UL)
75#define USER_END (USER_START + PGTABLE_EA_MASK)
76
77 57
78/* 58/*
79 * Bits in a linux-style PTE. These match the bits in the 59 * Bits in a linux-style PTE. These match the bits in the
@@ -168,10 +148,6 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
168/* shift to put page number into pte */ 148/* shift to put page number into pte */
169#define PTE_SHIFT (17) 149#define PTE_SHIFT (17)
170 150
171/* We allow 2^41 bytes of real memory, so we need 29 bits in the PMD
172 * to give the PTE page number. The bottom two bits are for flags. */
173#define PMD_TO_PTEPAGE_SHIFT (2)
174
175#ifdef CONFIG_HUGETLB_PAGE 151#ifdef CONFIG_HUGETLB_PAGE
176 152
177#ifndef __ASSEMBLY__ 153#ifndef __ASSEMBLY__
@@ -200,13 +176,14 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
200 */ 176 */
201#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) 177#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
202 178
203#define pfn_pte(pfn,pgprot) \ 179static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
204({ \ 180{
205 pte_t pte; \ 181 pte_t pte;
206 pte_val(pte) = ((unsigned long)(pfn) << PTE_SHIFT) | \ 182
207 pgprot_val(pgprot); \ 183
208 pte; \ 184 pte_val(pte) = (pfn << PTE_SHIFT) | pgprot_val(pgprot);
209}) 185 return pte;
186}
210 187
211#define pte_modify(_pte, newprot) \ 188#define pte_modify(_pte, newprot) \
212 (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))) 189 (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
@@ -220,20 +197,20 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
220#define pte_page(x) pfn_to_page(pte_pfn(x)) 197#define pte_page(x) pfn_to_page(pte_pfn(x))
221 198
222#define pmd_set(pmdp, ptep) \ 199#define pmd_set(pmdp, ptep) \
223 (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep) << PMD_TO_PTEPAGE_SHIFT)) 200 (pmd_val(*(pmdp)) = __ba_to_bpn(ptep))
224#define pmd_none(pmd) (!pmd_val(pmd)) 201#define pmd_none(pmd) (!pmd_val(pmd))
225#define pmd_bad(pmd) (pmd_val(pmd) == 0) 202#define pmd_bad(pmd) (pmd_val(pmd) == 0)
226#define pmd_present(pmd) (pmd_val(pmd) != 0) 203#define pmd_present(pmd) (pmd_val(pmd) != 0)
227#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) 204#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
228#define pmd_page_kernel(pmd) \ 205#define pmd_page_kernel(pmd) (__bpn_to_ba(pmd_val(pmd)))
229 (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT))
230#define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) 206#define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd))
231#define pgd_set(pgdp, pmdp) (pgd_val(*(pgdp)) = (__ba_to_bpn(pmdp))) 207
232#define pgd_none(pgd) (!pgd_val(pgd)) 208#define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (__ba_to_bpn(pmdp)))
233#define pgd_bad(pgd) ((pgd_val(pgd)) == 0) 209#define pud_none(pud) (!pud_val(pud))
234#define pgd_present(pgd) (pgd_val(pgd) != 0UL) 210#define pud_bad(pud) ((pud_val(pud)) == 0UL)
235#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) 211#define pud_present(pud) (pud_val(pud) != 0UL)
236#define pgd_page(pgd) (__bpn_to_ba(pgd_val(pgd))) 212#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
213#define pud_page(pud) (__bpn_to_ba(pud_val(pud)))
237 214
238/* 215/*
239 * Find an entry in a page-table-directory. We combine the address region 216 * Find an entry in a page-table-directory. We combine the address region
@@ -245,12 +222,13 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
245#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) 222#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
246 223
247/* Find an entry in the second-level page table.. */ 224/* Find an entry in the second-level page table.. */
248#define pmd_offset(dir,addr) \ 225#define pmd_offset(pudp,addr) \
249 ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) 226 ((pmd_t *) pud_page(*(pudp)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
250 227
251/* Find an entry in the third-level page table.. */ 228/* Find an entry in the third-level page table.. */
252#define pte_offset_kernel(dir,addr) \ 229#define pte_offset_kernel(dir,addr) \
253 ((pte_t *) pmd_page_kernel(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) 230 ((pte_t *) pmd_page_kernel(*(dir)) \
231 + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
254 232
255#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) 233#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
256#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) 234#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
@@ -264,8 +242,6 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
264/* to find an entry in the ioremap page-table-directory */ 242/* to find an entry in the ioremap page-table-directory */
265#define pgd_offset_i(address) (ioremap_pgd + pgd_index(address)) 243#define pgd_offset_i(address) (ioremap_pgd + pgd_index(address))
266 244
267#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
268
269/* 245/*
270 * The following only work if pte_present() is true. 246 * The following only work if pte_present() is true.
271 * Undefined behaviour if not.. 247 * Undefined behaviour if not..
@@ -440,7 +416,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
440 pte_clear(mm, addr, ptep); 416 pte_clear(mm, addr, ptep);
441 flush_tlb_pending(); 417 flush_tlb_pending();
442 } 418 }
443 *ptep = __pte(pte_val(pte)) & ~_PAGE_HPTEFLAGS; 419 *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
444} 420}
445 421
446/* Set the dirty and/or accessed bits atomically in a linux PTE, this 422/* Set the dirty and/or accessed bits atomically in a linux PTE, this
@@ -485,18 +461,13 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
485 461
486extern unsigned long ioremap_bot, ioremap_base; 462extern unsigned long ioremap_bot, ioremap_base;
487 463
488#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
489#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
490
491#define pte_ERROR(e) \
492 printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
493#define pmd_ERROR(e) \ 464#define pmd_ERROR(e) \
494 printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e)) 465 printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e))
495#define pgd_ERROR(e) \ 466#define pgd_ERROR(e) \
496 printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e)) 467 printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e))
497 468
498extern pgd_t swapper_pg_dir[1024]; 469extern pgd_t swapper_pg_dir[];
499extern pgd_t ioremap_dir[1024]; 470extern pgd_t ioremap_dir[];
500 471
501extern void paging_init(void); 472extern void paging_init(void);
502 473
@@ -538,43 +509,11 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
538 */ 509 */
539#define kern_addr_valid(addr) (1) 510#define kern_addr_valid(addr) (1)
540 511
541#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
542 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
543
544#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 512#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
545 remap_pfn_range(vma, vaddr, pfn, size, prot) 513 remap_pfn_range(vma, vaddr, pfn, size, prot)
546 514
547#define MK_IOSPACE_PFN(space, pfn) (pfn)
548#define GET_IOSPACE(pfn) 0
549#define GET_PFN(pfn) (pfn)
550
551void pgtable_cache_init(void); 515void pgtable_cache_init(void);
552 516
553extern void hpte_init_native(void);
554extern void hpte_init_lpar(void);
555extern void hpte_init_iSeries(void);
556
557/* imalloc region types */
558#define IM_REGION_UNUSED 0x1
559#define IM_REGION_SUBSET 0x2
560#define IM_REGION_EXISTS 0x4
561#define IM_REGION_OVERLAP 0x8
562#define IM_REGION_SUPERSET 0x10
563
564extern struct vm_struct * im_get_free_area(unsigned long size);
565extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
566 int region_type);
567unsigned long im_free(void *addr);
568
569extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
570 unsigned long va, unsigned long prpn,
571 int secondary, unsigned long hpteflags,
572 int bolted, int large);
573
574extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
575 unsigned long prpn, int secondary,
576 unsigned long hpteflags, int bolted, int large);
577
578/* 517/*
579 * find_linux_pte returns the address of a linux pte for a given 518 * find_linux_pte returns the address of a linux pte for a given
580 * effective address and directory. If not found, it returns zero. 519 * effective address and directory. If not found, it returns zero.
@@ -582,19 +521,22 @@ extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
582static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea) 521static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
583{ 522{
584 pgd_t *pg; 523 pgd_t *pg;
524 pud_t *pu;
585 pmd_t *pm; 525 pmd_t *pm;
586 pte_t *pt = NULL; 526 pte_t *pt = NULL;
587 pte_t pte; 527 pte_t pte;
588 528
589 pg = pgdir + pgd_index(ea); 529 pg = pgdir + pgd_index(ea);
590 if (!pgd_none(*pg)) { 530 if (!pgd_none(*pg)) {
591 531 pu = pud_offset(pg, ea);
592 pm = pmd_offset(pg, ea); 532 if (!pud_none(*pu)) {
593 if (pmd_present(*pm)) { 533 pm = pmd_offset(pu, ea);
594 pt = pte_offset_kernel(pm, ea); 534 if (pmd_present(*pm)) {
595 pte = *pt; 535 pt = pte_offset_kernel(pm, ea);
596 if (!pte_present(pte)) 536 pte = *pt;
597 pt = NULL; 537 if (!pte_present(pte))
538 pt = NULL;
539 }
598 } 540 }
599 } 541 }
600 542
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
index fe5401adb41b..432df7dd355d 100644
--- a/include/asm-ppc64/signal.h
+++ b/include/asm-ppc64/signal.h
@@ -96,47 +96,20 @@ typedef struct {
96 96
97#define MINSIGSTKSZ 2048 97#define MINSIGSTKSZ 2048
98#define SIGSTKSZ 8192 98#define SIGSTKSZ 8192
99#ifdef __KERNEL__
100 99
101/* 100#include <asm-generic/signal.h>
102 * These values of sa_flags are used only by the kernel as part of the
103 * irq handling routines.
104 *
105 * SA_INTERRUPT is also used by the irq handling routines.
106 * SA_SHIRQ is for shared interrupt support on PCI and EISA.
107 */
108#define SA_PROBE SA_ONESHOT
109#define SA_SAMPLE_RANDOM SA_RESTART
110#define SA_SHIRQ 0x04000000
111#endif
112
113#define SIG_BLOCK 0 /* for blocking signals */
114#define SIG_UNBLOCK 1 /* for unblocking signals */
115#define SIG_SETMASK 2 /* for setting the signal mask */
116
117/* Type of a signal handler. */
118typedef void __sigfunction(int);
119typedef __sigfunction __user * __sighandler_t;
120
121/* Type of the restorer function */
122typedef void __sigrestorer(void);
123typedef __sigrestorer __user * __sigrestorer_t;
124
125#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
126#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
127#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
128 101
129struct old_sigaction { 102struct old_sigaction {
130 __sighandler_t sa_handler; 103 __sighandler_t sa_handler;
131 old_sigset_t sa_mask; 104 old_sigset_t sa_mask;
132 unsigned long sa_flags; 105 unsigned long sa_flags;
133 __sigrestorer_t sa_restorer; 106 __sigrestore_t sa_restorer;
134}; 107};
135 108
136struct sigaction { 109struct sigaction {
137 __sighandler_t sa_handler; 110 __sighandler_t sa_handler;
138 unsigned long sa_flags; 111 unsigned long sa_flags;
139 __sigrestorer_t sa_restorer; 112 __sigrestore_t sa_restorer;
140 sigset_t sa_mask; /* mask last for extensibility */ 113 sigset_t sa_mask; /* mask last for extensibility */
141}; 114};
142 115
diff --git a/include/asm-ppc64/spinlock.h b/include/asm-ppc64/spinlock.h
index a9b2a1162cf7..acd11564dd75 100644
--- a/include/asm-ppc64/spinlock.h
+++ b/include/asm-ppc64/spinlock.h
@@ -110,7 +110,7 @@ static void __inline__ _raw_spin_lock(spinlock_t *lock)
110 HMT_low(); 110 HMT_low();
111 if (SHARED_PROCESSOR) 111 if (SHARED_PROCESSOR)
112 __spin_yield(lock); 112 __spin_yield(lock);
113 } while (likely(lock->lock != 0)); 113 } while (unlikely(lock->lock != 0));
114 HMT_medium(); 114 HMT_medium();
115 } 115 }
116} 116}
@@ -128,7 +128,7 @@ static void __inline__ _raw_spin_lock_flags(spinlock_t *lock, unsigned long flag
128 HMT_low(); 128 HMT_low();
129 if (SHARED_PROCESSOR) 129 if (SHARED_PROCESSOR)
130 __spin_yield(lock); 130 __spin_yield(lock);
131 } while (likely(lock->lock != 0)); 131 } while (unlikely(lock->lock != 0));
132 HMT_medium(); 132 HMT_medium();
133 local_irq_restore(flags_dis); 133 local_irq_restore(flags_dis);
134 } 134 }
@@ -194,7 +194,7 @@ static void __inline__ _raw_read_lock(rwlock_t *rw)
194 HMT_low(); 194 HMT_low();
195 if (SHARED_PROCESSOR) 195 if (SHARED_PROCESSOR)
196 __rw_yield(rw); 196 __rw_yield(rw);
197 } while (likely(rw->lock < 0)); 197 } while (unlikely(rw->lock < 0));
198 HMT_medium(); 198 HMT_medium();
199 } 199 }
200} 200}
@@ -251,7 +251,7 @@ static void __inline__ _raw_write_lock(rwlock_t *rw)
251 HMT_low(); 251 HMT_low();
252 if (SHARED_PROCESSOR) 252 if (SHARED_PROCESSOR)
253 __rw_yield(rw); 253 __rw_yield(rw);
254 } while (likely(rw->lock != 0)); 254 } while (unlikely(rw->lock != 0));
255 HMT_medium(); 255 HMT_medium();
256 } 256 }
257} 257}
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
index 0027da4364ac..fdec5e7a7af6 100644
--- a/include/asm-ppc64/xics.h
+++ b/include/asm-ppc64/xics.h
@@ -30,7 +30,4 @@ struct xics_ipi_struct {
30 30
31extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; 31extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
32 32
33extern unsigned int default_distrib_server;
34extern unsigned int interrupt_server_size;
35
36#endif /* _PPC64_KERNEL_XICS_H */ 33#endif /* _PPC64_KERNEL_XICS_H */