Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.5-rc2 143 lines 4.0 kB view raw
1/* 2 * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2008-2009 PetaLogix 4 * Copyright (C) 2006 Atmark Techno, Inc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11#ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H 12#define _ASM_MICROBLAZE_MMU_CONTEXT_H 13 14#include <linux/atomic.h> 15#include <linux/mm_types.h> 16#include <linux/sched.h> 17 18#include <asm/bitops.h> 19#include <asm/mmu.h> 20#include <asm-generic/mm_hooks.h> 21 22# ifdef __KERNEL__ 23/* 24 * This function defines the mapping from contexts to VSIDs (virtual 25 * segment IDs). We use a skew on both the context and the high 4 bits 26 * of the 32-bit virtual address (the "effective segment ID") in order 27 * to spread out the entries in the MMU hash table. 28 */ 29# define CTX_TO_VSID(ctx, va) (((ctx) * (897 * 16) + ((va) >> 28) * 0x111) \ 30 & 0xffffff) 31 32/* 33 MicroBlaze has 256 contexts, so we can just rotate through these 34 as a way of "switching" contexts. If the TID of the TLB is zero, 35 the PID/TID comparison is disabled, so we can use a TID of zero 36 to represent all kernel pages as shared among all contexts. 37 */ 38 39static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) 40{ 41} 42 43# define NO_CONTEXT 256 44# define LAST_CONTEXT 255 45# define FIRST_CONTEXT 1 46 47/* 48 * Set the current MMU context. 49 * This is done byloading up the segment registers for the user part of the 50 * address space. 51 * 52 * Since the PGD is immediately available, it is much faster to simply 53 * pass this along as a second parameter, which is required for 8xx and 54 * can be used for debugging on all processors (if you happen to have 55 * an Abatron). 56 */ 57extern void set_context(mm_context_t context, pgd_t *pgd); 58 59/* 60 * Bitmap of contexts in use. 61 * The size of this bitmap is LAST_CONTEXT + 1 bits. 62 */ 63extern unsigned long context_map[]; 64 65/* 66 * This caches the next context number that we expect to be free. 67 * Its use is an optimization only, we can't rely on this context 68 * number to be free, but it usually will be. 69 */ 70extern mm_context_t next_mmu_context; 71 72/* 73 * Since we don't have sufficient contexts to give one to every task 74 * that could be in the system, we need to be able to steal contexts. 75 * These variables support that. 76 */ 77extern atomic_t nr_free_contexts; 78extern struct mm_struct *context_mm[LAST_CONTEXT+1]; 79extern void steal_context(void); 80 81/* 82 * Get a new mmu context for the address space described by `mm'. 83 */ 84static inline void get_mmu_context(struct mm_struct *mm) 85{ 86 mm_context_t ctx; 87 88 if (mm->context != NO_CONTEXT) 89 return; 90 while (atomic_dec_if_positive(&nr_free_contexts) < 0) 91 steal_context(); 92 ctx = next_mmu_context; 93 while (test_and_set_bit(ctx, context_map)) { 94 ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx); 95 if (ctx > LAST_CONTEXT) 96 ctx = 0; 97 } 98 next_mmu_context = (ctx + 1) & LAST_CONTEXT; 99 mm->context = ctx; 100 context_mm[ctx] = mm; 101} 102 103/* 104 * Set up the context for a new address space. 105 */ 106# define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0) 107 108/* 109 * We're finished using the context for an address space. 110 */ 111static inline void destroy_context(struct mm_struct *mm) 112{ 113 if (mm->context != NO_CONTEXT) { 114 clear_bit(mm->context, context_map); 115 mm->context = NO_CONTEXT; 116 atomic_inc(&nr_free_contexts); 117 } 118} 119 120static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 121 struct task_struct *tsk) 122{ 123 tsk->thread.pgdir = next->pgd; 124 get_mmu_context(next); 125 set_context(next->context, next->pgd); 126} 127 128/* 129 * After we have set current->mm to a new value, this activates 130 * the context for the new mm so we see the new mappings. 131 */ 132static inline void activate_mm(struct mm_struct *active_mm, 133 struct mm_struct *mm) 134{ 135 current->thread.pgdir = mm->pgd; 136 get_mmu_context(mm); 137 set_context(mm->context, mm->pgd); 138} 139 140extern void mmu_context_init(void); 141 142# endif /* __KERNEL__ */ 143#endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */