Changeset 976c434 in mainline
- Timestamp:
- 2013-02-17T17:45:53Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2b95d13
- Parents:
- 192a23f0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/mips32/src/mm/tlb.c
r192a23f0 r976c434 57 57 58 58 59 static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *);60 61 59 /** Initialize TLB. 62 60 * … … 86 84 } 87 85 88 /** Verify the TLB still contains / does not contain a given entry after the89 * current thread possibly blocked.90 *91 * @param hi Remembered contents of the EntryHi register.92 * @param should_exist Flag saying whether the caller expect the entry to exist93 * or not to exist.94 * @returns True if the TLB contains or does not contain the mapping95 * according to the caller's expectation.96 * @returns False otherwise.97 */98 static bool tlb_recheck_entry(entry_hi_t hi, bool should_exist)99 {100 tlb_index_t index;101 102 cp0_entry_hi_write(hi.value);103 tlbp();104 index.value = cp0_index_read();105 106 if (!(should_exist ^ index.p)) {107 /* The old entry disappeared or the new entry already exists. */108 return false;109 }110 111 return true;112 }113 114 86 /** Process TLB Refill Exception. 115 87 * … … 118 90 void tlb_refill(istate_t *istate) 119 91 { 120 entry_hi_t hi;121 92 entry_lo_t lo; 122 93 uintptr_t badvaddr; … … 124 95 125 96 badvaddr = cp0_badvaddr_read(); 126 hi.value = cp0_entry_hi_read(); 127 128 /* We may block in find_mapping_and_check(). */ 129 pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate); 130 if (pte) { 131 if (!tlb_recheck_entry(hi, false)) 132 return; 133 97 98 pte = page_mapping_find(AS, badvaddr, true); 99 if (pte && pte->p) { 134 100 /* 135 101 * Record access to PTE. … … 152 118 cp0_pagemask_write(TLB_PAGE_MASK_16K); 153 119 tlbwr(); 154 } 120 return; 121 } 122 123 (void) as_page_fault(badvaddr, PF_ACCESS_READ, istate); 155 124 } 156 125 … … 161 130 void tlb_invalid(istate_t *istate) 162 131 { 163 entry_hi_t hi;164 132 entry_lo_t lo; 165 133 tlb_index_t index; … … 188 156 189 157 badvaddr = cp0_badvaddr_read(); 190 hi.value = cp0_entry_hi_read(); 191 192 /* We may block in find_mapping_and_check(). */ 193 pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate); 194 if (pte) { 195 if (!tlb_recheck_entry(hi, true)) 196 return; 197 158 159 pte = page_mapping_find(AS, badvaddr, true); 160 if (pte && pte->p) { 198 161 /* 199 162 * Read the faulting TLB entry. … … 217 180 cp0_entry_lo1_write(lo.value); 218 181 tlbwi(); 219 } 182 return; 183 } 184 185 (void) as_page_fault(badvaddr, PF_ACCESS_READ, istate); 220 186 } 221 187 … … 226 192 void tlb_modified(istate_t *istate) 227 193 { 228 entry_hi_t hi;229 194 entry_lo_t lo; 230 195 tlb_index_t index; … … 244 209 245 210 badvaddr = cp0_badvaddr_read(); 246 hi.value = cp0_entry_hi_read(); 247 248 /* We may block in find_mapping_and_check(). */ 249 pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE, istate); 250 if (pte) { 251 if (!tlb_recheck_entry(hi, true)) 252 return; 253 211 212 pte = page_mapping_find(AS, badvaddr, true); 213 if (pte && pte->p && pte->w) { 254 214 /* 255 215 * Read the faulting TLB entry. … … 274 234 cp0_entry_lo1_write(lo.value); 275 235 tlbwi(); 276 } 277 } 278 279 /** Try to find PTE for faulting address. 280 * 281 * @param badvaddr Faulting virtual address. 282 * @param access Access mode that caused the fault. 283 * @param istate Pointer to interrupted state. 284 * 285 * @return PTE on success, NULL otherwise. 286 */ 287 pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate) 288 { 289 entry_hi_t hi; 290 pte_t *pte; 291 292 hi.value = cp0_entry_hi_read(); 293 294 ASSERT(hi.asid == AS->asid); 295 296 /* 297 * Check if the mapping exists in page tables. 298 */ 299 pte = page_mapping_find(AS, badvaddr, true); 300 if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) { 301 /* 302 * Mapping found in page tables. 303 * Immediately succeed. 304 */ 305 return pte; 306 } 307 308 /* 309 * Mapping not found in page tables. 310 * Resort to higher-level page fault handler. 311 */ 312 if (as_page_fault(badvaddr, access, istate) == AS_PF_OK) { 313 pte = page_mapping_find(AS, badvaddr, true); 314 ASSERT(pte && pte->p); 315 ASSERT(pte->w || access != PF_ACCESS_WRITE); 316 return pte; 317 } 318 319 return NULL; 236 return; 237 } 238 239 (void) as_page_fault(badvaddr, PF_ACCESS_WRITE, istate); 320 240 } 321 241
Note:
See TracChangeset
for help on using the changeset viewer.