Subversion Repositories HelenOS

Rev

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

Rev 2745 Rev 3228
Line 51... Line 51...
51
static void tlb_invalid_fail(istate_t *istate);
51
static void tlb_invalid_fail(istate_t *istate);
52
static void tlb_modified_fail(istate_t *istate);
52
static void tlb_modified_fail(istate_t *istate);
53
 
53
 
54
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc);
54
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc);
55
 
55
 
56
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn);
-
 
57
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr);
-
 
58
 
-
 
59
/** Initialize TLB
56
/** Initialize TLB
60
 *
57
 *
61
 * Initialize TLB.
58
 * Initialize TLB.
62
 * Invalidate all entries and mark wired entries.
59
 * Invalidate all entries and mark wired entries.
63
 */
60
 */
Line 74... Line 71...
74
   
71
   
75
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
72
    for (i = 0; i < TLB_ENTRY_COUNT; i++) {
76
        cp0_index_write(i);
73
        cp0_index_write(i);
77
        tlbwi();
74
        tlbwi();
78
    }
75
    }
79
 
-
 
80
       
76
       
81
    /*
77
    /*
82
     * The kernel is going to make use of some wired
78
     * The kernel is going to make use of some wired
83
     * entries (e.g. mapping kernel stacks in kseg3).
79
     * entries (e.g. mapping kernel stacks in kseg3).
84
     */
80
     */
Line 129... Line 125...
129
    /*
125
    /*
130
     * Record access to PTE.
126
     * Record access to PTE.
131
     */
127
     */
132
    pte->a = 1;
128
    pte->a = 1;
133
 
129
 
134
    prepare_entry_hi(&hi, asid, badvaddr);
130
    tlb_prepare_entry_hi(&hi, asid, badvaddr);
135
    prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
131
    tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
136
 
132
 
137
    /*
133
    /*
138
     * New entry is to be inserted into TLB
134
     * New entry is to be inserted into TLB
139
     */
135
     */
140
    cp0_entry_hi_write(hi.value);
136
    cp0_entry_hi_write(hi.value);
Line 176... Line 172...
176
 
172
 
177
    /*
173
    /*
178
     * Locate the faulting entry in TLB.
174
     * Locate the faulting entry in TLB.
179
     */
175
     */
180
    hi.value = cp0_entry_hi_read();
176
    hi.value = cp0_entry_hi_read();
181
    prepare_entry_hi(&hi, hi.asid, badvaddr);
177
    tlb_prepare_entry_hi(&hi, hi.asid, badvaddr);
182
    cp0_entry_hi_write(hi.value);
178
    cp0_entry_hi_write(hi.value);
183
    tlbp();
179
    tlbp();
184
    index.value = cp0_index_read();
180
    index.value = cp0_index_read();
185
 
181
 
186
    page_table_lock(AS, true); 
182
    page_table_lock(AS, true); 
Line 219... Line 215...
219
    /*
215
    /*
220
     * Record access to PTE.
216
     * Record access to PTE.
221
     */
217
     */
222
    pte->a = 1;
218
    pte->a = 1;
223
 
219
 
224
    prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
220
    tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
225
 
221
 
226
    /*
222
    /*
227
     * The entry is to be updated in TLB.
223
     * The entry is to be updated in TLB.
228
     */
224
     */
229
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
225
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
Line 260... Line 256...
260
 
256
 
261
    /*
257
    /*
262
     * Locate the faulting entry in TLB.
258
     * Locate the faulting entry in TLB.
263
     */
259
     */
264
    hi.value = cp0_entry_hi_read();
260
    hi.value = cp0_entry_hi_read();
265
    prepare_entry_hi(&hi, hi.asid, badvaddr);
261
    tlb_prepare_entry_hi(&hi, hi.asid, badvaddr);
266
    cp0_entry_hi_write(hi.value);
262
    cp0_entry_hi_write(hi.value);
267
    tlbp();
263
    tlbp();
268
    index.value = cp0_index_read();
264
    index.value = cp0_index_read();
269
 
265
 
270
    page_table_lock(AS, true); 
266
    page_table_lock(AS, true); 
Line 310... Line 306...
310
     * Record access and write to PTE.
306
     * Record access and write to PTE.
311
     */
307
     */
312
    pte->a = 1;
308
    pte->a = 1;
313
    pte->d = 1;
309
    pte->d = 1;
314
 
310
 
315
    prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn);
311
    tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn);
316
 
312
 
317
    /*
313
    /*
318
     * The entry is to be updated in TLB.
314
     * The entry is to be updated in TLB.
319
     */
315
     */
320
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
316
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
Line 443... Line 439...
443
        }
439
        }
444
       
440
       
445
    }
441
    }
446
}
442
}
447
 
443
 
448
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn)
444
void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn)
449
{
445
{
450
    lo->value = 0;
446
    lo->value = 0;
451
    lo->g = g;
447
    lo->g = g;
452
    lo->v = v;
448
    lo->v = v;
453
    lo->d = d;
449
    lo->d = d;
454
    lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED;
450
    lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED;
455
    lo->pfn = pfn;
451
    lo->pfn = pfn;
456
}
452
}
457
 
453
 
458
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
454
void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
459
{
455
{
460
    hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2);
456
    hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2);
461
    hi->asid = asid;
457
    hi->asid = asid;
462
}
458
}
463
 
459
 
Line 583... Line 579...
583
    hi_save.value = cp0_entry_hi_read();
579
    hi_save.value = cp0_entry_hi_read();
584
    ipl = interrupts_disable();
580
    ipl = interrupts_disable();
585
 
581
 
586
    for (i = 0; i < cnt + 1; i += 2) {
582
    for (i = 0; i < cnt + 1; i += 2) {
587
        hi.value = 0;
583
        hi.value = 0;
588
        prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
584
        tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
589
        cp0_entry_hi_write(hi.value);
585
        cp0_entry_hi_write(hi.value);
590
 
586
 
591
        tlbp();
587
        tlbp();
592
        index.value = cp0_index_read();
588
        index.value = cp0_index_read();
593
 
589