xref: /openbmc/linux/arch/mips/kernel/watch.c (revision 8c0b9ee8)
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 }
197