Subversion Repositories HelenOS

Rev

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

Rev 830 Rev 831
Line 43... Line 43...
43
static void tlb_invalid_fail(struct exception_regdump *pstate);
43
static void tlb_invalid_fail(struct exception_regdump *pstate);
44
static void tlb_modified_fail(struct exception_regdump *pstate);
44
static void tlb_modified_fail(struct exception_regdump *pstate);
45
 
45
 
46
static pte_t *find_mapping_and_check(__address badvaddr);
46
static pte_t *find_mapping_and_check(__address badvaddr);
47
 
47
 
48
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn);
48
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn);
49
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr);
49
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr);
50
 
50
 
51
/** Initialize TLB
51
/** Initialize TLB
52
 *
52
 *
53
 * Initialize TLB.
53
 * Initialize TLB.
Line 102... Line 102...
102
     * Record access to PTE.
102
     * Record access to PTE.
103
     */
103
     */
104
    pte->a = 1;
104
    pte->a = 1;
105
 
105
 
106
    prepare_entry_hi(&hi, AS->asid, badvaddr);
106
    prepare_entry_hi(&hi, AS->asid, badvaddr);
107
    prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn);
107
    prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
108
 
108
 
109
    /*
109
    /*
110
     * New entry is to be inserted into TLB
110
     * New entry is to be inserted into TLB
111
     */
111
     */
112
    cp0_entry_hi_write(hi.value);
112
    cp0_entry_hi_write(hi.value);
Line 176... Line 176...
176
    /*
176
    /*
177
     * Record access to PTE.
177
     * Record access to PTE.
178
     */
178
     */
179
    pte->a = 1;
179
    pte->a = 1;
180
 
180
 
181
    prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn);
181
    prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
182
 
182
 
183
    /*
183
    /*
184
     * The entry is to be updated in TLB.
184
     * The entry is to be updated in TLB.
185
     */
185
     */
186
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
186
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
Line 250... Line 250...
250
 
250
 
251
    /*
251
    /*
252
     * Record access and write to PTE.
252
     * Record access and write to PTE.
253
     */
253
     */
254
    pte->a = 1;
254
    pte->a = 1;
255
    pte->lo.d = 1;
255
    pte->d = 1;
256
 
256
 
257
    prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->w, pte->lo.c, pte->lo.pfn);
257
    prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn);
258
 
258
 
259
    /*
259
    /*
260
     * The entry is to be updated in TLB.
260
     * The entry is to be updated in TLB.
261
     */
261
     */
262
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
262
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
Line 335... Line 335...
335
 
335
 
336
    /*
336
    /*
337
     * Check if the mapping exists in page tables.
337
     * Check if the mapping exists in page tables.
338
     */
338
     */
339
    pte = page_mapping_find(AS, badvaddr);
339
    pte = page_mapping_find(AS, badvaddr);
340
    if (pte && pte->lo.v) {
340
    if (pte && pte->p) {
341
        /*
341
        /*
342
         * Mapping found in page tables.
342
         * Mapping found in page tables.
343
         * Immediately succeed.
343
         * Immediately succeed.
344
         */
344
         */
345
        return pte;
345
        return pte;
Line 352... Line 352...
352
            /*
352
            /*
353
             * The higher-level page fault handler succeeded,
353
             * The higher-level page fault handler succeeded,
354
             * The mapping ought to be in place.
354
             * The mapping ought to be in place.
355
             */
355
             */
356
            pte = page_mapping_find(AS, badvaddr);
356
            pte = page_mapping_find(AS, badvaddr);
357
            ASSERT(pte && pte->lo.v);
357
            ASSERT(pte && pte->p);
358
            return pte;
358
            return pte;
359
        }
359
        }
360
    }
360
    }
361
 
361
 
362
    /*
362
    /*
Line 368... Line 368...
368
    }
368
    }
369
 
369
 
370
    /*
370
    /*
371
     * Handler cannot succeed if the mapping is marked as invalid.
371
     * Handler cannot succeed if the mapping is marked as invalid.
372
     */
372
     */
373
    if (!pte->lo.v) {
373
    if (!pte->p) {
374
        printf("Invalid mapping.\n");
374
        printf("Invalid mapping.\n");
375
        return NULL;
375
        return NULL;
376
    }
376
    }
377
 
377
 
378
    return pte;
378
    return pte;
379
}
379
}
380
 
380
 
381
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
381
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn)
382
{
382
{
383
    lo->value = 0;
383
    lo->value = 0;
384
    lo->g = g;
384
    lo->g = g;
385
    lo->v = v;
385
    lo->v = v;
386
    lo->d = d;
386
    lo->d = d;
387
    lo->c = c;
387
    lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED;
388
    lo->pfn = pfn;
388
    lo->pfn = pfn;
389
}
389
}
390
 
390
 
391
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr)
391
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr)
392
{
392
{