1 /*
2 * Copyright (c) 2015 Juniper Networks Inc.
3 * All rights reserved.
4 *
5 * Developed by Semihalf.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 #include "opt_ddb.h"
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/kdb.h>
35 #include <sys/pcpu.h>
36 #include <sys/reg.h>
37 #include <sys/smp.h>
38 #include <sys/systm.h>
39
40 #include <machine/atomic.h>
41 #include <machine/armreg.h>
42 #include <machine/cpu.h>
43 #include <machine/debug_monitor.h>
44 #include <machine/kdb.h>
45 #include <machine/pcb.h>
46
47 #include <ddb/ddb.h>
48 #include <ddb/db_access.h>
49 #include <ddb/db_sym.h>
50
51 enum dbg_t {
52 DBG_TYPE_BREAKPOINT = 0,
53 DBG_TYPE_WATCHPOINT = 1,
54 };
55
56 struct dbg_wb_conf {
57 enum dbg_t type;
58 enum dbg_access_t access;
59 db_addr_t address;
60 db_expr_t size;
61 u_int slot;
62 };
63
64 static int dbg_reset_state(void);
65 static int dbg_setup_breakpoint(db_expr_t, db_expr_t, u_int);
66 static int dbg_remove_breakpoint(u_int);
67 static u_int dbg_find_slot(enum dbg_t, db_expr_t);
68 static boolean_t dbg_check_slot_free(enum dbg_t, u_int);
69
70 static int dbg_remove_xpoint(struct dbg_wb_conf *);
71 static int dbg_setup_xpoint(struct dbg_wb_conf *);
72
73 static int dbg_capable_var; /* Indicates that machine is capable of using
74 HW watchpoints/breakpoints */
75
76 static uint32_t dbg_model; /* Debug Arch. Model */
77 static boolean_t dbg_ossr; /* OS Save and Restore implemented */
78
79 static uint32_t dbg_watchpoint_num;
80 static uint32_t dbg_breakpoint_num;
81
82 /* ID_DFR0 - Debug Feature Register 0 */
83 #define ID_DFR0_CP_DEBUG_M_SHIFT 0
84 #define ID_DFR0_CP_DEBUG_M_MASK (0xF << ID_DFR0_CP_DEBUG_M_SHIFT)
85 #define ID_DFR0_CP_DEBUG_M_NS (0x0) /* Not supported */
86 #define ID_DFR0_CP_DEBUG_M_V6 (0x2) /* v6 Debug arch. CP14 access */
87 #define ID_DFR0_CP_DEBUG_M_V6_1 (0x3) /* v6.1 Debug arch. CP14 access */
88 #define ID_DFR0_CP_DEBUG_M_V7 (0x4) /* v7 Debug arch. CP14 access */
89 #define ID_DFR0_CP_DEBUG_M_V7_1 (0x5) /* v7.1 Debug arch. CP14 access */
90
91 /* DBGDIDR - Debug ID Register */
92 #define DBGDIDR_WRPS_SHIFT 28
93 #define DBGDIDR_WRPS_MASK (0xF << DBGDIDR_WRPS_SHIFT)
94 #define DBGDIDR_WRPS_NUM(reg) \
95 ((((reg) & DBGDIDR_WRPS_MASK) >> DBGDIDR_WRPS_SHIFT) + 1)
96
97 #define DBGDIDR_BRPS_SHIFT 24
98 #define DBGDIDR_BRPS_MASK (0xF << DBGDIDR_BRPS_SHIFT)
99 #define DBGDIDR_BRPS_NUM(reg) \
100 ((((reg) & DBGDIDR_BRPS_MASK) >> DBGDIDR_BRPS_SHIFT) + 1)
101
102 /* DBGPRSR - Device Powerdown and Reset Status Register */
103 #define DBGPRSR_PU (1 << 0) /* Powerup status */
104
105 /* DBGOSLSR - OS Lock Status Register */
106 #define DBGOSLSR_OSLM0 (1 << 0)
107
108 /* DBGOSDLR - OS Double Lock Register */
109 #define DBGPRSR_DLK (1 << 0) /* OS Double Lock set */
110
111 /* DBGDSCR - Debug Status and Control Register */
112 #define DBGSCR_MDBG_EN (1 << 15) /* Monitor debug-mode enable */
113
114 /* DBGWVR - Watchpoint Value Register */
115 #define DBGWVR_ADDR_MASK (~0x3U)
116
117 /* Watchpoints/breakpoints control register bitfields */
118 #define DBG_WB_CTRL_LEN_1 (0x1 << 5)
119 #define DBG_WB_CTRL_LEN_2 (0x3 << 5)
120 #define DBG_WB_CTRL_LEN_4 (0xf << 5)
121 #define DBG_WB_CTRL_LEN_8 (0xff << 5)
122 #define DBG_WB_CTRL_LEN_MASK(x) ((x) & (0xff << 5))
123 #define DBG_WB_CTRL_EXEC (0x0 << 3)
124 #define DBG_WB_CTRL_LOAD (0x1 << 3)
125 #define DBG_WB_CTRL_STORE (0x2 << 3)
126 #define DBG_WB_CTRL_ACCESS_MASK(x) ((x) & (0x3 << 3))
127
128 /* Common for breakpoint and watchpoint */
129 #define DBG_WB_CTRL_PL1 (0x1 << 1)
130 #define DBG_WB_CTRL_PL0 (0x2 << 1)
131 #define DBG_WB_CTRL_PLX_MASK(x) ((x) & (0x3 << 1))
132 #define DBG_WB_CTRL_E (0x1 << 0)
133
134 /*
135 * Watchpoint/breakpoint helpers
136 */
137 #define DBG_BKPT_BT_SLOT 0 /* Slot for branch taken */
138 #define DBG_BKPT_BNT_SLOT 1 /* Slot for branch not taken */
139
140 #define OP2_SHIFT 4
141
142 /* Opc2 numbers for coprocessor instructions */
143 #define DBG_WB_BVR 4
144 #define DBG_WB_BCR 5
145 #define DBG_WB_WVR 6
146 #define DBG_WB_WCR 7
147
148 #define DBG_REG_BASE_BVR (DBG_WB_BVR << OP2_SHIFT)
149 #define DBG_REG_BASE_BCR (DBG_WB_BCR << OP2_SHIFT)
150 #define DBG_REG_BASE_WVR (DBG_WB_WVR << OP2_SHIFT)
151 #define DBG_REG_BASE_WCR (DBG_WB_WCR << OP2_SHIFT)
152
153 #define DBG_WB_READ(cn, cm, op2, val) do { \
154 __asm __volatile("mrc p14, 0, %0, " #cn "," #cm "," #op2 : "=r" (val)); \
155 } while (0)
156
157 #define DBG_WB_WRITE(cn, cm, op2, val) do { \
158 __asm __volatile("mcr p14, 0, %0, " #cn "," #cm "," #op2 :: "r" (val)); \
159 } while (0)
160
161 #define READ_WB_REG_CASE(op2, m, val) \
162 case (((op2) << OP2_SHIFT) + m): \
163 DBG_WB_READ(c0, c ## m, op2, val); \
164 break
165
166 #define WRITE_WB_REG_CASE(op2, m, val) \
167 case (((op2) << OP2_SHIFT) + m): \
168 DBG_WB_WRITE(c0, c ## m, op2, val); \
169 break
170
171 #define SWITCH_CASES_READ_WB_REG(op2, val) \
172 READ_WB_REG_CASE(op2, 0, val); \
173 READ_WB_REG_CASE(op2, 1, val); \
174 READ_WB_REG_CASE(op2, 2, val); \
175 READ_WB_REG_CASE(op2, 3, val); \
176 READ_WB_REG_CASE(op2, 4, val); \
177 READ_WB_REG_CASE(op2, 5, val); \
178 READ_WB_REG_CASE(op2, 6, val); \
179 READ_WB_REG_CASE(op2, 7, val); \
180 READ_WB_REG_CASE(op2, 8, val); \
181 READ_WB_REG_CASE(op2, 9, val); \
182 READ_WB_REG_CASE(op2, 10, val); \
183 READ_WB_REG_CASE(op2, 11, val); \
184 READ_WB_REG_CASE(op2, 12, val); \
185 READ_WB_REG_CASE(op2, 13, val); \
186 READ_WB_REG_CASE(op2, 14, val); \
187 READ_WB_REG_CASE(op2, 15, val)
188
189 #define SWITCH_CASES_WRITE_WB_REG(op2, val) \
190 WRITE_WB_REG_CASE(op2, 0, val); \
191 WRITE_WB_REG_CASE(op2, 1, val); \
192 WRITE_WB_REG_CASE(op2, 2, val); \
193 WRITE_WB_REG_CASE(op2, 3, val); \
194 WRITE_WB_REG_CASE(op2, 4, val); \
195 WRITE_WB_REG_CASE(op2, 5, val); \
196 WRITE_WB_REG_CASE(op2, 6, val); \
197 WRITE_WB_REG_CASE(op2, 7, val); \
198 WRITE_WB_REG_CASE(op2, 8, val); \
199 WRITE_WB_REG_CASE(op2, 9, val); \
200 WRITE_WB_REG_CASE(op2, 10, val); \
201 WRITE_WB_REG_CASE(op2, 11, val); \
202 WRITE_WB_REG_CASE(op2, 12, val); \
203 WRITE_WB_REG_CASE(op2, 13, val); \
204 WRITE_WB_REG_CASE(op2, 14, val); \
205 WRITE_WB_REG_CASE(op2, 15, val)
206
207 static uint32_t
dbg_wb_read_reg(int reg,int n)208 dbg_wb_read_reg(int reg, int n)
209 {
210 uint32_t val;
211
212 val = 0;
213
214 switch (reg + n) {
215 SWITCH_CASES_READ_WB_REG(DBG_WB_WVR, val);
216 SWITCH_CASES_READ_WB_REG(DBG_WB_WCR, val);
217 SWITCH_CASES_READ_WB_REG(DBG_WB_BVR, val);
218 SWITCH_CASES_READ_WB_REG(DBG_WB_BCR, val);
219 default:
220 db_printf(
221 "trying to read from CP14 reg. using wrong opc2 %d\n",
222 reg >> OP2_SHIFT);
223 }
224
225 return (val);
226 }
227
228 static void
dbg_wb_write_reg(int reg,int n,uint32_t val)229 dbg_wb_write_reg(int reg, int n, uint32_t val)
230 {
231
232 switch (reg + n) {
233 SWITCH_CASES_WRITE_WB_REG(DBG_WB_WVR, val);
234 SWITCH_CASES_WRITE_WB_REG(DBG_WB_WCR, val);
235 SWITCH_CASES_WRITE_WB_REG(DBG_WB_BVR, val);
236 SWITCH_CASES_WRITE_WB_REG(DBG_WB_BCR, val);
237 default:
238 db_printf(
239 "trying to write to CP14 reg. using wrong opc2 %d\n",
240 reg >> OP2_SHIFT);
241 }
242 isb();
243 }
244
245 static __inline boolean_t
dbg_capable(void)246 dbg_capable(void)
247 {
248
249 return (atomic_cmpset_int(&dbg_capable_var, 0, 0) == 0);
250 }
251
252 boolean_t
kdb_cpu_pc_is_singlestep(db_addr_t pc)253 kdb_cpu_pc_is_singlestep(db_addr_t pc)
254 {
255 /*
256 * XXX: If the platform fails to enable its debug arch.
257 * there will be no stepping capabilities
258 */
259 if (!dbg_capable())
260 return (FALSE);
261
262 if (dbg_find_slot(DBG_TYPE_BREAKPOINT, pc) != ~0U)
263 return (TRUE);
264
265 return (FALSE);
266 }
267
268 void
kdb_cpu_set_singlestep(void)269 kdb_cpu_set_singlestep(void)
270 {
271 db_expr_t inst;
272 db_addr_t pc, brpc;
273 uint32_t wcr;
274 u_int i;
275
276 if (!dbg_capable())
277 return;
278
279 /*
280 * Disable watchpoints, e.g. stepping over watched instruction will
281 * trigger break exception instead of single-step exception and locks
282 * CPU on that instruction for ever.
283 */
284 for (i = 0; i < dbg_watchpoint_num; i++) {
285 wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
286 if ((wcr & DBG_WB_CTRL_E) != 0) {
287 dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
288 (wcr & ~DBG_WB_CTRL_E));
289 }
290 }
291
292 pc = PC_REGS();
293
294 inst = db_get_value(pc, sizeof(pc), FALSE);
295 if (inst_branch(inst) || inst_call(inst) || inst_return(inst)) {
296 brpc = branch_taken(inst, pc);
297 dbg_setup_breakpoint(brpc, INSN_SIZE, DBG_BKPT_BT_SLOT);
298 }
299 pc = next_instr_address(pc, 0);
300 dbg_setup_breakpoint(pc, INSN_SIZE, DBG_BKPT_BNT_SLOT);
301 }
302
303 void
kdb_cpu_clear_singlestep(void)304 kdb_cpu_clear_singlestep(void)
305 {
306 uint32_t wvr, wcr;
307 u_int i;
308
309 if (!dbg_capable())
310 return;
311
312 dbg_remove_breakpoint(DBG_BKPT_BT_SLOT);
313 dbg_remove_breakpoint(DBG_BKPT_BNT_SLOT);
314
315 /* Restore all watchpoints */
316 for (i = 0; i < dbg_watchpoint_num; i++) {
317 wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
318 wvr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i);
319 /* Watchpoint considered not empty if address value is not 0 */
320 if ((wvr & DBGWVR_ADDR_MASK) != 0) {
321 dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
322 (wcr | DBG_WB_CTRL_E));
323 }
324 }
325 }
326
327 int
kdb_cpu_set_watchpoint(vm_offset_t addr,size_t size,int access)328 kdb_cpu_set_watchpoint(vm_offset_t addr, size_t size, int access)
329 {
330 enum dbg_access_t dbg_access;
331
332 switch (access) {
333 case KDB_DBG_ACCESS_R:
334 dbg_access = HW_WATCHPOINT_R;
335 break;
336 case KDB_DBG_ACCESS_W:
337 dbg_access = HW_WATCHPOINT_W;
338 break;
339 case KDB_DBG_ACCESS_RW:
340 dbg_access = HW_WATCHPOINT_RW;
341 break;
342 default:
343 return (EINVAL);
344 }
345
346 return (dbg_setup_watchpoint(addr, size, dbg_access));
347 }
348
349 int
kdb_cpu_clr_watchpoint(vm_offset_t addr,size_t size)350 kdb_cpu_clr_watchpoint(vm_offset_t addr, size_t size)
351 {
352
353 return (dbg_remove_watchpoint(addr, size));
354 }
355
356 int
dbg_setup_watchpoint(db_expr_t addr,db_expr_t size,enum dbg_access_t access)357 dbg_setup_watchpoint(db_expr_t addr, db_expr_t size, enum dbg_access_t access)
358 {
359 struct dbg_wb_conf conf;
360
361 if (access == HW_BREAKPOINT_X) {
362 db_printf("Invalid access type for watchpoint: %d\n", access);
363 return (EINVAL);
364 }
365
366 conf.address = addr;
367 conf.size = size;
368 conf.access = access;
369 conf.type = DBG_TYPE_WATCHPOINT;
370
371 return (dbg_setup_xpoint(&conf));
372 }
373
374 int
dbg_remove_watchpoint(db_expr_t addr,db_expr_t size __unused)375 dbg_remove_watchpoint(db_expr_t addr, db_expr_t size __unused)
376 {
377 struct dbg_wb_conf conf;
378
379 conf.address = addr;
380 conf.type = DBG_TYPE_WATCHPOINT;
381
382 return (dbg_remove_xpoint(&conf));
383 }
384
385 static int
dbg_setup_breakpoint(db_expr_t addr,db_expr_t size,u_int slot)386 dbg_setup_breakpoint(db_expr_t addr, db_expr_t size, u_int slot)
387 {
388 struct dbg_wb_conf conf;
389
390 conf.address = addr;
391 conf.size = size;
392 conf.access = HW_BREAKPOINT_X;
393 conf.type = DBG_TYPE_BREAKPOINT;
394 conf.slot = slot;
395
396 return (dbg_setup_xpoint(&conf));
397 }
398
399 static int
dbg_remove_breakpoint(u_int slot)400 dbg_remove_breakpoint(u_int slot)
401 {
402 struct dbg_wb_conf conf;
403
404 /* Slot already cleared. Don't recurse */
405 if (dbg_check_slot_free(DBG_TYPE_BREAKPOINT, slot))
406 return (0);
407
408 conf.slot = slot;
409 conf.type = DBG_TYPE_BREAKPOINT;
410
411 return (dbg_remove_xpoint(&conf));
412 }
413
414 static const char *
dbg_watchtype_str(uint32_t type)415 dbg_watchtype_str(uint32_t type)
416 {
417
418 switch (type) {
419 case DBG_WB_CTRL_EXEC:
420 return ("execute");
421 case DBG_WB_CTRL_STORE:
422 return ("write");
423 case DBG_WB_CTRL_LOAD:
424 return ("read");
425 case DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE:
426 return ("read/write");
427 default:
428 return ("invalid");
429 }
430 }
431
432 static int
dbg_watchtype_len(uint32_t len)433 dbg_watchtype_len(uint32_t len)
434 {
435
436 switch (len) {
437 case DBG_WB_CTRL_LEN_1:
438 return (1);
439 case DBG_WB_CTRL_LEN_2:
440 return (2);
441 case DBG_WB_CTRL_LEN_4:
442 return (4);
443 case DBG_WB_CTRL_LEN_8:
444 return (8);
445 default:
446 return (0);
447 }
448 }
449
450 void
dbg_show_watchpoint(void)451 dbg_show_watchpoint(void)
452 {
453 uint32_t wcr, len, type;
454 uint32_t addr;
455 boolean_t is_enabled;
456 int i;
457
458 if (!dbg_capable()) {
459 db_printf("Architecture does not support HW "
460 "breakpoints/watchpoints\n");
461 return;
462 }
463
464 db_printf("\nhardware watchpoints:\n");
465 db_printf(" watch status type len address symbol\n");
466 db_printf(" ----- -------- ---------- --- ---------- ------------------\n");
467 for (i = 0; i < dbg_watchpoint_num; i++) {
468 wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
469 if ((wcr & DBG_WB_CTRL_E) != 0)
470 is_enabled = TRUE;
471 else
472 is_enabled = FALSE;
473
474 type = DBG_WB_CTRL_ACCESS_MASK(wcr);
475 len = DBG_WB_CTRL_LEN_MASK(wcr);
476 addr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i) & DBGWVR_ADDR_MASK;
477 db_printf(" %-5d %-8s %10s %3d 0x%08x ", i,
478 is_enabled ? "enabled" : "disabled",
479 is_enabled ? dbg_watchtype_str(type) : "",
480 is_enabled ? dbg_watchtype_len(len) : 0,
481 addr);
482 db_printsym((db_addr_t)addr, DB_STGY_ANY);
483 db_printf("\n");
484 }
485 }
486
487 static boolean_t
dbg_check_slot_free(enum dbg_t type,u_int slot)488 dbg_check_slot_free(enum dbg_t type, u_int slot)
489 {
490 uint32_t cr, vr;
491 uint32_t max;
492
493 switch(type) {
494 case DBG_TYPE_BREAKPOINT:
495 max = dbg_breakpoint_num;
496 cr = DBG_REG_BASE_BCR;
497 vr = DBG_REG_BASE_BVR;
498 break;
499 case DBG_TYPE_WATCHPOINT:
500 max = dbg_watchpoint_num;
501 cr = DBG_REG_BASE_WCR;
502 vr = DBG_REG_BASE_WVR;
503 break;
504 default:
505 db_printf("%s: Unsupported event type %d\n", __func__, type);
506 return (FALSE);
507 }
508
509 if (slot >= max) {
510 db_printf("%s: Invalid slot number %d, max %d\n",
511 __func__, slot, max - 1);
512 return (FALSE);
513 }
514
515 if ((dbg_wb_read_reg(cr, slot) & DBG_WB_CTRL_E) == 0 &&
516 (dbg_wb_read_reg(vr, slot) & DBGWVR_ADDR_MASK) == 0)
517 return (TRUE);
518
519 return (FALSE);
520 }
521
522 static u_int
dbg_find_free_slot(enum dbg_t type)523 dbg_find_free_slot(enum dbg_t type)
524 {
525 u_int max, i;
526
527 switch(type) {
528 case DBG_TYPE_BREAKPOINT:
529 max = dbg_breakpoint_num;
530 break;
531 case DBG_TYPE_WATCHPOINT:
532 max = dbg_watchpoint_num;
533 break;
534 default:
535 db_printf("Unsupported debug type\n");
536 return (~0U);
537 }
538
539 for (i = 0; i < max; i++) {
540 if (dbg_check_slot_free(type, i))
541 return (i);
542 }
543
544 return (~0U);
545 }
546
547 static u_int
dbg_find_slot(enum dbg_t type,db_expr_t addr)548 dbg_find_slot(enum dbg_t type, db_expr_t addr)
549 {
550 uint32_t reg_addr, reg_ctrl;
551 u_int max, i;
552
553 switch(type) {
554 case DBG_TYPE_BREAKPOINT:
555 max = dbg_breakpoint_num;
556 reg_addr = DBG_REG_BASE_BVR;
557 reg_ctrl = DBG_REG_BASE_BCR;
558 break;
559 case DBG_TYPE_WATCHPOINT:
560 max = dbg_watchpoint_num;
561 reg_addr = DBG_REG_BASE_WVR;
562 reg_ctrl = DBG_REG_BASE_WCR;
563 break;
564 default:
565 db_printf("Unsupported debug type\n");
566 return (~0U);
567 }
568
569 for (i = 0; i < max; i++) {
570 if ((dbg_wb_read_reg(reg_addr, i) == addr) &&
571 ((dbg_wb_read_reg(reg_ctrl, i) & DBG_WB_CTRL_E) != 0))
572 return (i);
573 }
574
575 return (~0U);
576 }
577
578 static __inline boolean_t
dbg_monitor_is_enabled(void)579 dbg_monitor_is_enabled(void)
580 {
581
582 return ((cp14_dbgdscrint_get() & DBGSCR_MDBG_EN) != 0);
583 }
584
585 static int
dbg_enable_monitor(void)586 dbg_enable_monitor(void)
587 {
588 uint32_t dbg_dscr;
589
590 /* Already enabled? Just return */
591 if (dbg_monitor_is_enabled())
592 return (0);
593
594 dbg_dscr = cp14_dbgdscrint_get();
595
596 switch (dbg_model) {
597 case ID_DFR0_CP_DEBUG_M_V6:
598 case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */
599 cp14_dbgdscr_v6_set(dbg_dscr | DBGSCR_MDBG_EN);
600 break;
601 case ID_DFR0_CP_DEBUG_M_V7: /* fall through */
602 case ID_DFR0_CP_DEBUG_M_V7_1:
603 cp14_dbgdscr_v7_set(dbg_dscr | DBGSCR_MDBG_EN);
604 break;
605 default:
606 break;
607 }
608 isb();
609
610 /* Verify that Monitor mode is set */
611 if (dbg_monitor_is_enabled())
612 return (0);
613
614 return (ENXIO);
615 }
616
617 static int
dbg_setup_xpoint(struct dbg_wb_conf * conf)618 dbg_setup_xpoint(struct dbg_wb_conf *conf)
619 {
620 struct pcpu *pcpu;
621 struct dbreg *d;
622 const char *typestr;
623 uint32_t cr_size, cr_priv, cr_access;
624 uint32_t reg_ctrl, reg_addr, ctrl, addr;
625 boolean_t is_bkpt;
626 u_int cpu;
627 u_int i;
628
629 if (!dbg_capable())
630 return (ENXIO);
631
632 is_bkpt = (conf->type == DBG_TYPE_BREAKPOINT);
633 typestr = is_bkpt ? "breakpoint" : "watchpoint";
634
635 if (is_bkpt) {
636 if (dbg_breakpoint_num == 0) {
637 db_printf("Breakpoints not supported on this architecture\n");
638 return (ENXIO);
639 }
640 i = conf->slot;
641 if (!dbg_check_slot_free(DBG_TYPE_BREAKPOINT, i)) {
642 /*
643 * This should never happen. If it does it means that
644 * there is an erroneus scenario somewhere. Still, it can
645 * be done but let's inform the user.
646 */
647 db_printf("ERROR: Breakpoint already set. Replacing...\n");
648 }
649 } else {
650 i = dbg_find_free_slot(DBG_TYPE_WATCHPOINT);
651 if (i == ~0U) {
652 db_printf("Can not find slot for %s, max %d slots supported\n",
653 typestr, dbg_watchpoint_num);
654 return (EBUSY);
655 }
656 }
657
658 /* Kernel access only */
659 cr_priv = DBG_WB_CTRL_PL1;
660
661 switch(conf->size) {
662 case 1:
663 cr_size = DBG_WB_CTRL_LEN_1;
664 break;
665 case 2:
666 cr_size = DBG_WB_CTRL_LEN_2;
667 break;
668 case 4:
669 cr_size = DBG_WB_CTRL_LEN_4;
670 break;
671 case 8:
672 cr_size = DBG_WB_CTRL_LEN_8;
673 break;
674 default:
675 db_printf("Unsupported address size for %s: %zu\n", typestr,
676 conf->size);
677 return (EINVAL);
678 }
679
680 if (is_bkpt) {
681 cr_access = DBG_WB_CTRL_EXEC;
682 reg_ctrl = DBG_REG_BASE_BCR;
683 reg_addr = DBG_REG_BASE_BVR;
684 /* Always unlinked BKPT */
685 ctrl = (cr_size | cr_access | cr_priv | DBG_WB_CTRL_E);
686 } else {
687 switch(conf->access) {
688 case HW_WATCHPOINT_R:
689 cr_access = DBG_WB_CTRL_LOAD;
690 break;
691 case HW_WATCHPOINT_W:
692 cr_access = DBG_WB_CTRL_STORE;
693 break;
694 case HW_WATCHPOINT_RW:
695 cr_access = DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE;
696 break;
697 default:
698 db_printf("Unsupported access type for %s: %d\n",
699 typestr, conf->access);
700 return (EINVAL);
701 }
702
703 reg_ctrl = DBG_REG_BASE_WCR;
704 reg_addr = DBG_REG_BASE_WVR;
705 ctrl = (cr_size | cr_access | cr_priv | DBG_WB_CTRL_E);
706 }
707
708 addr = conf->address;
709
710 dbg_wb_write_reg(reg_addr, i, addr);
711 dbg_wb_write_reg(reg_ctrl, i, ctrl);
712
713 /*
714 * Save watchpoint settings for all CPUs.
715 * We don't need to do the same with breakpoints since HW breakpoints
716 * are only used to perform single stepping.
717 */
718 if (!is_bkpt) {
719 CPU_FOREACH(cpu) {
720 pcpu = pcpu_find(cpu);
721 /* Fill out the settings for watchpoint */
722 d = (struct dbreg *)pcpu->pc_dbreg;
723 d->dbg_wvr[i] = addr;
724 d->dbg_wcr[i] = ctrl;
725 /* Skip update command for the current CPU */
726 if (cpu != PCPU_GET(cpuid))
727 pcpu->pc_dbreg_cmd = PC_DBREG_CMD_LOAD;
728 }
729 }
730 /* Ensure all data is written before waking other CPUs */
731 atomic_thread_fence_rel();
732
733 return (0);
734 }
735
736 static int
dbg_remove_xpoint(struct dbg_wb_conf * conf)737 dbg_remove_xpoint(struct dbg_wb_conf *conf)
738 {
739 struct pcpu *pcpu;
740 struct dbreg *d;
741 uint32_t reg_ctrl, reg_addr, addr;
742 boolean_t is_bkpt;
743 u_int cpu;
744 u_int i;
745
746 if (!dbg_capable())
747 return (ENXIO);
748
749 is_bkpt = (conf->type == DBG_TYPE_BREAKPOINT);
750 addr = conf->address;
751
752 if (is_bkpt) {
753 i = conf->slot;
754 reg_ctrl = DBG_REG_BASE_BCR;
755 reg_addr = DBG_REG_BASE_BVR;
756 } else {
757 i = dbg_find_slot(DBG_TYPE_WATCHPOINT, addr);
758 if (i == ~0U) {
759 db_printf("Can not find watchpoint for address 0%x\n", addr);
760 return (EINVAL);
761 }
762 reg_ctrl = DBG_REG_BASE_WCR;
763 reg_addr = DBG_REG_BASE_WVR;
764 }
765
766 dbg_wb_write_reg(reg_ctrl, i, 0);
767 dbg_wb_write_reg(reg_addr, i, 0);
768
769 /*
770 * Save watchpoint settings for all CPUs.
771 * We don't need to do the same with breakpoints since HW breakpoints
772 * are only used to perform single stepping.
773 */
774 if (!is_bkpt) {
775 CPU_FOREACH(cpu) {
776 pcpu = pcpu_find(cpu);
777 /* Fill out the settings for watchpoint */
778 d = (struct dbreg *)pcpu->pc_dbreg;
779 d->dbg_wvr[i] = 0;
780 d->dbg_wcr[i] = 0;
781 /* Skip update command for the current CPU */
782 if (cpu != PCPU_GET(cpuid))
783 pcpu->pc_dbreg_cmd = PC_DBREG_CMD_LOAD;
784 }
785 /* Ensure all data is written before waking other CPUs */
786 atomic_thread_fence_rel();
787 }
788
789 return (0);
790 }
791
792 static __inline uint32_t
dbg_get_debug_model(void)793 dbg_get_debug_model(void)
794 {
795 uint32_t dbg_m;
796
797 dbg_m = ((cpuinfo.id_dfr0 & ID_DFR0_CP_DEBUG_M_MASK) >>
798 ID_DFR0_CP_DEBUG_M_SHIFT);
799
800 return (dbg_m);
801 }
802
803 static __inline boolean_t
dbg_get_ossr(void)804 dbg_get_ossr(void)
805 {
806
807 switch (dbg_model) {
808 case ID_DFR0_CP_DEBUG_M_V7:
809 if ((cp14_dbgoslsr_get() & DBGOSLSR_OSLM0) != 0)
810 return (TRUE);
811
812 return (FALSE);
813 case ID_DFR0_CP_DEBUG_M_V7_1:
814 return (TRUE);
815 default:
816 return (FALSE);
817 }
818 }
819
820 static __inline boolean_t
dbg_arch_supported(void)821 dbg_arch_supported(void)
822 {
823 uint32_t dbg_didr;
824
825 switch (dbg_model) {
826 case ID_DFR0_CP_DEBUG_M_V6:
827 case ID_DFR0_CP_DEBUG_M_V6_1:
828 dbg_didr = cp14_dbgdidr_get();
829 /*
830 * read-all-zeroes is used by QEMU
831 * to indicate that ARMv6 debug support
832 * is not implemented. Real hardware has at
833 * least version bits set
834 */
835 if (dbg_didr == 0)
836 return (FALSE);
837 return (TRUE);
838 case ID_DFR0_CP_DEBUG_M_V7:
839 case ID_DFR0_CP_DEBUG_M_V7_1: /* fall through */
840 return (TRUE);
841 default:
842 /* We only support valid v6.x/v7.x modes through CP14 */
843 return (FALSE);
844 }
845 }
846
847 static __inline uint32_t
dbg_get_wrp_num(void)848 dbg_get_wrp_num(void)
849 {
850 uint32_t dbg_didr;
851
852 dbg_didr = cp14_dbgdidr_get();
853
854 return (DBGDIDR_WRPS_NUM(dbg_didr));
855 }
856
857 static __inline uint32_t
dgb_get_brp_num(void)858 dgb_get_brp_num(void)
859 {
860 uint32_t dbg_didr;
861
862 dbg_didr = cp14_dbgdidr_get();
863
864 return (DBGDIDR_BRPS_NUM(dbg_didr));
865 }
866
867 static int
dbg_reset_state(void)868 dbg_reset_state(void)
869 {
870 u_int cpuid;
871 size_t i;
872 int err;
873
874 cpuid = PCPU_GET(cpuid);
875 err = 0;
876
877 switch (dbg_model) {
878 case ID_DFR0_CP_DEBUG_M_V6:
879 case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */
880 /*
881 * Arch needs monitor mode selected and enabled
882 * to be able to access breakpoint/watchpoint registers.
883 */
884 err = dbg_enable_monitor();
885 if (err != 0)
886 return (err);
887 goto vectr_clr;
888 case ID_DFR0_CP_DEBUG_M_V7:
889 /* Is core power domain powered up? */
890 if ((cp14_dbgprsr_get() & DBGPRSR_PU) == 0)
891 err = ENXIO;
892
893 if (err != 0)
894 break;
895
896 if (dbg_ossr)
897 goto vectr_clr;
898 break;
899 case ID_DFR0_CP_DEBUG_M_V7_1:
900 /* Is double lock set? */
901 if ((cp14_dbgosdlr_get() & DBGPRSR_DLK) != 0)
902 err = ENXIO;
903
904 break;
905 default:
906 break;
907 }
908
909 if (err != 0) {
910 db_printf("Debug facility locked (CPU%d)\n", cpuid);
911 return (err);
912 }
913
914 /*
915 * DBGOSLAR is always implemented for v7.1 Debug Arch. however is
916 * optional for v7 (depends on OS save and restore support).
917 */
918 if (((dbg_model & ID_DFR0_CP_DEBUG_M_V7_1) != 0) || dbg_ossr) {
919 /*
920 * Clear OS lock.
921 * Writing any other value than 0xC5ACCESS will unlock.
922 */
923 cp14_dbgoslar_set(0);
924 isb();
925 }
926
927 vectr_clr:
928 /*
929 * After reset we must ensure that DBGVCR has a defined value.
930 * Disable all vector catch events. Safe to use - required in all
931 * implementations.
932 */
933 cp14_dbgvcr_set(0);
934 isb();
935
936 /*
937 * We have limited number of {watch,break}points, each consists of
938 * two registers:
939 * - wcr/bcr regsiter configurates corresponding {watch,break}point
940 * behaviour
941 * - wvr/bvr register keeps address we are hunting for
942 *
943 * Reset all breakpoints and watchpoints.
944 */
945 for (i = 0; i < dbg_watchpoint_num; ++i) {
946 dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
947 dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
948 }
949
950 for (i = 0; i < dbg_breakpoint_num; ++i) {
951 dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
952 dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
953 }
954
955 return (0);
956 }
957
958 void
dbg_monitor_init(void)959 dbg_monitor_init(void)
960 {
961 #ifdef ARM_FORCE_DBG_MONITOR_DISABLE
962 db_printf("ARM Debug Architecture disabled in kernel compilation.\n");
963 return;
964 #else
965 int err;
966
967 /* Fetch ARM Debug Architecture model */
968 dbg_model = dbg_get_debug_model();
969
970 if (!dbg_arch_supported()) {
971 db_printf("ARM Debug Architecture not supported\n");
972 return;
973 }
974
975 if (bootverbose) {
976 db_printf("ARM Debug Architecture %s\n",
977 (dbg_model == ID_DFR0_CP_DEBUG_M_V6) ? "v6" :
978 (dbg_model == ID_DFR0_CP_DEBUG_M_V6_1) ? "v6.1" :
979 (dbg_model == ID_DFR0_CP_DEBUG_M_V7) ? "v7" :
980 (dbg_model == ID_DFR0_CP_DEBUG_M_V7_1) ? "v7.1" : "unknown");
981 }
982
983 /* Do we have OS Save and Restore mechanism? */
984 dbg_ossr = dbg_get_ossr();
985
986 /* Find out many breakpoints and watchpoints we can use */
987 dbg_watchpoint_num = dbg_get_wrp_num();
988 dbg_breakpoint_num = dgb_get_brp_num();
989
990 if (bootverbose) {
991 db_printf("%d watchpoints and %d breakpoints supported\n",
992 dbg_watchpoint_num, dbg_breakpoint_num);
993 }
994
995 err = dbg_reset_state();
996 if (err == 0) {
997 err = dbg_enable_monitor();
998 if (err == 0) {
999 atomic_set_int(&dbg_capable_var, 1);
1000 return;
1001 }
1002 }
1003
1004 db_printf("HW Breakpoints/Watchpoints not enabled on CPU%d\n",
1005 PCPU_GET(cpuid));
1006 #endif /* ARM_FORCE_DBG_MONITOR_DISABLE */
1007 }
1008
1009 CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg));
1010
1011 void
dbg_monitor_init_secondary(void)1012 dbg_monitor_init_secondary(void)
1013 {
1014 int err;
1015 /*
1016 * This flag is set on the primary CPU
1017 * and its meaning is valid for other CPUs too.
1018 */
1019 if (!dbg_capable())
1020 return;
1021
1022 err = dbg_reset_state();
1023 if (err != 0) {
1024 /*
1025 * Something is very wrong.
1026 * WPs/BPs will not work correctly on this CPU.
1027 */
1028 KASSERT(0, ("%s: Failed to reset Debug Architecture "
1029 "state on CPU%d", __func__, PCPU_GET(cpuid)));
1030 /* Disable HW debug capabilities for all CPUs */
1031 atomic_set_int(&dbg_capable_var, 0);
1032 return;
1033 }
1034 err = dbg_enable_monitor();
1035 if (err != 0) {
1036 KASSERT(0, ("%s: Failed to enable Debug Monitor"
1037 " on CPU%d", __func__, PCPU_GET(cpuid)));
1038 atomic_set_int(&dbg_capable_var, 0);
1039 }
1040 }
1041
1042 void
dbg_resume_dbreg(void)1043 dbg_resume_dbreg(void)
1044 {
1045 struct dbreg *d;
1046 u_int i;
1047
1048 /*
1049 * This flag is set on the primary CPU
1050 * and its meaning is valid for other CPUs too.
1051 */
1052 if (!dbg_capable())
1053 return;
1054
1055 atomic_thread_fence_acq();
1056
1057 switch (PCPU_GET(dbreg_cmd)) {
1058 case PC_DBREG_CMD_LOAD:
1059 d = (struct dbreg *)PCPU_PTR(dbreg);
1060
1061 /* Restore watchpoints */
1062 for (i = 0; i < dbg_watchpoint_num; i++) {
1063 dbg_wb_write_reg(DBG_REG_BASE_WVR, i, d->dbg_wvr[i]);
1064 dbg_wb_write_reg(DBG_REG_BASE_WCR, i, d->dbg_wcr[i]);
1065 }
1066
1067 PCPU_SET(dbreg_cmd, PC_DBREG_CMD_NONE);
1068 break;
1069 }
1070 }
1071