1 /*-
2 * Copyright (c) 2014 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Semihalf under
6 * the sponsorship of the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include "opt_ddb.h"
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <sys/param.h>
36 #include <sys/types.h>
37 #include <sys/kdb.h>
38 #include <sys/pcpu.h>
39 #include <sys/proc.h>
40 #include <sys/systm.h>
41 #include <sys/sysent.h>
42
43 #include <machine/armreg.h>
44 #include <machine/cpu.h>
45 #include <machine/debug_monitor.h>
46 #include <machine/kdb.h>
47
48 #ifdef DDB
49 #include <ddb/ddb.h>
50 #include <ddb/db_sym.h>
51 #endif
52
53 enum dbg_t {
54 DBG_TYPE_BREAKPOINT = 0,
55 DBG_TYPE_WATCHPOINT = 1,
56 };
57
58 static int dbg_watchpoint_num;
59 static int dbg_breakpoint_num;
60 static struct debug_monitor_state kernel_monitor = {
61 .dbg_flags = DBGMON_KERNEL
62 };
63
64 /* Called from the exception handlers */
65 void dbg_monitor_enter(struct thread *);
66 void dbg_monitor_exit(struct thread *, struct trapframe *);
67
68 /* Watchpoints/breakpoints control register bitfields */
69 #define DBG_WATCH_CTRL_LEN_1 (0x1 << 5)
70 #define DBG_WATCH_CTRL_LEN_2 (0x3 << 5)
71 #define DBG_WATCH_CTRL_LEN_4 (0xf << 5)
72 #define DBG_WATCH_CTRL_LEN_8 (0xff << 5)
73 #define DBG_WATCH_CTRL_LEN_MASK(x) ((x) & (0xff << 5))
74 #define DBG_WATCH_CTRL_EXEC (0x0 << 3)
75 #define DBG_WATCH_CTRL_LOAD (0x1 << 3)
76 #define DBG_WATCH_CTRL_STORE (0x2 << 3)
77 #define DBG_WATCH_CTRL_ACCESS_MASK(x) ((x) & (0x3 << 3))
78
79 /* Common for breakpoint and watchpoint */
80 #define DBG_WB_CTRL_EL1 (0x1 << 1)
81 #define DBG_WB_CTRL_EL0 (0x2 << 1)
82 #define DBG_WB_CTRL_ELX_MASK(x) ((x) & (0x3 << 1))
83 #define DBG_WB_CTRL_E (0x1 << 0)
84
85 #define DBG_REG_BASE_BVR 0
86 #define DBG_REG_BASE_BCR (DBG_REG_BASE_BVR + 16)
87 #define DBG_REG_BASE_WVR (DBG_REG_BASE_BCR + 16)
88 #define DBG_REG_BASE_WCR (DBG_REG_BASE_WVR + 16)
89
90 /* Watchpoint/breakpoint helpers */
91 #define DBG_WB_WVR "wvr"
92 #define DBG_WB_WCR "wcr"
93 #define DBG_WB_BVR "bvr"
94 #define DBG_WB_BCR "bcr"
95
96 #define DBG_WB_READ(reg, num, val) do { \
97 __asm __volatile("mrs %0, dbg" reg #num "_el1" : "=r" (val)); \
98 } while (0)
99
100 #define DBG_WB_WRITE(reg, num, val) do { \
101 __asm __volatile("msr dbg" reg #num "_el1, %0" :: "r" (val)); \
102 } while (0)
103
104 #define READ_WB_REG_CASE(reg, num, offset, val) \
105 case (num + offset): \
106 DBG_WB_READ(reg, num, val); \
107 break
108
109 #define WRITE_WB_REG_CASE(reg, num, offset, val) \
110 case (num + offset): \
111 DBG_WB_WRITE(reg, num, val); \
112 break
113
114 #define SWITCH_CASES_READ_WB_REG(reg, offset, val) \
115 READ_WB_REG_CASE(reg, 0, offset, val); \
116 READ_WB_REG_CASE(reg, 1, offset, val); \
117 READ_WB_REG_CASE(reg, 2, offset, val); \
118 READ_WB_REG_CASE(reg, 3, offset, val); \
119 READ_WB_REG_CASE(reg, 4, offset, val); \
120 READ_WB_REG_CASE(reg, 5, offset, val); \
121 READ_WB_REG_CASE(reg, 6, offset, val); \
122 READ_WB_REG_CASE(reg, 7, offset, val); \
123 READ_WB_REG_CASE(reg, 8, offset, val); \
124 READ_WB_REG_CASE(reg, 9, offset, val); \
125 READ_WB_REG_CASE(reg, 10, offset, val); \
126 READ_WB_REG_CASE(reg, 11, offset, val); \
127 READ_WB_REG_CASE(reg, 12, offset, val); \
128 READ_WB_REG_CASE(reg, 13, offset, val); \
129 READ_WB_REG_CASE(reg, 14, offset, val); \
130 READ_WB_REG_CASE(reg, 15, offset, val)
131
132 #define SWITCH_CASES_WRITE_WB_REG(reg, offset, val) \
133 WRITE_WB_REG_CASE(reg, 0, offset, val); \
134 WRITE_WB_REG_CASE(reg, 1, offset, val); \
135 WRITE_WB_REG_CASE(reg, 2, offset, val); \
136 WRITE_WB_REG_CASE(reg, 3, offset, val); \
137 WRITE_WB_REG_CASE(reg, 4, offset, val); \
138 WRITE_WB_REG_CASE(reg, 5, offset, val); \
139 WRITE_WB_REG_CASE(reg, 6, offset, val); \
140 WRITE_WB_REG_CASE(reg, 7, offset, val); \
141 WRITE_WB_REG_CASE(reg, 8, offset, val); \
142 WRITE_WB_REG_CASE(reg, 9, offset, val); \
143 WRITE_WB_REG_CASE(reg, 10, offset, val); \
144 WRITE_WB_REG_CASE(reg, 11, offset, val); \
145 WRITE_WB_REG_CASE(reg, 12, offset, val); \
146 WRITE_WB_REG_CASE(reg, 13, offset, val); \
147 WRITE_WB_REG_CASE(reg, 14, offset, val); \
148 WRITE_WB_REG_CASE(reg, 15, offset, val)
149
150 #ifdef DDB
151 static uint64_t
dbg_wb_read_reg(int reg,int n)152 dbg_wb_read_reg(int reg, int n)
153 {
154 uint64_t val = 0;
155
156 switch (reg + n) {
157 SWITCH_CASES_READ_WB_REG(DBG_WB_WVR, DBG_REG_BASE_WVR, val);
158 SWITCH_CASES_READ_WB_REG(DBG_WB_WCR, DBG_REG_BASE_WCR, val);
159 SWITCH_CASES_READ_WB_REG(DBG_WB_BVR, DBG_REG_BASE_BVR, val);
160 SWITCH_CASES_READ_WB_REG(DBG_WB_BCR, DBG_REG_BASE_BCR, val);
161 default:
162 printf("trying to read from wrong debug register %d\n", n);
163 }
164
165 return val;
166 }
167 #endif /* DDB */
168
169 static void
dbg_wb_write_reg(int reg,int n,uint64_t val)170 dbg_wb_write_reg(int reg, int n, uint64_t val)
171 {
172 switch (reg + n) {
173 SWITCH_CASES_WRITE_WB_REG(DBG_WB_WVR, DBG_REG_BASE_WVR, val);
174 SWITCH_CASES_WRITE_WB_REG(DBG_WB_WCR, DBG_REG_BASE_WCR, val);
175 SWITCH_CASES_WRITE_WB_REG(DBG_WB_BVR, DBG_REG_BASE_BVR, val);
176 SWITCH_CASES_WRITE_WB_REG(DBG_WB_BCR, DBG_REG_BASE_BCR, val);
177 default:
178 printf("trying to write to wrong debug register %d\n", n);
179 return;
180 }
181 isb();
182 }
183
184 #ifdef DDB
185 void
kdb_cpu_set_singlestep(void)186 kdb_cpu_set_singlestep(void)
187 {
188
189 kdb_frame->tf_spsr |= DBG_SPSR_SS;
190 WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) |
191 DBG_MDSCR_SS | DBG_MDSCR_KDE);
192
193 /*
194 * Disable breakpoints and watchpoints, e.g. stepping
195 * over watched instruction will trigger break exception instead of
196 * single-step exception and locks CPU on that instruction for ever.
197 */
198 if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) {
199 WRITE_SPECIALREG(mdscr_el1,
200 READ_SPECIALREG(mdscr_el1) & ~DBG_MDSCR_MDE);
201 }
202 }
203
204 void
kdb_cpu_clear_singlestep(void)205 kdb_cpu_clear_singlestep(void)
206 {
207
208 WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) &
209 ~(DBG_MDSCR_SS | DBG_MDSCR_KDE));
210
211 /* Restore breakpoints and watchpoints */
212 if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) {
213 WRITE_SPECIALREG(mdscr_el1,
214 READ_SPECIALREG(mdscr_el1) | DBG_MDSCR_MDE);
215
216 if ((kernel_monitor.dbg_flags & DBGMON_KERNEL) != 0) {
217 WRITE_SPECIALREG(mdscr_el1,
218 READ_SPECIALREG(mdscr_el1) | DBG_MDSCR_KDE);
219 }
220 }
221 }
222
223 static const char *
dbg_watchtype_str(uint32_t type)224 dbg_watchtype_str(uint32_t type)
225 {
226 switch (type) {
227 case DBG_WATCH_CTRL_EXEC:
228 return ("execute");
229 case DBG_WATCH_CTRL_STORE:
230 return ("write");
231 case DBG_WATCH_CTRL_LOAD:
232 return ("read");
233 case DBG_WATCH_CTRL_LOAD | DBG_WATCH_CTRL_STORE:
234 return ("read/write");
235 default:
236 return ("invalid");
237 }
238 }
239
240 static int
dbg_watchtype_len(uint32_t len)241 dbg_watchtype_len(uint32_t len)
242 {
243 switch (len) {
244 case DBG_WATCH_CTRL_LEN_1:
245 return (1);
246 case DBG_WATCH_CTRL_LEN_2:
247 return (2);
248 case DBG_WATCH_CTRL_LEN_4:
249 return (4);
250 case DBG_WATCH_CTRL_LEN_8:
251 return (8);
252 default:
253 return (0);
254 }
255 }
256
257 void
dbg_show_watchpoint(void)258 dbg_show_watchpoint(void)
259 {
260 uint32_t wcr, len, type;
261 uint64_t addr;
262 int i;
263
264 db_printf("\nhardware watchpoints:\n");
265 db_printf(" watch status type len address symbol\n");
266 db_printf(" ----- -------- ---------- --- ------------------ ------------------\n");
267 for (i = 0; i < dbg_watchpoint_num; i++) {
268 wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
269 if ((wcr & DBG_WB_CTRL_E) != 0) {
270 type = DBG_WATCH_CTRL_ACCESS_MASK(wcr);
271 len = DBG_WATCH_CTRL_LEN_MASK(wcr);
272 addr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i);
273 db_printf(" %-5d %-8s %10s %3d 0x%16lx ",
274 i, "enabled", dbg_watchtype_str(type),
275 dbg_watchtype_len(len), addr);
276 db_printsym((db_addr_t)addr, DB_STGY_ANY);
277 db_printf("\n");
278 } else {
279 db_printf(" %-5d disabled\n", i);
280 }
281 }
282 }
283 #endif /* DDB */
284
285 static int
dbg_find_free_slot(struct debug_monitor_state * monitor,enum dbg_t type)286 dbg_find_free_slot(struct debug_monitor_state *monitor, enum dbg_t type)
287 {
288 uint64_t *reg;
289 u_int max, i;
290
291 switch(type) {
292 case DBG_TYPE_BREAKPOINT:
293 max = dbg_breakpoint_num;
294 reg = monitor->dbg_bcr;
295 break;
296 case DBG_TYPE_WATCHPOINT:
297 max = dbg_watchpoint_num;
298 reg = monitor->dbg_wcr;
299 break;
300 default:
301 printf("Unsupported debug type\n");
302 return (i);
303 }
304
305 for (i = 0; i < max; i++) {
306 if ((reg[i] & DBG_WB_CTRL_E) == 0)
307 return (i);
308 }
309
310 return (-1);
311 }
312
313 static int
dbg_find_slot(struct debug_monitor_state * monitor,enum dbg_t type,vm_offset_t addr)314 dbg_find_slot(struct debug_monitor_state *monitor, enum dbg_t type,
315 vm_offset_t addr)
316 {
317 uint64_t *reg_addr, *reg_ctrl;
318 u_int max, i;
319
320 switch(type) {
321 case DBG_TYPE_BREAKPOINT:
322 max = dbg_breakpoint_num;
323 reg_addr = monitor->dbg_bvr;
324 reg_ctrl = monitor->dbg_bcr;
325 break;
326 case DBG_TYPE_WATCHPOINT:
327 max = dbg_watchpoint_num;
328 reg_addr = monitor->dbg_wvr;
329 reg_ctrl = monitor->dbg_wcr;
330 break;
331 default:
332 printf("Unsupported debug type\n");
333 return (i);
334 }
335
336 for (i = 0; i < max; i++) {
337 if (reg_addr[i] == addr &&
338 (reg_ctrl[i] & DBG_WB_CTRL_E) != 0)
339 return (i);
340 }
341
342 return (-1);
343 }
344
345 int
dbg_setup_watchpoint(struct debug_monitor_state * monitor,vm_offset_t addr,vm_size_t size,enum dbg_access_t access)346 dbg_setup_watchpoint(struct debug_monitor_state *monitor, vm_offset_t addr,
347 vm_size_t size, enum dbg_access_t access)
348 {
349 uint64_t wcr_size, wcr_priv, wcr_access;
350 u_int i;
351
352 if (monitor == NULL)
353 monitor = &kernel_monitor;
354
355 i = dbg_find_free_slot(monitor, DBG_TYPE_WATCHPOINT);
356 if (i == -1) {
357 printf("Can not find slot for watchpoint, max %d"
358 " watchpoints supported\n", dbg_watchpoint_num);
359 return (i);
360 }
361
362 switch(size) {
363 case 1:
364 wcr_size = DBG_WATCH_CTRL_LEN_1;
365 break;
366 case 2:
367 wcr_size = DBG_WATCH_CTRL_LEN_2;
368 break;
369 case 4:
370 wcr_size = DBG_WATCH_CTRL_LEN_4;
371 break;
372 case 8:
373 wcr_size = DBG_WATCH_CTRL_LEN_8;
374 break;
375 default:
376 printf("Unsupported address size for watchpoint\n");
377 return (-1);
378 }
379
380 if ((monitor->dbg_flags & DBGMON_KERNEL) == 0)
381 wcr_priv = DBG_WB_CTRL_EL0;
382 else
383 wcr_priv = DBG_WB_CTRL_EL1;
384
385 switch(access) {
386 case HW_BREAKPOINT_X:
387 wcr_access = DBG_WATCH_CTRL_EXEC;
388 break;
389 case HW_BREAKPOINT_R:
390 wcr_access = DBG_WATCH_CTRL_LOAD;
391 break;
392 case HW_BREAKPOINT_W:
393 wcr_access = DBG_WATCH_CTRL_STORE;
394 break;
395 case HW_BREAKPOINT_RW:
396 wcr_access = DBG_WATCH_CTRL_LOAD | DBG_WATCH_CTRL_STORE;
397 break;
398 default:
399 printf("Unsupported exception level for watchpoint\n");
400 return (-1);
401 }
402
403 monitor->dbg_wvr[i] = addr;
404 monitor->dbg_wcr[i] = wcr_size | wcr_access | wcr_priv | DBG_WB_CTRL_E;
405 monitor->dbg_enable_count++;
406 monitor->dbg_flags |= DBGMON_ENABLED;
407
408 dbg_register_sync(monitor);
409 return (0);
410 }
411
412 int
dbg_remove_watchpoint(struct debug_monitor_state * monitor,vm_offset_t addr,vm_size_t size)413 dbg_remove_watchpoint(struct debug_monitor_state *monitor, vm_offset_t addr,
414 vm_size_t size)
415 {
416 u_int i;
417
418 if (monitor == NULL)
419 monitor = &kernel_monitor;
420
421 i = dbg_find_slot(monitor, DBG_TYPE_WATCHPOINT, addr);
422 if (i == -1) {
423 printf("Can not find watchpoint for address 0%lx\n", addr);
424 return (i);
425 }
426
427 monitor->dbg_wvr[i] = 0;
428 monitor->dbg_wcr[i] = 0;
429 monitor->dbg_enable_count--;
430 if (monitor->dbg_enable_count == 0)
431 monitor->dbg_flags &= ~DBGMON_ENABLED;
432
433 dbg_register_sync(monitor);
434 return (0);
435 }
436
437 void
dbg_register_sync(struct debug_monitor_state * monitor)438 dbg_register_sync(struct debug_monitor_state *monitor)
439 {
440 uint64_t mdscr;
441 int i;
442
443 if (monitor == NULL)
444 monitor = &kernel_monitor;
445
446 mdscr = READ_SPECIALREG(mdscr_el1);
447 if ((monitor->dbg_flags & DBGMON_ENABLED) == 0) {
448 mdscr &= ~(DBG_MDSCR_MDE | DBG_MDSCR_KDE);
449 } else {
450 for (i = 0; i < dbg_breakpoint_num; i++) {
451 dbg_wb_write_reg(DBG_REG_BASE_BCR, i,
452 monitor->dbg_bcr[i]);
453 dbg_wb_write_reg(DBG_REG_BASE_BVR, i,
454 monitor->dbg_bvr[i]);
455 }
456
457 for (i = 0; i < dbg_watchpoint_num; i++) {
458 dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
459 monitor->dbg_wcr[i]);
460 dbg_wb_write_reg(DBG_REG_BASE_WVR, i,
461 monitor->dbg_wvr[i]);
462 }
463 mdscr |= DBG_MDSCR_MDE;
464 if ((monitor->dbg_flags & DBGMON_KERNEL) == DBGMON_KERNEL)
465 mdscr |= DBG_MDSCR_KDE;
466 }
467 WRITE_SPECIALREG(mdscr_el1, mdscr);
468 isb();
469 }
470
471 void
dbg_monitor_init(void)472 dbg_monitor_init(void)
473 {
474 u_int i;
475
476 /* Find out many breakpoints and watchpoints we can use */
477 dbg_watchpoint_num = ((READ_SPECIALREG(id_aa64dfr0_el1) >> 20) & 0xf) + 1;
478 dbg_breakpoint_num = ((READ_SPECIALREG(id_aa64dfr0_el1) >> 12) & 0xf) + 1;
479
480 if (bootverbose && PCPU_GET(cpuid) == 0) {
481 printf("%d watchpoints and %d breakpoints supported\n",
482 dbg_watchpoint_num, dbg_breakpoint_num);
483 }
484
485 /*
486 * We have limited number of {watch,break}points, each consists of
487 * two registers:
488 * - wcr/bcr regsiter configurates corresponding {watch,break}point
489 * behaviour
490 * - wvr/bvr register keeps address we are hunting for
491 *
492 * Reset all breakpoints and watchpoints.
493 */
494 for (i = 0; i < dbg_watchpoint_num; i++) {
495 dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
496 dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
497 }
498
499 for (i = 0; i < dbg_breakpoint_num; i++) {
500 dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
501 dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
502 }
503
504 dbg_enable();
505 }
506
507 void
dbg_monitor_enter(struct thread * thread)508 dbg_monitor_enter(struct thread *thread)
509 {
510 int i;
511
512 if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) {
513 /* Install the kernel version of the registers */
514 dbg_register_sync(&kernel_monitor);
515 } else if ((thread->td_pcb->pcb_dbg_regs.dbg_flags & DBGMON_ENABLED) != 0) {
516 /* Disable the user breakpoints until we return to userspace */
517 for (i = 0; i < dbg_watchpoint_num; i++) {
518 dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
519 dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
520 }
521
522 for (i = 0; i < dbg_breakpoint_num; ++i) {
523 dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
524 dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
525 }
526 WRITE_SPECIALREG(mdscr_el1,
527 READ_SPECIALREG(mdscr_el1) &
528 ~(DBG_MDSCR_MDE | DBG_MDSCR_KDE));
529 isb();
530 }
531 }
532
533 void
dbg_monitor_exit(struct thread * thread,struct trapframe * frame)534 dbg_monitor_exit(struct thread *thread, struct trapframe *frame)
535 {
536 int i;
537
538 /*
539 * PSR_D is an aarch64-only flag. On aarch32, it switches
540 * the processor to big-endian, so avoid setting it for
541 * 32bits binaries.
542 */
543 if (!(SV_PROC_FLAG(thread->td_proc, SV_ILP32)))
544 frame->tf_spsr |= PSR_D;
545 if ((thread->td_pcb->pcb_dbg_regs.dbg_flags & DBGMON_ENABLED) != 0) {
546 /* Install the kernel version of the registers */
547 dbg_register_sync(&thread->td_pcb->pcb_dbg_regs);
548 frame->tf_spsr &= ~PSR_D;
549 } else if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) {
550 /* Disable the user breakpoints until we return to userspace */
551 for (i = 0; i < dbg_watchpoint_num; i++) {
552 dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
553 dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
554 }
555
556 for (i = 0; i < dbg_breakpoint_num; ++i) {
557 dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
558 dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
559 }
560 WRITE_SPECIALREG(mdscr_el1,
561 READ_SPECIALREG(mdscr_el1) &
562 ~(DBG_MDSCR_MDE | DBG_MDSCR_KDE));
563 isb();
564 }
565 }
566