MIPS: Use fallthrough for arch/mips
[linux-2.6-microblaze.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(struct task_struct *t)
19 {
20         struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
21         unsigned int watchhi = MIPS_WATCHHI_G |         /* Trap all ASIDs */
22                                MIPS_WATCHHI_IRW;        /* Clear result bits */
23
24         switch (current_cpu_data.watch_reg_use_cnt) {
25         default:
26                 BUG();
27         case 4:
28                 write_c0_watchlo3(watches->watchlo[3]);
29                 write_c0_watchhi3(watchhi | watches->watchhi[3]);
30                 fallthrough;
31         case 3:
32                 write_c0_watchlo2(watches->watchlo[2]);
33                 write_c0_watchhi2(watchhi | watches->watchhi[2]);
34                 fallthrough;
35         case 2:
36                 write_c0_watchlo1(watches->watchlo[1]);
37                 write_c0_watchhi1(watchhi | watches->watchhi[1]);
38                 fallthrough;
39         case 1:
40                 write_c0_watchlo0(watches->watchlo[0]);
41                 write_c0_watchhi0(watchhi | watches->watchhi[0]);
42         }
43 }
44
45 /*
46  * Read back the watchhi registers so the user space debugger has
47  * access to the I, R, and W bits.  A maximum of four registers are
48  * read although the machine may have more.
49  */
50 void mips_read_watch_registers(void)
51 {
52         struct mips3264_watch_reg_state *watches =
53                 &current->thread.watch.mips3264;
54         unsigned int watchhi_mask = MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW;
55
56         switch (current_cpu_data.watch_reg_use_cnt) {
57         default:
58                 BUG();
59         case 4:
60                 watches->watchhi[3] = (read_c0_watchhi3() & watchhi_mask);
61                 fallthrough;
62         case 3:
63                 watches->watchhi[2] = (read_c0_watchhi2() & watchhi_mask);
64                 fallthrough;
65         case 2:
66                 watches->watchhi[1] = (read_c0_watchhi1() & watchhi_mask);
67                 fallthrough;
68         case 1:
69                 watches->watchhi[0] = (read_c0_watchhi0() & watchhi_mask);
70         }
71         if (current_cpu_data.watch_reg_use_cnt == 1 &&
72             (watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) {
73                 /* Pathological case of release 1 architecture that
74                  * doesn't set the condition bits.  We assume that
75                  * since we got here, the watch condition was met and
76                  * signal that the conditions requested in watchlo
77                  * were met.  */
78                 watches->watchhi[0] |= (watches->watchlo[0] & MIPS_WATCHHI_IRW);
79         }
80  }
81
82 /*
83  * Disable all watch registers.  Although only four registers are
84  * installed, all are cleared to eliminate the possibility of endless
85  * looping in the watch handler.
86  */
87 void mips_clear_watch_registers(void)
88 {
89         switch (current_cpu_data.watch_reg_count) {
90         default:
91                 BUG();
92         case 8:
93                 write_c0_watchlo7(0);
94                 fallthrough;
95         case 7:
96                 write_c0_watchlo6(0);
97                 fallthrough;
98         case 6:
99                 write_c0_watchlo5(0);
100                 fallthrough;
101         case 5:
102                 write_c0_watchlo4(0);
103                 fallthrough;
104         case 4:
105                 write_c0_watchlo3(0);
106                 fallthrough;
107         case 3:
108                 write_c0_watchlo2(0);
109                 fallthrough;
110         case 2:
111                 write_c0_watchlo1(0);
112                 fallthrough;
113         case 1:
114                 write_c0_watchlo0(0);
115         }
116 }
117
118 void mips_probe_watch_registers(struct cpuinfo_mips *c)
119 {
120         unsigned int t;
121
122         if ((c->options & MIPS_CPU_WATCH) == 0)
123                 return;
124         /*
125          * Check which of the I,R and W bits are supported, then
126          * disable the register.
127          */
128         write_c0_watchlo0(MIPS_WATCHLO_IRW);
129         back_to_back_c0_hazard();
130         t = read_c0_watchlo0();
131         write_c0_watchlo0(0);
132         c->watch_reg_masks[0] = t & MIPS_WATCHLO_IRW;
133
134         /* Write the mask bits and read them back to determine which
135          * can be used. */
136         c->watch_reg_count = 1;
137         c->watch_reg_use_cnt = 1;
138         t = read_c0_watchhi0();
139         write_c0_watchhi0(t | MIPS_WATCHHI_MASK);
140         back_to_back_c0_hazard();
141         t = read_c0_watchhi0();
142         c->watch_reg_masks[0] |= (t & MIPS_WATCHHI_MASK);
143         if ((t & MIPS_WATCHHI_M) == 0)
144                 return;
145
146         write_c0_watchlo1(MIPS_WATCHLO_IRW);
147         back_to_back_c0_hazard();
148         t = read_c0_watchlo1();
149         write_c0_watchlo1(0);
150         c->watch_reg_masks[1] = t & MIPS_WATCHLO_IRW;
151
152         c->watch_reg_count = 2;
153         c->watch_reg_use_cnt = 2;
154         t = read_c0_watchhi1();
155         write_c0_watchhi1(t | MIPS_WATCHHI_MASK);
156         back_to_back_c0_hazard();
157         t = read_c0_watchhi1();
158         c->watch_reg_masks[1] |= (t & MIPS_WATCHHI_MASK);
159         if ((t & MIPS_WATCHHI_M) == 0)
160                 return;
161
162         write_c0_watchlo2(MIPS_WATCHLO_IRW);
163         back_to_back_c0_hazard();
164         t = read_c0_watchlo2();
165         write_c0_watchlo2(0);
166         c->watch_reg_masks[2] = t & MIPS_WATCHLO_IRW;
167
168         c->watch_reg_count = 3;
169         c->watch_reg_use_cnt = 3;
170         t = read_c0_watchhi2();
171         write_c0_watchhi2(t | MIPS_WATCHHI_MASK);
172         back_to_back_c0_hazard();
173         t = read_c0_watchhi2();
174         c->watch_reg_masks[2] |= (t & MIPS_WATCHHI_MASK);
175         if ((t & MIPS_WATCHHI_M) == 0)
176                 return;
177
178         write_c0_watchlo3(MIPS_WATCHLO_IRW);
179         back_to_back_c0_hazard();
180         t = read_c0_watchlo3();
181         write_c0_watchlo3(0);
182         c->watch_reg_masks[3] = t & MIPS_WATCHLO_IRW;
183
184         c->watch_reg_count = 4;
185         c->watch_reg_use_cnt = 4;
186         t = read_c0_watchhi3();
187         write_c0_watchhi3(t | MIPS_WATCHHI_MASK);
188         back_to_back_c0_hazard();
189         t = read_c0_watchhi3();
190         c->watch_reg_masks[3] |= (t & MIPS_WATCHHI_MASK);
191         if ((t & MIPS_WATCHHI_M) == 0)
192                 return;
193
194         /* We use at most 4, but probe and report up to 8. */
195         c->watch_reg_count = 5;
196         t = read_c0_watchhi4();
197         if ((t & MIPS_WATCHHI_M) == 0)
198                 return;
199
200         c->watch_reg_count = 6;
201         t = read_c0_watchhi5();
202         if ((t & MIPS_WATCHHI_M) == 0)
203                 return;
204
205         c->watch_reg_count = 7;
206         t = read_c0_watchhi6();
207         if ((t & MIPS_WATCHHI_M) == 0)
208                 return;
209
210         c->watch_reg_count = 8;
211 }