aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/mm/tlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/mm/tlb.c')
-rw-r--r--arch/arc/mm/tlb.c38
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 */
101int asid_cache = FIRST_ASID; 102int 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 */
467void __cpuinit read_decode_mmu_bcr(void) 472void 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
513void __cpuinit arc_mmu_init(void) 533void 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;