Subversion Repositories HelenOS

Rev

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

Rev 4055 Rev 4296
Line 197... Line 197...
197
}
197
}
198
 
198
 
199
/** ITLB miss handler. */
199
/** ITLB miss handler. */
200
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
200
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
201
{
201
{
202
    uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
202
    uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
203
    index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
203
    index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
204
    pte_t *t;
204
    pte_t *t;
205
 
205
 
206
    page_table_lock(AS, true);
206
    page_table_lock(AS, true);
207
    t = page_mapping_find(AS, va);
207
    t = page_mapping_find(AS, page_16k);
208
    if (t && PTE_EXECUTABLE(t)) {
208
    if (t && PTE_EXECUTABLE(t)) {
209
        /*
209
        /*
210
         * The mapping was found in the software page hash table.
210
         * The mapping was found in the software page hash table.
211
         * Insert it into ITLB.
211
         * Insert it into ITLB.
212
         */
212
         */
Line 220... Line 220...
220
        /*
220
        /*
221
         * Forward the page fault to the address space page fault
221
         * Forward the page fault to the address space page fault
222
         * handler.
222
         * handler.
223
         */    
223
         */    
224
        page_table_unlock(AS, true);
224
        page_table_unlock(AS, true);
225
        if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
225
        if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
-
 
226
            AS_PF_FAULT) {
226
            do_fast_instruction_access_mmu_miss_fault(istate,
227
            do_fast_instruction_access_mmu_miss_fault(istate,
227
                __func__);
228
                __func__);
228
        }
229
        }
229
    }
230
    }
230
}
231
}
Line 240... Line 241...
240
 *          DTLB miss.
241
 *          DTLB miss.
241
 * @param istate    Interrupted state saved on the stack.
242
 * @param istate    Interrupted state saved on the stack.
242
 */
243
 */
243
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
244
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
244
{
245
{
245
    uintptr_t va;
246
    uintptr_t page_8k;
-
 
247
    uintptr_t page_16k;
246
    index_t index;
248
    index_t index;
247
    pte_t *t;
249
    pte_t *t;
248
 
250
 
249
    va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
251
    page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
-
 
252
    page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
250
    index = tag.vpn % MMU_PAGES_PER_PAGE;
253
    index = tag.vpn % MMU_PAGES_PER_PAGE;
251
 
254
 
252
    if (tag.context == ASID_KERNEL) {
255
    if (tag.context == ASID_KERNEL) {
253
        if (!tag.vpn) {
256
        if (!tag.vpn) {
254
            /* NULL access in kernel */
257
            /* NULL access in kernel */
255
            do_fast_data_access_mmu_miss_fault(istate, tag,
258
            do_fast_data_access_mmu_miss_fault(istate, tag,
256
                __func__);
259
                __func__);
-
 
260
        } else if (page_8k >= end_of_identity) {
-
 
261
            /*
-
 
262
             * The kernel is accessing the I/O space.
-
 
263
             * We still do identity mapping for I/O,
-
 
264
             * but without caching.
-
 
265
             */
-
 
266
            dtlb_insert_mapping(page_8k, KA2PA(page_8k),
-
 
267
                PAGESIZE_8K, false, false);
-
 
268
            return;
257
        }
269
        }
258
        do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
270
        do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
259
            "kernel page fault.");
271
            "kernel page fault.");
260
    }
272
    }
261
 
273
 
262
    page_table_lock(AS, true);
274
    page_table_lock(AS, true);
263
    t = page_mapping_find(AS, va);
275
    t = page_mapping_find(AS, page_16k);
264
    if (t) {
276
    if (t) {
265
        /*
277
        /*
266
         * The mapping was found in the software page hash table.
278
         * The mapping was found in the software page hash table.
267
         * Insert it into DTLB.
279
         * Insert it into DTLB.
268
         */
280
         */
Line 276... Line 288...
276
        /*
288
        /*
277
         * Forward the page fault to the address space page fault
289
         * Forward the page fault to the address space page fault
278
         * handler.
290
         * handler.
279
         */    
291
         */    
280
        page_table_unlock(AS, true);
292
        page_table_unlock(AS, true);
281
        if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
293
        if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
-
 
294
            AS_PF_FAULT) {
282
            do_fast_data_access_mmu_miss_fault(istate, tag,
295
            do_fast_data_access_mmu_miss_fault(istate, tag,
283
                __func__);
296
                __func__);
284
        }
297
        }
285
    }
298
    }
286
}
299
}
Line 293... Line 306...
293
 *          DTLB miss.
306
 *          DTLB miss.
294
 * @param istate    Interrupted state saved on the stack.
307
 * @param istate    Interrupted state saved on the stack.
295
 */
308
 */
296
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
309
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
297
{
310
{
298
    uintptr_t va;
311
    uintptr_t page_16k;
299
    index_t index;
312
    index_t index;
300
    pte_t *t;
313
    pte_t *t;
301
 
314
 
302
    va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
315
    page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
303
    index = tag.vpn % MMU_PAGES_PER_PAGE;   /* 16K-page emulation */
316
    index = tag.vpn % MMU_PAGES_PER_PAGE;   /* 16K-page emulation */
304
 
317
 
305
    page_table_lock(AS, true);
318
    page_table_lock(AS, true);
306
    t = page_mapping_find(AS, va);
319
    t = page_mapping_find(AS, page_16k);
307
    if (t && PTE_WRITABLE(t)) {
320
    if (t && PTE_WRITABLE(t)) {
308
        /*
321
        /*
309
         * The mapping was found in the software page hash table and is
322
         * The mapping was found in the software page hash table and is
310
         * writable. Demap the old mapping and insert an updated mapping
323
         * writable. Demap the old mapping and insert an updated mapping
311
         * into DTLB.
324
         * into DTLB.
312
         */
325
         */
313
        t->a = true;
326
        t->a = true;
314
        t->d = true;
327
        t->d = true;
315
        dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
328
        dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
316
            va + index * MMU_PAGE_SIZE);
329
            page_16k + index * MMU_PAGE_SIZE);
317
        dtlb_pte_copy(t, index, false);
330
        dtlb_pte_copy(t, index, false);
318
#ifdef CONFIG_TSB
331
#ifdef CONFIG_TSB
319
        dtsb_pte_copy(t, index, false);
332
        dtsb_pte_copy(t, index, false);
320
#endif
333
#endif
321
        page_table_unlock(AS, true);
334
        page_table_unlock(AS, true);
Line 323... Line 336...
323
        /*
336
        /*
324
         * Forward the page fault to the address space page fault
337
         * Forward the page fault to the address space page fault
325
         * handler.
338
         * handler.
326
         */    
339
         */    
327
        page_table_unlock(AS, true);
340
        page_table_unlock(AS, true);
328
        if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
341
        if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
-
 
342
            AS_PF_FAULT) {
329
            do_fast_data_access_protection_fault(istate, tag,
343
            do_fast_data_access_protection_fault(istate, tag,
330
                __func__);
344
                __func__);
331
        }
345
        }
332
    }
346
    }
333
}
347
}