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