diff options
Diffstat (limited to 'arch/mips/mm/tlb-r4k.c')
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 84 |
1 files changed, 16 insertions, 68 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index d73428b18b0a..c618eed933a1 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -303,7 +303,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
303 | unsigned long lo; | 303 | unsigned long lo; |
304 | write_c0_pagemask(PM_HUGE_MASK); | 304 | write_c0_pagemask(PM_HUGE_MASK); |
305 | ptep = (pte_t *)pmdp; | 305 | ptep = (pte_t *)pmdp; |
306 | lo = pte_val(*ptep) >> 6; | 306 | lo = pte_to_entrylo(pte_val(*ptep)); |
307 | write_c0_entrylo0(lo); | 307 | write_c0_entrylo0(lo); |
308 | write_c0_entrylo1(lo + (HPAGE_SIZE >> 7)); | 308 | write_c0_entrylo1(lo + (HPAGE_SIZE >> 7)); |
309 | 309 | ||
@@ -323,8 +323,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
323 | ptep++; | 323 | ptep++; |
324 | write_c0_entrylo1(ptep->pte_high); | 324 | write_c0_entrylo1(ptep->pte_high); |
325 | #else | 325 | #else |
326 | write_c0_entrylo0(pte_val(*ptep++) >> 6); | 326 | write_c0_entrylo0(pte_to_entrylo(pte_val(*ptep++))); |
327 | write_c0_entrylo1(pte_val(*ptep) >> 6); | 327 | write_c0_entrylo1(pte_to_entrylo(pte_val(*ptep))); |
328 | #endif | 328 | #endif |
329 | mtc0_tlbw_hazard(); | 329 | mtc0_tlbw_hazard(); |
330 | if (idx < 0) | 330 | if (idx < 0) |
@@ -337,40 +337,6 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
337 | EXIT_CRITICAL(flags); | 337 | EXIT_CRITICAL(flags); |
338 | } | 338 | } |
339 | 339 | ||
340 | #if 0 | ||
341 | static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, | ||
342 | unsigned long address, pte_t pte) | ||
343 | { | ||
344 | unsigned long flags; | ||
345 | unsigned int asid; | ||
346 | pgd_t *pgdp; | ||
347 | pmd_t *pmdp; | ||
348 | pte_t *ptep; | ||
349 | int idx; | ||
350 | |||
351 | ENTER_CRITICAL(flags); | ||
352 | address &= (PAGE_MASK << 1); | ||
353 | asid = read_c0_entryhi() & ASID_MASK; | ||
354 | write_c0_entryhi(address | asid); | ||
355 | pgdp = pgd_offset(vma->vm_mm, address); | ||
356 | mtc0_tlbw_hazard(); | ||
357 | tlb_probe(); | ||
358 | tlb_probe_hazard(); | ||
359 | pmdp = pmd_offset(pgdp, address); | ||
360 | idx = read_c0_index(); | ||
361 | ptep = pte_offset_map(pmdp, address); | ||
362 | write_c0_entrylo0(pte_val(*ptep++) >> 6); | ||
363 | write_c0_entrylo1(pte_val(*ptep) >> 6); | ||
364 | mtc0_tlbw_hazard(); | ||
365 | if (idx < 0) | ||
366 | tlb_write_random(); | ||
367 | else | ||
368 | tlb_write_indexed(); | ||
369 | tlbw_use_hazard(); | ||
370 | EXIT_CRITICAL(flags); | ||
371 | } | ||
372 | #endif | ||
373 | |||
374 | void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | 340 | void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, |
375 | unsigned long entryhi, unsigned long pagemask) | 341 | unsigned long entryhi, unsigned long pagemask) |
376 | { | 342 | { |
@@ -447,34 +413,6 @@ out: | |||
447 | return ret; | 413 | return ret; |
448 | } | 414 | } |
449 | 415 | ||
450 | static void __cpuinit probe_tlb(unsigned long config) | ||
451 | { | ||
452 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
453 | unsigned int reg; | ||
454 | |||
455 | /* | ||
456 | * If this isn't a MIPS32 / MIPS64 compliant CPU. Config 1 register | ||
457 | * is not supported, we assume R4k style. Cpu probing already figured | ||
458 | * out the number of tlb entries. | ||
459 | */ | ||
460 | if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) | ||
461 | return; | ||
462 | #ifdef CONFIG_MIPS_MT_SMTC | ||
463 | /* | ||
464 | * If TLB is shared in SMTC system, total size already | ||
465 | * has been calculated and written into cpu_data tlbsize | ||
466 | */ | ||
467 | if((smtc_status & SMTC_TLB_SHARED) == SMTC_TLB_SHARED) | ||
468 | return; | ||
469 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
470 | |||
471 | reg = read_c0_config1(); | ||
472 | if (!((config >> 7) & 3)) | ||
473 | panic("No TLB present"); | ||
474 | |||
475 | c->tlbsize = ((reg >> 25) & 0x3f) + 1; | ||
476 | } | ||
477 | |||
478 | static int __cpuinitdata ntlb; | 416 | static int __cpuinitdata ntlb; |
479 | static int __init set_ntlb(char *str) | 417 | static int __init set_ntlb(char *str) |
480 | { | 418 | { |
@@ -486,8 +424,6 @@ __setup("ntlb=", set_ntlb); | |||
486 | 424 | ||
487 | void __cpuinit tlb_init(void) | 425 | void __cpuinit tlb_init(void) |
488 | { | 426 | { |
489 | unsigned int config = read_c0_config(); | ||
490 | |||
491 | /* | 427 | /* |
492 | * You should never change this register: | 428 | * You should never change this register: |
493 | * - On R4600 1.7 the tlbp never hits for pages smaller than | 429 | * - On R4600 1.7 the tlbp never hits for pages smaller than |
@@ -495,13 +431,25 @@ void __cpuinit tlb_init(void) | |||
495 | * - The entire mm handling assumes the c0_pagemask register to | 431 | * - The entire mm handling assumes the c0_pagemask register to |
496 | * be set to fixed-size pages. | 432 | * be set to fixed-size pages. |
497 | */ | 433 | */ |
498 | probe_tlb(config); | ||
499 | write_c0_pagemask(PM_DEFAULT_MASK); | 434 | write_c0_pagemask(PM_DEFAULT_MASK); |
500 | write_c0_wired(0); | 435 | write_c0_wired(0); |
501 | if (current_cpu_type() == CPU_R10000 || | 436 | if (current_cpu_type() == CPU_R10000 || |
502 | current_cpu_type() == CPU_R12000 || | 437 | current_cpu_type() == CPU_R12000 || |
503 | current_cpu_type() == CPU_R14000) | 438 | current_cpu_type() == CPU_R14000) |
504 | write_c0_framemask(0); | 439 | write_c0_framemask(0); |
440 | |||
441 | if (kernel_uses_smartmips_rixi) { | ||
442 | /* | ||
443 | * Enable the no read, no exec bits, and enable large virtual | ||
444 | * address. | ||
445 | */ | ||
446 | u32 pg = PG_RIE | PG_XIE; | ||
447 | #ifdef CONFIG_64BIT | ||
448 | pg |= PG_ELPA; | ||
449 | #endif | ||
450 | write_c0_pagegrain(pg); | ||
451 | } | ||
452 | |||
505 | temp_tlb_entry = current_cpu_data.tlbsize - 1; | 453 | temp_tlb_entry = current_cpu_data.tlbsize - 1; |
506 | 454 | ||
507 | /* From this point on the ARC firmware is dead. */ | 455 | /* From this point on the ARC firmware is dead. */ |