Changes in kernel/arch/ppc32/src/mm/tlb.c [26aafe8:7e752b2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ppc32/src/mm/tlb.c
r26aafe8 r7e752b2 44 44 #include <symtab.h> 45 45 46 static unsigned int seed = 42; 46 static unsigned int seed = 10; 47 static unsigned int seed_real 48 __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; 47 49 48 50 /** Try to find PTE for faulting address … … 223 225 switch (pfrc) { 224 226 case AS_PF_FAULT: 225 page_table_unlock(as, true); 226 pht_refill_fail(badvaddr, istate); 227 return; 227 goto fail; 228 break; 228 229 case AS_PF_DEFER: 229 230 /* … … 243 244 244 245 page_table_unlock(as, true); 245 } 246 247 void tlb_refill(unsigned int n, istate_t *istate) 248 { 249 uint32_t tlbmiss; 250 ptehi_t ptehi; 251 ptelo_t ptelo; 252 253 asm volatile ( 254 "mfspr %[tlbmiss], 980\n" 255 "mfspr %[ptehi], 981\n" 256 "mfspr %[ptelo], 982\n" 257 : [tlbmiss] "=r" (tlbmiss), 258 [ptehi] "=r" (ptehi), 259 [ptelo] "=r" (ptelo) 260 ); 261 246 return; 247 248 fail: 249 page_table_unlock(as, true); 250 pht_refill_fail(badvaddr, istate); 251 } 252 253 /** Process Instruction/Data Storage Exception in Real Mode 254 * 255 * @param n Exception vector number. 256 * @param istate Interrupted register context. 257 * 258 */ 259 bool pht_refill_real(unsigned int n, istate_t *istate) 260 { 261 uintptr_t badvaddr; 262 263 if (n == VECTOR_DATA_STORAGE) 264 badvaddr = istate->dar; 265 else 266 badvaddr = istate->pc; 267 268 uint32_t physmem = physmem_top(); 269 270 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) 271 return false; 272 273 uint32_t page = (badvaddr >> 12) & 0xffff; 274 uint32_t api = (badvaddr >> 22) & 0x3f; 275 276 uint32_t vsid = sr_get(badvaddr); 277 uint32_t sdr1 = sdr1_get(); 278 279 // FIXME: compute size of PHT exactly 280 phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); 281 282 /* Primary hash (xor) */ 283 uint32_t h = 0; 284 uint32_t hash = vsid ^ page; 285 uint32_t base = (hash & 0x3ff) << 3; 286 uint32_t i; 287 bool found = false; 288 289 /* Find colliding PTE in PTEG */ 290 for (i = 0; i < 8; i++) { 291 if ((phte_real[base + i].v) 292 && (phte_real[base + i].vsid == vsid) 293 && (phte_real[base + i].api == api) 294 && (phte_real[base + i].h == 0)) { 295 found = true; 296 break; 297 } 298 } 299 300 if (!found) { 301 /* Find unused PTE in PTEG */ 302 for (i = 0; i < 8; i++) { 303 if (!phte_real[base + i].v) { 304 found = true; 305 break; 306 } 307 } 308 } 309 310 if (!found) { 311 /* Secondary hash (not) */ 312 uint32_t base2 = (~hash & 0x3ff) << 3; 313 314 /* Find colliding PTE in PTEG */ 315 for (i = 0; i < 8; i++) { 316 if ((phte_real[base2 + i].v) 317 && (phte_real[base2 + i].vsid == vsid) 318 && (phte_real[base2 + i].api == api) 319 && (phte_real[base2 + i].h == 1)) { 320 found = true; 321 base = base2; 322 h = 1; 323 break; 324 } 325 } 326 327 if (!found) { 328 /* Find unused PTE in PTEG */ 329 for (i = 0; i < 8; i++) { 330 if (!phte_real[base2 + i].v) { 331 found = true; 332 base = base2; 333 h = 1; 334 break; 335 } 336 } 337 } 338 339 if (!found) { 340 /* Use secondary hash to avoid collisions 341 with usual PHT refill handler. */ 342 i = RANDI(seed_real) % 8; 343 base = base2; 344 h = 1; 345 } 346 } 347 348 phte_real[base + i].v = 1; 349 phte_real[base + i].vsid = vsid; 350 phte_real[base + i].h = h; 351 phte_real[base + i].api = api; 352 phte_real[base + i].rpn = KA2PA(badvaddr) >> 12; 353 phte_real[base + i].r = 0; 354 phte_real[base + i].c = 0; 355 phte_real[base + i].wimg = 0; 356 phte_real[base + i].pp = 2; // FIXME 357 358 return true; 359 } 360 361 /** Process ITLB/DTLB Miss Exception in Real Mode 362 * 363 * 364 */ 365 void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi, 366 ptelo_t ptelo, istate_t *istate) 367 { 262 368 uint32_t badvaddr = tlbmiss & 0xfffffffc; 263 369 uint32_t physmem = physmem_top();
Note:
See TracChangeset
for help on using the changeset viewer.