blob: a242b5d7cbe477c109a78152a344b663444738a1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * ppc64 MMU hashtable management routines
3 *
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +11004 * (c) Copyright IBM Corp. 2003, 2005
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Maintained by: Benjamin Herrenschmidt
7 * <benh@kernel.crashing.org>
8 *
9 * This file is covered by the GNU Public Licence v2 as
10 * described in the kernel's COPYING file.
11 */
12
Paul Mackerrasab1f9da2005-10-10 21:58:35 +100013#include <asm/reg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <asm/pgtable.h>
15#include <asm/mmu.h>
16#include <asm/page.h>
17#include <asm/types.h>
18#include <asm/ppc_asm.h>
Sam Ravnborg0013a852005-09-09 20:57:26 +020019#include <asm/asm-offsets.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <asm/cputable.h>
21
22 .text
23
24/*
25 * Stackframe:
26 *
27 * +-> Back chain (SP + 256)
28 * | General register save area (SP + 112)
29 * | Parameter save area (SP + 48)
30 * | TOC save area (SP + 40)
31 * | link editor doubleword (SP + 32)
32 * | compiler doubleword (SP + 24)
33 * | LR save area (SP + 16)
34 * | CR save area (SP + 8)
35 * SP ---> +-- Back chain (SP + 0)
36 */
37#define STACKFRAMESIZE 256
38
39/* Save parameters offsets */
40#define STK_PARM(i) (STACKFRAMESIZE + 48 + ((i)-3)*8)
41
42/* Save non-volatile offsets */
43#define STK_REG(i) (112 + ((i)-14)*8)
44
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +110045
46#ifndef CONFIG_PPC_64K_PAGES
47
48/*****************************************************************************
49 * *
50 * 4K SW & 4K HW pages implementation *
51 * *
52 *****************************************************************************/
53
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055/*
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +110056 * _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
Paul Mackerras1189be62007-10-11 20:37:10 +100057 * pte_t *ptep, unsigned long trap, int local, int ssize)
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 *
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +110059 * Adds a 4K page to the hash table in a segment of 4K pages only
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 */
61
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +110062_GLOBAL(__hash_page_4K)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 mflr r0
64 std r0,16(r1)
65 stdu r1,-STACKFRAMESIZE(r1)
66 /* Save all params that we need after a function call */
67 std r6,STK_PARM(r6)(r1)
68 std r8,STK_PARM(r8)(r1)
Paul Mackerras1189be62007-10-11 20:37:10 +100069 std r9,STK_PARM(r9)(r1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 /* Save non-volatile registers.
72 * r31 will hold "old PTE"
73 * r30 is "new PTE"
74 * r29 is "va"
75 * r28 is a hash value
76 * r27 is hashtab mask (maybe dynamic patched instead ?)
77 */
78 std r27,STK_REG(r27)(r1)
79 std r28,STK_REG(r28)(r1)
80 std r29,STK_REG(r29)(r1)
81 std r30,STK_REG(r30)(r1)
82 std r31,STK_REG(r31)(r1)
83
84 /* Step 1:
85 *
86 * Check permissions, atomically mark the linux PTE busy
87 * and hashed.
88 */
891:
90 ldarx r31,0,r6
91 /* Check access rights (access & ~(pte_val(*ptep))) */
92 andc. r0,r4,r31
93 bne- htab_wrong_access
94 /* Check if PTE is busy */
95 andi. r0,r31,_PAGE_BUSY
Olof Johanssond03853d2005-05-01 08:58:45 -070096 /* If so, just bail out and refault if needed. Someone else
97 * is changing this PTE anyway and might hash it.
98 */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +110099 bne- htab_bail_ok
100
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 /* Prepare new PTE value (turn access RW into DIRTY, then
102 * add BUSY,HASHPTE and ACCESSED)
103 */
104 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
105 or r30,r30,r31
106 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
107 /* Write the linux PTE atomically (setting busy) */
108 stdcx. r30,0,r6
109 bne- 1b
110 isync
111
112 /* Step 2:
113 *
114 * Insert/Update the HPTE in the hash table. At this point,
115 * r4 (access) is re-useable, we use it for the new HPTE flags
116 */
117
Paul Mackerras1189be62007-10-11 20:37:10 +1000118BEGIN_FTR_SECTION
119 cmpdi r9,0 /* check segment size */
120 bne 3f
Matt Evans44ae3ab2011-04-06 19:48:50 +0000121END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 /* Calc va and put it in r29 */
123 rldicr r29,r5,28,63-28
124 rldicl r3,r3,0,36
125 or r29,r3,r29
126
127 /* Calculate hash value for primary slot and store it in r28 */
128 rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
129 rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
130 xor r28,r5,r0
Paul Mackerras1189be62007-10-11 20:37:10 +1000131 b 4f
132
1333: /* Calc VA and hash in r29 and r28 for 1T segment */
134 sldi r29,r5,40 /* vsid << 40 */
135 clrldi r3,r3,24 /* ea & 0xffffffffff */
136 rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
137 clrldi r5,r5,40 /* vsid & 0xffffff */
138 rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
139 xor r28,r28,r5
140 or r29,r3,r29 /* VA */
141 xor r28,r28,r0 /* hash */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
143 /* Convert linux PTE bits into HW equivalents */
Paul Mackerras1189be62007-10-11 20:37:10 +10001444: andi. r3,r30,0x1fe /* Get basic set of flags */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100145 xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
147 rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100148 and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 andc r0,r30,r0 /* r0 = pte & ~r0 */
150 rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
Benjamin Herrenschmidtc5cf0e32006-05-30 14:14:19 +1000151 ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152
153 /* We eventually do the icache sync here (maybe inline that
154 * code rather than call a C function...)
155 */
156BEGIN_FTR_SECTION
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 mr r4,r30
158 mr r5,r7
159 bl .hash_page_do_lazy_icache
David Gibson8913ca12005-07-27 15:47:23 +1000160END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162 /* At this point, r3 contains new PP bits, save them in
163 * place of "access" in the param area (sic)
164 */
165 std r3,STK_PARM(r4)(r1)
166
167 /* Get htab_hash_mask */
168 ld r4,htab_hash_mask@got(2)
169 ld r27,0(r4) /* htab_hash_mask -> r27 */
170
171 /* Check if we may already be in the hashtable, in this case, we
172 * go to out-of-line code to try to modify the HPTE
173 */
174 andi. r0,r31,_PAGE_HASHPTE
175 bne htab_modify_pte
176
177htab_insert_pte:
178 /* Clear hpte bits in new pte (we also clear BUSY btw) and
179 * add _PAGE_HASHPTE
180 */
181 lis r0,_PAGE_HPTEFLAGS@h
182 ori r0,r0,_PAGE_HPTEFLAGS@l
183 andc r30,r30,r0
184 ori r30,r30,_PAGE_HASHPTE
185
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100186 /* physical address r5 */
187 rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
188 sldi r5,r5,PAGE_SHIFT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190 /* Calculate primary group hash */
191 and r0,r28,r27
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100192 rldicr r3,r0,3,63-3 /* r3 = (hash & mask) << 3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
194 /* Call ppc_md.hpte_insert */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300195 ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */
196 mr r4,r29 /* Retrieve va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100197 li r7,0 /* !bolted, !secondary */
198 li r8,MMU_PAGE_4K /* page size */
Paul Mackerras1189be62007-10-11 20:37:10 +1000199 ld r9,STK_PARM(r9)(r1) /* segment size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200_GLOBAL(htab_call_hpte_insert1)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100201 bl . /* Patched by htab_finish_init() */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 cmpdi 0,r3,0
203 bge htab_pte_insert_ok /* Insertion successful */
204 cmpdi 0,r3,-2 /* Critical failure */
205 beq- htab_pte_insert_failure
206
207 /* Now try secondary slot */
208
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100209 /* physical address r5 */
210 rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
211 sldi r5,r5,PAGE_SHIFT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
213 /* Calculate secondary group hash */
214 andc r0,r27,r28
215 rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
216
217 /* Call ppc_md.hpte_insert */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300218 ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */
219 mr r4,r29 /* Retrieve va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100220 li r7,HPTE_V_SECONDARY /* !bolted, secondary */
221 li r8,MMU_PAGE_4K /* page size */
Paul Mackerras1189be62007-10-11 20:37:10 +1000222 ld r9,STK_PARM(r9)(r1) /* segment size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223_GLOBAL(htab_call_hpte_insert2)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100224 bl . /* Patched by htab_finish_init() */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 cmpdi 0,r3,0
226 bge+ htab_pte_insert_ok /* Insertion successful */
227 cmpdi 0,r3,-2 /* Critical failure */
228 beq- htab_pte_insert_failure
229
230 /* Both are full, we need to evict something */
231 mftb r0
232 /* Pick a random group based on TB */
233 andi. r0,r0,1
234 mr r5,r28
235 bne 2f
236 not r5,r5
2372: and r0,r5,r27
238 rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
239 /* Call ppc_md.hpte_remove */
240_GLOBAL(htab_call_hpte_remove)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100241 bl . /* Patched by htab_finish_init() */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
243 /* Try all again */
244 b htab_insert_pte
245
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100246htab_bail_ok:
Olof Johanssond03853d2005-05-01 08:58:45 -0700247 li r3,0
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100248 b htab_bail
Olof Johanssond03853d2005-05-01 08:58:45 -0700249
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250htab_pte_insert_ok:
251 /* Insert slot number & secondary bit in PTE */
252 rldimi r30,r3,12,63-15
253
254 /* Write out the PTE with a normal write
255 * (maybe add eieio may be good still ?)
256 */
257htab_write_out_pte:
258 ld r6,STK_PARM(r6)(r1)
259 std r30,0(r6)
260 li r3, 0
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100261htab_bail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 ld r27,STK_REG(r27)(r1)
263 ld r28,STK_REG(r28)(r1)
264 ld r29,STK_REG(r29)(r1)
265 ld r30,STK_REG(r30)(r1)
266 ld r31,STK_REG(r31)(r1)
267 addi r1,r1,STACKFRAMESIZE
268 ld r0,16(r1)
269 mtlr r0
270 blr
271
272htab_modify_pte:
273 /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
274 mr r4,r3
275 rlwinm r3,r31,32-12,29,31
276
277 /* Secondary group ? if yes, get a inverted hash value */
278 mr r5,r28
279 andi. r0,r31,_PAGE_SECONDARY
280 beq 1f
281 not r5,r5
2821:
283 /* Calculate proper slot value for ppc_md.hpte_updatepp */
284 and r0,r5,r27
285 rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
286 add r3,r0,r3 /* add slot idx */
287
288 /* Call ppc_md.hpte_updatepp */
289 mr r5,r29 /* va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100290 li r6,MMU_PAGE_4K /* page size */
Paul Mackerras1189be62007-10-11 20:37:10 +1000291 ld r7,STK_PARM(r9)(r1) /* segment size */
292 ld r8,STK_PARM(r8)(r1) /* get "local" param */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293_GLOBAL(htab_call_hpte_updatepp)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100294 bl . /* Patched by htab_finish_init() */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295
296 /* if we failed because typically the HPTE wasn't really here
297 * we try an insertion.
298 */
299 cmpdi 0,r3,-1
300 beq- htab_insert_pte
301
302 /* Clear the BUSY bit and Write out the PTE */
303 li r0,_PAGE_BUSY
304 andc r30,r30,r0
305 b htab_write_out_pte
306
307htab_wrong_access:
308 /* Bail out clearing reservation */
309 stdcx. r31,0,r6
310 li r3,1
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100311 b htab_bail
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
313htab_pte_insert_failure:
314 /* Bail out restoring old PTE */
315 ld r6,STK_PARM(r6)(r1)
316 std r31,0(r6)
317 li r3,-1
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100318 b htab_bail
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319
320
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100321#else /* CONFIG_PPC_64K_PAGES */
322
323
324/*****************************************************************************
325 * *
326 * 64K SW & 4K or 64K HW in a 4K segment pages implementation *
327 * *
328 *****************************************************************************/
329
330/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
Paul Mackerrasfa282372008-01-24 08:35:13 +1100331 * pte_t *ptep, unsigned long trap, int local, int ssize,
332 * int subpg_prot)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100333 */
334
335/*
336 * For now, we do NOT implement Admixed pages
337 */
338_GLOBAL(__hash_page_4K)
339 mflr r0
340 std r0,16(r1)
341 stdu r1,-STACKFRAMESIZE(r1)
342 /* Save all params that we need after a function call */
343 std r6,STK_PARM(r6)(r1)
344 std r8,STK_PARM(r8)(r1)
Paul Mackerras1189be62007-10-11 20:37:10 +1000345 std r9,STK_PARM(r9)(r1)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100346
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100347 /* Save non-volatile registers.
348 * r31 will hold "old PTE"
349 * r30 is "new PTE"
350 * r29 is "va"
351 * r28 is a hash value
352 * r27 is hashtab mask (maybe dynamic patched instead ?)
353 * r26 is the hidx mask
354 * r25 is the index in combo page
355 */
356 std r25,STK_REG(r25)(r1)
357 std r26,STK_REG(r26)(r1)
358 std r27,STK_REG(r27)(r1)
359 std r28,STK_REG(r28)(r1)
360 std r29,STK_REG(r29)(r1)
361 std r30,STK_REG(r30)(r1)
362 std r31,STK_REG(r31)(r1)
363
364 /* Step 1:
365 *
366 * Check permissions, atomically mark the linux PTE busy
367 * and hashed.
368 */
3691:
370 ldarx r31,0,r6
371 /* Check access rights (access & ~(pte_val(*ptep))) */
372 andc. r0,r4,r31
373 bne- htab_wrong_access
374 /* Check if PTE is busy */
375 andi. r0,r31,_PAGE_BUSY
376 /* If so, just bail out and refault if needed. Someone else
377 * is changing this PTE anyway and might hash it.
378 */
379 bne- htab_bail_ok
380 /* Prepare new PTE value (turn access RW into DIRTY, then
381 * add BUSY and ACCESSED)
382 */
383 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
384 or r30,r30,r31
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000385 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
Paul Mackerrasbf72aeb2006-06-15 10:45:18 +1000386 oris r30,r30,_PAGE_COMBO@h
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100387 /* Write the linux PTE atomically (setting busy) */
388 stdcx. r30,0,r6
389 bne- 1b
390 isync
391
392 /* Step 2:
393 *
394 * Insert/Update the HPTE in the hash table. At this point,
395 * r4 (access) is re-useable, we use it for the new HPTE flags
396 */
397
398 /* Load the hidx index */
399 rldicl r25,r3,64-12,60
400
Paul Mackerras1189be62007-10-11 20:37:10 +1000401BEGIN_FTR_SECTION
402 cmpdi r9,0 /* check segment size */
403 bne 3f
Matt Evans44ae3ab2011-04-06 19:48:50 +0000404END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100405 /* Calc va and put it in r29 */
406 rldicr r29,r5,28,63-28 /* r29 = (vsid << 28) */
407 rldicl r3,r3,0,36 /* r3 = (ea & 0x0fffffff) */
Paul Mackerras1189be62007-10-11 20:37:10 +1000408 or r29,r3,r29 /* r29 = va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100409
410 /* Calculate hash value for primary slot and store it in r28 */
411 rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
412 rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
413 xor r28,r5,r0
Paul Mackerras1189be62007-10-11 20:37:10 +1000414 b 4f
415
4163: /* Calc VA and hash in r29 and r28 for 1T segment */
417 sldi r29,r5,40 /* vsid << 40 */
418 clrldi r3,r3,24 /* ea & 0xffffffffff */
419 rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
420 clrldi r5,r5,40 /* vsid & 0xffffff */
421 rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
422 xor r28,r28,r5
423 or r29,r3,r29 /* VA */
424 xor r28,r28,r0 /* hash */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100425
426 /* Convert linux PTE bits into HW equivalents */
Paul Mackerrasfa282372008-01-24 08:35:13 +11004274:
428#ifdef CONFIG_PPC_SUBPAGE_PROT
429 andc r10,r30,r10
430 andi. r3,r10,0x1fe /* Get basic set of flags */
431 rlwinm r0,r10,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
432#else
433 andi. r3,r30,0x1fe /* Get basic set of flags */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100434 rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
Paul Mackerrasfa282372008-01-24 08:35:13 +1100435#endif
436 xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100437 rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
438 and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
Paul Mackerrasfa282372008-01-24 08:35:13 +1100439 andc r0,r3,r0 /* r0 = pte & ~r0 */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100440 rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
Benjamin Herrenschmidtc5cf0e32006-05-30 14:14:19 +1000441 ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100442
443 /* We eventually do the icache sync here (maybe inline that
444 * code rather than call a C function...)
445 */
446BEGIN_FTR_SECTION
447 mr r4,r30
448 mr r5,r7
449 bl .hash_page_do_lazy_icache
450END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
451
452 /* At this point, r3 contains new PP bits, save them in
453 * place of "access" in the param area (sic)
454 */
455 std r3,STK_PARM(r4)(r1)
456
457 /* Get htab_hash_mask */
458 ld r4,htab_hash_mask@got(2)
459 ld r27,0(r4) /* htab_hash_mask -> r27 */
460
461 /* Check if we may already be in the hashtable, in this case, we
462 * go to out-of-line code to try to modify the HPTE. We look for
463 * the bit at (1 >> (index + 32))
464 */
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000465 rldicl. r0,r31,64-12,48
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100466 li r26,0 /* Default hidx */
467 beq htab_insert_pte
Paul Mackerrasbf72aeb2006-06-15 10:45:18 +1000468
469 /*
470 * Check if the pte was already inserted into the hash table
471 * as a 64k HW page, and invalidate the 64k HPTE if so.
472 */
473 andis. r0,r31,_PAGE_COMBO@h
474 beq htab_inval_old_hpte
475
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100476 ld r6,STK_PARM(r6)(r1)
477 ori r26,r6,0x8000 /* Load the hidx mask */
478 ld r26,0(r26)
479 addi r5,r25,36 /* Check actual HPTE_SUB bit, this */
480 rldcr. r0,r31,r5,0 /* must match pgtable.h definition */
481 bne htab_modify_pte
482
483htab_insert_pte:
484 /* real page number in r5, PTE RPN value + index */
Paul Mackerras721151d2007-04-03 21:24:02 +1000485 andis. r0,r31,_PAGE_4K_PFN@h
486 srdi r5,r31,PTE_RPN_SHIFT
487 bne- htab_special_pfn
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100488 sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
489 add r5,r5,r25
Paul Mackerras721151d2007-04-03 21:24:02 +1000490htab_special_pfn:
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100491 sldi r5,r5,HW_PAGE_SHIFT
492
493 /* Calculate primary group hash */
494 and r0,r28,r27
495 rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
496
497 /* Call ppc_md.hpte_insert */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300498 ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */
499 mr r4,r29 /* Retrieve va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100500 li r7,0 /* !bolted, !secondary */
501 li r8,MMU_PAGE_4K /* page size */
Paul Mackerras1189be62007-10-11 20:37:10 +1000502 ld r9,STK_PARM(r9)(r1) /* segment size */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100503_GLOBAL(htab_call_hpte_insert1)
504 bl . /* patched by htab_finish_init() */
505 cmpdi 0,r3,0
506 bge htab_pte_insert_ok /* Insertion successful */
507 cmpdi 0,r3,-2 /* Critical failure */
508 beq- htab_pte_insert_failure
509
510 /* Now try secondary slot */
511
512 /* real page number in r5, PTE RPN value + index */
Paul Mackerras430404e2007-08-03 19:16:11 +1000513 andis. r0,r31,_PAGE_4K_PFN@h
514 srdi r5,r31,PTE_RPN_SHIFT
515 bne- 3f
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100516 sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
517 add r5,r5,r25
Paul Mackerras430404e2007-08-03 19:16:11 +10005183: sldi r5,r5,HW_PAGE_SHIFT
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100519
520 /* Calculate secondary group hash */
521 andc r0,r27,r28
522 rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
523
524 /* Call ppc_md.hpte_insert */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300525 ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */
526 mr r4,r29 /* Retrieve va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100527 li r7,HPTE_V_SECONDARY /* !bolted, secondary */
528 li r8,MMU_PAGE_4K /* page size */
Paul Mackerras1189be62007-10-11 20:37:10 +1000529 ld r9,STK_PARM(r9)(r1) /* segment size */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100530_GLOBAL(htab_call_hpte_insert2)
531 bl . /* patched by htab_finish_init() */
532 cmpdi 0,r3,0
533 bge+ htab_pte_insert_ok /* Insertion successful */
534 cmpdi 0,r3,-2 /* Critical failure */
535 beq- htab_pte_insert_failure
536
537 /* Both are full, we need to evict something */
538 mftb r0
539 /* Pick a random group based on TB */
540 andi. r0,r0,1
541 mr r5,r28
542 bne 2f
543 not r5,r5
5442: and r0,r5,r27
545 rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
546 /* Call ppc_md.hpte_remove */
547_GLOBAL(htab_call_hpte_remove)
548 bl . /* patched by htab_finish_init() */
549
550 /* Try all again */
551 b htab_insert_pte
552
Paul Mackerrasbf72aeb2006-06-15 10:45:18 +1000553 /*
554 * Call out to C code to invalidate an 64k HW HPTE that is
555 * useless now that the segment has been switched to 4k pages.
556 */
557htab_inval_old_hpte:
558 mr r3,r29 /* virtual addr */
559 mr r4,r31 /* PTE.pte */
560 li r5,0 /* PTE.hidx */
561 li r6,MMU_PAGE_64K /* psize */
Benjamin Herrenschmidtf6ab0b92007-10-29 12:05:18 +1100562 ld r7,STK_PARM(r9)(r1) /* ssize */
563 ld r8,STK_PARM(r8)(r1) /* local */
Paul Mackerrasbf72aeb2006-06-15 10:45:18 +1000564 bl .flush_hash_page
Paul Mackerras65ba6cd2008-06-18 16:40:35 +1000565 /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */
566 lis r0,_PAGE_HPTE_SUB@h
567 ori r0,r0,_PAGE_HPTE_SUB@l
568 andc r30,r30,r0
Paul Mackerrasbf72aeb2006-06-15 10:45:18 +1000569 b htab_insert_pte
570
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100571htab_bail_ok:
572 li r3,0
573 b htab_bail
574
575htab_pte_insert_ok:
576 /* Insert slot number & secondary bit in PTE second half,
577 * clear _PAGE_BUSY and set approriate HPTE slot bit
578 */
579 ld r6,STK_PARM(r6)(r1)
580 li r0,_PAGE_BUSY
581 andc r30,r30,r0
582 /* HPTE SUB bit */
583 li r0,1
584 subfic r5,r25,27 /* Must match bit position in */
585 sld r0,r0,r5 /* pgtable.h */
586 or r30,r30,r0
587 /* hindx */
588 sldi r5,r25,2
589 sld r3,r3,r5
590 li r4,0xf
591 sld r4,r4,r5
592 andc r26,r26,r4
593 or r26,r26,r3
594 ori r5,r6,0x8000
595 std r26,0(r5)
596 lwsync
597 std r30,0(r6)
598 li r3, 0
599htab_bail:
600 ld r25,STK_REG(r25)(r1)
601 ld r26,STK_REG(r26)(r1)
602 ld r27,STK_REG(r27)(r1)
603 ld r28,STK_REG(r28)(r1)
604 ld r29,STK_REG(r29)(r1)
605 ld r30,STK_REG(r30)(r1)
606 ld r31,STK_REG(r31)(r1)
607 addi r1,r1,STACKFRAMESIZE
608 ld r0,16(r1)
609 mtlr r0
610 blr
611
612htab_modify_pte:
613 /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
614 mr r4,r3
615 sldi r5,r25,2
616 srd r3,r26,r5
617
618 /* Secondary group ? if yes, get a inverted hash value */
619 mr r5,r28
620 andi. r0,r3,0x8 /* page secondary ? */
621 beq 1f
622 not r5,r5
6231: andi. r3,r3,0x7 /* extract idx alone */
624
625 /* Calculate proper slot value for ppc_md.hpte_updatepp */
626 and r0,r5,r27
627 rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
628 add r3,r0,r3 /* add slot idx */
629
630 /* Call ppc_md.hpte_updatepp */
631 mr r5,r29 /* va */
632 li r6,MMU_PAGE_4K /* page size */
Paul Mackerras1189be62007-10-11 20:37:10 +1000633 ld r7,STK_PARM(r9)(r1) /* segment size */
634 ld r8,STK_PARM(r8)(r1) /* get "local" param */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100635_GLOBAL(htab_call_hpte_updatepp)
636 bl . /* patched by htab_finish_init() */
637
638 /* if we failed because typically the HPTE wasn't really here
639 * we try an insertion.
640 */
641 cmpdi 0,r3,-1
642 beq- htab_insert_pte
643
644 /* Clear the BUSY bit and Write out the PTE */
645 li r0,_PAGE_BUSY
646 andc r30,r30,r0
647 ld r6,STK_PARM(r6)(r1)
648 std r30,0(r6)
649 li r3,0
650 b htab_bail
651
652htab_wrong_access:
653 /* Bail out clearing reservation */
654 stdcx. r31,0,r6
655 li r3,1
656 b htab_bail
657
658htab_pte_insert_failure:
659 /* Bail out restoring old PTE */
660 ld r6,STK_PARM(r6)(r1)
661 std r31,0(r6)
662 li r3,-1
663 b htab_bail
664
Benjamin Herrenschmidt16c2d472007-05-08 16:27:28 +1000665#endif /* CONFIG_PPC_64K_PAGES */
666
667#ifdef CONFIG_PPC_HAS_HASH_64K
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100668
669/*****************************************************************************
670 * *
671 * 64K SW & 64K HW in a 64K segment pages implementation *
672 * *
673 *****************************************************************************/
674
675_GLOBAL(__hash_page_64K)
676 mflr r0
677 std r0,16(r1)
678 stdu r1,-STACKFRAMESIZE(r1)
679 /* Save all params that we need after a function call */
680 std r6,STK_PARM(r6)(r1)
681 std r8,STK_PARM(r8)(r1)
Paul Mackerras1189be62007-10-11 20:37:10 +1000682 std r9,STK_PARM(r9)(r1)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100683
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100684 /* Save non-volatile registers.
685 * r31 will hold "old PTE"
686 * r30 is "new PTE"
687 * r29 is "va"
688 * r28 is a hash value
689 * r27 is hashtab mask (maybe dynamic patched instead ?)
690 */
691 std r27,STK_REG(r27)(r1)
692 std r28,STK_REG(r28)(r1)
693 std r29,STK_REG(r29)(r1)
694 std r30,STK_REG(r30)(r1)
695 std r31,STK_REG(r31)(r1)
696
697 /* Step 1:
698 *
699 * Check permissions, atomically mark the linux PTE busy
700 * and hashed.
701 */
7021:
703 ldarx r31,0,r6
704 /* Check access rights (access & ~(pte_val(*ptep))) */
705 andc. r0,r4,r31
706 bne- ht64_wrong_access
707 /* Check if PTE is busy */
708 andi. r0,r31,_PAGE_BUSY
709 /* If so, just bail out and refault if needed. Someone else
710 * is changing this PTE anyway and might hash it.
711 */
712 bne- ht64_bail_ok
Paul Mackerrasbf72aeb2006-06-15 10:45:18 +1000713BEGIN_FTR_SECTION
714 /* Check if PTE has the cache-inhibit bit set */
715 andi. r0,r31,_PAGE_NO_CACHE
716 /* If so, bail out and refault as a 4k page */
717 bne- ht64_bail_ok
Matt Evans44ae3ab2011-04-06 19:48:50 +0000718END_MMU_FTR_SECTION_IFCLR(MMU_FTR_CI_LARGE_PAGE)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100719 /* Prepare new PTE value (turn access RW into DIRTY, then
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000720 * add BUSY and ACCESSED)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100721 */
722 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
723 or r30,r30,r31
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000724 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100725 /* Write the linux PTE atomically (setting busy) */
726 stdcx. r30,0,r6
727 bne- 1b
728 isync
729
730 /* Step 2:
731 *
732 * Insert/Update the HPTE in the hash table. At this point,
733 * r4 (access) is re-useable, we use it for the new HPTE flags
734 */
735
Paul Mackerras1189be62007-10-11 20:37:10 +1000736BEGIN_FTR_SECTION
737 cmpdi r9,0 /* check segment size */
738 bne 3f
Matt Evans44ae3ab2011-04-06 19:48:50 +0000739END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100740 /* Calc va and put it in r29 */
741 rldicr r29,r5,28,63-28
742 rldicl r3,r3,0,36
743 or r29,r3,r29
744
745 /* Calculate hash value for primary slot and store it in r28 */
746 rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
747 rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */
748 xor r28,r5,r0
Paul Mackerras1189be62007-10-11 20:37:10 +1000749 b 4f
750
7513: /* Calc VA and hash in r29 and r28 for 1T segment */
752 sldi r29,r5,40 /* vsid << 40 */
753 clrldi r3,r3,24 /* ea & 0xffffffffff */
754 rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
755 clrldi r5,r5,40 /* vsid & 0xffffff */
756 rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */
757 xor r28,r28,r5
758 or r29,r3,r29 /* VA */
759 xor r28,r28,r0 /* hash */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100760
761 /* Convert linux PTE bits into HW equivalents */
Paul Mackerras1189be62007-10-11 20:37:10 +10007624: andi. r3,r30,0x1fe /* Get basic set of flags */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100763 xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
764 rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
765 rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
766 and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
767 andc r0,r30,r0 /* r0 = pte & ~r0 */
768 rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
Benjamin Herrenschmidtc5cf0e32006-05-30 14:14:19 +1000769 ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100770
771 /* We eventually do the icache sync here (maybe inline that
772 * code rather than call a C function...)
773 */
774BEGIN_FTR_SECTION
775 mr r4,r30
776 mr r5,r7
777 bl .hash_page_do_lazy_icache
778END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
779
780 /* At this point, r3 contains new PP bits, save them in
781 * place of "access" in the param area (sic)
782 */
783 std r3,STK_PARM(r4)(r1)
784
785 /* Get htab_hash_mask */
786 ld r4,htab_hash_mask@got(2)
787 ld r27,0(r4) /* htab_hash_mask -> r27 */
788
789 /* Check if we may already be in the hashtable, in this case, we
790 * go to out-of-line code to try to modify the HPTE
791 */
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000792 rldicl. r0,r31,64-12,48
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100793 bne ht64_modify_pte
794
795ht64_insert_pte:
796 /* Clear hpte bits in new pte (we also clear BUSY btw) and
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000797 * add _PAGE_HPTE_SUB0
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100798 */
799 lis r0,_PAGE_HPTEFLAGS@h
800 ori r0,r0,_PAGE_HPTEFLAGS@l
801 andc r30,r30,r0
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000802#ifdef CONFIG_PPC_64K_PAGES
803 oris r30,r30,_PAGE_HPTE_SUB0@h
804#else
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100805 ori r30,r30,_PAGE_HASHPTE
Benjamin Herrenschmidt41743a42008-06-11 15:37:10 +1000806#endif
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100807 /* Phyical address in r5 */
808 rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
809 sldi r5,r5,PAGE_SHIFT
810
811 /* Calculate primary group hash */
812 and r0,r28,r27
813 rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
814
815 /* Call ppc_md.hpte_insert */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300816 ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */
817 mr r4,r29 /* Retrieve va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100818 li r7,0 /* !bolted, !secondary */
819 li r8,MMU_PAGE_64K
Paul Mackerras1189be62007-10-11 20:37:10 +1000820 ld r9,STK_PARM(r9)(r1) /* segment size */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100821_GLOBAL(ht64_call_hpte_insert1)
822 bl . /* patched by htab_finish_init() */
823 cmpdi 0,r3,0
824 bge ht64_pte_insert_ok /* Insertion successful */
825 cmpdi 0,r3,-2 /* Critical failure */
826 beq- ht64_pte_insert_failure
827
828 /* Now try secondary slot */
829
830 /* Phyical address in r5 */
831 rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
832 sldi r5,r5,PAGE_SHIFT
833
834 /* Calculate secondary group hash */
835 andc r0,r27,r28
836 rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
837
838 /* Call ppc_md.hpte_insert */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300839 ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */
840 mr r4,r29 /* Retrieve va */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100841 li r7,HPTE_V_SECONDARY /* !bolted, secondary */
842 li r8,MMU_PAGE_64K
Paul Mackerras1189be62007-10-11 20:37:10 +1000843 ld r9,STK_PARM(r9)(r1) /* segment size */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100844_GLOBAL(ht64_call_hpte_insert2)
845 bl . /* patched by htab_finish_init() */
846 cmpdi 0,r3,0
847 bge+ ht64_pte_insert_ok /* Insertion successful */
848 cmpdi 0,r3,-2 /* Critical failure */
849 beq- ht64_pte_insert_failure
850
851 /* Both are full, we need to evict something */
852 mftb r0
853 /* Pick a random group based on TB */
854 andi. r0,r0,1
855 mr r5,r28
856 bne 2f
857 not r5,r5
8582: and r0,r5,r27
859 rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
860 /* Call ppc_md.hpte_remove */
861_GLOBAL(ht64_call_hpte_remove)
862 bl . /* patched by htab_finish_init() */
863
864 /* Try all again */
865 b ht64_insert_pte
866
867ht64_bail_ok:
868 li r3,0
869 b ht64_bail
870
871ht64_pte_insert_ok:
872 /* Insert slot number & secondary bit in PTE */
873 rldimi r30,r3,12,63-15
874
875 /* Write out the PTE with a normal write
876 * (maybe add eieio may be good still ?)
877 */
878ht64_write_out_pte:
879 ld r6,STK_PARM(r6)(r1)
880 std r30,0(r6)
881 li r3, 0
882ht64_bail:
883 ld r27,STK_REG(r27)(r1)
884 ld r28,STK_REG(r28)(r1)
885 ld r29,STK_REG(r29)(r1)
886 ld r30,STK_REG(r30)(r1)
887 ld r31,STK_REG(r31)(r1)
888 addi r1,r1,STACKFRAMESIZE
889 ld r0,16(r1)
890 mtlr r0
891 blr
892
893ht64_modify_pte:
894 /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
895 mr r4,r3
896 rlwinm r3,r31,32-12,29,31
897
898 /* Secondary group ? if yes, get a inverted hash value */
899 mr r5,r28
900 andi. r0,r31,_PAGE_F_SECOND
901 beq 1f
902 not r5,r5
9031:
904 /* Calculate proper slot value for ppc_md.hpte_updatepp */
905 and r0,r5,r27
906 rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
907 add r3,r0,r3 /* add slot idx */
908
909 /* Call ppc_md.hpte_updatepp */
910 mr r5,r29 /* va */
911 li r6,MMU_PAGE_64K
Paul Mackerras1189be62007-10-11 20:37:10 +1000912 ld r7,STK_PARM(r9)(r1) /* segment size */
913 ld r8,STK_PARM(r8)(r1) /* get "local" param */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100914_GLOBAL(ht64_call_hpte_updatepp)
915 bl . /* patched by htab_finish_init() */
916
917 /* if we failed because typically the HPTE wasn't really here
918 * we try an insertion.
919 */
920 cmpdi 0,r3,-1
921 beq- ht64_insert_pte
922
923 /* Clear the BUSY bit and Write out the PTE */
924 li r0,_PAGE_BUSY
925 andc r30,r30,r0
926 b ht64_write_out_pte
927
928ht64_wrong_access:
929 /* Bail out clearing reservation */
930 stdcx. r31,0,r6
931 li r3,1
932 b ht64_bail
933
934ht64_pte_insert_failure:
935 /* Bail out restoring old PTE */
936 ld r6,STK_PARM(r6)(r1)
937 std r31,0(r6)
938 li r3,-1
939 b ht64_bail
940
941
Benjamin Herrenschmidt16c2d472007-05-08 16:27:28 +1000942#endif /* CONFIG_PPC_HAS_HASH_64K */
Benjamin Herrenschmidt3c726f82005-11-07 11:06:55 +1100943
944
945/*****************************************************************************
946 * *
947 * Huge pages implementation is in hugetlbpage.c *
948 * *
949 *****************************************************************************/