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