Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[linux-2.6] / arch / frv / mm / tlb-flush.S
1 /* tlb-flush.S: TLB flushing routines
2  *
3  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/sys.h>
13 #include <linux/linkage.h>
14 #include <asm/page.h>
15 #include <asm/ptrace.h>
16 #include <asm/spr-regs.h>
17
18 .macro DEBUG ch
19 #       sethi.p         %hi(0xfeff9c00),gr4
20 #       setlo           %lo(0xfeff9c00),gr4
21 #       setlos          #\ch,gr5
22 #       stbi            gr5,@(gr4,#0)
23 #       membar
24 .endm
25
26         .section        .rodata
27
28         # sizes corresponding to TPXR.LMAX
29         .balign         1
30 __tlb_lmax_sizes:
31         .byte           0, 64, 0, 0
32         .byte           0, 0, 0, 0
33         .byte           0, 0, 0, 0
34         .byte           0, 0, 0, 0
35
36         .section        .text
37         .balign         4
38
39 ###############################################################################
40 #
41 # flush everything
42 # - void __flush_tlb_all(void)
43 #
44 ###############################################################################
45         .globl          __flush_tlb_all
46         .type           __flush_tlb_all,@function
47 __flush_tlb_all:
48         DEBUG           'A'
49
50         # kill cached PGE value
51         setlos          #0xffffffff,gr4
52         movgs           gr4,scr0
53         movgs           gr4,scr1
54
55         # kill AMPR-cached TLB values
56         movgs           gr0,iamlr1
57         movgs           gr0,iampr1
58         movgs           gr0,damlr1
59         movgs           gr0,dampr1
60
61         # find out how many lines there are
62         movsg           tpxr,gr5
63         sethi.p         %hi(__tlb_lmax_sizes),gr4
64         srli            gr5,#TPXR_LMAX_SHIFT,gr5
65         setlo.p         %lo(__tlb_lmax_sizes),gr4
66         andi            gr5,#TPXR_LMAX_SMASK,gr5
67         ldub            @(gr4,gr5),gr4
68
69         # now, we assume that the TLB line step is page size in size
70         setlos.p        #PAGE_SIZE,gr5
71         setlos          #0,gr6
72 1:
73         tlbpr           gr6,gr0,#6,#0
74         subicc.p        gr4,#1,gr4,icc0
75         add             gr6,gr5,gr6
76         bne             icc0,#2,1b
77
78         DEBUG           'B'
79         bralr
80
81         .size           __flush_tlb_all, .-__flush_tlb_all
82
83 ###############################################################################
84 #
85 # flush everything to do with one context
86 # - void __flush_tlb_mm(unsigned long contextid [GR8])
87 #
88 ###############################################################################
89         .globl          __flush_tlb_mm
90         .type           __flush_tlb_mm,@function
91 __flush_tlb_mm:
92         DEBUG           'M'
93
94         # kill cached PGE value
95         setlos          #0xffffffff,gr4
96         movgs           gr4,scr0
97         movgs           gr4,scr1
98
99         # specify the context we want to flush
100         movgs           gr8,tplr
101
102         # find out how many lines there are
103         movsg           tpxr,gr5
104         sethi.p         %hi(__tlb_lmax_sizes),gr4
105         srli            gr5,#TPXR_LMAX_SHIFT,gr5
106         setlo.p         %lo(__tlb_lmax_sizes),gr4
107         andi            gr5,#TPXR_LMAX_SMASK,gr5
108         ldub            @(gr4,gr5),gr4
109
110         # now, we assume that the TLB line step is page size in size
111         setlos.p        #PAGE_SIZE,gr5
112         setlos          #0,gr6
113 0:
114         tlbpr           gr6,gr0,#5,#0
115         subicc.p        gr4,#1,gr4,icc0
116         add             gr6,gr5,gr6
117         bne             icc0,#2,0b
118
119         DEBUG           'N'
120         bralr
121
122         .size           __flush_tlb_mm, .-__flush_tlb_mm
123
124 ###############################################################################
125 #
126 # flush a range of addresses from the TLB
127 # - void __flush_tlb_page(unsigned long contextid [GR8],
128 #                         unsigned long start [GR9])
129 #
130 ###############################################################################
131         .globl          __flush_tlb_page
132         .type           __flush_tlb_page,@function
133 __flush_tlb_page:
134         # kill cached PGE value
135         setlos          #0xffffffff,gr4
136         movgs           gr4,scr0
137         movgs           gr4,scr1
138
139         # specify the context we want to flush
140         movgs           gr8,tplr
141
142         # zap the matching TLB line and AMR values
143         setlos          #~(PAGE_SIZE-1),gr5
144         and             gr9,gr5,gr9
145         tlbpr           gr9,gr0,#5,#0
146
147         bralr
148
149         .size           __flush_tlb_page, .-__flush_tlb_page
150
151 ###############################################################################
152 #
153 # flush a range of addresses from the TLB
154 # - void __flush_tlb_range(unsigned long contextid [GR8],
155 #                          unsigned long start [GR9],
156 #                          unsigned long end [GR10])
157 #
158 ###############################################################################
159         .globl          __flush_tlb_range
160         .type           __flush_tlb_range,@function
161 __flush_tlb_range:
162         # kill cached PGE value
163         setlos          #0xffffffff,gr4
164         movgs           gr4,scr0
165         movgs           gr4,scr1
166
167         # specify the context we want to flush
168         movgs           gr8,tplr
169
170         # round the start down to beginning of TLB line and end up to beginning of next TLB line
171         setlos.p        #~(PAGE_SIZE-1),gr5
172         setlos          #PAGE_SIZE,gr6
173         subi.p          gr10,#1,gr10
174         and             gr9,gr5,gr9
175         and             gr10,gr5,gr10
176 2:
177         tlbpr           gr9,gr0,#5,#0
178         subcc.p         gr9,gr10,gr0,icc0
179         add             gr9,gr6,gr9
180         bne             icc0,#0,2b              ; most likely a 1-page flush
181
182         bralr
183
184         .size           __flush_tlb_range, .-__flush_tlb_range