Blame view

include/asm-xtensa/mmu_context.h 2.91 KB
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * include/asm-xtensa/mmu_context.h
   *
   * Switch an MMU context.
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Copyright (C) 2001 - 2005 Tensilica Inc.
   */
  
  #ifndef _XTENSA_MMU_CONTEXT_H
  #define _XTENSA_MMU_CONTEXT_H
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
15
  #include <linux/stringify.h>
de4f6e5b4   Chris Zankel   [XTENSA] clean-up...
16
  #include <linux/sched.h>
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
17
18
  
  #include <asm/pgtable.h>
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
19
20
  #include <asm/cacheflush.h>
  #include <asm/tlbflush.h>
d6dd61c83   Jeremy Fitzhardinge   [PATCH] x86: PARA...
21
  #include <asm-generic/mm_hooks.h>
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
22

173d66813   Chris Zankel   [PATCH] xtensa: r...
23
  #define XCHAL_MMU_ASID_BITS	8
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
24
25
26
27
  
  #if (XCHAL_HAVE_TLBS != 1)
  # error "Linux must have an MMU!"
  #endif
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
28
  extern unsigned long asid_cache;
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
29
30
31
  
  /*
   * NO_CONTEXT is the invalid ASID value that we don't ever assign to
173d66813   Chris Zankel   [PATCH] xtensa: r...
32
33
34
35
36
37
38
   * any user or kernel context.
   *
   * 0 invalid
   * 1 kernel
   * 2 reserved
   * 3 reserved
   * 4...255 available
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
39
   */
173d66813   Chris Zankel   [PATCH] xtensa: r...
40
41
42
43
  #define NO_CONTEXT	0
  #define ASID_USER_FIRST	4
  #define ASID_MASK	((1 << XCHAL_MMU_ASID_BITS) - 1)
  #define ASID_INSERT(x)	(0x03020001 | (((x) & ASID_MASK) << 8))
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
44

d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
45
  static inline void set_rasid_register (unsigned long val)
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
46
47
48
49
50
51
  {
  	__asm__ __volatile__ (" wsr %0, "__stringify(RASID)"
  \t"
  			      " isync
  " : : "a" (val));
  }
d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
52
  static inline unsigned long get_rasid_register (void)
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
53
54
  {
  	unsigned long tmp;
173d66813   Chris Zankel   [PATCH] xtensa: r...
55
56
  	__asm__ __volatile__ (" rsr %0,"__stringify(RASID)"
  \t" : "=a" (tmp));
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
57
58
  	return tmp;
  }
d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
59
  static inline void
173d66813   Chris Zankel   [PATCH] xtensa: r...
60
  __get_new_mmu_context(struct mm_struct *mm)
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
61
62
  {
  	extern void flush_tlb_all(void);
173d66813   Chris Zankel   [PATCH] xtensa: r...
63
  	if (! (++asid_cache & ASID_MASK) ) {
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
64
  		flush_tlb_all(); /* start new asid cycle */
173d66813   Chris Zankel   [PATCH] xtensa: r...
65
  		asid_cache += ASID_USER_FIRST;
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
66
  	}
173d66813   Chris Zankel   [PATCH] xtensa: r...
67
  	mm->context = asid_cache;
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
68
  }
d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
69
  static inline void
173d66813   Chris Zankel   [PATCH] xtensa: r...
70
  __load_mmu_context(struct mm_struct *mm)
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
71
  {
173d66813   Chris Zankel   [PATCH] xtensa: r...
72
73
  	set_rasid_register(ASID_INSERT(mm->context));
  	invalidate_page_directory();
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
74
  }
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
75
76
77
78
  /*
   * Initialize the context related info for a new mm_struct
   * instance.
   */
d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
79
  static inline int
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
80
81
82
83
84
  init_new_context(struct task_struct *tsk, struct mm_struct *mm)
  {
  	mm->context = NO_CONTEXT;
  	return 0;
  }
173d66813   Chris Zankel   [PATCH] xtensa: r...
85
86
87
88
89
90
91
92
93
94
95
96
  /*
   * After we have set current->mm to a new value, this activates
   * the context for the new mm so we see the new mappings.
   */
  static inline void
  activate_mm(struct mm_struct *prev, struct mm_struct *next)
  {
  	/* Unconditionally get a new ASID.  */
  
  	__get_new_mmu_context(next);
  	__load_mmu_context(next);
  }
d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
97
  static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
98
99
100
101
102
                               struct task_struct *tsk)
  {
  	unsigned long asid = asid_cache;
  
  	/* Check if our ASID is of an older version and thus invalid */
173d66813   Chris Zankel   [PATCH] xtensa: r...
103
104
  	if (next->context == NO_CONTEXT || ((next->context^asid) & ~ASID_MASK))
  		__get_new_mmu_context(next);
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
105

173d66813   Chris Zankel   [PATCH] xtensa: r...
106
  	__load_mmu_context(next);
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
107
108
109
110
111
112
113
114
  }
  
  #define deactivate_mm(tsk, mm)	do { } while(0)
  
  /*
   * Destroy context related info for an mm_struct that is about
   * to be put to rest.
   */
d99cf715a   Adrian Bunk   [PATCH] xtensa: r...
115
  static inline void destroy_context(struct mm_struct *mm)
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
116
  {
9a8fd5589   Chris Zankel   [PATCH] xtensa: A...
117
118
119
120
121
122
123
124
125
126
127
  	invalidate_page_directory();
  }
  
  
  static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  {
  	/* Nothing to do. */
  
  }
  
  #endif /* _XTENSA_MMU_CONTEXT_H */