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: stable/11/sys/arm/arm/debug_monitor.c 317976 2017-05-08 20:09:23Z gonzo $");
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
53enum dbg_t {
54	DBG_TYPE_BREAKPOINT = 0,
55	DBG_TYPE_WATCHPOINT = 1,
56};
57
58struct 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
66static int dbg_reset_state(void);
67static int dbg_setup_breakpoint(db_expr_t, db_expr_t, u_int);
68static int dbg_remove_breakpoint(u_int);
69static u_int dbg_find_slot(enum dbg_t, db_expr_t);
70static boolean_t dbg_check_slot_free(enum dbg_t, u_int);
71
72static int dbg_remove_xpoint(struct dbg_wb_conf *);
73static int dbg_setup_xpoint(struct dbg_wb_conf *);
74
75static int dbg_capable_var;	/* Indicates that machine is capable of using
76				   HW watchpoints/breakpoints */
77
78static uint32_t dbg_model;	/* Debug Arch. Model */
79static boolean_t dbg_ossr;	/* OS Save and Restore implemented */
80
81static uint32_t dbg_watchpoint_num;
82static 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
209static uint32_t
210dbg_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
230static void
231dbg_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
247static __inline boolean_t
248dbg_capable(void)
249{
250
251	return (atomic_cmpset_int(&dbg_capable_var, 0, 0) == 0);
252}
253
254boolean_t
255kdb_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	 *      (SOFTWARE_SSTEP is not defined for __ARM_ARCH >= 6).
261	 */
262	if (!dbg_capable())
263		return (FALSE);
264
265	if (dbg_find_slot(DBG_TYPE_BREAKPOINT, pc) != ~0U)
266		return (TRUE);
267
268	return (FALSE);
269}
270
271void
272kdb_cpu_set_singlestep(void)
273{
274	db_expr_t inst;
275	db_addr_t pc, brpc;
276	uint32_t wcr;
277	u_int i;
278
279	if (!dbg_capable())
280		return;
281
282	/*
283	 * Disable watchpoints, e.g. stepping over watched instruction will
284	 * trigger break exception instead of single-step exception and locks
285	 * CPU on that instruction for ever.
286	 */
287	for (i = 0; i < dbg_watchpoint_num; i++) {
288		wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
289		if ((wcr & DBG_WB_CTRL_E) != 0) {
290			dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
291			    (wcr & ~DBG_WB_CTRL_E));
292		}
293	}
294
295	pc = PC_REGS();
296
297	inst = db_get_value(pc, sizeof(pc), FALSE);
298	if (inst_branch(inst) || inst_call(inst) || inst_return(inst)) {
299		brpc = branch_taken(inst, pc);
300		dbg_setup_breakpoint(brpc, INSN_SIZE, DBG_BKPT_BT_SLOT);
301	}
302	pc = next_instr_address(pc, 0);
303	dbg_setup_breakpoint(pc, INSN_SIZE, DBG_BKPT_BNT_SLOT);
304}
305
306void
307kdb_cpu_clear_singlestep(void)
308{
309	uint32_t wvr, wcr;
310	u_int i;
311
312	if (!dbg_capable())
313		return;
314
315	dbg_remove_breakpoint(DBG_BKPT_BT_SLOT);
316	dbg_remove_breakpoint(DBG_BKPT_BNT_SLOT);
317
318	/* Restore all watchpoints */
319	for (i = 0; i < dbg_watchpoint_num; i++) {
320		wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
321		wvr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i);
322		/* Watchpoint considered not empty if address value is not 0 */
323		if ((wvr & DBGWVR_ADDR_MASK) != 0) {
324			dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
325			    (wcr | DBG_WB_CTRL_E));
326		}
327	}
328}
329
330int
331dbg_setup_watchpoint(db_expr_t addr, db_expr_t size, enum dbg_access_t access)
332{
333	struct dbg_wb_conf conf;
334
335	if (access == HW_BREAKPOINT_X) {
336		db_printf("Invalid access type for watchpoint: %d\n", access);
337		return (EINVAL);
338	}
339
340	conf.address = addr;
341	conf.size = size;
342	conf.access = access;
343	conf.type = DBG_TYPE_WATCHPOINT;
344
345	return (dbg_setup_xpoint(&conf));
346}
347
348int
349dbg_remove_watchpoint(db_expr_t addr, db_expr_t size __unused)
350{
351	struct dbg_wb_conf conf;
352
353	conf.address = addr;
354	conf.type = DBG_TYPE_WATCHPOINT;
355
356	return (dbg_remove_xpoint(&conf));
357}
358
359static int
360dbg_setup_breakpoint(db_expr_t addr, db_expr_t size, u_int slot)
361{
362	struct dbg_wb_conf conf;
363
364	conf.address = addr;
365	conf.size = size;
366	conf.access = HW_BREAKPOINT_X;
367	conf.type = DBG_TYPE_BREAKPOINT;
368	conf.slot = slot;
369
370	return (dbg_setup_xpoint(&conf));
371}
372
373static int
374dbg_remove_breakpoint(u_int slot)
375{
376	struct dbg_wb_conf conf;
377
378	/* Slot already cleared. Don't recurse */
379	if (dbg_check_slot_free(DBG_TYPE_BREAKPOINT, slot))
380		return (0);
381
382	conf.slot = slot;
383	conf.type = DBG_TYPE_BREAKPOINT;
384
385	return (dbg_remove_xpoint(&conf));
386}
387
388static const char *
389dbg_watchtype_str(uint32_t type)
390{
391
392	switch (type) {
393		case DBG_WB_CTRL_EXEC:
394			return ("execute");
395		case DBG_WB_CTRL_STORE:
396			return ("write");
397		case DBG_WB_CTRL_LOAD:
398			return ("read");
399		case DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE:
400			return ("read/write");
401		default:
402			return ("invalid");
403	}
404}
405
406static int
407dbg_watchtype_len(uint32_t len)
408{
409
410	switch (len) {
411	case DBG_WB_CTRL_LEN_1:
412		return (1);
413	case DBG_WB_CTRL_LEN_2:
414		return (2);
415	case DBG_WB_CTRL_LEN_4:
416		return (4);
417	case DBG_WB_CTRL_LEN_8:
418		return (8);
419	default:
420		return (0);
421	}
422}
423
424void
425dbg_show_watchpoint(void)
426{
427	uint32_t wcr, len, type;
428	uint32_t addr;
429	boolean_t is_enabled;
430	int i;
431
432	if (!dbg_capable()) {
433		db_printf("Architecture does not support HW "
434		    "breakpoints/watchpoints\n");
435		return;
436	}
437
438	db_printf("\nhardware watchpoints:\n");
439	db_printf("  watch    status        type  len     address              symbol\n");
440	db_printf("  -----  --------  ----------  ---  ----------  ------------------\n");
441	for (i = 0; i < dbg_watchpoint_num; i++) {
442		wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
443		if ((wcr & DBG_WB_CTRL_E) != 0)
444			is_enabled = TRUE;
445		else
446			is_enabled = FALSE;
447
448		type = DBG_WB_CTRL_ACCESS_MASK(wcr);
449		len = DBG_WB_CTRL_LEN_MASK(wcr);
450		addr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i) & DBGWVR_ADDR_MASK;
451		db_printf("  %-5d  %-8s  %10s  %3d  0x%08x  ", i,
452		    is_enabled ? "enabled" : "disabled",
453		    is_enabled ? dbg_watchtype_str(type) : "",
454		    is_enabled ? dbg_watchtype_len(len) : 0,
455		    addr);
456		db_printsym((db_addr_t)addr, DB_STGY_ANY);
457		db_printf("\n");
458	}
459}
460
461static boolean_t
462dbg_check_slot_free(enum dbg_t type, u_int slot)
463{
464	uint32_t cr, vr;
465	uint32_t max;
466
467	switch(type) {
468	case DBG_TYPE_BREAKPOINT:
469		max = dbg_breakpoint_num;
470		cr = DBG_REG_BASE_BCR;
471		vr = DBG_REG_BASE_BVR;
472		break;
473	case DBG_TYPE_WATCHPOINT:
474		max = dbg_watchpoint_num;
475		cr = DBG_REG_BASE_WCR;
476		vr = DBG_REG_BASE_WVR;
477		break;
478	default:
479		db_printf("%s: Unsupported event type %d\n", __func__, type);
480		return (FALSE);
481	}
482
483	if (slot >= max) {
484		db_printf("%s: Invalid slot number %d, max %d\n",
485		    __func__, slot, max - 1);
486		return (FALSE);
487	}
488
489	if ((dbg_wb_read_reg(cr, slot) & DBG_WB_CTRL_E) == 0 &&
490	    (dbg_wb_read_reg(vr, slot) & DBGWVR_ADDR_MASK) == 0)
491		return (TRUE);
492
493	return (FALSE);
494}
495
496static u_int
497dbg_find_free_slot(enum dbg_t type)
498{
499	u_int max, i;
500
501	switch(type) {
502	case DBG_TYPE_BREAKPOINT:
503		max = dbg_breakpoint_num;
504		break;
505	case DBG_TYPE_WATCHPOINT:
506		max = dbg_watchpoint_num;
507		break;
508	default:
509		db_printf("Unsupported debug type\n");
510		return (~0U);
511	}
512
513	for (i = 0; i < max; i++) {
514		if (dbg_check_slot_free(type, i))
515			return (i);
516	}
517
518	return (~0U);
519}
520
521static u_int
522dbg_find_slot(enum dbg_t type, db_expr_t addr)
523{
524	uint32_t reg_addr, reg_ctrl;
525	u_int max, i;
526
527	switch(type) {
528	case DBG_TYPE_BREAKPOINT:
529		max = dbg_breakpoint_num;
530		reg_addr = DBG_REG_BASE_BVR;
531		reg_ctrl = DBG_REG_BASE_BCR;
532		break;
533	case DBG_TYPE_WATCHPOINT:
534		max = dbg_watchpoint_num;
535		reg_addr = DBG_REG_BASE_WVR;
536		reg_ctrl = DBG_REG_BASE_WCR;
537		break;
538	default:
539		db_printf("Unsupported debug type\n");
540		return (~0U);
541	}
542
543	for (i = 0; i < max; i++) {
544		if ((dbg_wb_read_reg(reg_addr, i) == addr) &&
545		    ((dbg_wb_read_reg(reg_ctrl, i) & DBG_WB_CTRL_E) != 0))
546			return (i);
547	}
548
549	return (~0U);
550}
551
552static __inline boolean_t
553dbg_monitor_is_enabled(void)
554{
555
556	return ((cp14_dbgdscrint_get() & DBGSCR_MDBG_EN) != 0);
557}
558
559static int
560dbg_enable_monitor(void)
561{
562	uint32_t dbg_dscr;
563
564	/* Already enabled? Just return */
565	if (dbg_monitor_is_enabled())
566		return (0);
567
568	dbg_dscr = cp14_dbgdscrint_get();
569
570	switch (dbg_model) {
571	case ID_DFR0_CP_DEBUG_M_V6:
572	case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */
573		cp14_dbgdscr_v6_set(dbg_dscr | DBGSCR_MDBG_EN);
574		break;
575	case ID_DFR0_CP_DEBUG_M_V7: /* fall through */
576	case ID_DFR0_CP_DEBUG_M_V7_1:
577		cp14_dbgdscr_v7_set(dbg_dscr | DBGSCR_MDBG_EN);
578		break;
579	default:
580		break;
581	}
582	isb();
583
584	/* Verify that Monitor mode is set */
585	if (dbg_monitor_is_enabled())
586		return (0);
587
588	return (ENXIO);
589}
590
591static int
592dbg_setup_xpoint(struct dbg_wb_conf *conf)
593{
594	struct pcpu *pcpu;
595	struct dbreg *d;
596	const char *typestr;
597	uint32_t cr_size, cr_priv, cr_access;
598	uint32_t reg_ctrl, reg_addr, ctrl, addr;
599	boolean_t is_bkpt;
600	u_int cpu;
601	u_int i;
602
603	if (!dbg_capable())
604		return (ENXIO);
605
606	is_bkpt = (conf->type == DBG_TYPE_BREAKPOINT);
607	typestr = is_bkpt ? "breakpoint" : "watchpoint";
608
609	if (is_bkpt) {
610		if (dbg_breakpoint_num == 0) {
611			db_printf("Breakpoints not supported on this architecture\n");
612			return (ENXIO);
613		}
614		i = conf->slot;
615		if (!dbg_check_slot_free(DBG_TYPE_BREAKPOINT, i)) {
616			/*
617			 * This should never happen. If it does it means that
618			 * there is an erroneus scenario somewhere. Still, it can
619			 * be done but let's inform the user.
620			 */
621			db_printf("ERROR: Breakpoint already set. Replacing...\n");
622		}
623	} else {
624		i = dbg_find_free_slot(DBG_TYPE_WATCHPOINT);
625		if (i == ~0U) {
626			db_printf("Can not find slot for %s, max %d slots supported\n",
627			    typestr, dbg_watchpoint_num);
628			return (ENXIO);
629		}
630	}
631
632	/* Kernel access only */
633	cr_priv = DBG_WB_CTRL_PL1;
634
635	switch(conf->size) {
636	case 1:
637		cr_size = DBG_WB_CTRL_LEN_1;
638		break;
639	case 2:
640		cr_size = DBG_WB_CTRL_LEN_2;
641		break;
642	case 4:
643		cr_size = DBG_WB_CTRL_LEN_4;
644		break;
645	case 8:
646		cr_size = DBG_WB_CTRL_LEN_8;
647		break;
648	default:
649		db_printf("Unsupported address size for %s\n", typestr);
650		return (EINVAL);
651	}
652
653	if (is_bkpt) {
654		cr_access = DBG_WB_CTRL_EXEC;
655		reg_ctrl = DBG_REG_BASE_BCR;
656		reg_addr = DBG_REG_BASE_BVR;
657		/* Always unlinked BKPT */
658		ctrl = (cr_size | cr_access | cr_priv | DBG_WB_CTRL_E);
659	} else {
660		switch(conf->access) {
661		case HW_WATCHPOINT_R:
662			cr_access = DBG_WB_CTRL_LOAD;
663			break;
664		case HW_WATCHPOINT_W:
665			cr_access = DBG_WB_CTRL_STORE;
666			break;
667		case HW_WATCHPOINT_RW:
668			cr_access = DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE;
669			break;
670		default:
671			db_printf("Unsupported exception level for %s\n", typestr);
672			return (EINVAL);
673		}
674
675		reg_ctrl = DBG_REG_BASE_WCR;
676		reg_addr = DBG_REG_BASE_WVR;
677		ctrl = (cr_size | cr_access | cr_priv | DBG_WB_CTRL_E);
678	}
679
680	addr = conf->address;
681
682	dbg_wb_write_reg(reg_addr, i, addr);
683	dbg_wb_write_reg(reg_ctrl, i, ctrl);
684
685	/*
686	 * Save watchpoint settings for all CPUs.
687	 * We don't need to do the same with breakpoints since HW breakpoints
688	 * are only used to perform single stepping.
689	 */
690	if (!is_bkpt) {
691		CPU_FOREACH(cpu) {
692			pcpu = pcpu_find(cpu);
693			/* Fill out the settings for watchpoint */
694			d = (struct dbreg *)pcpu->pc_dbreg;
695			d->dbg_wvr[i] = addr;
696			d->dbg_wcr[i] = ctrl;
697			/* Skip update command for the current CPU */
698			if (cpu != PCPU_GET(cpuid))
699				pcpu->pc_dbreg_cmd = PC_DBREG_CMD_LOAD;
700		}
701	}
702	/* Ensure all data is written before waking other CPUs */
703	atomic_thread_fence_rel();
704
705	return (0);
706}
707
708static int
709dbg_remove_xpoint(struct dbg_wb_conf *conf)
710{
711	struct pcpu *pcpu;
712	struct dbreg *d;
713	uint32_t reg_ctrl, reg_addr, addr;
714	boolean_t is_bkpt;
715	u_int cpu;
716	u_int i;
717
718	if (!dbg_capable())
719		return (ENXIO);
720
721	is_bkpt = (conf->type == DBG_TYPE_BREAKPOINT);
722	addr = conf->address;
723
724	if (is_bkpt) {
725		i = conf->slot;
726		reg_ctrl = DBG_REG_BASE_BCR;
727		reg_addr = DBG_REG_BASE_BVR;
728	} else {
729		i = dbg_find_slot(DBG_TYPE_WATCHPOINT, addr);
730		if (i == ~0U) {
731			db_printf("Can not find watchpoint for address 0%x\n", addr);
732			return (EINVAL);
733		}
734		reg_ctrl = DBG_REG_BASE_WCR;
735		reg_addr = DBG_REG_BASE_WVR;
736	}
737
738	dbg_wb_write_reg(reg_ctrl, i, 0);
739	dbg_wb_write_reg(reg_addr, i, 0);
740
741	/*
742	 * Save watchpoint settings for all CPUs.
743	 * We don't need to do the same with breakpoints since HW breakpoints
744	 * are only used to perform single stepping.
745	 */
746	if (!is_bkpt) {
747		CPU_FOREACH(cpu) {
748			pcpu = pcpu_find(cpu);
749			/* Fill out the settings for watchpoint */
750			d = (struct dbreg *)pcpu->pc_dbreg;
751			d->dbg_wvr[i] = 0;
752			d->dbg_wcr[i] = 0;
753			/* Skip update command for the current CPU */
754			if (cpu != PCPU_GET(cpuid))
755				pcpu->pc_dbreg_cmd = PC_DBREG_CMD_LOAD;
756		}
757		/* Ensure all data is written before waking other CPUs */
758		atomic_thread_fence_rel();
759	}
760
761	return (0);
762}
763
764static __inline uint32_t
765dbg_get_debug_model(void)
766{
767	uint32_t dbg_m;
768
769	dbg_m = ((cpuinfo.id_dfr0 & ID_DFR0_CP_DEBUG_M_MASK) >>
770	    ID_DFR0_CP_DEBUG_M_SHIFT);
771
772	return (dbg_m);
773}
774
775static __inline boolean_t
776dbg_get_ossr(void)
777{
778
779	switch (dbg_model) {
780	case ID_DFR0_CP_DEBUG_M_V7:
781		if ((cp14_dbgoslsr_get() & DBGOSLSR_OSLM0) != 0)
782			return (TRUE);
783
784		return (FALSE);
785	case ID_DFR0_CP_DEBUG_M_V7_1:
786		return (TRUE);
787	default:
788		return (FALSE);
789	}
790}
791
792static __inline boolean_t
793dbg_arch_supported(void)
794{
795	uint32_t dbg_didr;
796
797	switch (dbg_model) {
798	case ID_DFR0_CP_DEBUG_M_V6:
799	case ID_DFR0_CP_DEBUG_M_V6_1:
800		dbg_didr = cp14_dbgdidr_get();
801		/*
802		 * read-all-zeroes is used by QEMU
803		 * to indicate that ARMv6 debug support
804		 * is not implemented. Real hardware has at
805		 * least version bits set
806		 */
807		if (dbg_didr == 0)
808			return (FALSE);
809		return (TRUE);
810	case ID_DFR0_CP_DEBUG_M_V7:
811	case ID_DFR0_CP_DEBUG_M_V7_1:	/* fall through */
812		return (TRUE);
813	default:
814		/* We only support valid v6.x/v7.x modes through CP14 */
815		return (FALSE);
816	}
817}
818
819static __inline uint32_t
820dbg_get_wrp_num(void)
821{
822	uint32_t dbg_didr;
823
824	dbg_didr = cp14_dbgdidr_get();
825
826	return (DBGDIDR_WRPS_NUM(dbg_didr));
827}
828
829static __inline uint32_t
830dgb_get_brp_num(void)
831{
832	uint32_t dbg_didr;
833
834	dbg_didr = cp14_dbgdidr_get();
835
836	return (DBGDIDR_BRPS_NUM(dbg_didr));
837}
838
839static int
840dbg_reset_state(void)
841{
842	u_int cpuid;
843	size_t i;
844	int err;
845
846	cpuid = PCPU_GET(cpuid);
847	err = 0;
848
849	switch (dbg_model) {
850	case ID_DFR0_CP_DEBUG_M_V6:
851	case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */
852		/*
853		 * Arch needs monitor mode selected and enabled
854		 * to be able to access breakpoint/watchpoint registers.
855		 */
856		err = dbg_enable_monitor();
857		if (err != 0)
858			return (err);
859		goto vectr_clr;
860	case ID_DFR0_CP_DEBUG_M_V7:
861		/* Is core power domain powered up? */
862		if ((cp14_dbgprsr_get() & DBGPRSR_PU) == 0)
863			err = ENXIO;
864
865		if (err != 0)
866			break;
867
868		if (dbg_ossr)
869			goto vectr_clr;
870		break;
871	case ID_DFR0_CP_DEBUG_M_V7_1:
872		/* Is double lock set? */
873		if ((cp14_dbgosdlr_get() & DBGPRSR_DLK) != 0)
874			err = ENXIO;
875
876		break;
877	default:
878		break;
879	}
880
881	if (err != 0) {
882		db_printf("Debug facility locked (CPU%d)\n", cpuid);
883		return (err);
884	}
885
886	/*
887	 * DBGOSLAR is always implemented for v7.1 Debug Arch. however is
888	 * optional for v7 (depends on OS save and restore support).
889	 */
890	if (((dbg_model & ID_DFR0_CP_DEBUG_M_V7_1) != 0) || dbg_ossr) {
891		/*
892		 * Clear OS lock.
893		 * Writing any other value than 0xC5ACCESS will unlock.
894		 */
895		cp14_dbgoslar_set(0);
896		isb();
897	}
898
899vectr_clr:
900	/*
901	 * After reset we must ensure that DBGVCR has a defined value.
902	 * Disable all vector catch events. Safe to use - required in all
903	 * implementations.
904	 */
905	cp14_dbgvcr_set(0);
906	isb();
907
908	/*
909	 * We have limited number of {watch,break}points, each consists of
910	 * two registers:
911	 * - wcr/bcr regsiter configurates corresponding {watch,break}point
912	 *   behaviour
913	 * - wvr/bvr register keeps address we are hunting for
914	 *
915	 * Reset all breakpoints and watchpoints.
916	 */
917	for (i = 0; i < dbg_watchpoint_num; ++i) {
918		dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
919		dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
920	}
921
922	for (i = 0; i < dbg_breakpoint_num; ++i) {
923		dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
924		dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
925	}
926
927	return (0);
928}
929
930void
931dbg_monitor_init(void)
932{
933	int err;
934
935	/* Fetch ARM Debug Architecture model */
936	dbg_model = dbg_get_debug_model();
937
938	if (!dbg_arch_supported()) {
939		db_printf("ARM Debug Architecture not supported\n");
940		return;
941	}
942
943	if (bootverbose) {
944		db_printf("ARM Debug Architecture %s\n",
945		    (dbg_model == ID_DFR0_CP_DEBUG_M_V6) ? "v6" :
946		    (dbg_model == ID_DFR0_CP_DEBUG_M_V6_1) ? "v6.1" :
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}
975
976CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg));
977
978void
979dbg_monitor_init_secondary(void)
980{
981	u_int cpuid;
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	cpuid = PCPU_GET(cpuid);
991
992	err = dbg_reset_state();
993	if (err != 0) {
994		/*
995		 * Something is very wrong.
996		 * WPs/BPs will not work correctly on this CPU.
997		 */
998		KASSERT(0, ("%s: Failed to reset Debug Architecture "
999		    "state on CPU%d", __func__, cpuid));
1000		/* Disable HW debug capabilities for all CPUs */
1001		atomic_set_int(&dbg_capable_var, 0);
1002		return;
1003	}
1004	err = dbg_enable_monitor();
1005	if (err != 0) {
1006		KASSERT(0, ("%s: Failed to enable Debug Monitor"
1007		    " on CPU%d", __func__, cpuid));
1008		atomic_set_int(&dbg_capable_var, 0);
1009	}
1010}
1011
1012void
1013dbg_resume_dbreg(void)
1014{
1015	struct dbreg *d;
1016	u_int i;
1017
1018	/*
1019	 * This flag is set on the primary CPU
1020	 * and its meaning is valid for other CPUs too.
1021	 */
1022	if (!dbg_capable())
1023		return;
1024
1025	atomic_thread_fence_acq();
1026
1027	switch (PCPU_GET(dbreg_cmd)) {
1028	case PC_DBREG_CMD_LOAD:
1029		d = (struct dbreg *)PCPU_PTR(dbreg);
1030
1031		/* Restore watchpoints */
1032		for (i = 0; i < dbg_watchpoint_num; i++) {
1033			dbg_wb_write_reg(DBG_REG_BASE_WVR, i, d->dbg_wvr[i]);
1034			dbg_wb_write_reg(DBG_REG_BASE_WCR, i, d->dbg_wcr[i]);
1035		}
1036
1037		PCPU_SET(dbreg_cmd, PC_DBREG_CMD_NONE);
1038		break;
1039	}
1040}
1041