Subversion Repositories HelenOS

Rev

Rev 818 | Rev 899 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 818 Rev 819
1
/*
1
/*
2
 * Copyright (C) 2006 Jakub Jermar
2
 * Copyright (C) 2006 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/*
29
/*
30
 * TLB management.
30
 * TLB management.
31
 */
31
 */
32
 
32
 
33
#include <mm/tlb.h>
33
#include <mm/tlb.h>
34
#include <arch/mm/tlb.h>
34
#include <arch/mm/tlb.h>
-
 
35
#include <arch/barrier.h>
35
 
36
 
36
 
37
 
37
/** Invalidate all TLB entries. */
38
/** Invalidate all TLB entries. */
38
void tlb_invalidate_all(void)
39
void tlb_invalidate_all(void)
39
{
40
{
40
    /* TODO */
41
    /* TODO */
41
}
42
}
42
 
43
 
43
/** Invalidate entries belonging to an address space.
44
/** Invalidate entries belonging to an address space.
44
 *
45
 *
45
 * @param asid Address space identifier.
46
 * @param asid Address space identifier.
46
 */
47
 */
47
void tlb_invalidate_asid(asid_t asid)
48
void tlb_invalidate_asid(asid_t asid)
48
{
49
{
49
    /* TODO */
50
    /* TODO */
50
}
51
}
51
 
52
 
52
 
53
 
53
 
54
 
54
void tlb_fill_data(__address va,asid_t asid,vhpt_entry_t entry)
55
void tlb_fill_data(__address va,asid_t asid,tlb_entry_t entry)
55
{
56
{
56
    region_register rr;
57
    region_register rr;
57
 
58
 
58
 
59
 
59
    if(!(entry.not_present.p)) return;
60
    if(!(entry.not_present.p)) return;
60
 
61
 
61
    rr.word=rr_read(VA_REGION(va));
62
    rr.word=rr_read(VA_REGION(va));
62
 
63
 
63
    if(rr.map.rid==ASID2RID(asid,VA_REGION(va)))
64
    if(rr.map.rid==ASID2RID(asid,VA_REGION(va)))
64
    {
65
    {
65
        asm
66
        asm volatile
66
        (
67
        (
67
            "srlz.i;;\n"
68
            "srlz.i;;\n"
68
            "srlz.d;;\n"
69
            "srlz.d;;\n"
69
            "mov r8=psr;;\n"
70
            "mov r8=psr;;\n"
70
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
71
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
71
            "mov psr.l=r9;;\n"
72
            "mov psr.l=r9;;\n"
72
            "srlz.d;;\n"
73
            "srlz.d;;\n"
73
            "srlz.i;;\n"
74
            "srlz.i;;\n"
74
            "mov cr20=%1\n"             /*va*/      /*cr20 == IFA*/
75
            "mov cr.ifa=%1\n"               /*va*/       
75
            "mov cr21=%2;;\n"                   /*entry.word[1]*/ /*cr21=ITIR*/
76
            "mov cr.itir=%2;;\n"                /*entry.word[1]*/
76
            "itc.d %3;;\n"                      /*entry.word[0]*/
77
            "itc.d %3;;\n"                      /*entry.word[0]*/
77
            "mov psr.l=r8;;\n"
78
            "mov psr.l=r8;;\n"
78
            "srlz.d;;\n"
79
            "srlz.d;;\n"
79
            :
80
            :
80
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
81
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
81
            :"r8","r9"
82
            :"r8","r9"
82
        );
83
        );
83
    }
84
    }
84
    else
85
    else
85
    {
86
    {
86
        region_register rr0;
87
        region_register rr0;
87
        rr0=rr;
88
        rr0=rr;
88
        rr0.map.rid=ASID2RID(asid,VA_REGION(va));
89
        rr0.map.rid=ASID2RID(asid,VA_REGION(va));
89
        rr_write(VA_REGION(va),rr0.word);
90
        rr_write(VA_REGION(va),rr0.word);
-
 
91
        srlz_d();
90
        asm
92
        asm volatile
91
        (
93
        (
92
            "mov r8=psr;;\n"
94
            "mov r8=psr;;\n"
93
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
95
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
94
            "mov psr.l=r9;;\n"
96
            "mov psr.l=r9;;\n"
95
            "srlz.d;;\n"
97
            "srlz.d;;\n"
96
            "mov cr20=%1\n"             /*va*/      /*cr20 == IFA*/
98
            "mov cr.ifa=%1\n"               /*va*/       
97
            "mov cr21=%2;;\n"                   /*entry.word[1]*/ /*cr21=ITIR*/
99
            "mov cr.itir=%2;;\n"                /*entry.word[1]*/
98
            "itc.d %3;;\n"                      /*entry.word[0]*/
100
            "itc.d %3;;\n"                      /*entry.word[0]*/
99
            "mov psr.l=r8;;\n"
101
            "mov psr.l=r8;;\n"
100
            "srlz.d;;\n"
102
            "srlz.d;;\n"
101
            :
103
            :
102
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
104
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
103
            :"r8","r9"
105
            :"r8","r9"
104
        );
106
        );
105
        rr_write(VA_REGION(va),rr.word);
107
        rr_write(VA_REGION(va),rr.word);
106
    }
108
    }
107
 
109
 
108
 
110
 
109
}
111
}
110
 
112
 
111
void tlb_fill_code(__address va,asid_t asid,vhpt_entry_t entry)
113
void tlb_fill_code(__address va,asid_t asid,tlb_entry_t entry)
112
{
114
{
113
    region_register rr;
115
    region_register rr;
114
 
116
 
115
 
117
 
116
    if(!(entry.not_present.p)) return;
118
    if(!(entry.not_present.p)) return;
117
 
119
 
118
    rr.word=rr_read(VA_REGION(va));
120
    rr.word=rr_read(VA_REGION(va));
119
 
121
 
120
    if(rr.map.rid==ASID2RID(asid,VA_REGION(va)))
122
    if(rr.map.rid==ASID2RID(asid,VA_REGION(va)))
121
    {
123
    {
122
        asm
124
        asm volatile
123
        (
125
        (
124
            "srlz.i;;\n"
126
            "srlz.i;;\n"
125
            "srlz.d;;\n"
127
            "srlz.d;;\n"
126
            "mov r8=psr;;\n"
128
            "mov r8=psr;;\n"
127
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
129
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
128
            "mov psr.l=r9;;\n"
130
            "mov psr.l=r9;;\n"
129
            "srlz.d;;\n"
131
            "srlz.d;;\n"
130
            "srlz.i;;\n"
132
            "srlz.i;;\n"
131
            "mov cr20=%1\n"             /*va*/      /*cr20 == IFA*/
133
            "mov cr.ifa=%1\n"               /*va*/       
132
            "mov cr21=%2;;\n"                   /*entry.word[1]*/ /*cr21=ITIR*/
134
            "mov cr.itir=%2;;\n"                /*entry.word[1]*/
133
            "itc.i %3;;\n"                      /*entry.word[0]*/
135
            "itc.i %3;;\n"                      /*entry.word[0]*/
134
            "mov psr.l=r8;;\n"
136
            "mov psr.l=r8;;\n"
135
            "srlz.d;;\n"
137
            "srlz.d;;\n"
136
            :
138
            :
137
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
139
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
138
            :"r8","r9"
140
            :"r8","r9"
139
        );
141
        );
140
    }
142
    }
141
    else
143
    else
142
    {
144
    {
143
        region_register rr0;
145
        region_register rr0;
144
        rr0=rr;
146
        rr0=rr;
145
        rr0.map.rid=ASID2RID(asid,VA_REGION(va));
147
        rr0.map.rid=ASID2RID(asid,VA_REGION(va));
146
        rr_write(VA_REGION(va),rr0.word);
148
        rr_write(VA_REGION(va),rr0.word);
-
 
149
        srlz_d();
147
        asm
150
        asm volatile
148
        (
151
        (
149
            "mov r8=psr;;\n"
152
            "mov r8=psr;;\n"
150
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
153
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
151
            "mov psr.l=r9;;\n"
154
            "mov psr.l=r9;;\n"
152
            "srlz.d;;\n"
155
            "srlz.d;;\n"
153
            "mov cr20=%1\n"             /*va*/      /*cr20 == IFA*/
156
            "mov cr.ifa=%1\n"           /*va*/       
154
            "mov cr21=%2;;\n"                   /*entry.word[1]*/ /*cr21=ITIR*/
157
            "mov cr.itir=%2;;\n"            /*entry.word[1]*/
155
            "itc.i %3;;\n"                      /*entry.word[0]*/
158
            "itc.i %3;;\n"                      /*entry.word[0]*/
156
            "mov psr.l=r8;;\n"
159
            "mov psr.l=r8;;\n"
157
            "srlz.d;;\n"
160
            "srlz.d;;\n"
158
            :
161
            :
159
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
162
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0])
160
            :"r8","r9"
163
            :"r8","r9"
161
        );
164
        );
162
        rr_write(VA_REGION(va),rr.word);
165
        rr_write(VA_REGION(va),rr.word);
163
    }
166
    }
164
 
167
 
165
 
168
 
166
}
169
}
167
 
170
 
168
 
171
 
-
 
172
void tlb_fill_data_tr(__u64 tr,__address va,asid_t asid,tlb_entry_t entry)
-
 
173
{
-
 
174
    region_register rr;
-
 
175
 
-
 
176
 
-
 
177
    if(!(entry.not_present.p)) return;
-
 
178
 
-
 
179
    rr.word=rr_read(VA_REGION(va));
-
 
180
 
-
 
181
    if(rr.map.rid==ASID2RID(asid,VA_REGION(va)))
-
 
182
    {
-
 
183
        asm volatile
-
 
184
        (
-
 
185
            "srlz.i;;\n"
-
 
186
            "srlz.d;;\n"
-
 
187
            "mov r8=psr;;\n"
-
 
188
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
-
 
189
            "mov psr.l=r9;;\n"
-
 
190
            "srlz.d;;\n"
-
 
191
            "srlz.i;;\n"
-
 
192
            "mov cr.ifa=%1\n"               /*va*/       
-
 
193
            "mov cr.itir=%2;;\n"                /*entry.word[1]*/
-
 
194
            "itr.d dtr[%4]=%3;;\n"                      /*entry.word[0]*/
-
 
195
            "mov psr.l=r8;;\n"
-
 
196
            "srlz.d;;\n"
-
 
197
            :
-
 
198
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr)
-
 
199
            :"r8","r9"
-
 
200
        );
-
 
201
    }
-
 
202
    else
-
 
203
    {
-
 
204
        region_register rr0;
-
 
205
        rr0=rr;
-
 
206
        rr0.map.rid=ASID2RID(asid,VA_REGION(va));
-
 
207
        rr_write(VA_REGION(va),rr0.word);
-
 
208
        srlz_d();
-
 
209
        asm volatile
-
 
210
        (
-
 
211
            "mov r8=psr;;\n"
-
 
212
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
-
 
213
            "mov psr.l=r9;;\n"
-
 
214
            "srlz.d;;\n"
-
 
215
            "mov cr.ifa=%1\n"               /*va*/       
-
 
216
            "mov cr.itir=%2;;\n"                /*entry.word[1]*/
-
 
217
            "itr.d dtr[%4]=%3;;\n"                      /*entry.word[0]*/
-
 
218
            "mov psr.l=r8;;\n"
-
 
219
            "srlz.d;;\n"
-
 
220
            :
-
 
221
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr)
-
 
222
            :"r8","r9"
-
 
223
        );
-
 
224
        rr_write(VA_REGION(va),rr.word);
-
 
225
    }
-
 
226
 
-
 
227
 
-
 
228
}
-
 
229
 
-
 
230
void tlb_fill_code_tr(__u64 tr,__address va,asid_t asid,tlb_entry_t entry)
-
 
231
{
-
 
232
    region_register rr;
-
 
233
 
-
 
234
 
-
 
235
    if(!(entry.not_present.p)) return;
-
 
236
 
-
 
237
    rr.word=rr_read(VA_REGION(va));
-
 
238
 
-
 
239
    if(rr.map.rid==ASID2RID(asid,VA_REGION(va)))
-
 
240
    {
-
 
241
        asm volatile
-
 
242
        (
-
 
243
            "srlz.i;;\n"
-
 
244
            "srlz.d;;\n"
-
 
245
            "mov r8=psr;;\n"
-
 
246
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
-
 
247
            "mov psr.l=r9;;\n"
-
 
248
            "srlz.d;;\n"
-
 
249
            "srlz.i;;\n"
-
 
250
            "mov cr.ifa=%1\n"               /*va*/       
-
 
251
            "mov cr.itir=%2;;\n"                /*entry.word[1]*/
-
 
252
            "itr.i itr[%4]=%3;;\n"                      /*entry.word[0]*/
-
 
253
            "mov psr.l=r8;;\n"
-
 
254
            "srlz.d;;\n"
-
 
255
            :
-
 
256
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr)
-
 
257
            :"r8","r9"
-
 
258
        );
-
 
259
    }
-
 
260
    else
-
 
261
    {
-
 
262
        region_register rr0;
-
 
263
        rr0=rr;
-
 
264
        rr0.map.rid=ASID2RID(asid,VA_REGION(va));
-
 
265
        rr_write(VA_REGION(va),rr0.word);
-
 
266
        srlz_d();
-
 
267
        asm volatile
-
 
268
        (
-
 
269
            "mov r8=psr;;\n"
-
 
270
            "and r9=r8,%0;;\n"                  /*(~PSR_IC_MASK)*/
-
 
271
            "mov psr.l=r9;;\n"
-
 
272
            "srlz.d;;\n"
-
 
273
            "mov cr.ifa=%1\n"           /*va*/       
-
 
274
            "mov cr.itir=%2;;\n"            /*entry.word[1]*/
-
 
275
            "itr.i itr[%4]=%3;;\n"                      /*entry.word[0]*/
-
 
276
            "mov psr.l=r8;;\n"
-
 
277
            "srlz.d;;\n"
-
 
278
            :
-
 
279
            :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr)
-
 
280
            :"r8","r9"
-
 
281
        );
-
 
282
        rr_write(VA_REGION(va),rr.word);
-
 
283
    }
-
 
284
 
-
 
285
 
-
 
286
}
-
 
287
 
169
 
288