Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sh
mm
tlbflush_32.c
Go to the documentation of this file.
1
/*
2
* TLB flushing operations for SH with an MMU.
3
*
4
* Copyright (C) 1999 Niibe Yutaka
5
* Copyright (C) 2003 Paul Mundt
6
*
7
* This file is subject to the terms and conditions of the GNU General Public
8
* License. See the file "COPYING" in the main directory of this archive
9
* for more details.
10
*/
11
#include <
linux/mm.h
>
12
#include <asm/mmu_context.h>
13
#include <asm/tlbflush.h>
14
15
void
local_flush_tlb_page
(
struct
vm_area_struct
*vma,
unsigned
long
page
)
16
{
17
unsigned
int
cpu
=
smp_processor_id
();
18
19
if
(vma->
vm_mm
&&
cpu_context
(cpu, vma->
vm_mm
) !=
NO_CONTEXT
) {
20
unsigned
long
flags
;
21
unsigned
long
asid
;
22
unsigned
long
saved_asid =
MMU_NO_ASID
;
23
24
asid =
cpu_asid
(cpu, vma->
vm_mm
);
25
page &=
PAGE_MASK
;
26
27
local_irq_save
(flags);
28
if
(vma->
vm_mm
!=
current
->mm) {
29
saved_asid = get_asid();
30
set_asid(asid);
31
}
32
local_flush_tlb_one
(asid, page);
33
if
(saved_asid !=
MMU_NO_ASID
)
34
set_asid(saved_asid);
35
local_irq_restore
(flags);
36
}
37
}
38
39
void
local_flush_tlb_range
(
struct
vm_area_struct
*vma,
unsigned
long
start
,
40
unsigned
long
end
)
41
{
42
struct
mm_struct
*mm = vma->
vm_mm
;
43
unsigned
int
cpu
=
smp_processor_id
();
44
45
if
(
cpu_context
(cpu, mm) !=
NO_CONTEXT
) {
46
unsigned
long
flags
;
47
int
size
;
48
49
local_irq_save
(flags);
50
size = (end - start + (
PAGE_SIZE
- 1)) >>
PAGE_SHIFT
;
51
if
(size > (
MMU_NTLB_ENTRIES
/4)) {
/* Too many TLB to flush */
52
cpu_context
(cpu, mm) =
NO_CONTEXT
;
53
if
(mm ==
current
->mm)
54
activate_context
(mm, cpu);
55
}
else
{
56
unsigned
long
asid
;
57
unsigned
long
saved_asid =
MMU_NO_ASID
;
58
59
asid =
cpu_asid
(cpu, mm);
60
start &=
PAGE_MASK
;
61
end += (
PAGE_SIZE
- 1);
62
end &=
PAGE_MASK
;
63
if
(mm !=
current
->mm) {
64
saved_asid = get_asid();
65
set_asid(asid);
66
}
67
while
(start < end) {
68
local_flush_tlb_one
(asid, start);
69
start +=
PAGE_SIZE
;
70
}
71
if
(saved_asid !=
MMU_NO_ASID
)
72
set_asid(saved_asid);
73
}
74
local_irq_restore
(flags);
75
}
76
}
77
78
void
local_flush_tlb_kernel_range
(
unsigned
long
start
,
unsigned
long
end
)
79
{
80
unsigned
int
cpu
=
smp_processor_id
();
81
unsigned
long
flags
;
82
int
size
;
83
84
local_irq_save
(flags);
85
size = (end - start + (
PAGE_SIZE
- 1)) >>
PAGE_SHIFT
;
86
if
(size > (
MMU_NTLB_ENTRIES
/4)) {
/* Too many TLB to flush */
87
local_flush_tlb_all
();
88
}
else
{
89
unsigned
long
asid
;
90
unsigned
long
saved_asid = get_asid();
91
92
asid =
cpu_asid
(cpu, &
init_mm
);
93
start &=
PAGE_MASK
;
94
end += (
PAGE_SIZE
- 1);
95
end &=
PAGE_MASK
;
96
set_asid(asid);
97
while
(start < end) {
98
local_flush_tlb_one
(asid, start);
99
start +=
PAGE_SIZE
;
100
}
101
set_asid(saved_asid);
102
}
103
local_irq_restore
(flags);
104
}
105
106
void
local_flush_tlb_mm
(
struct
mm_struct
*mm)
107
{
108
unsigned
int
cpu
=
smp_processor_id
();
109
110
/* Invalidate all TLB of this process. */
111
/* Instead of invalidating each TLB, we get new MMU context. */
112
if
(
cpu_context
(cpu, mm) !=
NO_CONTEXT
) {
113
unsigned
long
flags
;
114
115
local_irq_save
(flags);
116
cpu_context
(cpu, mm) =
NO_CONTEXT
;
117
if
(mm ==
current
->mm)
118
activate_context
(mm, cpu);
119
local_irq_restore
(flags);
120
}
121
}
122
123
void
__flush_tlb_global
(
void
)
124
{
125
unsigned
long
flags
;
126
127
local_irq_save
(flags);
128
129
/*
130
* This is the most destructive of the TLB flushing options,
131
* and will tear down all of the UTLB/ITLB mappings, including
132
* wired entries.
133
*/
134
__raw_writel
(
__raw_readl
(
MMUCR
) |
MMUCR_TI
,
MMUCR
);
135
136
local_irq_restore
(flags);
137
}
Generated on Thu Jan 10 2013 13:18:02 for Linux Kernel by
1.8.2