1#ifndef _ASM_SCORE_MMU_CONTEXT_H 2#define _ASM_SCORE_MMU_CONTEXT_H 3 4#include <linux/errno.h> 5#include <linux/sched.h> 6#include <linux/mm_types.h> 7#include <linux/slab.h> 8 9#include <asm-generic/mm_hooks.h> 10 11#include <asm/cacheflush.h> 12#include <asm/tlbflush.h> 13#include <asm/scoreregs.h> 14 15/* 16 * For the fast tlb miss handlers, we keep a per cpu array of pointers 17 * to the current pgd for each processor. Also, the proc. id is stuffed 18 * into the context register. 19 */ 20extern unsigned long asid_cache; 21extern unsigned long pgd_current; 22 23#define TLBMISS_HANDLER_SETUP_PGD(pgd) (pgd_current = (unsigned long)(pgd)) 24 25#define TLBMISS_HANDLER_SETUP() \ 26do { \ 27 write_c0_context(0); \ 28 TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) \ 29} while (0) 30 31/* 32 * All unused by hardware upper bits will be considered 33 * as a software asid extension. 34 */ 35#define ASID_VERSION_MASK 0xfffff000 36#define ASID_FIRST_VERSION 0x1000 37 38/* PEVN --------- VPN ---------- --ASID--- -NA- */ 39/* binary: 0000 0000 0000 0000 0000 0000 0001 0000 */ 40/* binary: 0000 0000 0000 0000 0000 1111 1111 0000 */ 41#define ASID_INC 0x10 42#define ASID_MASK 0xff0 43 44static inline void enter_lazy_tlb(struct mm_struct *mm, 45 struct task_struct *tsk) 46{} 47 48static inline void 49get_new_mmu_context(struct mm_struct *mm) 50{ 51 unsigned long asid = asid_cache + ASID_INC; 52 53 if (!(asid & ASID_MASK)) { 54 local_flush_tlb_all(); /* start new asid cycle */ 55 if (!asid) /* fix version if needed */ 56 asid = ASID_FIRST_VERSION; 57 } 58 59 mm->context = asid; 60 asid_cache = asid; 61} 62 63/* 64 * Initialize the context related info for a new mm_struct 65 * instance. 66 */ 67static inline int 68init_new_context(struct task_struct *tsk, struct mm_struct *mm) 69{ 70 mm->context = 0; 71 return 0; 72} 73 74static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 75 struct task_struct *tsk) 76{ 77 unsigned long flags; 78 79 local_irq_save(flags); 80 if ((next->context ^ asid_cache) & ASID_VERSION_MASK) 81 get_new_mmu_context(next); 82 83 pevn_set(next->context); 84 TLBMISS_HANDLER_SETUP_PGD(next->pgd); 85 local_irq_restore(flags); 86} 87 88/* 89 * Destroy context related info for an mm_struct that is about 90 * to be put to rest. 91 */ 92static inline void destroy_context(struct mm_struct *mm) 93{} 94 95static inline void 96deactivate_mm(struct task_struct *task, struct mm_struct *mm) 97{} 98 99/* 100 * After we have set current->mm to a new value, this activates 101 * the context for the new mm so we see the new mappings. 102 */ 103static inline void 104activate_mm(struct mm_struct *prev, struct mm_struct *next) 105{ 106 unsigned long flags; 107 108 local_irq_save(flags); 109 get_new_mmu_context(next); 110 pevn_set(next->context); 111 TLBMISS_HANDLER_SETUP_PGD(next->pgd); 112 local_irq_restore(flags); 113} 114 115#endif /* _ASM_SCORE_MMU_CONTEXT_H */ 116