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