aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm/page_64.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include/asm/page_64.h')
-rw-r--r--arch/powerpc/include/asm/page_64.h43
1 files changed, 31 insertions, 12 deletions
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index 88693cef4f3d..d908a46d05c0 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -42,20 +42,40 @@
42 42
43typedef unsigned long pte_basic_t; 43typedef unsigned long pte_basic_t;
44 44
45static __inline__ void clear_page(void *addr) 45static inline void clear_page(void *addr)
46{ 46{
47 unsigned long lines, line_size; 47 unsigned long iterations;
48 48 unsigned long onex, twox, fourx, eightx;
49 line_size = ppc64_caches.dline_size; 49
50 lines = ppc64_caches.dlines_per_page; 50 iterations = ppc64_caches.dlines_per_page / 8;
51 51
52 __asm__ __volatile__( 52 /*
53 * Some verisions of gcc use multiply instructions to
54 * calculate the offsets so lets give it a hand to
55 * do better.
56 */
57 onex = ppc64_caches.dline_size;
58 twox = onex << 1;
59 fourx = onex << 2;
60 eightx = onex << 3;
61
62 asm volatile(
53 "mtctr %1 # clear_page\n\ 63 "mtctr %1 # clear_page\n\
541: dcbz 0,%0\n\ 64 .balign 16\n\
55 add %0,%0,%3\n\ 651: dcbz 0,%0\n\
66 dcbz %3,%0\n\
67 dcbz %4,%0\n\
68 dcbz %5,%0\n\
69 dcbz %6,%0\n\
70 dcbz %7,%0\n\
71 dcbz %8,%0\n\
72 dcbz %9,%0\n\
73 add %0,%0,%10\n\
56 bdnz+ 1b" 74 bdnz+ 1b"
57 : "=r" (addr) 75 : "=&r" (addr)
58 : "r" (lines), "0" (addr), "r" (line_size) 76 : "r" (iterations), "0" (addr), "b" (onex), "b" (twox),
77 "b" (twox+onex), "b" (fourx), "b" (fourx+onex),
78 "b" (twox+fourx), "b" (eightx-onex), "r" (eightx)
59 : "ctr", "memory"); 79 : "ctr", "memory");
60} 80}
61 81
@@ -104,7 +124,6 @@ extern unsigned long slice_get_unmapped_area(unsigned long addr,
104extern unsigned int get_slice_psize(struct mm_struct *mm, 124extern unsigned int get_slice_psize(struct mm_struct *mm,
105 unsigned long addr); 125 unsigned long addr);
106 126
107extern void slice_init_context(struct mm_struct *mm, unsigned int psize);
108extern void slice_set_user_psize(struct mm_struct *mm, unsigned int psize); 127extern void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
109extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start, 128extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
110 unsigned long len, unsigned int psize); 129 unsigned long len, unsigned int psize);