]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/mips/kernel/watch.c
MLK-10058-1 ARM: imx6sx: add one pcie phy regulator in gpc dts
[karo-tx-linux.git] / arch / mips / kernel / watch.c
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 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         back_to_back_c0_hazard();
115         t = read_c0_watchlo0();
116         write_c0_watchlo0(0);
117         c->watch_reg_masks[0] = t & 7;
118
119         /* Write the mask bits and read them back to determine which
120          * can be used. */
121         c->watch_reg_count = 1;
122         c->watch_reg_use_cnt = 1;
123         t = read_c0_watchhi0();
124         write_c0_watchhi0(t | 0xff8);
125         back_to_back_c0_hazard();
126         t = read_c0_watchhi0();
127         c->watch_reg_masks[0] |= (t & 0xff8);
128         if ((t & 0x80000000) == 0)
129                 return;
130
131         write_c0_watchlo1(7);
132         back_to_back_c0_hazard();
133         t = read_c0_watchlo1();
134         write_c0_watchlo1(0);
135         c->watch_reg_masks[1] = t & 7;
136
137         c->watch_reg_count = 2;
138         c->watch_reg_use_cnt = 2;
139         t = read_c0_watchhi1();
140         write_c0_watchhi1(t | 0xff8);
141         back_to_back_c0_hazard();
142         t = read_c0_watchhi1();
143         c->watch_reg_masks[1] |= (t & 0xff8);
144         if ((t & 0x80000000) == 0)
145                 return;
146
147         write_c0_watchlo2(7);
148         back_to_back_c0_hazard();
149         t = read_c0_watchlo2();
150         write_c0_watchlo2(0);
151         c->watch_reg_masks[2] = t & 7;
152
153         c->watch_reg_count = 3;
154         c->watch_reg_use_cnt = 3;
155         t = read_c0_watchhi2();
156         write_c0_watchhi2(t | 0xff8);
157         back_to_back_c0_hazard();
158         t = read_c0_watchhi2();
159         c->watch_reg_masks[2] |= (t & 0xff8);
160         if ((t & 0x80000000) == 0)
161                 return;
162
163         write_c0_watchlo3(7);
164         back_to_back_c0_hazard();
165         t = read_c0_watchlo3();
166         write_c0_watchlo3(0);
167         c->watch_reg_masks[3] = t & 7;
168
169         c->watch_reg_count = 4;
170         c->watch_reg_use_cnt = 4;
171         t = read_c0_watchhi3();
172         write_c0_watchhi3(t | 0xff8);
173         back_to_back_c0_hazard();
174         t = read_c0_watchhi3();
175         c->watch_reg_masks[3] |= (t & 0xff8);
176         if ((t & 0x80000000) == 0)
177                 return;
178
179         /* We use at most 4, but probe and report up to 8. */
180         c->watch_reg_count = 5;
181         t = read_c0_watchhi4();
182         if ((t & 0x80000000) == 0)
183                 return;
184
185         c->watch_reg_count = 6;
186         t = read_c0_watchhi5();
187         if ((t & 0x80000000) == 0)
188                 return;
189
190         c->watch_reg_count = 7;
191         t = read_c0_watchhi6();
192         if ((t & 0x80000000) == 0)
193                 return;
194
195         c->watch_reg_count = 8;
196 }