Linux-2.6.12-rc2
[linux-2.6.git] / arch / um / sys-ppc / misc.S
1 /*
2  * This file contains miscellaneous low-level functions.
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *
5  * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6  * and Paul Mackerras.
7  *
8  * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
9  * by Chris Emerson.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version
14  * 2 of the License, or (at your option) any later version.
15  *
16  */
17
18 #include <linux/config.h>
19 #include <asm/processor.h>
20 #include "ppc_asm.h"
21
22 #if defined(CONFIG_4xx) || defined(CONFIG_8xx)
23 #define CACHE_LINE_SIZE         16
24 #define LG_CACHE_LINE_SIZE      4
25 #define MAX_COPY_PREFETCH       1
26 #elif !defined(CONFIG_PPC64BRIDGE)
27 #define CACHE_LINE_SIZE         32
28 #define LG_CACHE_LINE_SIZE      5
29 #define MAX_COPY_PREFETCH       4
30 #else
31 #define CACHE_LINE_SIZE         128
32 #define LG_CACHE_LINE_SIZE      7
33 #define MAX_COPY_PREFETCH       1
34 #endif /* CONFIG_4xx || CONFIG_8xx */
35
36         .text
37
38 /*
39  * Clear a page using the dcbz instruction, which doesn't cause any
40  * memory traffic (except to write out any cache lines which get
41  * displaced).  This only works on cacheable memory.
42  */
43 _GLOBAL(clear_page)
44         li      r0,4096/CACHE_LINE_SIZE
45         mtctr   r0
46 #ifdef CONFIG_8xx
47         li      r4, 0
48 1:      stw     r4, 0(r3)
49         stw     r4, 4(r3)
50         stw     r4, 8(r3)
51         stw     r4, 12(r3)
52 #else
53 1:      dcbz    0,r3
54 #endif
55         addi    r3,r3,CACHE_LINE_SIZE
56         bdnz    1b
57         blr
58
59 /*
60  * Copy a whole page.  We use the dcbz instruction on the destination
61  * to reduce memory traffic (it eliminates the unnecessary reads of
62  * the destination into cache).  This requires that the destination
63  * is cacheable.
64  */
65 #define COPY_16_BYTES           \
66         lwz     r6,4(r4);       \
67         lwz     r7,8(r4);       \
68         lwz     r8,12(r4);      \
69         lwzu    r9,16(r4);      \
70         stw     r6,4(r3);       \
71         stw     r7,8(r3);       \
72         stw     r8,12(r3);      \
73         stwu    r9,16(r3)
74
75 _GLOBAL(copy_page)
76         addi    r3,r3,-4
77         addi    r4,r4,-4
78         li      r5,4
79
80 #ifndef CONFIG_8xx
81 #if MAX_COPY_PREFETCH > 1
82         li      r0,MAX_COPY_PREFETCH
83         li      r11,4
84         mtctr   r0
85 11:     dcbt    r11,r4
86         addi    r11,r11,CACHE_LINE_SIZE
87         bdnz    11b
88 #else /* MAX_COPY_PREFETCH == 1 */
89         dcbt    r5,r4
90         li      r11,CACHE_LINE_SIZE+4
91 #endif /* MAX_COPY_PREFETCH */
92 #endif /* CONFIG_8xx */
93
94         li      r0,4096/CACHE_LINE_SIZE
95         mtctr   r0
96 1:
97 #ifndef CONFIG_8xx
98         dcbt    r11,r4
99         dcbz    r5,r3
100 #endif
101         COPY_16_BYTES
102 #if CACHE_LINE_SIZE >= 32
103         COPY_16_BYTES
104 #if CACHE_LINE_SIZE >= 64
105         COPY_16_BYTES
106         COPY_16_BYTES
107 #if CACHE_LINE_SIZE >= 128
108         COPY_16_BYTES
109         COPY_16_BYTES
110         COPY_16_BYTES
111         COPY_16_BYTES
112 #endif
113 #endif
114 #endif
115         bdnz    1b
116         blr