Subversion Repositories HelenOS-historic

Rev

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

Rev 899 Rev 900
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
#include <arch/barrier.h>
-
 
36
#include <arch/interrupt.h>
36
#include <typedefs.h>
37
#include <typedefs.h>
-
 
38
#include <panic.h>
37
 
39
 
38
/** Invalidate all TLB entries. */
40
/** Invalidate all TLB entries. */
39
void tlb_invalidate_all(void)
41
void tlb_invalidate_all(void)
40
{
42
{
41
    /* TODO */
43
    /* TODO */
42
}
44
}
43
 
45
 
44
/** Invalidate entries belonging to an address space.
46
/** Invalidate entries belonging to an address space.
45
 *
47
 *
46
 * @param asid Address space identifier.
48
 * @param asid Address space identifier.
47
 */
49
 */
48
void tlb_invalidate_asid(asid_t asid)
50
void tlb_invalidate_asid(asid_t asid)
49
{
51
{
50
    /* TODO */
52
    /* TODO */
51
}
53
}
52
 
54
 
53
/** Insert data into data translation cache.
55
/** Insert data into data translation cache.
54
 *
56
 *
55
 * @param va Virtual page address.
57
 * @param va Virtual page address.
56
 * @param asid Address space identifier.
58
 * @param asid Address space identifier.
57
 * @param entry The rest of TLB entry as required by TLB insertion format.
59
 * @param entry The rest of TLB entry as required by TLB insertion format.
58
 */
60
 */
59
void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
61
void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
60
    tc_mapping_insert(va, asid, entry, true);
62
    tc_mapping_insert(va, asid, entry, true);
61
}
63
}
62
 
64
 
63
/** Insert data into instruction translation cache.
65
/** Insert data into instruction translation cache.
64
 *
66
 *
65
 * @param va Virtual page address.
67
 * @param va Virtual page address.
66
 * @param asid Address space identifier.
68
 * @param asid Address space identifier.
67
 * @param entry The rest of TLB entry as required by TLB insertion format.
69
 * @param entry The rest of TLB entry as required by TLB insertion format.
68
 */
70
 */
69
void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
71
void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
70
    tc_mapping_insert(va, asid, entry, false);
72
    tc_mapping_insert(va, asid, entry, false);
71
}
73
}
72
 
74
 
73
/** Insert data into instruction or data translation cache.
75
/** Insert data into instruction or data translation cache.
74
 *
76
 *
75
 * @param va Virtual page address.
77
 * @param va Virtual page address.
76
 * @param asid Address space identifier.
78
 * @param asid Address space identifier.
77
 * @param entry The rest of TLB entry as required by TLB insertion format.
79
 * @param entry The rest of TLB entry as required by TLB insertion format.
78
 * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
80
 * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
79
 */
81
 */
80
void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc)
82
void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc)
81
{
83
{
82
    region_register rr;
84
    region_register rr;
83
    bool restore_rr = false;
85
    bool restore_rr = false;
84
 
86
 
85
    if (!(entry.not_present.p))
87
    if (!(entry.not_present.p))
86
        return;
88
        return;
87
 
89
 
88
    rr.word = rr_read(VA_REGION(va));
90
    rr.word = rr_read(VA_REGION(va));
89
    if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
91
    if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
90
        /*
92
        /*
91
         * The selected region register does not contain required RID.
93
         * The selected region register does not contain required RID.
92
         * Save the old content of the register and replace the RID.
94
         * Save the old content of the register and replace the RID.
93
         */
95
         */
94
        region_register rr0;
96
        region_register rr0;
95
 
97
 
96
        rr0 = rr;
98
        rr0 = rr;
97
        rr0.map.rid = ASID2RID(asid, VA_REGION(va));
99
        rr0.map.rid = ASID2RID(asid, VA_REGION(va));
98
        rr_write(VA_REGION(va), rr0.word);
100
        rr_write(VA_REGION(va), rr0.word);
99
        srlz_d();
101
        srlz_d();
100
        srlz_i();
102
        srlz_i();
101
    }
103
    }
102
   
104
   
103
    __asm__ volatile (
105
    __asm__ volatile (
104
        "mov r8=psr;;\n"
106
        "mov r8=psr;;\n"
105
        "and r9=r8,%0;;\n"          /* (~PSR_IC_MASK) */
107
        "rsm %0;;\n"            /* PSR_IC_MASK */
106
        "mov psr.l=r9;;\n"
-
 
107
        "srlz.d;;\n"
108
        "srlz.d;;\n"
108
        "srlz.i;;\n"
109
        "srlz.i;;\n"
109
        "mov cr.ifa=%1\n"       /* va */
110
        "mov cr.ifa=%1\n"       /* va */
110
        "mov cr.itir=%2;;\n"        /* entry.word[1] */
111
        "mov cr.itir=%2;;\n"        /* entry.word[1] */
111
        "cmp.eq p6,p7 = %4,r0;;\n"  /* decide between itc and dtc */
112
        "cmp.eq p6,p7 = %4,r0;;\n"  /* decide between itc and dtc */
112
        "(p6) itc.i %3;;\n"
113
        "(p6) itc.i %3;;\n"
113
        "(p7) itc.d %3;;\n"
114
        "(p7) itc.d %3;;\n"
114
        "mov psr.l=r8;;\n"
115
        "mov psr.l=r8;;\n"
115
        "srlz.d;;\n"
116
        "srlz.d;;\n"
116
        :
117
        :
117
        : "r" (~PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
118
        : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
118
        : "p6", "p7", "r8", "r9"
119
        : "p6", "p7", "r8"
119
    );
120
    );
120
   
121
   
121
    if (restore_rr) {
122
    if (restore_rr) {
122
        rr_write(VA_REGION(va),rr.word);
123
        rr_write(VA_REGION(va),rr.word);
123
        srlz_d();
124
        srlz_d();
124
        srlz_i();
125
        srlz_i();
125
    }
126
    }
126
}
127
}
127
 
128
 
128
/** Insert data into instruction translation register.
129
/** Insert data into instruction translation register.
129
 *
130
 *
130
 * @param va Virtual page address.
131
 * @param va Virtual page address.
131
 * @param asid Address space identifier.
132
 * @param asid Address space identifier.
132
 * @param entry The rest of TLB entry as required by TLB insertion format.
133
 * @param entry The rest of TLB entry as required by TLB insertion format.
133
 * @param tr Translation register.
134
 * @param tr Translation register.
134
 */
135
 */
135
void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
136
void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
136
{
137
{
137
    tr_mapping_insert(va, asid, entry, false, tr);
138
    tr_mapping_insert(va, asid, entry, false, tr);
138
}
139
}
139
 
140
 
140
/** Insert data into data translation register.
141
/** Insert data into data translation register.
141
 *
142
 *
142
 * @param va Virtual page address.
143
 * @param va Virtual page address.
143
 * @param asid Address space identifier.
144
 * @param asid Address space identifier.
144
 * @param entry The rest of TLB entry as required by TLB insertion format.
145
 * @param entry The rest of TLB entry as required by TLB insertion format.
145
 * @param tr Translation register.
146
 * @param tr Translation register.
146
 */
147
 */
147
void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
148
void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
148
{
149
{
149
    tr_mapping_insert(va, asid, entry, true, tr);
150
    tr_mapping_insert(va, asid, entry, true, tr);
150
}
151
}
151
 
152
 
152
/** Insert data into instruction or data translation register.
153
/** Insert data into instruction or data translation register.
153
 *
154
 *
154
 * @param va Virtual page address.
155
 * @param va Virtual page address.
155
 * @param asid Address space identifier.
156
 * @param asid Address space identifier.
156
 * @param entry The rest of TLB entry as required by TLB insertion format.
157
 * @param entry The rest of TLB entry as required by TLB insertion format.
157
 * @param dtc If true, insert into data translation register, use instruction translation register otherwise.
158
 * @param dtc If true, insert into data translation register, use instruction translation register otherwise.
158
 * @param tr Translation register.
159
 * @param tr Translation register.
159
 */
160
 */
160
void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
161
void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
161
{
162
{
162
    region_register rr;
163
    region_register rr;
163
    bool restore_rr = false;
164
    bool restore_rr = false;
164
 
165
 
165
    if (!(entry.not_present.p))
166
    if (!(entry.not_present.p))
166
        return;
167
        return;
167
 
168
 
168
    rr.word = rr_read(VA_REGION(va));
169
    rr.word = rr_read(VA_REGION(va));
169
    if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
170
    if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
170
        /*
171
        /*
171
         * The selected region register does not contain required RID.
172
         * The selected region register does not contain required RID.
172
         * Save the old content of the register and replace the RID.
173
         * Save the old content of the register and replace the RID.
173
         */
174
         */
174
        region_register rr0;
175
        region_register rr0;
175
 
176
 
176
        rr0 = rr;
177
        rr0 = rr;
177
        rr0.map.rid = ASID2RID(asid, VA_REGION(va));
178
        rr0.map.rid = ASID2RID(asid, VA_REGION(va));
178
        rr_write(VA_REGION(va), rr0.word);
179
        rr_write(VA_REGION(va), rr0.word);
179
        srlz_d();
180
        srlz_d();
180
        srlz_i();
181
        srlz_i();
181
    }
182
    }
182
 
183
 
183
    __asm__ volatile (
184
    __asm__ volatile (
184
        "mov r8=psr;;\n"
185
        "mov r8=psr;;\n"
185
        "and r9=r8,%0;;\n"      /* (~PSR_IC_MASK) */
186
        "rsm %0;;\n"            /* PSR_IC_MASK */
186
        "mov psr.l=r9;;\n"
-
 
187
        "srlz.d;;\n"
187
        "srlz.d;;\n"
188
        "srlz.i;;\n"
188
        "srlz.i;;\n"
189
        "mov cr.ifa=%1\n"           /* va */         
189
        "mov cr.ifa=%1\n"           /* va */         
190
        "mov cr.itir=%2;;\n"        /* entry.word[1] */
190
        "mov cr.itir=%2;;\n"        /* entry.word[1] */
191
        "cmp.eq p6,p7=%5,r0;;\n"    /* decide between itr and dtr */
191
        "cmp.eq p6,p7=%5,r0;;\n"    /* decide between itr and dtr */
192
        "(p6) itr.i itr[%4]=%3;;\n"
192
        "(p6) itr.i itr[%4]=%3;;\n"
193
        "(p7) itr.d dtr[%4]=%3;;\n"
193
        "(p7) itr.d dtr[%4]=%3;;\n"
194
        "mov psr.l=r8;;\n"
194
        "mov psr.l=r8;;\n"
195
        "srlz.d;;\n"
195
        "srlz.d;;\n"
196
        :
196
        :
197
        :"r" (~PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
197
        : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
198
        : "p6", "p7", "r8", "r9"
198
        : "p6", "p7", "r8"
199
    );
199
    );
200
   
200
   
201
    if (restore_rr) {
201
    if (restore_rr) {
202
        rr_write(VA_REGION(va),rr.word);
202
        rr_write(VA_REGION(va),rr.word);
203
        srlz_d();
203
        srlz_d();
204
        srlz_i();
204
        srlz_i();
205
    }
205
    }
206
}
206
}
207
 
207
 
208
void alternate_instruction_tlb_fault(void)
208
void alternate_instruction_tlb_fault(__u64 vector, struct exception_regdump *pstate)
209
{
209
{
210
    panic("%s\n", __FUNCTION__);
210
    panic("%s\n", __FUNCTION__);
211
}
211
}
212
 
212
 
213
void alternate_data_tlb_fault(void)
213
void alternate_data_tlb_fault(__u64 vector, struct exception_regdump *pstate)
214
{
214
{
215
    panic("%s\n", __FUNCTION__);
215
    panic("%s: %P\n", __FUNCTION__, pstate->cr_ifa);
216
}
216
}
217
 
217
 
218
void data_nested_tlb_fault(void)
218
void data_nested_tlb_fault(__u64 vector, struct exception_regdump *pstate)
219
{
219
{
220
    panic("%s\n", __FUNCTION__);
220
    panic("%s\n", __FUNCTION__);
221
}
221
}
222
 
222
 
223
void data_dirty_bit_fault(void)
223
void data_dirty_bit_fault(__u64 vector, struct exception_regdump *pstate)
224
{
224
{
225
    panic("%s\n", __FUNCTION__);
225
    panic("%s\n", __FUNCTION__);
226
}
226
}
227
 
227
 
228
void instruction_access_bit_fault(void)
228
void instruction_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
229
{
229
{
230
    panic("%s\n", __FUNCTION__);
230
    panic("%s\n", __FUNCTION__);
231
}
231
}
232
 
232
 
233
void data_access_bit_fault(void)
233
void data_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
234
{
234
{
235
    panic("%s\n", __FUNCTION__);
235
    panic("%s\n", __FUNCTION__);
236
}
236
}
237
 
237
 
238
void page_not_present(void)
238
void page_not_present(__u64 vector, struct exception_regdump *pstate)
239
{
239
{
240
    panic("%s\n", __FUNCTION__);
240
    panic("%s\n", __FUNCTION__);
241
}
241
}
242
 
242