Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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  */
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  */
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  */
80 {
81  switch (current_cpu_data.watch_reg_count) {
82  default:
83  BUG();
84  case 8:
86  case 7:
88  case 6:
90  case 5:
92  case 4:
94  case 3:
96  case 2:
98  case 1:
100  }
101 }
102 
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  */
114  t = read_c0_watchlo0();
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 
130  t = read_c0_watchlo1();
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 
144  t = read_c0_watchlo2();
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 
158  t = read_c0_watchlo3();
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 }