Subversion Repositories HelenOS

Rev

Rev 1851 | Rev 1859 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1851 Rev 1852
Line 48... Line 48...
48
#include <arch/trap/trap.h>
48
#include <arch/trap/trap.h>
49
#include <panic.h>
49
#include <panic.h>
50
#include <arch/asm.h>
50
#include <arch/asm.h>
51
#include <symtab.h>
51
#include <symtab.h>
52
 
52
 
-
 
53
static void dtlb_pte_copy(pte_t *t, bool ro);
53
static void dtlb_pte_copy(pte_t *t);
54
static void itlb_pte_copy(pte_t *t);
54
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
55
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
-
 
56
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str);
55
 
57
 
56
char *context_encoding[] = {
58
char *context_encoding[] = {
57
    "Primary",
59
    "Primary",
58
    "Secondary",
60
    "Secondary",
59
    "Nucleus",
61
    "Nucleus",
Line 103... Line 105...
103
    data.g = true;
105
    data.g = true;
104
 
106
 
105
    dtlb_data_in_write(data.value);
107
    dtlb_data_in_write(data.value);
106
}
108
}
107
 
109
 
-
 
110
/** Copy PTE to TLB.
-
 
111
 *
-
 
112
 * @param t Page Table Entry to be copied.
-
 
113
 * @param ro If true, the entry will be created read-only, regardless of its w field.
-
 
114
 */
108
void dtlb_pte_copy(pte_t *t)
115
void dtlb_pte_copy(pte_t *t, bool ro)
109
{
116
{
-
 
117
    tlb_tag_access_reg_t tag;
-
 
118
    tlb_data_t data;
-
 
119
    page_address_t pg;
-
 
120
    frame_address_t fr;
-
 
121
 
-
 
122
    pg.address = t->page;
-
 
123
    fr.address = t->frame;
-
 
124
 
-
 
125
    tag.value = 0;
-
 
126
    tag.context = t->as->asid;
-
 
127
    tag.vpn = pg.vpn;
-
 
128
   
-
 
129
    dtlb_tag_access_write(tag.value);
-
 
130
   
-
 
131
    data.value = 0;
-
 
132
    data.v = true;
-
 
133
    data.size = PAGESIZE_8K;
-
 
134
    data.pfn = fr.pfn;
-
 
135
    data.l = false;
-
 
136
    data.cp = t->c;
-
 
137
    data.cv = t->c;
-
 
138
    data.p = t->p;
-
 
139
    data.w = ro ? false : t->w;
-
 
140
    data.g = t->g;
-
 
141
   
-
 
142
    dtlb_data_in_write(data.value);
-
 
143
}
-
 
144
 
-
 
145
void itlb_pte_copy(pte_t *t)
-
 
146
{
-
 
147
    tlb_tag_access_reg_t tag;
-
 
148
    tlb_data_t data;
-
 
149
    page_address_t pg;
-
 
150
    frame_address_t fr;
-
 
151
 
-
 
152
    pg.address = t->page;
-
 
153
    fr.address = t->frame;
-
 
154
 
-
 
155
    tag.value = 0;
-
 
156
    tag.context = t->as->asid;
-
 
157
    tag.vpn = pg.vpn;
-
 
158
   
-
 
159
    itlb_tag_access_write(tag.value);
-
 
160
   
-
 
161
    data.value = 0;
-
 
162
    data.v = true;
-
 
163
    data.size = PAGESIZE_8K;
-
 
164
    data.pfn = fr.pfn;
-
 
165
    data.l = false;
-
 
166
    data.cp = t->c;
-
 
167
    data.cv = t->c;
-
 
168
    data.p = t->p;
-
 
169
    data.w = false;
-
 
170
    data.g = t->g;
-
 
171
   
-
 
172
    itlb_data_in_write(data.value);
110
}
173
}
111
 
174
 
112
/** ITLB miss handler. */
175
/** ITLB miss handler. */
113
void fast_instruction_access_mmu_miss(int n, istate_t *istate)
176
void fast_instruction_access_mmu_miss(int n, istate_t *istate)
114
{
177
{
-
 
178
    uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
-
 
179
    pte_t *t;
-
 
180
 
-
 
181
    page_table_lock(AS, true);
-
 
182
    t = page_mapping_find(AS, va);
-
 
183
    if (t && PTE_EXECUTABLE(t)) {
-
 
184
        /*
-
 
185
         * The mapping was found in the software page hash table.
-
 
186
         * Insert it into ITLB.
-
 
187
         */
-
 
188
        t->a = true;
-
 
189
        itlb_pte_copy(t);
115
    panic("%s\n", __FUNCTION__);
190
        page_table_unlock(AS, true);
-
 
191
    } else {
-
 
192
        /*
-
 
193
         * Forward the page fault to the address space page fault handler.
-
 
194
         */    
-
 
195
        page_table_unlock(AS, true);
-
 
196
        if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
-
 
197
            do_fast_instruction_access_mmu_miss_fault(istate, __FUNCTION__);
-
 
198
        }
-
 
199
    }
116
}
200
}
117
 
201
 
118
/** DTLB miss handler.
202
/** DTLB miss handler.
119
 *
203
 *
120
 * Note that some faults (e.g. kernel faults) were already resolved
204
 * Note that some faults (e.g. kernel faults) were already resolved
Line 142... Line 226...
142
    if (t) {
226
    if (t) {
143
        /*
227
        /*
144
         * The mapping was found in the software page hash table.
228
         * The mapping was found in the software page hash table.
145
         * Insert it into DTLB.
229
         * Insert it into DTLB.
146
         */
230
         */
-
 
231
        t->a = true;
147
        dtlb_pte_copy(t);
232
        dtlb_pte_copy(t, true);
148
        page_table_unlock(AS, true);
233
        page_table_unlock(AS, true);
149
    } else {
234
    } else {
150
        /*
235
        /*
151
         * Forward the page fault to the address space page fault handler.
236
         * Forward the page fault to the address space page fault handler.
152
         */    
237
         */    
Line 188... Line 273...
188
            i, t.vpn, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
273
            i, t.vpn, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
189
    }
274
    }
190
 
275
 
191
}
276
}
192
 
277
 
-
 
278
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str)
-
 
279
{
-
 
280
    char *tpc_str = get_symtab_entry(istate->tpc);
-
 
281
 
-
 
282
    printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
-
 
283
    panic("%s\n", str);
-
 
284
}
-
 
285
 
193
void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
286
void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
194
{
287
{
195
    tlb_tag_access_reg_t tag;
288
    tlb_tag_access_reg_t tag;
196
    uintptr_t va;
289
    uintptr_t va;
197
    char *tpc_str = get_symtab_entry(istate->tpc);
290
    char *tpc_str = get_symtab_entry(istate->tpc);