18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci// Copyright (C) 2005-2017 Andes Technology Corporation 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef __ASM_NDS32_MMU_CONTEXT_H 58c2ecf20Sopenharmony_ci#define __ASM_NDS32_MMU_CONTEXT_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 88c2ecf20Sopenharmony_ci#include <asm/tlbflush.h> 98c2ecf20Sopenharmony_ci#include <asm/proc-fns.h> 108c2ecf20Sopenharmony_ci#include <asm-generic/mm_hooks.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic inline int 138c2ecf20Sopenharmony_ciinit_new_context(struct task_struct *tsk, struct mm_struct *mm) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci mm->context.id = 0; 168c2ecf20Sopenharmony_ci return 0; 178c2ecf20Sopenharmony_ci} 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define destroy_context(mm) do { } while(0) 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define CID_BITS 9 228c2ecf20Sopenharmony_ciextern spinlock_t cid_lock; 238c2ecf20Sopenharmony_ciextern unsigned int cpu_last_cid; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic inline void __new_context(struct mm_struct *mm) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci unsigned int cid; 288c2ecf20Sopenharmony_ci unsigned long flags; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci spin_lock_irqsave(&cid_lock, flags); 318c2ecf20Sopenharmony_ci cid = cpu_last_cid; 328c2ecf20Sopenharmony_ci cpu_last_cid += 1 << TLB_MISC_offCID; 338c2ecf20Sopenharmony_ci if (cpu_last_cid == 0) 348c2ecf20Sopenharmony_ci cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci if ((cid & TLB_MISC_mskCID) == 0) 378c2ecf20Sopenharmony_ci flush_tlb_all(); 388c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&cid_lock, flags); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci mm->context.id = cid; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic inline void check_context(struct mm_struct *mm) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci if (unlikely 468c2ecf20Sopenharmony_ci ((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS)) 478c2ecf20Sopenharmony_ci __new_context(mm); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 558c2ecf20Sopenharmony_ci struct task_struct *tsk) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci unsigned int cpu = smp_processor_id(); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { 608c2ecf20Sopenharmony_ci check_context(next); 618c2ecf20Sopenharmony_ci cpu_switch_mm(next); 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#define deactivate_mm(tsk,mm) do { } while (0) 668c2ecf20Sopenharmony_ci#define activate_mm(prev,next) switch_mm(prev, next, NULL) 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci#endif 69