source: svn/newcon3bcm2_21bu/toolchain/mips-linux-uclibc/include/asm/mmu_context.h @ 43

Last change on this file since 43 was 43, checked in by megakiss, 11 years ago

광주방송 OTC 주파수 369Mhz로 변경

  • Property svn:executable set to *
File size: 4.8 KB
Line 
1/*
2 * Switch a MMU context.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License.  See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 */
11#ifndef _ASM_MMU_CONTEXT_H
12#define _ASM_MMU_CONTEXT_H
13
14#include <linux/errno.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <asm/cacheflush.h>
18#include <asm/tlbflush.h>
19
20/*
21 * For the fast tlb miss handlers, we keep a per cpu array of pointers
22 * to the current pgd for each processor. Also, the proc. id is stuffed
23 * into the context register.
24 */
25extern unsigned long pgd_current[];
26
27#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
28        pgd_current[smp_processor_id()] = (unsigned long)(pgd)
29
30#ifndef __mips64
31#define TLBMISS_HANDLER_SETUP()                                         \
32        write_c0_context((unsigned long) smp_processor_id() << 23);     \
33        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
34#endif
35#if defined(__mips64) && !defined(CONFIG_BUILD_ELF64)
36#define TLBMISS_HANDLER_SETUP()                                         \
37        write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \
38        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
39#endif
40#if defined(__mips64) && defined(CONFIG_BUILD_ELF64)
41#define TLBMISS_HANDLER_SETUP()                                         \
42        write_c0_context((unsigned long) smp_processor_id() << 23);     \
43        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
44#endif
45
46#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
47
48#define ASID_INC        0x40
49#define ASID_MASK       0xfc0
50
51#elif defined(CONFIG_CPU_R8000)
52
53#define ASID_INC        0x10
54#define ASID_MASK       0xff0
55
56#elif defined(CONFIG_CPU_RM9000)
57
58#define ASID_INC        0x1
59#define ASID_MASK       0xfff
60
61#else /* FIXME: not correct for R6000 */
62
63#define ASID_INC        0x1
64#define ASID_MASK       0xff
65
66#endif
67
68#define cpu_context(cpu, mm)    ((mm)->context[cpu])
69#define cpu_asid(cpu, mm)       (cpu_context((cpu), (mm)) & ASID_MASK)
70#define asid_cache(cpu)         (cpu_data[cpu].asid_cache)
71
72static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
73{
74}
75
76/*
77 *  All unused by hardware upper bits will be considered
78 *  as a software asid extension.
79 */
80#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
81#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
82
83static inline void
84get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
85{
86        unsigned long asid = asid_cache(cpu);
87
88        if (! ((asid += ASID_INC) & ASID_MASK) ) {
89                if (cpu_has_vtag_icache)
90                        flush_icache_all();
91                local_flush_tlb_all();  /* start new asid cycle */
92                if (!asid)              /* fix version if needed */
93                        asid = ASID_FIRST_VERSION;
94        }
95        cpu_context(cpu, mm) = asid_cache(cpu) = asid;
96}
97
98/*
99 * Initialize the context related info for a new mm_struct
100 * instance.
101 */
102static inline int
103init_new_context(struct task_struct *tsk, struct mm_struct *mm)
104{
105        int i;
106
107        for (i = 0; i < num_online_cpus(); i++)
108                cpu_context(i, mm) = 0;
109
110        return 0;
111}
112
113static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
114                             struct task_struct *tsk)
115{
116        unsigned int cpu = smp_processor_id();
117        unsigned long flags;
118
119        local_irq_save(flags);
120
121        /* Check if our ASID is of an older version and thus invalid */
122        if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
123                get_new_mmu_context(next, cpu);
124
125        write_c0_entryhi(cpu_context(cpu, next));
126        TLBMISS_HANDLER_SETUP_PGD(next->pgd);
127
128        /*
129         * Mark current->active_mm as not "active" anymore.
130         * We don't want to mislead possible IPI tlb flush routines.
131         */
132        cpu_clear(cpu, prev->cpu_vm_mask);
133        cpu_set(cpu, next->cpu_vm_mask);
134
135        local_irq_restore(flags);
136}
137
138/*
139 * Destroy context related info for an mm_struct that is about
140 * to be put to rest.
141 */
142static inline void destroy_context(struct mm_struct *mm)
143{
144}
145
146#define deactivate_mm(tsk,mm)   do { } while (0)
147
148/*
149 * After we have set current->mm to a new value, this activates
150 * the context for the new mm so we see the new mappings.
151 */
152static inline void
153activate_mm(struct mm_struct *prev, struct mm_struct *next)
154{
155        unsigned long flags;
156        unsigned int cpu = smp_processor_id();
157
158        local_irq_save(flags);
159
160        /* Unconditionally get a new ASID.  */
161        get_new_mmu_context(next, cpu);
162
163        write_c0_entryhi(cpu_context(cpu, next));
164        TLBMISS_HANDLER_SETUP_PGD(next->pgd);
165
166        /* mark mmu ownership change */
167        cpu_clear(cpu, prev->cpu_vm_mask);
168        cpu_set(cpu, next->cpu_vm_mask);
169
170        local_irq_restore(flags);
171}
172
173/*
174 * If mm is currently active_mm, we can't really drop it.  Instead,
175 * we will get a new one for it.
176 */
177static inline void
178drop_mmu_context(struct mm_struct *mm, unsigned cpu)
179{
180        unsigned long flags;
181
182        local_irq_save(flags);
183
184        if (cpu_isset(cpu, mm->cpu_vm_mask))  {
185                get_new_mmu_context(mm, cpu);
186                write_c0_entryhi(cpu_asid(cpu, mm));
187        } else {
188                /* will get a new context next time */
189                cpu_context(cpu, mm) = 0;
190        }
191
192        local_irq_restore(flags);
193}
194
195#endif /* _ASM_MMU_CONTEXT_H */
Note: See TracBrowser for help on using the repository browser.