Commit 89d0d424 authored by Vineet Gupta's avatar Vineet Gupta

ARC: mm: move MMU specific bits out of ASID allocator

And while at it, rewrite commentary on ASID allocator
Signed-off-by: default avatarVineet Gupta <vgupta@kernel.org>
parent be43b096
...@@ -64,6 +64,19 @@ typedef struct { ...@@ -64,6 +64,19 @@ typedef struct {
unsigned long asid[NR_CPUS]; /* 8 bit MMU PID + Generation cycle */ unsigned long asid[NR_CPUS]; /* 8 bit MMU PID + Generation cycle */
} mm_context_t; } mm_context_t;
static inline void mmu_setup_asid(struct mm_struct *mm, unsigned int asid)
{
write_aux_reg(ARC_REG_PID, asid | MMU_ENABLE);
}
static inline void mmu_setup_pgd(struct mm_struct *mm, void *pgd)
{
/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
#ifdef CONFIG_ISA_ARCV2
write_aux_reg(ARC_REG_SCRATCH_DATA0, (unsigned int)pgd);
#endif
}
static inline int is_pae40_enabled(void) static inline int is_pae40_enabled(void)
{ {
return IS_ENABLED(CONFIG_ARC_HAS_PAE40); return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
......
...@@ -15,22 +15,23 @@ ...@@ -15,22 +15,23 @@
#ifndef _ASM_ARC_MMU_CONTEXT_H #ifndef _ASM_ARC_MMU_CONTEXT_H
#define _ASM_ARC_MMU_CONTEXT_H #define _ASM_ARC_MMU_CONTEXT_H
#include <asm/arcregs.h>
#include <asm/tlb.h>
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
#include <asm/tlb.h>
#include <asm-generic/mm_hooks.h> #include <asm-generic/mm_hooks.h>
/* ARC700 ASID Management /* ARC ASID Management
*
* MMU tags TLBs with an 8-bit ASID, avoiding need to flush the TLB on
* context-switch.
* *
* ARC MMU provides 8-bit ASID (0..255) to TAG TLB entries, allowing entries * ASID is managed per cpu, so task threads across CPUs can have different
* with same vaddr (different tasks) to co-exit. This provides for * ASID. Global ASID management is needed if hardware supports TLB shootdown
* "Fast Context Switch" i.e. no TLB flush on ctxt-switch * and/or shared TLB across cores, which ARC doesn't.
* *
* Linux assigns each task a unique ASID. A simple round-robin allocation * Each task is assigned unique ASID, with a simple round-robin allocator
* of H/w ASID is done using software tracker @asid_cpu. * tracked in @asid_cpu. When 8-bit value rolls over,a new cycle is started
* When it reaches max 255, the allocation cycle starts afresh by flushing * over from 0, and TLB is flushed
* the entire TLB and wrapping ASID back to zero.
* *
* A new allocation cycle, post rollover, could potentially reassign an ASID * A new allocation cycle, post rollover, could potentially reassign an ASID
* to a different task. Thus the rule is to refresh the ASID in a new cycle. * to a different task. Thus the rule is to refresh the ASID in a new cycle.
...@@ -93,7 +94,7 @@ static inline void get_new_mmu_context(struct mm_struct *mm) ...@@ -93,7 +94,7 @@ static inline void get_new_mmu_context(struct mm_struct *mm)
asid_mm(mm, cpu) = asid_cpu(cpu); asid_mm(mm, cpu) = asid_cpu(cpu);
set_hw: set_hw:
write_aux_reg(ARC_REG_PID, hw_pid(mm, cpu) | MMU_ENABLE); mmu_setup_asid(mm, hw_pid(mm, cpu));
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -146,10 +147,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, ...@@ -146,10 +147,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
*/ */
cpumask_set_cpu(cpu, mm_cpumask(next)); cpumask_set_cpu(cpu, mm_cpumask(next));
#ifdef CONFIG_ISA_ARCV2 mmu_setup_pgd(next, next->pgd);
/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
#endif
get_new_mmu_context(next); get_new_mmu_context(next);
} }
......
...@@ -716,14 +716,11 @@ void arc_mmu_init(void) ...@@ -716,14 +716,11 @@ void arc_mmu_init(void)
if (IS_ENABLED(CONFIG_ARC_HAS_PAE40) && !mmu->pae) if (IS_ENABLED(CONFIG_ARC_HAS_PAE40) && !mmu->pae)
panic("Hardware doesn't support PAE40\n"); panic("Hardware doesn't support PAE40\n");
/* Enable the MMU */ /* Enable the MMU with ASID 0 */
write_aux_reg(ARC_REG_PID, MMU_ENABLE); mmu_setup_asid(NULL, 0);
/* In arc700/smp needed for re-entrant interrupt handling */ /* cache the pgd pointer in MMU SCRATCH reg (ARCv2 only) */
#ifdef CONFIG_ISA_ARCV2 mmu_setup_pgd(NULL, swapper_pg_dir);
/* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
#endif
if (pae40_exist_but_not_enab()) if (pae40_exist_but_not_enab())
write_aux_reg(ARC_REG_TLBPD1HI, 0); write_aux_reg(ARC_REG_TLBPD1HI, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment