Rev 397 | Rev 403 | Go to most recent revision | Show entire file | Regard 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 | } |