linux/arch/nds32/mm/tlb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2005-2017 Andes Technology Corporation
   3
   4#include <linux/spinlock_types.h>
   5#include <linux/mm.h>
   6#include <linux/sched.h>
   7#include <asm/nds32.h>
   8#include <nds32_intrinsic.h>
   9
  10unsigned int cpu_last_cid = { TLB_MISC_mskCID + (2 << TLB_MISC_offCID) };
  11
  12DEFINE_SPINLOCK(cid_lock);
  13
  14void local_flush_tlb_range(struct vm_area_struct *vma,
  15                           unsigned long start, unsigned long end)
  16{
  17        unsigned long flags, ocid, ncid;
  18
  19        if ((end - start) > 0x400000) {
  20                __nds32__tlbop_flua();
  21                __nds32__isb();
  22                return;
  23        }
  24
  25        spin_lock_irqsave(&cid_lock, flags);
  26        ocid = __nds32__mfsr(NDS32_SR_TLB_MISC);
  27        ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id;
  28        __nds32__mtsr_dsb(ncid, NDS32_SR_TLB_MISC);
  29        while (start < end) {
  30                __nds32__tlbop_inv(start);
  31                __nds32__isb();
  32                start += PAGE_SIZE;
  33        }
  34        __nds32__mtsr_dsb(ocid, NDS32_SR_TLB_MISC);
  35        spin_unlock_irqrestore(&cid_lock, flags);
  36}
  37
  38void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
  39{
  40        unsigned long flags, ocid, ncid;
  41
  42        spin_lock_irqsave(&cid_lock, flags);
  43        ocid = __nds32__mfsr(NDS32_SR_TLB_MISC);
  44        ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id;
  45        __nds32__mtsr_dsb(ncid, NDS32_SR_TLB_MISC);
  46        __nds32__tlbop_inv(addr);
  47        __nds32__isb();
  48        __nds32__mtsr_dsb(ocid, NDS32_SR_TLB_MISC);
  49        spin_unlock_irqrestore(&cid_lock, flags);
  50}
  51