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
cache-sh3.c
Go to the documentation of this file.
1
/*
2
* arch/sh/mm/cache-sh3.c
3
*
4
* Copyright (C) 1999, 2000 Niibe Yutaka
5
* Copyright (C) 2002 Paul Mundt
6
*
7
* Released under the terms of the GNU GPL v2.0.
8
*/
9
10
#include <
linux/init.h
>
11
#include <linux/mman.h>
12
#include <
linux/mm.h
>
13
#include <
linux/threads.h
>
14
#include <asm/addrspace.h>
15
#include <asm/page.h>
16
#include <asm/pgtable.h>
17
#include <asm/processor.h>
18
#include <asm/cache.h>
19
#include <asm/io.h>
20
#include <asm/uaccess.h>
21
#include <asm/pgalloc.h>
22
#include <asm/mmu_context.h>
23
#include <asm/cacheflush.h>
24
25
/*
26
* Write back the dirty D-caches, but not invalidate them.
27
*
28
* Is this really worth it, or should we just alias this routine
29
* to __flush_purge_region too?
30
*
31
* START: Virtual Address (U0, P1, or P3)
32
* SIZE: Size of the region.
33
*/
34
35
static
void
sh3__flush_wback_region(
void
*
start
,
int
size
)
36
{
37
unsigned
long
v
,
j
;
38
unsigned
long
begin,
end
;
39
unsigned
long
flags
;
40
41
begin = (
unsigned
long
)start & ~(
L1_CACHE_BYTES
-1);
42
end = ((
unsigned
long
)start + size +
L1_CACHE_BYTES
-1)
43
& ~(
L1_CACHE_BYTES
-1);
44
45
for
(v = begin; v <
end
; v+=
L1_CACHE_BYTES
) {
46
unsigned
long
addrstart =
CACHE_OC_ADDRESS_ARRAY
;
47
for
(j = 0; j <
current_cpu_data
.dcache.ways; j++) {
48
unsigned
long
data
,
addr
,
p
;
49
50
p =
__pa
(v);
51
addr = addrstart | (v &
current_cpu_data
.dcache.entry_mask);
52
local_irq_save
(flags);
53
data =
__raw_readl
(addr);
54
55
if
((data &
CACHE_PHYSADDR_MASK
) ==
56
(p & CACHE_PHYSADDR_MASK)) {
57
data &= ~
SH_CACHE_UPDATED
;
58
__raw_writel
(data, addr);
59
local_irq_restore
(flags);
60
break
;
61
}
62
local_irq_restore
(flags);
63
addrstart +=
current_cpu_data
.dcache.way_incr;
64
}
65
}
66
}
67
68
/*
69
* Write back the dirty D-caches and invalidate them.
70
*
71
* START: Virtual Address (U0, P1, or P3)
72
* SIZE: Size of the region.
73
*/
74
static
void
sh3__flush_purge_region(
void
*start,
int
size)
75
{
76
unsigned
long
v
;
77
unsigned
long
begin,
end
;
78
79
begin = (
unsigned
long
)start & ~(
L1_CACHE_BYTES
-1);
80
end = ((
unsigned
long
)start + size +
L1_CACHE_BYTES
-1)
81
& ~(
L1_CACHE_BYTES
-1);
82
83
for
(v = begin; v <
end
; v+=
L1_CACHE_BYTES
) {
84
unsigned
long
data
,
addr
;
85
86
data = (v & 0xfffffc00);
/* _Virtual_ address, ~U, ~V */
87
addr =
CACHE_OC_ADDRESS_ARRAY
|
88
(v &
current_cpu_data
.dcache.entry_mask) |
SH_CACHE_ASSOC
;
89
__raw_writel
(data, addr);
90
}
91
}
92
93
void
__init
sh3_cache_init
(
void
)
94
{
95
__flush_wback_region
= sh3__flush_wback_region;
96
__flush_purge_region
= sh3__flush_purge_region;
97
98
/*
99
* No write back please
100
*
101
* Except I don't think there's any way to avoid the writeback.
102
* So we just alias it to sh3__flush_purge_region(). dwmw2.
103
*/
104
__flush_invalidate_region
= sh3__flush_purge_region;
105
}
Generated on Thu Jan 10 2013 13:18:01 for Linux Kernel by
1.8.2