Subversion Repositories HelenOS-historic

Rev

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

Rev 598 Rev 599
Line 53... Line 53...
53
 * Initialize TLB.
53
 * Initialize TLB.
54
 * Invalidate all entries and mark wired entries.
54
 * Invalidate all entries and mark wired entries.
55
 */
55
 */
56
void tlb_arch_init(void)
56
void tlb_arch_init(void)
57
{
57
{
-
 
58
    int i;
-
 
59
 
58
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
60
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
-
 
61
    cp0_entry_hi_write(0);
-
 
62
    cp0_entry_lo0_write(0);
-
 
63
    cp0_entry_lo1_write(0);
59
 
64
 
-
 
65
    /* Clear and initialize TLB. */
-
 
66
   
-
 
67
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
60
    tlb_invalidate_all();
68
        cp0_index_write(i);
-
 
69
        tlbwi();
-
 
70
    }
61
       
71
       
62
    /*
72
    /*
63
     * The kernel is going to make use of some wired
73
     * The kernel is going to make use of some wired
64
     * entries (e.g. mapping kernel stacks in kseg3).
74
     * entries (e.g. mapping kernel stacks in kseg3).
65
     */
75
     */
Line 293... Line 303...
293
    if (s)
303
    if (s)
294
        symbol = s;
304
        symbol = s;
295
    panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
305
    panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
296
}
306
}
297
 
307
 
298
/** Invalidate TLB entries with specified ASID
-
 
299
 *
-
 
300
 * Invalidate TLB entries with specified ASID.
-
 
301
 *
-
 
302
 * @param asid ASID.
-
 
303
 */
-
 
304
void tlb_invalidate(asid_t asid)
-
 
305
{
-
 
306
    entry_hi_t hi;
-
 
307
    ipl_t ipl;
-
 
308
    int i; 
-
 
309
   
-
 
310
    ASSERT(asid != ASID_INVALID);
-
 
311
 
-
 
312
    ipl = interrupts_disable();
-
 
313
   
-
 
314
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
-
 
315
        cp0_index_write(i);
-
 
316
        tlbr();
-
 
317
       
-
 
318
        hi.value = cp0_entry_hi_read();
-
 
319
        if (hi.asid == asid) {
-
 
320
            cp0_pagemask_write(TLB_PAGE_MASK_16K);
-
 
321
            cp0_entry_hi_write(0);
-
 
322
            cp0_entry_lo0_write(0);
-
 
323
            cp0_entry_lo1_write(0);
-
 
324
            tlbwi();
-
 
325
        }
-
 
326
    }
-
 
327
   
-
 
328
    interrupts_restore(ipl);
-
 
329
}
-
 
330
 
-
 
331
/** Try to find PTE for faulting address
308
/** Try to find PTE for faulting address
332
 *
309
 *
333
 * Try to find PTE for faulting address.
310
 * Try to find PTE for faulting address.
334
 * The VM->lock must be held on entry to this function.
311
 * The VM->lock must be held on entry to this function.
335
 *
312
 *
Line 412... Line 389...
412
}
389
}
413
 
390
 
414
/** Invalidate all TLB entries. */
391
/** Invalidate all TLB entries. */
415
void tlb_invalidate_all(void)
392
void tlb_invalidate_all(void)
416
{
393
{
-
 
394
    ipl_t ipl;
-
 
395
    entry_lo_t lo0, lo1;
417
    int i;
396
    int i;
418
 
397
 
419
    cp0_entry_hi_write(0);
-
 
420
    cp0_entry_lo0_write(0);
-
 
421
    cp0_entry_lo1_write(0);
398
    ipl = interrupts_disable();
422
 
399
 
423
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
400
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
424
        cp0_index_write(i);
401
        cp0_index_write(i);
-
 
402
        tlbr();
-
 
403
 
-
 
404
        lo0.value = cp0_entry_lo0_read();
-
 
405
        lo1.value = cp0_entry_lo1_read();
-
 
406
 
-
 
407
        lo0.v = 0;
-
 
408
        lo1.v = 0;
-
 
409
 
-
 
410
        cp0_entry_lo0_write(lo0.value);
-
 
411
        cp0_entry_lo1_write(lo1.value);
-
 
412
               
425
        tlbwi();
413
        tlbwi();
426
    }
414
    }
-
 
415
   
-
 
416
    interrupts_restore(ipl);
427
}
417
}
428
 
418
 
429
/** Invalidate all TLB entries belonging to specified address space.
419
/** Invalidate all TLB entries belonging to specified address space.
430
 *
420
 *
431
 * @param asid Address space identifier.
421
 * @param asid Address space identifier.
432
 */
422
 */
433
void tlb_invalidate_asid(asid_t asid)
423
void tlb_invalidate_asid(asid_t asid)
434
{
424
{
-
 
425
    ipl_t ipl;
-
 
426
    entry_lo_t lo0, lo1;
435
    entry_hi_t hi;
427
    entry_hi_t hi;
436
    int i;
428
    int i;
437
 
429
 
-
 
430
    ASSERT(asid != ASID_INVALID);
-
 
431
 
-
 
432
    ipl = interrupts_disable();
-
 
433
   
438
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
434
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
439
        cp0_index_write(i);
435
        cp0_index_write(i);
440
        tlbr();
436
        tlbr();
441
       
437
       
-
 
438
        hi.value = cp0_entry_hi_read();
-
 
439
       
442
        if (hi.asid == asid) {
440
        if (hi.asid == asid) {
-
 
441
            lo0.value = cp0_entry_lo0_read();
-
 
442
            lo1.value = cp0_entry_lo1_read();
-
 
443
 
-
 
444
            lo0.v = 0;
-
 
445
            lo1.v = 0;
-
 
446
 
443
            cp0_entry_lo0_write(0);
447
            cp0_entry_lo0_write(lo0.value);
444
            cp0_entry_lo1_write(0);
448
            cp0_entry_lo1_write(lo1.value);
-
 
449
 
445
            tlbwi();
450
            tlbwi();
446
        }
451
        }
447
    }
452
    }
448
 
453
   
-
 
454
    interrupts_restore(ipl);
449
}
455
}
450
 
456
 
451
/** Invalidate TLB entry for specified page belonging to specified address space.
457
/** Invalidate TLB entry for specified page belonging to specified address space.
452
 *
458
 *
453
 * @param asid Address space identifier.
459
 * @param asid Address space identifier.
454
 * @param page Page whose TLB entry is to be invalidated.
460
 * @param page Page whose TLB entry is to be invalidated.
455
 */
461
 */
456
void tlb_invalidate_page(asid_t asid, __address page)
462
void tlb_invalidate_page(asid_t asid, __address page)
457
{
463
{
-
 
464
    ipl_t ipl;
-
 
465
    entry_lo_t lo0, lo1;
458
    entry_hi_t hi;
466
    entry_hi_t hi;
459
    tlb_index_t index;
467
    tlb_index_t index;
-
 
468
 
-
 
469
    ASSERT(asid != ASID_INVALID);
-
 
470
 
460
    int i;
471
    ipl = interrupts_disable();
461
 
472
 
462
    hi.value = 0;
473
    hi.value = 0;
463
    prepare_entry_hi(&hi, asid, page);
474
    prepare_entry_hi(&hi, asid, page);
-
 
475
    cp0_entry_hi_write(hi.value);
464
   
476
 
465
    tlbp();
477
    tlbp();
466
    index.value = cp0_index_read();
478
    index.value = cp0_index_read();
467
 
479
 
468
    if (!index.p) {
480
    if (!index.p) {
469
        /* Entry was found, index register contains valid index. */
481
        /* Entry was found, index register contains valid index. */
-
 
482
        tlbr();
-
 
483
 
-
 
484
        lo0.value = cp0_entry_lo0_read();
-
 
485
        lo1.value = cp0_entry_lo1_read();
-
 
486
 
-
 
487
        lo0.v = 0;
-
 
488
        lo1.v = 0;
-
 
489
 
470
        cp0_entry_lo0_write(0);
490
        cp0_entry_lo0_write(lo0.value);
471
        cp0_entry_lo1_write(0);
491
        cp0_entry_lo1_write(lo1.value);
-
 
492
 
472
        tlbwi();
493
        tlbwi();
473
    }
494
    }
-
 
495
   
-
 
496
    interrupts_restore(ipl);
474
}
497
}