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
mips
kernel
watch.c
Go to the documentation of this file.
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (C) 2008 David Daney
7
*/
8
9
#include <linux/sched.h>
10
11
#include <asm/processor.h>
12
#include <
asm/watch.h
>
13
14
/*
15
* Install the watch registers for the current thread. A maximum of
16
* four registers are installed although the machine may have more.
17
*/
18
void
mips_install_watch_registers
(
void
)
19
{
20
struct
mips3264_watch_reg_state
*watches =
21
&
current
->thread.watch.mips3264;
22
switch
(
current_cpu_data
.watch_reg_use_cnt) {
23
default
:
24
BUG
();
25
case
4:
26
write_c0_watchlo3
(watches->
watchlo
[3]);
27
/* Write 1 to the I, R, and W bits to clear them, and
28
1 to G so all ASIDs are trapped. */
29
write_c0_watchhi3
(0x40000007 | watches->
watchhi
[3]);
30
case
3:
31
write_c0_watchlo2
(watches->
watchlo
[2]);
32
write_c0_watchhi2
(0x40000007 | watches->
watchhi
[2]);
33
case
2:
34
write_c0_watchlo1
(watches->
watchlo
[1]);
35
write_c0_watchhi1
(0x40000007 | watches->
watchhi
[1]);
36
case
1:
37
write_c0_watchlo0
(watches->
watchlo
[0]);
38
write_c0_watchhi0
(0x40000007 | watches->
watchhi
[0]);
39
}
40
}
41
42
/*
43
* Read back the watchhi registers so the user space debugger has
44
* access to the I, R, and W bits. A maximum of four registers are
45
* read although the machine may have more.
46
*/
47
void
mips_read_watch_registers
(
void
)
48
{
49
struct
mips3264_watch_reg_state
*watches =
50
&
current
->thread.watch.mips3264;
51
switch
(
current_cpu_data
.watch_reg_use_cnt) {
52
default
:
53
BUG
();
54
case
4:
55
watches->
watchhi
[3] = (
read_c0_watchhi3
() & 0x0fff);
56
case
3:
57
watches->
watchhi
[2] = (
read_c0_watchhi2
() & 0x0fff);
58
case
2:
59
watches->
watchhi
[1] = (
read_c0_watchhi1
() & 0x0fff);
60
case
1:
61
watches->
watchhi
[0] = (
read_c0_watchhi0
() & 0x0fff);
62
}
63
if
(
current_cpu_data
.watch_reg_use_cnt == 1 &&
64
(watches->
watchhi
[0] & 7) == 0) {
65
/* Pathological case of release 1 architecture that
66
* doesn't set the condition bits. We assume that
67
* since we got here, the watch condition was met and
68
* signal that the conditions requested in watchlo
69
* were met. */
70
watches->
watchhi
[0] |= (watches->
watchlo
[0] & 7);
71
}
72
}
73
74
/*
75
* Disable all watch registers. Although only four registers are
76
* installed, all are cleared to eliminate the possibility of endless
77
* looping in the watch handler.
78
*/
79
void
mips_clear_watch_registers
(
void
)
80
{
81
switch
(
current_cpu_data
.watch_reg_count) {
82
default
:
83
BUG
();
84
case
8:
85
write_c0_watchlo7
(0);
86
case
7:
87
write_c0_watchlo6
(0);
88
case
6:
89
write_c0_watchlo5
(0);
90
case
5:
91
write_c0_watchlo4
(0);
92
case
4:
93
write_c0_watchlo3
(0);
94
case
3:
95
write_c0_watchlo2
(0);
96
case
2:
97
write_c0_watchlo1
(0);
98
case
1:
99
write_c0_watchlo0
(0);
100
}
101
}
102
103
__cpuinit
void
mips_probe_watch_registers
(
struct
cpuinfo_mips
*
c
)
104
{
105
unsigned
int
t
;
106
107
if
((c->
options
&
MIPS_CPU_WATCH
) == 0)
108
return
;
109
/*
110
* Check which of the I,R and W bits are supported, then
111
* disable the register.
112
*/
113
write_c0_watchlo0
(7);
114
t =
read_c0_watchlo0
();
115
write_c0_watchlo0
(0);
116
c->
watch_reg_masks
[0] = t & 7;
117
118
/* Write the mask bits and read them back to determine which
119
* can be used. */
120
c->
watch_reg_count
= 1;
121
c->
watch_reg_use_cnt
= 1;
122
t =
read_c0_watchhi0
();
123
write_c0_watchhi0
(t | 0xff8);
124
t =
read_c0_watchhi0
();
125
c->
watch_reg_masks
[0] |= (t & 0xff8);
126
if
((t & 0x80000000) == 0)
127
return
;
128
129
write_c0_watchlo1
(7);
130
t =
read_c0_watchlo1
();
131
write_c0_watchlo1
(0);
132
c->
watch_reg_masks
[1] = t & 7;
133
134
c->
watch_reg_count
= 2;
135
c->
watch_reg_use_cnt
= 2;
136
t =
read_c0_watchhi1
();
137
write_c0_watchhi1
(t | 0xff8);
138
t =
read_c0_watchhi1
();
139
c->
watch_reg_masks
[1] |= (t & 0xff8);
140
if
((t & 0x80000000) == 0)
141
return
;
142
143
write_c0_watchlo2
(7);
144
t =
read_c0_watchlo2
();
145
write_c0_watchlo2
(0);
146
c->
watch_reg_masks
[2] = t & 7;
147
148
c->
watch_reg_count
= 3;
149
c->
watch_reg_use_cnt
= 3;
150
t =
read_c0_watchhi2
();
151
write_c0_watchhi2
(t | 0xff8);
152
t =
read_c0_watchhi2
();
153
c->
watch_reg_masks
[2] |= (t & 0xff8);
154
if
((t & 0x80000000) == 0)
155
return
;
156
157
write_c0_watchlo3
(7);
158
t =
read_c0_watchlo3
();
159
write_c0_watchlo3
(0);
160
c->
watch_reg_masks
[3] = t & 7;
161
162
c->
watch_reg_count
= 4;
163
c->
watch_reg_use_cnt
= 4;
164
t =
read_c0_watchhi3
();
165
write_c0_watchhi3
(t | 0xff8);
166
t =
read_c0_watchhi3
();
167
c->
watch_reg_masks
[3] |= (t & 0xff8);
168
if
((t & 0x80000000) == 0)
169
return
;
170
171
/* We use at most 4, but probe and report up to 8. */
172
c->
watch_reg_count
= 5;
173
t =
read_c0_watchhi4
();
174
if
((t & 0x80000000) == 0)
175
return
;
176
177
c->
watch_reg_count
= 6;
178
t =
read_c0_watchhi5
();
179
if
((t & 0x80000000) == 0)
180
return
;
181
182
c->
watch_reg_count
= 7;
183
t =
read_c0_watchhi6
();
184
if
((t & 0x80000000) == 0)
185
return
;
186
187
c->
watch_reg_count
= 8;
188
}
Generated on Thu Jan 10 2013 13:11:27 for Linux Kernel by
1.8.2