Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 |