Subversion Repositories HelenOS-historic

Rev

Rev 900 | Rev 902 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
740 jermar 1
/*
2
 * Copyright (C) 2006 Jakub Jermar
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
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
15
 *   derived from this software without specific prior written permission.
16
 *
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
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
/*
30
 * TLB management.
31
 */
32
 
33
#include <mm/tlb.h>
901 jermar 34
#include <mm/asid.h>
818 vana 35
#include <arch/mm/tlb.h>
901 jermar 36
#include <arch/mm/page.h>
819 vana 37
#include <arch/barrier.h>
900 jermar 38
#include <arch/interrupt.h>
899 jermar 39
#include <typedefs.h>
900 jermar 40
#include <panic.h>
901 jermar 41
#include <print.h>
740 jermar 42
 
756 jermar 43
/** Invalidate all TLB entries. */
740 jermar 44
void tlb_invalidate_all(void)
45
{
46
    /* TODO */
47
}
48
 
49
/** Invalidate entries belonging to an address space.
50
 *
51
 * @param asid Address space identifier.
52
 */
53
void tlb_invalidate_asid(asid_t asid)
54
{
55
    /* TODO */
56
}
818 vana 57
 
899 jermar 58
/** Insert data into data translation cache.
59
 *
60
 * @param va Virtual page address.
61
 * @param asid Address space identifier.
62
 * @param entry The rest of TLB entry as required by TLB insertion format.
63
 */
64
void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
65
    tc_mapping_insert(va, asid, entry, true);
66
}
818 vana 67
 
899 jermar 68
/** Insert data into instruction translation cache.
69
 *
70
 * @param va Virtual page address.
71
 * @param asid Address space identifier.
72
 * @param entry The rest of TLB entry as required by TLB insertion format.
73
 */
74
void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
75
    tc_mapping_insert(va, asid, entry, false);
76
}
818 vana 77
 
899 jermar 78
/** Insert data into instruction or data translation cache.
79
 *
80
 * @param va Virtual page address.
81
 * @param asid Address space identifier.
82
 * @param entry The rest of TLB entry as required by TLB insertion format.
83
 * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
84
 */
85
void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc)
818 vana 86
{
87
    region_register rr;
899 jermar 88
    bool restore_rr = false;
818 vana 89
 
901 jermar 90
    if (!(entry.p))
899 jermar 91
        return;
818 vana 92
 
901 jermar 93
    rr.word = rr_read(VA2VRN(va));
94
    if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
899 jermar 95
        /*
96
         * The selected region register does not contain required RID.
97
         * Save the old content of the register and replace the RID.
98
         */
99
        region_register rr0;
818 vana 100
 
899 jermar 101
        rr0 = rr;
901 jermar 102
        rr0.map.rid = ASID2RID(asid, VA2VRN(va));
103
        rr_write(VA2VRN(va), rr0.word);
899 jermar 104
        srlz_d();
105
        srlz_i();
818 vana 106
    }
899 jermar 107
 
108
    __asm__ volatile (
109
        "mov r8=psr;;\n"
900 jermar 110
        "rsm %0;;\n"            /* PSR_IC_MASK */
899 jermar 111
        "srlz.d;;\n"
112
        "srlz.i;;\n"
113
        "mov cr.ifa=%1\n"       /* va */
114
        "mov cr.itir=%2;;\n"        /* entry.word[1] */
115
        "cmp.eq p6,p7 = %4,r0;;\n"  /* decide between itc and dtc */
116
        "(p6) itc.i %3;;\n"
117
        "(p7) itc.d %3;;\n"
118
        "mov psr.l=r8;;\n"
119
        "srlz.d;;\n"
120
        :
900 jermar 121
        : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
122
        : "p6", "p7", "r8"
899 jermar 123
    );
124
 
125
    if (restore_rr) {
901 jermar 126
        rr_write(VA2VRN(va), rr.word);
819 vana 127
        srlz_d();
899 jermar 128
        srlz_i();
818 vana 129
    }
899 jermar 130
}
818 vana 131
 
899 jermar 132
/** Insert data into instruction translation register.
133
 *
134
 * @param va Virtual page address.
135
 * @param asid Address space identifier.
136
 * @param entry The rest of TLB entry as required by TLB insertion format.
137
 * @param tr Translation register.
138
 */
139
void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
140
{
141
    tr_mapping_insert(va, asid, entry, false, tr);
142
}
818 vana 143
 
899 jermar 144
/** Insert data into data translation register.
145
 *
146
 * @param va Virtual page address.
147
 * @param asid Address space identifier.
148
 * @param entry The rest of TLB entry as required by TLB insertion format.
149
 * @param tr Translation register.
150
 */
151
void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
152
{
153
    tr_mapping_insert(va, asid, entry, true, tr);
818 vana 154
}
155
 
899 jermar 156
/** Insert data into instruction or data translation register.
157
 *
158
 * @param va Virtual page address.
159
 * @param asid Address space identifier.
160
 * @param entry The rest of TLB entry as required by TLB insertion format.
161
 * @param dtc If true, insert into data translation register, use instruction translation register otherwise.
162
 * @param tr Translation register.
163
 */
164
void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
818 vana 165
{
166
    region_register rr;
899 jermar 167
    bool restore_rr = false;
818 vana 168
 
901 jermar 169
    if (!(entry.p))
899 jermar 170
        return;
818 vana 171
 
901 jermar 172
    rr.word = rr_read(VA2VRN(va));
173
    if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
899 jermar 174
        /*
175
         * The selected region register does not contain required RID.
176
         * Save the old content of the register and replace the RID.
177
         */
178
        region_register rr0;
818 vana 179
 
899 jermar 180
        rr0 = rr;
901 jermar 181
        rr0.map.rid = ASID2RID(asid, VA2VRN(va));
182
        rr_write(VA2VRN(va), rr0.word);
899 jermar 183
        srlz_d();
184
        srlz_i();
185
    }
818 vana 186
 
899 jermar 187
    __asm__ volatile (
188
        "mov r8=psr;;\n"
900 jermar 189
        "rsm %0;;\n"            /* PSR_IC_MASK */
899 jermar 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
        "cmp.eq p6,p7=%5,r0;;\n"    /* decide between itr and dtr */
195
        "(p6) itr.i itr[%4]=%3;;\n"
196
        "(p7) itr.d dtr[%4]=%3;;\n"
197
        "mov psr.l=r8;;\n"
198
        "srlz.d;;\n"
199
        :
900 jermar 200
        : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
201
        : "p6", "p7", "r8"
899 jermar 202
    );
203
 
204
    if (restore_rr) {
901 jermar 205
        rr_write(VA2VRN(va), rr.word);
819 vana 206
        srlz_d();
899 jermar 207
        srlz_i();
818 vana 208
    }
899 jermar 209
}
818 vana 210
 
901 jermar 211
/** Insert data into DTLB.
212
 *
213
 * @param va Virtual page address.
214
 * @param asid Address space identifier.
215
 * @param entry The rest of TLB entry as required by TLB insertion format.
216
 * @param dtr If true, insert into data translation register, use data translation cache otherwise.
217
 * @param tr Translation register if dtr is true, ignored otherwise.
218
 */
219
void dtlb_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
220
{
221
    tlb_entry_t entry;
222
 
223
    entry.word[0] = 0;
224
    entry.word[1] = 0;
225
 
226
    entry.p = true;         /* present */
227
    entry.ma = MA_WRITEBACK;
228
    entry.a = true;         /* already accessed */
229
    entry.d = true;         /* already dirty */
230
    entry.pl = PL_KERNEL;
231
    entry.ar = AR_READ | AR_WRITE;
232
    entry.ppn = frame >> PPN_SHIFT;
233
    entry.ps = PAGE_WIDTH;
234
 
235
    if (dtr)
236
        dtr_mapping_insert(page, ASID_KERNEL, entry, tr);
237
    else
238
        dtc_mapping_insert(page, ASID_KERNEL, entry);
239
}
240
 
900 jermar 241
void alternate_instruction_tlb_fault(__u64 vector, struct exception_regdump *pstate)
899 jermar 242
{
243
    panic("%s\n", __FUNCTION__);
244
}
818 vana 245
 
901 jermar 246
/** Data TLB fault with VHPT turned off.
247
 *
248
 * @param vector Interruption vector.
249
 * @param pstate Structure with saved interruption state.
250
 */
900 jermar 251
void alternate_data_tlb_fault(__u64 vector, struct exception_regdump *pstate)
899 jermar 252
{
901 jermar 253
    region_register rr;
254
    rid_t rid;
255
    __address va;
256
 
257
    va = pstate->cr_ifa;    /* faulting address */
258
    rr.word = rr_read(VA2VRN(va));
259
    rid = rr.map.rid;
260
    if (RID2ASID(rid) == ASID_KERNEL) {
261
        if (VA2VRN(va) == VRN_KERNEL) {
262
            /*
263
             * Provide KA2PA(identity) mapping for faulting piece of
264
             * kernel address space.
265
             */
266
            dtlb_mapping_insert(va, KA2PA(va), false, 0);
267
            return;
268
        }
269
    }
270
    panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
818 vana 271
}
272
 
900 jermar 273
void data_nested_tlb_fault(__u64 vector, struct exception_regdump *pstate)
899 jermar 274
{
275
    panic("%s\n", __FUNCTION__);
276
}
818 vana 277
 
900 jermar 278
void data_dirty_bit_fault(__u64 vector, struct exception_regdump *pstate)
819 vana 279
{
899 jermar 280
    panic("%s\n", __FUNCTION__);
281
}
819 vana 282
 
900 jermar 283
void instruction_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
899 jermar 284
{
285
    panic("%s\n", __FUNCTION__);
286
}
819 vana 287
 
900 jermar 288
void data_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
899 jermar 289
{
290
    panic("%s\n", __FUNCTION__);
819 vana 291
}
292
 
900 jermar 293
void page_not_present(__u64 vector, struct exception_regdump *pstate)
819 vana 294
{
899 jermar 295
    panic("%s\n", __FUNCTION__);
819 vana 296
}