diff options
Diffstat (limited to 'arch/arc/mm/tlb.c')
-rw-r--r-- | arch/arc/mm/tlb.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index fe1c5a073afe..7957dc4e4d4a 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <asm/arcregs.h> | 55 | #include <asm/arcregs.h> |
56 | #include <asm/setup.h> | 56 | #include <asm/setup.h> |
57 | #include <asm/mmu_context.h> | 57 | #include <asm/mmu_context.h> |
58 | #include <asm/tlb.h> | 58 | #include <asm/mmu.h> |
59 | 59 | ||
60 | /* Need for ARC MMU v2 | 60 | /* Need for ARC MMU v2 |
61 | * | 61 | * |
@@ -97,6 +97,7 @@ | |||
97 | * J-TLB entry got evicted/replaced. | 97 | * J-TLB entry got evicted/replaced. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | |||
100 | /* A copy of the ASID from the PID reg is kept in asid_cache */ | 101 | /* A copy of the ASID from the PID reg is kept in asid_cache */ |
101 | int asid_cache = FIRST_ASID; | 102 | int asid_cache = FIRST_ASID; |
102 | 103 | ||
@@ -432,9 +433,14 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, | |||
432 | { | 433 | { |
433 | unsigned long vaddr = vaddr_unaligned & PAGE_MASK; | 434 | unsigned long vaddr = vaddr_unaligned & PAGE_MASK; |
434 | unsigned long paddr = pte_val(*ptep) & PAGE_MASK; | 435 | unsigned long paddr = pte_val(*ptep) & PAGE_MASK; |
436 | struct page *page = pfn_to_page(pte_pfn(*ptep)); | ||
435 | 437 | ||
436 | create_tlb(vma, vaddr, ptep); | 438 | create_tlb(vma, vaddr, ptep); |
437 | 439 | ||
440 | if (page == ZERO_PAGE(0)) { | ||
441 | return; | ||
442 | } | ||
443 | |||
438 | /* | 444 | /* |
439 | * Exec page : Independent of aliasing/page-color considerations, | 445 | * Exec page : Independent of aliasing/page-color considerations, |
440 | * since icache doesn't snoop dcache on ARC, any dirty | 446 | * since icache doesn't snoop dcache on ARC, any dirty |
@@ -446,9 +452,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, | |||
446 | */ | 452 | */ |
447 | if ((vma->vm_flags & VM_EXEC) || | 453 | if ((vma->vm_flags & VM_EXEC) || |
448 | addr_not_cache_congruent(paddr, vaddr)) { | 454 | addr_not_cache_congruent(paddr, vaddr)) { |
449 | struct page *page = pfn_to_page(pte_pfn(*ptep)); | ||
450 | 455 | ||
451 | int dirty = test_and_clear_bit(PG_arch_1, &page->flags); | 456 | int dirty = !test_and_set_bit(PG_dc_clean, &page->flags); |
452 | if (dirty) { | 457 | if (dirty) { |
453 | /* wback + inv dcache lines */ | 458 | /* wback + inv dcache lines */ |
454 | __flush_dcache_page(paddr, paddr); | 459 | __flush_dcache_page(paddr, paddr); |
@@ -464,12 +469,27 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, | |||
464 | * the cpuinfo structure for later use. | 469 | * the cpuinfo structure for later use. |
465 | * No Validation is done here, simply read/convert the BCRs | 470 | * No Validation is done here, simply read/convert the BCRs |
466 | */ | 471 | */ |
467 | void __cpuinit read_decode_mmu_bcr(void) | 472 | void read_decode_mmu_bcr(void) |
468 | { | 473 | { |
469 | unsigned int tmp; | ||
470 | struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */ | ||
471 | struct bcr_mmu_3 *mmu3; /* encoded MMU3 attr */ | ||
472 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; | 474 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; |
475 | unsigned int tmp; | ||
476 | struct bcr_mmu_1_2 { | ||
477 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
478 | unsigned int ver:8, ways:4, sets:4, u_itlb:8, u_dtlb:8; | ||
479 | #else | ||
480 | unsigned int u_dtlb:8, u_itlb:8, sets:4, ways:4, ver:8; | ||
481 | #endif | ||
482 | } *mmu2; | ||
483 | |||
484 | struct bcr_mmu_3 { | ||
485 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
486 | unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4, | ||
487 | u_itlb:4, u_dtlb:4; | ||
488 | #else | ||
489 | unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4, | ||
490 | ways:4, ver:8; | ||
491 | #endif | ||
492 | } *mmu3; | ||
473 | 493 | ||
474 | tmp = read_aux_reg(ARC_REG_MMU_BCR); | 494 | tmp = read_aux_reg(ARC_REG_MMU_BCR); |
475 | mmu->ver = (tmp >> 24); | 495 | mmu->ver = (tmp >> 24); |
@@ -505,12 +525,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) | |||
505 | "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", | 525 | "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", |
506 | p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, | 526 | p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, |
507 | p_mmu->u_dtlb, p_mmu->u_itlb, | 527 | p_mmu->u_dtlb, p_mmu->u_itlb, |
508 | __CONFIG_ARC_MMU_SASID_VAL ? "SASID" : ""); | 528 | IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : ""); |
509 | 529 | ||
510 | return buf; | 530 | return buf; |
511 | } | 531 | } |
512 | 532 | ||
513 | void __cpuinit arc_mmu_init(void) | 533 | void arc_mmu_init(void) |
514 | { | 534 | { |
515 | char str[256]; | 535 | char str[256]; |
516 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; | 536 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; |