Subversion Repositories HelenOS-historic

Rev

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

Rev 983 Rev 1044
Line 85... Line 85...
85
 * @param istate Interrupted register context.
85
 * @param istate Interrupted register context.
86
 */
86
 */
87
void tlb_refill(istate_t *istate)
87
void tlb_refill(istate_t *istate)
88
{
88
{
89
    entry_lo_t lo;
89
    entry_lo_t lo;
90
    entry_hi_t hi; 
90
    entry_hi_t hi;
-
 
91
    asid_t asid;
91
    __address badvaddr;
92
    __address badvaddr;
92
    pte_t *pte;
93
    pte_t *pte;
93
 
94
 
94
    badvaddr = cp0_badvaddr_read();
95
    badvaddr = cp0_badvaddr_read();
95
 
96
 
96
    spinlock_lock(&AS->lock);      
97
    spinlock_lock(&AS->lock);
-
 
98
    asid = AS->asid;
-
 
99
    spinlock_unlock(&AS->lock);
-
 
100
 
-
 
101
    page_table_lock(AS, true);
97
 
102
 
98
    pte = find_mapping_and_check(badvaddr);
103
    pte = find_mapping_and_check(badvaddr);
99
    if (!pte)
104
    if (!pte)
100
        goto fail;
105
        goto fail;
101
 
106
 
102
    /*
107
    /*
103
     * Record access to PTE.
108
     * Record access to PTE.
104
     */
109
     */
105
    pte->a = 1;
110
    pte->a = 1;
106
 
111
 
107
    prepare_entry_hi(&hi, AS->asid, badvaddr);
112
    prepare_entry_hi(&hi, asid, badvaddr);
108
    prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
113
    prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
109
 
114
 
110
    /*
115
    /*
111
     * New entry is to be inserted into TLB
116
     * New entry is to be inserted into TLB
112
     */
117
     */
Line 120... Line 125...
120
        cp0_entry_lo1_write(lo.value);
125
        cp0_entry_lo1_write(lo.value);
121
    }
126
    }
122
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
127
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
123
    tlbwr();
128
    tlbwr();
124
 
129
 
125
    spinlock_unlock(&AS->lock);
130
    page_table_unlock(AS, true);
126
    return;
131
    return;
127
   
132
   
128
fail:
133
fail:
129
    spinlock_unlock(&AS->lock);
134
    page_table_unlock(AS, true);
130
    tlb_refill_fail(istate);
135
    tlb_refill_fail(istate);
131
}
136
}
132
 
137
 
133
/** Process TLB Invalid Exception
138
/** Process TLB Invalid Exception
134
 *
139
 *
Line 152... Line 157...
152
    hi.value = cp0_entry_hi_read();
157
    hi.value = cp0_entry_hi_read();
153
    prepare_entry_hi(&hi, hi.asid, badvaddr);
158
    prepare_entry_hi(&hi, hi.asid, badvaddr);
154
    cp0_entry_hi_write(hi.value);
159
    cp0_entry_hi_write(hi.value);
155
    tlbp();
160
    tlbp();
156
    index.value = cp0_index_read();
161
    index.value = cp0_index_read();
157
   
162
 
158
    spinlock_lock(&AS->lock);  
163
    page_table_lock(AS, true); 
159
   
164
   
160
    /*
165
    /*
161
     * Fail if the entry is not in TLB.
166
     * Fail if the entry is not in TLB.
162
     */
167
     */
163
    if (index.p) {
168
    if (index.p) {
Line 189... Line 194...
189
    else
194
    else
190
        cp0_entry_lo1_write(lo.value);
195
        cp0_entry_lo1_write(lo.value);
191
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
196
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
192
    tlbwi();
197
    tlbwi();
193
 
198
 
194
    spinlock_unlock(&AS->lock);
199
    page_table_unlock(AS, true);
195
    return;
200
    return;
196
   
201
   
197
fail:
202
fail:
198
    spinlock_unlock(&AS->lock);
203
    page_table_unlock(AS, true);
199
    tlb_invalid_fail(istate);
204
    tlb_invalid_fail(istate);
200
}
205
}
201
 
206
 
202
/** Process TLB Modified Exception
207
/** Process TLB Modified Exception
203
 *
208
 *
Line 221... Line 226...
221
    hi.value = cp0_entry_hi_read();
226
    hi.value = cp0_entry_hi_read();
222
    prepare_entry_hi(&hi, hi.asid, badvaddr);
227
    prepare_entry_hi(&hi, hi.asid, badvaddr);
223
    cp0_entry_hi_write(hi.value);
228
    cp0_entry_hi_write(hi.value);
224
    tlbp();
229
    tlbp();
225
    index.value = cp0_index_read();
230
    index.value = cp0_index_read();
226
   
231
 
227
    spinlock_lock(&AS->lock);  
232
    page_table_lock(AS, true); 
228
   
233
   
229
    /*
234
    /*
230
     * Fail if the entry is not in TLB.
235
     * Fail if the entry is not in TLB.
231
     */
236
     */
232
    if (index.p) {
237
    if (index.p) {
Line 265... Line 270...
265
    else
270
    else
266
        cp0_entry_lo1_write(lo.value);
271
        cp0_entry_lo1_write(lo.value);
267
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
272
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
268
    tlbwi();
273
    tlbwi();
269
 
274
 
270
    spinlock_unlock(&AS->lock);
275
    page_table_unlock(AS, true);
271
    return;
276
    return;
272
   
277
   
273
fail:
278
fail:
274
    spinlock_unlock(&AS->lock);
279
    page_table_unlock(AS, true);
275
    tlb_modified_fail(istate);
280
    tlb_modified_fail(istate);
276
}
281
}
277
 
282
 
278
void tlb_refill_fail(istate_t *istate)
283
void tlb_refill_fail(istate_t *istate)
279
{
284
{
Line 347... Line 352...
347
    } else {
352
    } else {
348
        /*
353
        /*
349
         * Mapping not found in page tables.
354
         * Mapping not found in page tables.
350
         * Resort to higher-level page fault handler.
355
         * Resort to higher-level page fault handler.
351
         */
356
         */
-
 
357
        page_table_unlock(AS, true);
352
        if (as_page_fault(badvaddr)) {
358
        if (as_page_fault(badvaddr)) {
353
            /*
359
            /*
354
             * The higher-level page fault handler succeeded,
360
             * The higher-level page fault handler succeeded,
355
             * The mapping ought to be in place.
361
             * The mapping ought to be in place.
356
             */
362
             */
-
 
363
            page_table_lock(AS, true);
357
            pte = page_mapping_find(AS, badvaddr);
364
            pte = page_mapping_find(AS, badvaddr);
358
            ASSERT(pte && pte->p);
365
            ASSERT(pte && pte->p);
359
            return pte;
366
            return pte;
-
 
367
        } else {
-
 
368
            page_table_lock(AS, true);
-
 
369
            printf("Page fault.\n");
-
 
370
            return NULL;
360
        }
371
        }
-
 
372
       
361
    }
373
    }
362
 
-
 
363
    /*
-
 
364
     * Handler cannot succeed if badvaddr has no mapping.
-
 
365
     */
-
 
366
    if (!pte) {
-
 
367
        printf("No such mapping.\n");
-
 
368
        return NULL;
-
 
369
    }
-
 
370
 
-
 
371
    /*
-
 
372
     * Handler cannot succeed if the mapping is marked as invalid.
-
 
373
     */
-
 
374
    if (!pte->p) {
-
 
375
        printf("Invalid mapping.\n");
-
 
376
        return NULL;
-
 
377
    }
-
 
378
 
-
 
379
    return pte;
-
 
380
}
374
}
381
 
375
 
382
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn)
376
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn)
383
{
377
{
384
    lo->value = 0;
378
    lo->value = 0;