Subversion Repositories HelenOS

Rev

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

Rev 397 Rev 399
Line 42... Line 42...
42
static void tlb_refill_fail(struct exception_regdump *pstate);
42
static void tlb_refill_fail(struct exception_regdump *pstate);
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
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, int c, __address pfn);
-
 
49
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr);
48
 
50
 
49
/** Initialize TLB
51
/** Initialize TLB
50
 *
52
 *
51
 * Initialize TLB.
53
 * Initialize TLB.
52
 * Invalidate all entries and mark wired entries.
54
 * Invalidate all entries and mark wired entries.
Line 82... Line 84...
82
 * @param pstate Interrupted register context.
84
 * @param pstate Interrupted register context.
83
 */
85
 */
84
void tlb_refill(struct exception_regdump *pstate)
86
void tlb_refill(struct exception_regdump *pstate)
85
{
87
{
86
    entry_lo_t lo;
88
    entry_lo_t lo;
-
 
89
    entry_hi_t hi; 
87
    __address badvaddr;
90
    __address badvaddr;
88
    pte_t *pte;
91
    pte_t *pte;
89
 
92
 
90
// debug    
-
 
91
    entry_hi_t hi;
-
 
92
 
-
 
93
    badvaddr = cp0_badvaddr_read();
93
    badvaddr = cp0_badvaddr_read();
94
 
94
 
95
// debug
-
 
96
    hi.value = cp0_entry_hi_read();
-
 
97
    printf("TLB Refill: hi.vnp2=%X\n", hi.vpn2);
-
 
98
   
-
 
99
    spinlock_lock(&VM->lock);      
95
    spinlock_lock(&VM->lock);      
-
 
96
 
100
    pte = find_mapping_and_check(badvaddr);
97
    pte = find_mapping_and_check(badvaddr);
101
    if (!pte)
98
    if (!pte)
102
        goto fail;
99
        goto fail;
103
 
100
 
104
    /*
101
    /*
105
     * Record access to PTE.
102
     * Record access to PTE.
106
     */
103
     */
107
    pte->a = 1;
104
    pte->a = 1;
108
 
105
 
-
 
106
    prepare_entry_hi(&hi, VM->asid, badvaddr);
109
    prepare_entry_lo(&lo, pte->g, pte->v, pte->d, pte->c, pte->pfn);
107
    prepare_entry_lo(&lo, pte->g, pte->v, pte->d, pte->c, pte->pfn);
110
 
108
 
111
    /*
109
    /*
112
     * New entry is to be inserted into TLB
110
     * New entry is to be inserted into TLB
113
     */
111
     */
-
 
112
    cp0_entry_hi_write(hi.value);
114
    if ((badvaddr/PAGE_SIZE) % 2 == 0) {
113
    if ((badvaddr/PAGE_SIZE) % 2 == 0) {
115
        cp0_entry_lo0_write(lo.value);
114
        cp0_entry_lo0_write(lo.value);
116
        cp0_entry_lo1_write(0);
115
        cp0_entry_lo1_write(0);
117
    }
116
    }
118
    else {
117
    else {
Line 138... Line 137...
138
void tlb_invalid(struct exception_regdump *pstate)
137
void tlb_invalid(struct exception_regdump *pstate)
139
{
138
{
140
    tlb_index_t index;
139
    tlb_index_t index;
141
    __address badvaddr;
140
    __address badvaddr;
142
    entry_lo_t lo;
141
    entry_lo_t lo;
-
 
142
    entry_hi_t hi;
143
    pte_t *pte;
143
    pte_t *pte;
144
 
144
 
145
    badvaddr = cp0_badvaddr_read();
145
    badvaddr = cp0_badvaddr_read();
146
 
146
 
147
    /*
147
    /*
148
     * Locate the faulting entry in TLB.
148
     * Locate the faulting entry in TLB.
149
     */
149
     */
-
 
150
    hi.value = cp0_entry_hi_read();
-
 
151
    prepare_entry_hi(&hi, hi.asid, badvaddr);
-
 
152
    cp0_entry_hi_write(hi.value);
150
    tlbp();
153
    tlbp();
151
    index.value = cp0_index_read();
154
    index.value = cp0_index_read();
152
   
155
   
153
    spinlock_lock(&VM->lock);  
156
    spinlock_lock(&VM->lock);  
154
   
157
   
Line 202... Line 205...
202
void tlb_modified(struct exception_regdump *pstate)
205
void tlb_modified(struct exception_regdump *pstate)
203
{
206
{
204
    tlb_index_t index;
207
    tlb_index_t index;
205
    __address badvaddr;
208
    __address badvaddr;
206
    entry_lo_t lo;
209
    entry_lo_t lo;
-
 
210
    entry_hi_t hi;
207
    pte_t *pte;
211
    pte_t *pte;
208
 
212
 
209
    badvaddr = cp0_badvaddr_read();
213
    badvaddr = cp0_badvaddr_read();
210
 
214
 
211
    /*
215
    /*
212
     * Locate the faulting entry in TLB.
216
     * Locate the faulting entry in TLB.
213
     */
217
     */
-
 
218
    hi.value = cp0_entry_hi_read();
-
 
219
    prepare_entry_hi(&hi, hi.asid, badvaddr);
-
 
220
    cp0_entry_hi_write(hi.value);
214
    tlbp();
221
    tlbp();
215
    index.value = cp0_index_read();
222
    index.value = cp0_index_read();
216
   
223
   
217
    spinlock_lock(&VM->lock);  
224
    spinlock_lock(&VM->lock);  
218
   
225
   
Line 376... Line 383...
376
    return pte;
383
    return pte;
377
}
384
}
378
 
385
 
379
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
386
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
380
{
387
{
-
 
388
    lo->value = 0;
381
    lo->g = g;
389
    lo->g = g;
382
    lo->v = v;
390
    lo->v = v;
383
    lo->d = d;
391
    lo->d = d;
384
    lo->c = c;
392
    lo->c = c;
385
    lo->pfn = pfn;
393
    lo->pfn = pfn;
-
 
394
}
-
 
395
 
-
 
396
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr)
-
 
397
{
-
 
398
    hi->value = (((addr/PAGE_SIZE)/2)*PAGE_SIZE*2);
386
    lo->zero = 0;
399
    hi->asid = asid;
387
}
400
}