Loading arch/arc/Kconfig +5 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ choice prompt "MMU Version" default ARC_MMU_V3 if ARC_CPU_770 default ARC_MMU_V2 if ARC_CPU_750D default ARC_MMU_V4 if ARC_CPU_HS config ARC_MMU_V1 bool "MMU v1" Loading @@ -287,6 +288,10 @@ config ARC_MMU_V3 Variable Page size (1k-16k), var JTLB size 128 x (2 or 4) Shared Address Spaces (SASID) config ARC_MMU_V4 bool "MMU v4" depends on ISA_ARCV2 endchoice Loading arch/arc/include/asm/arcregs.h +1 −1 Original line number Diff line number Diff line Loading @@ -326,7 +326,7 @@ struct bcr_generic { */ struct cpuinfo_arc_mmu { unsigned int ver:4, pg_sz_k:8, pad:8, u_dtlb:6, u_itlb:6; unsigned int ver:4, pg_sz_k:8, s_pg_sz_m:8, u_dtlb:6, u_itlb:6; unsigned int num_tlb:16, sets:12, ways:4; }; Loading arch/arc/include/asm/mmu.h +23 −1 Original line number Diff line number Diff line Loading @@ -15,24 +15,41 @@ #define CONFIG_ARC_MMU_VER 2 #elif defined(CONFIG_ARC_MMU_V3) #define CONFIG_ARC_MMU_VER 3 #elif defined(CONFIG_ARC_MMU_V4) #define CONFIG_ARC_MMU_VER 4 #endif /* MMU Management regs */ #define ARC_REG_MMU_BCR 0x06f #if (CONFIG_ARC_MMU_VER < 4) #define ARC_REG_TLBPD0 0x405 #define ARC_REG_TLBPD1 0x406 #define ARC_REG_TLBINDEX 0x407 #define ARC_REG_TLBCOMMAND 0x408 #define ARC_REG_PID 0x409 #define ARC_REG_SCRATCH_DATA0 0x418 #else #define ARC_REG_TLBPD0 0x460 #define ARC_REG_TLBPD1 0x461 #define ARC_REG_TLBINDEX 0x464 #define ARC_REG_TLBCOMMAND 0x465 #define ARC_REG_PID 0x468 #define ARC_REG_SCRATCH_DATA0 0x46c #endif /* Bits in MMU PID register */ #define MMU_ENABLE (1 << 31) /* Enable MMU for process */ #define __TLB_ENABLE (1 << 31) #define __PROG_ENABLE (1 << 30) #define MMU_ENABLE (__TLB_ENABLE | __PROG_ENABLE) /* Error code if probe fails */ #define TLB_LKUP_ERR 0x80000000 #if (CONFIG_ARC_MMU_VER < 4) #define TLB_DUP_ERR (TLB_LKUP_ERR | 0x00000001) #else #define TLB_DUP_ERR (TLB_LKUP_ERR | 0x40000000) #endif /* TLB Commands */ #define TLBWrite 0x1 Loading @@ -45,6 +62,11 @@ #define TLBIVUTLB 0x6 /* explicitly inv uTLBs */ #endif #if (CONFIG_ARC_MMU_VER >= 4) #define TLBInsertEntry 0x7 #define TLBDeleteEntry 0x8 #endif #ifndef __ASSEMBLY__ typedef struct { Loading arch/arc/include/asm/pgtable.h +10 −0 Original line number Diff line number Diff line Loading @@ -72,8 +72,18 @@ #define _PAGE_READ (1<<3) /* Page has user read perm (H) */ #define _PAGE_ACCESSED (1<<4) /* Page is accessed (S) */ #define _PAGE_MODIFIED (1<<5) /* Page modified (dirty) (S) */ #if (CONFIG_ARC_MMU_VER >= 4) #define _PAGE_WTHRU (1<<7) /* Page cache mode write-thru (H) */ #endif #define _PAGE_GLOBAL (1<<8) /* Page is global (H) */ #define _PAGE_PRESENT (1<<9) /* TLB entry is valid (H) */ #if (CONFIG_ARC_MMU_VER >= 4) #define _PAGE_SZ (1<<10) /* Page Size indicator (H) */ #endif #define _PAGE_SHARED_CODE (1<<11) /* Shared Code page with cmn vaddr usable for shared TLB entries (H) */ #endif Loading arch/arc/mm/tlb.c +51 −3 Original line number Diff line number Diff line Loading @@ -113,6 +113,8 @@ static inline void __tlb_entry_erase(void) write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite); } #if (CONFIG_ARC_MMU_VER < 4) static inline unsigned int tlb_entry_lkup(unsigned long vaddr_n_asid) { unsigned int idx; Loading Loading @@ -210,6 +212,28 @@ static void tlb_entry_insert(unsigned int pd0, unsigned int pd1) write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite); } #else /* CONFIG_ARC_MMU_VER >= 4) */ static void utlb_invalidate(void) { /* No need since uTLB is always in sync with JTLB */ } static void tlb_entry_erase(unsigned int vaddr_n_asid) { write_aux_reg(ARC_REG_TLBPD0, vaddr_n_asid | _PAGE_PRESENT); write_aux_reg(ARC_REG_TLBCOMMAND, TLBDeleteEntry); } static void tlb_entry_insert(unsigned int pd0, unsigned int pd1) { write_aux_reg(ARC_REG_TLBPD0, pd0); write_aux_reg(ARC_REG_TLBPD1, pd1); write_aux_reg(ARC_REG_TLBCOMMAND, TLBInsertEntry); } #endif /* * Un-conditionally (without lookup) erase the entire MMU contents */ Loading Loading @@ -582,6 +606,17 @@ void read_decode_mmu_bcr(void) #endif } *mmu3; struct bcr_mmu_4 { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1, n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3; #else /* DTLB ITLB JES JE JA */ unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2, pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8; #endif } *mmu4; tmp = read_aux_reg(ARC_REG_MMU_BCR); mmu->ver = (tmp >> 24); Loading @@ -592,13 +627,21 @@ void read_decode_mmu_bcr(void) mmu->ways = 1 << mmu2->ways; mmu->u_dtlb = mmu2->u_dtlb; mmu->u_itlb = mmu2->u_itlb; } else { } else if (mmu->ver == 3) { mmu3 = (struct bcr_mmu_3 *)&tmp; mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1); mmu->sets = 1 << mmu3->sets; mmu->ways = 1 << mmu3->ways; mmu->u_dtlb = mmu3->u_dtlb; mmu->u_itlb = mmu3->u_itlb; } else { mmu4 = (struct bcr_mmu_4 *)&tmp; mmu->pg_sz_k = 1 << (mmu4->sz0 - 1); mmu->s_pg_sz_m = 1 << (mmu4->sz1 - 11); mmu->sets = 64 << mmu4->n_entry; mmu->ways = mmu4->n_ways * 2; mmu->u_dtlb = mmu4->u_dtlb * 4; mmu->u_itlb = mmu4->u_itlb * 4; } mmu->num_tlb = mmu->sets * mmu->ways; Loading @@ -608,10 +651,15 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu; char super_pg[64] = ""; if (p_mmu->s_pg_sz_m) scnprintf(super_pg, 64, "%dM Super Page%s, ", p_mmu->s_pg_sz_m, " (not used)"); n += scnprintf(buf + n, len - n, "MMU [v%x]\t: %dk PAGE, JTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n", p_mmu->ver, p_mmu->pg_sz_k, "MMU [v%x]\t: %dk PAGE, %sJTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n", p_mmu->ver, p_mmu->pg_sz_k, super_pg, p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, p_mmu->u_dtlb, p_mmu->u_itlb, IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : ""); Loading Loading
arch/arc/Kconfig +5 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ choice prompt "MMU Version" default ARC_MMU_V3 if ARC_CPU_770 default ARC_MMU_V2 if ARC_CPU_750D default ARC_MMU_V4 if ARC_CPU_HS config ARC_MMU_V1 bool "MMU v1" Loading @@ -287,6 +288,10 @@ config ARC_MMU_V3 Variable Page size (1k-16k), var JTLB size 128 x (2 or 4) Shared Address Spaces (SASID) config ARC_MMU_V4 bool "MMU v4" depends on ISA_ARCV2 endchoice Loading
arch/arc/include/asm/arcregs.h +1 −1 Original line number Diff line number Diff line Loading @@ -326,7 +326,7 @@ struct bcr_generic { */ struct cpuinfo_arc_mmu { unsigned int ver:4, pg_sz_k:8, pad:8, u_dtlb:6, u_itlb:6; unsigned int ver:4, pg_sz_k:8, s_pg_sz_m:8, u_dtlb:6, u_itlb:6; unsigned int num_tlb:16, sets:12, ways:4; }; Loading
arch/arc/include/asm/mmu.h +23 −1 Original line number Diff line number Diff line Loading @@ -15,24 +15,41 @@ #define CONFIG_ARC_MMU_VER 2 #elif defined(CONFIG_ARC_MMU_V3) #define CONFIG_ARC_MMU_VER 3 #elif defined(CONFIG_ARC_MMU_V4) #define CONFIG_ARC_MMU_VER 4 #endif /* MMU Management regs */ #define ARC_REG_MMU_BCR 0x06f #if (CONFIG_ARC_MMU_VER < 4) #define ARC_REG_TLBPD0 0x405 #define ARC_REG_TLBPD1 0x406 #define ARC_REG_TLBINDEX 0x407 #define ARC_REG_TLBCOMMAND 0x408 #define ARC_REG_PID 0x409 #define ARC_REG_SCRATCH_DATA0 0x418 #else #define ARC_REG_TLBPD0 0x460 #define ARC_REG_TLBPD1 0x461 #define ARC_REG_TLBINDEX 0x464 #define ARC_REG_TLBCOMMAND 0x465 #define ARC_REG_PID 0x468 #define ARC_REG_SCRATCH_DATA0 0x46c #endif /* Bits in MMU PID register */ #define MMU_ENABLE (1 << 31) /* Enable MMU for process */ #define __TLB_ENABLE (1 << 31) #define __PROG_ENABLE (1 << 30) #define MMU_ENABLE (__TLB_ENABLE | __PROG_ENABLE) /* Error code if probe fails */ #define TLB_LKUP_ERR 0x80000000 #if (CONFIG_ARC_MMU_VER < 4) #define TLB_DUP_ERR (TLB_LKUP_ERR | 0x00000001) #else #define TLB_DUP_ERR (TLB_LKUP_ERR | 0x40000000) #endif /* TLB Commands */ #define TLBWrite 0x1 Loading @@ -45,6 +62,11 @@ #define TLBIVUTLB 0x6 /* explicitly inv uTLBs */ #endif #if (CONFIG_ARC_MMU_VER >= 4) #define TLBInsertEntry 0x7 #define TLBDeleteEntry 0x8 #endif #ifndef __ASSEMBLY__ typedef struct { Loading
arch/arc/include/asm/pgtable.h +10 −0 Original line number Diff line number Diff line Loading @@ -72,8 +72,18 @@ #define _PAGE_READ (1<<3) /* Page has user read perm (H) */ #define _PAGE_ACCESSED (1<<4) /* Page is accessed (S) */ #define _PAGE_MODIFIED (1<<5) /* Page modified (dirty) (S) */ #if (CONFIG_ARC_MMU_VER >= 4) #define _PAGE_WTHRU (1<<7) /* Page cache mode write-thru (H) */ #endif #define _PAGE_GLOBAL (1<<8) /* Page is global (H) */ #define _PAGE_PRESENT (1<<9) /* TLB entry is valid (H) */ #if (CONFIG_ARC_MMU_VER >= 4) #define _PAGE_SZ (1<<10) /* Page Size indicator (H) */ #endif #define _PAGE_SHARED_CODE (1<<11) /* Shared Code page with cmn vaddr usable for shared TLB entries (H) */ #endif Loading
arch/arc/mm/tlb.c +51 −3 Original line number Diff line number Diff line Loading @@ -113,6 +113,8 @@ static inline void __tlb_entry_erase(void) write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite); } #if (CONFIG_ARC_MMU_VER < 4) static inline unsigned int tlb_entry_lkup(unsigned long vaddr_n_asid) { unsigned int idx; Loading Loading @@ -210,6 +212,28 @@ static void tlb_entry_insert(unsigned int pd0, unsigned int pd1) write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite); } #else /* CONFIG_ARC_MMU_VER >= 4) */ static void utlb_invalidate(void) { /* No need since uTLB is always in sync with JTLB */ } static void tlb_entry_erase(unsigned int vaddr_n_asid) { write_aux_reg(ARC_REG_TLBPD0, vaddr_n_asid | _PAGE_PRESENT); write_aux_reg(ARC_REG_TLBCOMMAND, TLBDeleteEntry); } static void tlb_entry_insert(unsigned int pd0, unsigned int pd1) { write_aux_reg(ARC_REG_TLBPD0, pd0); write_aux_reg(ARC_REG_TLBPD1, pd1); write_aux_reg(ARC_REG_TLBCOMMAND, TLBInsertEntry); } #endif /* * Un-conditionally (without lookup) erase the entire MMU contents */ Loading Loading @@ -582,6 +606,17 @@ void read_decode_mmu_bcr(void) #endif } *mmu3; struct bcr_mmu_4 { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1, n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3; #else /* DTLB ITLB JES JE JA */ unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2, pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8; #endif } *mmu4; tmp = read_aux_reg(ARC_REG_MMU_BCR); mmu->ver = (tmp >> 24); Loading @@ -592,13 +627,21 @@ void read_decode_mmu_bcr(void) mmu->ways = 1 << mmu2->ways; mmu->u_dtlb = mmu2->u_dtlb; mmu->u_itlb = mmu2->u_itlb; } else { } else if (mmu->ver == 3) { mmu3 = (struct bcr_mmu_3 *)&tmp; mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1); mmu->sets = 1 << mmu3->sets; mmu->ways = 1 << mmu3->ways; mmu->u_dtlb = mmu3->u_dtlb; mmu->u_itlb = mmu3->u_itlb; } else { mmu4 = (struct bcr_mmu_4 *)&tmp; mmu->pg_sz_k = 1 << (mmu4->sz0 - 1); mmu->s_pg_sz_m = 1 << (mmu4->sz1 - 11); mmu->sets = 64 << mmu4->n_entry; mmu->ways = mmu4->n_ways * 2; mmu->u_dtlb = mmu4->u_dtlb * 4; mmu->u_itlb = mmu4->u_itlb * 4; } mmu->num_tlb = mmu->sets * mmu->ways; Loading @@ -608,10 +651,15 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu; char super_pg[64] = ""; if (p_mmu->s_pg_sz_m) scnprintf(super_pg, 64, "%dM Super Page%s, ", p_mmu->s_pg_sz_m, " (not used)"); n += scnprintf(buf + n, len - n, "MMU [v%x]\t: %dk PAGE, JTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n", p_mmu->ver, p_mmu->pg_sz_k, "MMU [v%x]\t: %dk PAGE, %sJTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n", p_mmu->ver, p_mmu->pg_sz_k, super_pg, p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, p_mmu->u_dtlb, p_mmu->u_itlb, IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : ""); Loading