Subversion Repositories HelenOS-historic

Rev

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