Subversion Repositories HelenOS

Rev

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

Rev 3675 Rev 4377
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
}
Line 422... Line 436...
422
#endif
436
#endif
423
 
437
 
424
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
438
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
425
    const char *str)
439
    const char *str)
426
{
440
{
427
    fault_if_from_uspace(istate, "%s\n", str);
441
    fault_if_from_uspace(istate, "%s.", str);
428
    dump_istate(istate);
442
    dump_istate(istate);
429
    panic("%s\n", str);
443
    panic("%s.", str);
430
}
444
}
431
 
445
 
432
void do_fast_data_access_mmu_miss_fault(istate_t *istate,
446
void do_fast_data_access_mmu_miss_fault(istate_t *istate,
433
    tlb_tag_access_reg_t tag, const char *str)
447
    tlb_tag_access_reg_t tag, const char *str)
434
{
448
{
435
    uintptr_t va;
449
    uintptr_t va;
436
 
450
 
437
    va = tag.vpn << MMU_PAGE_WIDTH;
451
    va = tag.vpn << MMU_PAGE_WIDTH;
438
    if (tag.context) {
452
    if (tag.context) {
439
        fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
453
        fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
440
            tag.context);
454
            tag.context);
441
    }
455
    }
442
    dump_istate(istate);
456
    dump_istate(istate);
443
    printf("Faulting page: %p, ASID=%d\n", va, tag.context);
457
    printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
444
    panic("%s\n", str);
458
    panic("%s.", str);
445
}
459
}
446
 
460
 
447
void do_fast_data_access_protection_fault(istate_t *istate,
461
void do_fast_data_access_protection_fault(istate_t *istate,
448
    tlb_tag_access_reg_t tag, const char *str)
462
    tlb_tag_access_reg_t tag, const char *str)
449
{
463
{
450
    uintptr_t va;
464
    uintptr_t va;
451
 
465
 
452
    va = tag.vpn << MMU_PAGE_WIDTH;
466
    va = tag.vpn << MMU_PAGE_WIDTH;
453
 
467
 
454
    if (tag.context) {
468
    if (tag.context) {
455
        fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
469
        fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
456
            tag.context);
470
            tag.context);
457
    }
471
    }
458
    printf("Faulting page: %p, ASID=%d\n", va, tag.context);
472
    printf("Faulting page: %p, ASID=%d\n", va, tag.context);
459
    dump_istate(istate);
473
    dump_istate(istate);
460
    panic("%s\n", str);
474
    panic("%s.", str);
461
}
475
}
462
 
476
 
463
void dump_sfsr_and_sfar(void)
477
void dump_sfsr_and_sfar(void)
464
{
478
{
465
    tlb_sfsr_reg_t sfsr;
479
    tlb_sfsr_reg_t sfsr;