blob: 6f43c74c5d9597350c0aee4de4f59c18e2040412 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 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
731:
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
1140:
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
1772:
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