xref: /openbmc/qemu/target/riscv/debug.c (revision 31b9798d)
1 /*
2  * QEMU RISC-V Native Debug Support
3  *
4  * Copyright (c) 2022 Wind River Systems, Inc.
5  *
6  * Author:
7  *   Bin Meng <bin.meng@windriver.com>
8  *
9  * This provides the native debug support via the Trigger Module, as defined
10  * in the RISC-V Debug Specification:
11  * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms and conditions of the GNU General Public License,
15  * version 2 or later, as published by the Free Software Foundation.
16  *
17  * This program is distributed in the hope it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
20  * more details.
21  *
22  * You should have received a copy of the GNU General Public License along with
23  * this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #include "qemu/osdep.h"
27 #include "qemu/log.h"
28 #include "qapi/error.h"
29 #include "cpu.h"
30 #include "trace.h"
31 #include "exec/exec-all.h"
32 
33 /*
34  * The following M-mode trigger CSRs are implemented:
35  *
36  * - tselect
37  * - tdata1
38  * - tdata2
39  * - tdata3
40  * - tinfo
41  *
42  * The following triggers are implemented:
43  *
44  * Index | Type |          tdata mapping | Description
45  * ------+------+------------------------+------------
46  *     0 |    2 |         tdata1, tdata2 | Address / Data Match
47  *     1 |    2 |         tdata1, tdata2 | Address / Data Match
48  */
49 
50 /* tdata availability of a trigger */
51 typedef bool tdata_avail[TDATA_NUM];
52 
53 static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = {
54     [TRIGGER_TYPE_NO_EXIST] = { false, false, false },
55     [TRIGGER_TYPE_AD_MATCH] = { true, true, true },
56     [TRIGGER_TYPE_INST_CNT] = { true, false, true },
57     [TRIGGER_TYPE_INT] = { true, true, true },
58     [TRIGGER_TYPE_EXCP] = { true, true, true },
59     [TRIGGER_TYPE_AD_MATCH6] = { true, true, true },
60     [TRIGGER_TYPE_EXT_SRC] = { true, false, false },
61     [TRIGGER_TYPE_UNAVAIL] = { true, true, true }
62 };
63 
64 /* only breakpoint size 1/2/4/8 supported */
65 static int access_size[SIZE_NUM] = {
66     [SIZE_ANY] = 0,
67     [SIZE_1B]  = 1,
68     [SIZE_2B]  = 2,
69     [SIZE_4B]  = 4,
70     [SIZE_6B]  = -1,
71     [SIZE_8B]  = 8,
72     [6 ... 15] = -1,
73 };
74 
75 static inline target_ulong extract_trigger_type(CPURISCVState *env,
76                                                 target_ulong tdata1)
77 {
78     switch (riscv_cpu_mxl(env)) {
79     case MXL_RV32:
80         return extract32(tdata1, 28, 4);
81     case MXL_RV64:
82     case MXL_RV128:
83         return extract64(tdata1, 60, 4);
84     default:
85         g_assert_not_reached();
86     }
87 }
88 
89 static inline target_ulong get_trigger_type(CPURISCVState *env,
90                                             target_ulong trigger_index)
91 {
92     return extract_trigger_type(env, env->tdata1[trigger_index]);
93 }
94 
95 static inline target_ulong build_tdata1(CPURISCVState *env,
96                                         trigger_type_t type,
97                                         bool dmode, target_ulong data)
98 {
99     target_ulong tdata1;
100 
101     switch (riscv_cpu_mxl(env)) {
102     case MXL_RV32:
103         tdata1 = RV32_TYPE(type) |
104                  (dmode ? RV32_DMODE : 0) |
105                  (data & RV32_DATA_MASK);
106         break;
107     case MXL_RV64:
108     case MXL_RV128:
109         tdata1 = RV64_TYPE(type) |
110                  (dmode ? RV64_DMODE : 0) |
111                  (data & RV64_DATA_MASK);
112         break;
113     default:
114         g_assert_not_reached();
115     }
116 
117     return tdata1;
118 }
119 
120 bool tdata_available(CPURISCVState *env, int tdata_index)
121 {
122     int trigger_type = get_trigger_type(env, env->trigger_cur);
123 
124     if (unlikely(tdata_index >= TDATA_NUM)) {
125         return false;
126     }
127 
128     return tdata_mapping[trigger_type][tdata_index];
129 }
130 
131 target_ulong tselect_csr_read(CPURISCVState *env)
132 {
133     return env->trigger_cur;
134 }
135 
136 void tselect_csr_write(CPURISCVState *env, target_ulong val)
137 {
138     if (val < RV_MAX_TRIGGERS) {
139         env->trigger_cur = val;
140     }
141 }
142 
143 static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val,
144                                     trigger_type_t t)
145 {
146     uint32_t type, dmode;
147     target_ulong tdata1;
148 
149     switch (riscv_cpu_mxl(env)) {
150     case MXL_RV32:
151         type = extract32(val, 28, 4);
152         dmode = extract32(val, 27, 1);
153         tdata1 = RV32_TYPE(t);
154         break;
155     case MXL_RV64:
156     case MXL_RV128:
157         type = extract64(val, 60, 4);
158         dmode = extract64(val, 59, 1);
159         tdata1 = RV64_TYPE(t);
160         break;
161     default:
162         g_assert_not_reached();
163     }
164 
165     if (type != t) {
166         qemu_log_mask(LOG_GUEST_ERROR,
167                       "ignoring type write to tdata1 register\n");
168     }
169 
170     if (dmode != 0) {
171         qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n");
172     }
173 
174     return tdata1;
175 }
176 
177 static inline void warn_always_zero_bit(target_ulong val, target_ulong mask,
178                                         const char *msg)
179 {
180     if (val & mask) {
181         qemu_log_mask(LOG_UNIMP, "%s bit is always zero\n", msg);
182     }
183 }
184 
185 /* type 2 trigger */
186 
187 static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl)
188 {
189     uint32_t size, sizelo, sizehi = 0;
190 
191     if (riscv_cpu_mxl(env) == MXL_RV64) {
192         sizehi = extract32(ctrl, 21, 2);
193     }
194     sizelo = extract32(ctrl, 16, 2);
195     size = (sizehi << 2) | sizelo;
196 
197     return size;
198 }
199 
200 static inline bool type2_breakpoint_enabled(target_ulong ctrl)
201 {
202     bool mode = !!(ctrl & (TYPE2_U | TYPE2_S | TYPE2_M));
203     bool rwx = !!(ctrl & (TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC));
204 
205     return mode && rwx;
206 }
207 
208 static target_ulong type2_mcontrol_validate(CPURISCVState *env,
209                                             target_ulong ctrl)
210 {
211     target_ulong val;
212     uint32_t size;
213 
214     /* validate the generic part first */
215     val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH);
216 
217     /* validate unimplemented (always zero) bits */
218     warn_always_zero_bit(ctrl, TYPE2_MATCH, "match");
219     warn_always_zero_bit(ctrl, TYPE2_CHAIN, "chain");
220     warn_always_zero_bit(ctrl, TYPE2_ACTION, "action");
221     warn_always_zero_bit(ctrl, TYPE2_TIMING, "timing");
222     warn_always_zero_bit(ctrl, TYPE2_SELECT, "select");
223     warn_always_zero_bit(ctrl, TYPE2_HIT, "hit");
224 
225     /* validate size encoding */
226     size = type2_breakpoint_size(env, ctrl);
227     if (access_size[size] == -1) {
228         qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n",
229                       size);
230     } else {
231         val |= (ctrl & TYPE2_SIZELO);
232         if (riscv_cpu_mxl(env) == MXL_RV64) {
233             val |= (ctrl & TYPE2_SIZEHI);
234         }
235     }
236 
237     /* keep the mode and attribute bits */
238     val |= (ctrl & (TYPE2_U | TYPE2_S | TYPE2_M |
239                     TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC));
240 
241     return val;
242 }
243 
244 static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index)
245 {
246     target_ulong ctrl = env->tdata1[index];
247     target_ulong addr = env->tdata2[index];
248     bool enabled = type2_breakpoint_enabled(ctrl);
249     CPUState *cs = env_cpu(env);
250     int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
251     uint32_t size;
252 
253     if (!enabled) {
254         return;
255     }
256 
257     if (ctrl & TYPE2_EXEC) {
258         cpu_breakpoint_insert(cs, addr, flags, &env->cpu_breakpoint[index]);
259     }
260 
261     if (ctrl & TYPE2_LOAD) {
262         flags |= BP_MEM_READ;
263     }
264     if (ctrl & TYPE2_STORE) {
265         flags |= BP_MEM_WRITE;
266     }
267 
268     if (flags & BP_MEM_ACCESS) {
269         size = type2_breakpoint_size(env, ctrl);
270         if (size != 0) {
271             cpu_watchpoint_insert(cs, addr, size, flags,
272                                   &env->cpu_watchpoint[index]);
273         } else {
274             cpu_watchpoint_insert(cs, addr, 8, flags,
275                                   &env->cpu_watchpoint[index]);
276         }
277     }
278 }
279 
280 static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index)
281 {
282     CPUState *cs = env_cpu(env);
283 
284     if (env->cpu_breakpoint[index]) {
285         cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
286         env->cpu_breakpoint[index] = NULL;
287     }
288 
289     if (env->cpu_watchpoint[index]) {
290         cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
291         env->cpu_watchpoint[index] = NULL;
292     }
293 }
294 
295 static void type2_reg_write(CPURISCVState *env, target_ulong index,
296                             int tdata_index, target_ulong val)
297 {
298     target_ulong new_val;
299 
300     switch (tdata_index) {
301     case TDATA1:
302         new_val = type2_mcontrol_validate(env, val);
303         if (new_val != env->tdata1[index]) {
304             env->tdata1[index] = new_val;
305             type2_breakpoint_remove(env, index);
306             type2_breakpoint_insert(env, index);
307         }
308         break;
309     case TDATA2:
310         if (val != env->tdata2[index]) {
311             env->tdata2[index] = val;
312             type2_breakpoint_remove(env, index);
313             type2_breakpoint_insert(env, index);
314         }
315         break;
316     case TDATA3:
317         qemu_log_mask(LOG_UNIMP,
318                       "tdata3 is not supported for type 2 trigger\n");
319         break;
320     default:
321         g_assert_not_reached();
322     }
323 
324     return;
325 }
326 
327 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
328 {
329     switch (tdata_index) {
330     case TDATA1:
331         return env->tdata1[env->trigger_cur];
332     case TDATA2:
333         return env->tdata2[env->trigger_cur];
334     case TDATA3:
335         return env->tdata3[env->trigger_cur];
336     default:
337         g_assert_not_reached();
338     }
339 }
340 
341 void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
342 {
343     int trigger_type;
344 
345     if (tdata_index == TDATA1) {
346         trigger_type = extract_trigger_type(env, val);
347     } else {
348         trigger_type = get_trigger_type(env, env->trigger_cur);
349     }
350 
351     switch (trigger_type) {
352     case TRIGGER_TYPE_AD_MATCH:
353         type2_reg_write(env, env->trigger_cur, tdata_index, val);
354         break;
355     case TRIGGER_TYPE_INST_CNT:
356     case TRIGGER_TYPE_INT:
357     case TRIGGER_TYPE_EXCP:
358     case TRIGGER_TYPE_AD_MATCH6:
359     case TRIGGER_TYPE_EXT_SRC:
360         qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
361                       trigger_type);
362         break;
363     case TRIGGER_TYPE_NO_EXIST:
364     case TRIGGER_TYPE_UNAVAIL:
365         qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n",
366                       trigger_type);
367         break;
368     default:
369         g_assert_not_reached();
370     }
371 }
372 
373 target_ulong tinfo_csr_read(CPURISCVState *env)
374 {
375     /* assume all triggers support the same types of triggers */
376     return BIT(TRIGGER_TYPE_AD_MATCH);
377 }
378 
379 void riscv_cpu_debug_excp_handler(CPUState *cs)
380 {
381     RISCVCPU *cpu = RISCV_CPU(cs);
382     CPURISCVState *env = &cpu->env;
383 
384     if (cs->watchpoint_hit) {
385         if (cs->watchpoint_hit->flags & BP_CPU) {
386             cs->watchpoint_hit = NULL;
387             riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
388         }
389     } else {
390         if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
391             riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
392         }
393     }
394 }
395 
396 bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
397 {
398     RISCVCPU *cpu = RISCV_CPU(cs);
399     CPURISCVState *env = &cpu->env;
400     CPUBreakpoint *bp;
401     target_ulong ctrl;
402     target_ulong pc;
403     int trigger_type;
404     int i;
405 
406     QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
407         for (i = 0; i < RV_MAX_TRIGGERS; i++) {
408             trigger_type = get_trigger_type(env, i);
409 
410             switch (trigger_type) {
411             case TRIGGER_TYPE_AD_MATCH:
412                 ctrl = env->tdata1[i];
413                 pc = env->tdata2[i];
414 
415                 if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
416                     /* check U/S/M bit against current privilege level */
417                     if ((ctrl >> 3) & BIT(env->priv)) {
418                         return true;
419                     }
420                 }
421                 break;
422             default:
423                 /* other trigger types are not supported or irrelevant */
424                 break;
425             }
426         }
427     }
428 
429     return false;
430 }
431 
432 bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
433 {
434     RISCVCPU *cpu = RISCV_CPU(cs);
435     CPURISCVState *env = &cpu->env;
436     target_ulong ctrl;
437     target_ulong addr;
438     int trigger_type;
439     int flags;
440     int i;
441 
442     for (i = 0; i < RV_MAX_TRIGGERS; i++) {
443         trigger_type = get_trigger_type(env, i);
444 
445         switch (trigger_type) {
446         case TRIGGER_TYPE_AD_MATCH:
447             ctrl = env->tdata1[i];
448             addr = env->tdata2[i];
449             flags = 0;
450 
451             if (ctrl & TYPE2_LOAD) {
452                 flags |= BP_MEM_READ;
453             }
454             if (ctrl & TYPE2_STORE) {
455                 flags |= BP_MEM_WRITE;
456             }
457 
458             if ((wp->flags & flags) && (wp->vaddr == addr)) {
459                 /* check U/S/M bit against current privilege level */
460                 if ((ctrl >> 3) & BIT(env->priv)) {
461                     return true;
462                 }
463             }
464             break;
465         default:
466             /* other trigger types are not supported */
467             break;
468         }
469     }
470 
471     return false;
472 }
473 
474 void riscv_trigger_init(CPURISCVState *env)
475 {
476     target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
477     int i;
478 
479     /* init to type 2 triggers */
480     for (i = 0; i < RV_MAX_TRIGGERS; i++) {
481         /*
482          * type = TRIGGER_TYPE_AD_MATCH
483          * dmode = 0 (both debug and M-mode can write tdata)
484          * maskmax = 0 (unimplemented, always 0)
485          * sizehi = 0 (match against any size, RV64 only)
486          * hit = 0 (unimplemented, always 0)
487          * select = 0 (always 0, perform match on address)
488          * timing = 0 (always 0, trigger before instruction)
489          * sizelo = 0 (match against any size)
490          * action = 0 (always 0, raise a breakpoint exception)
491          * chain = 0 (unimplemented, always 0)
492          * match = 0 (always 0, when any compare value equals tdata2)
493          */
494         env->tdata1[i] = tdata1;
495         env->tdata2[i] = 0;
496         env->tdata3[i] = 0;
497         env->cpu_breakpoint[i] = NULL;
498         env->cpu_watchpoint[i] = NULL;
499     }
500 }
501