File: mmu_context.h

package info (click to toggle)
kernel-source-sparc-2.2.1 2.2.1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 62,800 kB
  • ctags: 188,320
  • sloc: ansic: 1,114,164; asm: 49,922; makefile: 8,272; sh: 1,831; perl: 1,584; tcl: 409; lisp: 218; cpp: 186; awk: 133; sed: 72
file content (134 lines) | stat: -rw-r--r-- 3,664 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* $Id: mmu_context.h,v 1.3 1998/10/16 19:22:54 ralf Exp $
 *
 * Switch a 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) 1996, 1997, 1998 by Ralf Baechle
 */
#ifndef __ASM_MIPS_MMU_CONTEXT_H
#define __ASM_MIPS_MMU_CONTEXT_H

/* Fuck.  The f-word is here so you can grep for it :-)  */
extern unsigned long asid_cache;

/* I patch, therefore I am ...  */
#define ASID_INC(asid)						\
 ({ unsigned long __asid = asid;				\
   __asm__("1:\taddiu\t%0,0\t\t\t\t# patched\n\t"		\
           ".section\t__asid_inc,\"a\"\n\t"			\
           ".word\t1b\n\t"					\
           ".previous"						\
           :"=r" (__asid)					\
           :"0" (__asid));					\
   __asid; })
#define ASID_MASK(asid)						\
 ({ unsigned long __asid = asid;				\
   __asm__("1:\tandi\t%0,%1,0\t\t\t# patched\n\t"			\
           ".section\t__asid_mask,\"a\"\n\t"			\
           ".word\t1b\n\t"					\
           ".previous"						\
           :"=r" (__asid)					\
           :"r" (__asid));					\
   __asid; })
#define ASID_VERSION_MASK					\
 ({ unsigned long __asid;					\
   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
           ".section\t__asid_version_mask,\"a\"\n\t"		\
           ".word\t1b\n\t"					\
           ".previous"						\
           :"=r" (__asid));					\
   __asid; })
#define ASID_FIRST_VERSION					\
 ({ unsigned long __asid = asid;				\
   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
           ".section\t__asid_first_version,\"a\"\n\t"		\
           ".word\t1b\n\t"					\
           ".previous"						\
           :"=r" (__asid));					\
   __asid; })

#define ASID_FIRST_VERSION_R3000 0x1000
#define ASID_FIRST_VERSION_R4000 0x100

extern inline void
get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
{
	if (!ASID_MASK((asid = ASID_INC(asid)))) {
		flush_tlb_all(); /* start new asid cycle */
		if (!asid)      /* fix version if needed */
			asid = ASID_FIRST_VERSION;
	}
	mm->context = asid_cache = asid;
}

extern inline void
get_mmu_context(struct task_struct *p)
{
	struct mm_struct *mm = p->mm;

	if (mm) {
		unsigned long asid = asid_cache;
		/* Check if our ASID is of an older version and thus invalid */
		if ((mm->context ^ asid) & ASID_VERSION_MASK)
			get_new_mmu_context(mm, asid);
	}
}

/*
 * Initialize the context related info for a new mm_struct
 * instance.
 */
extern inline void init_new_context(struct mm_struct *mm)
{
	mm->context = 0;
}

/*
 * Destroy context related info for an mm_struct that is about
 * to be put to rest.
 */
extern inline void destroy_context(struct mm_struct *mm)
{
	mm->context = 0;
}

/*
 * After we have set current->mm to a new value, this activates
 * the context for the new mm so we see the new mappings.
 */
extern inline void activate_context(struct task_struct *tsk)
{
	get_mmu_context(tsk);
	set_entryhi(tsk->mm->context);
}

extern void __asid_setup(unsigned int inc, unsigned int mask,
                         unsigned int version_mask, unsigned int first_version);

extern inline void r3000_asid_setup(void)
{
	__asid_setup(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000);
}

extern inline void r6000_asid_setup(void)
{
	panic("r6000_asid_setup: implement me");	/* No idea ...  */
}

extern inline void tfp_asid_setup(void)
{
	panic("tfp_asid_setup: implement me");	/* No idea ...  */
}

extern inline void r4xx0_asid_setup(void)
{
	__asid_setup(1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000);
}

/* R10000 has the same ASID mechanism as the R4000.  */
#define andes_asid_setup r4xx0_asid_setup

#endif /* __ASM_MIPS_MMU_CONTEXT_H */