]> git.sur5r.net Git - openocd/blob - src/target/hla_target.c
target: restructure dap support
[openocd] / src / target / hla_target.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by Mathias Kuester                                 *
3  *   Mathias Kuester <kesmtp@freenet.de>                                   *
4  *                                                                         *
5  *   Copyright (C) 2011 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
7  *                                                                         *
8  *   revised:  4/25/13 by brent@mbari.org [DCC target request support]     *
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
22  ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "jtag/jtag.h"
29 #include "jtag/hla/hla_transport.h"
30 #include "jtag/hla/hla_interface.h"
31 #include "jtag/hla/hla_layout.h"
32 #include "register.h"
33 #include "algorithm.h"
34 #include "target.h"
35 #include "breakpoints.h"
36 #include "target_type.h"
37 #include "armv7m.h"
38 #include "cortex_m.h"
39 #include "arm_semihosting.h"
40 #include "target_request.h"
41
42 #define savedDCRDR  dbgbase  /* FIXME: using target->dbgbase to preserve DCRDR */
43
44 #define ARMV7M_SCS_DCRSR        DCB_DCRSR
45 #define ARMV7M_SCS_DCRDR        DCB_DCRDR
46
47 static inline struct hl_interface_s *target_to_adapter(struct target *target)
48 {
49         return target->tap->priv;
50 }
51
52 static int adapter_load_core_reg_u32(struct target *target,
53                 uint32_t num, uint32_t *value)
54 {
55         int retval;
56         struct hl_interface_s *adapter = target_to_adapter(target);
57
58         LOG_DEBUG("%s", __func__);
59
60         /* NOTE:  we "know" here that the register identifiers used
61          * in the v7m header match the Cortex-M3 Debug Core Register
62          * Selector values for R0..R15, xPSR, MSP, and PSP.
63          */
64         switch (num) {
65         case 0 ... 18:
66                 /* read a normal core register */
67                 retval = adapter->layout->api->read_reg(adapter->handle, num, value);
68
69                 if (retval != ERROR_OK) {
70                         LOG_ERROR("JTAG failure %i", retval);
71                         return ERROR_JTAG_DEVICE_ERROR;
72                 }
73                 LOG_DEBUG("load from core reg %i  value 0x%" PRIx32 "", (int)num, *value);
74                 break;
75
76         case ARMV7M_FPSCR:
77                 /* Floating-point Status and Registers */
78                 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
79                 if (retval != ERROR_OK)
80                         return retval;
81                 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
82                 if (retval != ERROR_OK)
83                         return retval;
84                 LOG_DEBUG("load from FPSCR  value 0x%" PRIx32, *value);
85                 break;
86
87         case ARMV7M_S0 ... ARMV7M_S31:
88                 /* Floating-point Status and Registers */
89                 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
90                 if (retval != ERROR_OK)
91                         return retval;
92                 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
93                 if (retval != ERROR_OK)
94                         return retval;
95                 LOG_DEBUG("load from FPU reg S%d  value 0x%" PRIx32,
96                           (int)(num - ARMV7M_S0), *value);
97                 break;
98
99         case ARMV7M_PRIMASK:
100         case ARMV7M_BASEPRI:
101         case ARMV7M_FAULTMASK:
102         case ARMV7M_CONTROL:
103                 /* Cortex-M3 packages these four registers as bitfields
104                  * in one Debug Core register.  So say r0 and r2 docs;
105                  * it was removed from r1 docs, but still works.
106                  */
107                 retval = adapter->layout->api->read_reg(adapter->handle, 20, value);
108                 if (retval != ERROR_OK)
109                         return retval;
110
111                 switch (num) {
112                 case ARMV7M_PRIMASK:
113                         *value = buf_get_u32((uint8_t *) value, 0, 1);
114                         break;
115
116                 case ARMV7M_BASEPRI:
117                         *value = buf_get_u32((uint8_t *) value, 8, 8);
118                         break;
119
120                 case ARMV7M_FAULTMASK:
121                         *value = buf_get_u32((uint8_t *) value, 16, 1);
122                         break;
123
124                 case ARMV7M_CONTROL:
125                         *value = buf_get_u32((uint8_t *) value, 24, 2);
126                         break;
127                 }
128
129                 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
130                           (int)num, *value);
131                 break;
132
133         default:
134                 return ERROR_COMMAND_SYNTAX_ERROR;
135         }
136
137         return ERROR_OK;
138 }
139
140 static int adapter_store_core_reg_u32(struct target *target,
141                 uint32_t num, uint32_t value)
142 {
143         int retval;
144         uint32_t reg;
145         struct armv7m_common *armv7m = target_to_armv7m(target);
146         struct hl_interface_s *adapter = target_to_adapter(target);
147
148         LOG_DEBUG("%s", __func__);
149
150         /* NOTE:  we "know" here that the register identifiers used
151          * in the v7m header match the Cortex-M3 Debug Core Register
152          * Selector values for R0..R15, xPSR, MSP, and PSP.
153          */
154         switch (num) {
155         case 0 ... 18:
156                 retval = adapter->layout->api->write_reg(adapter->handle, num, value);
157
158                 if (retval != ERROR_OK) {
159                         struct reg *r;
160
161                         LOG_ERROR("JTAG failure");
162                         r = armv7m->arm.core_cache->reg_list + num;
163                         r->dirty = r->valid;
164                         return ERROR_JTAG_DEVICE_ERROR;
165                 }
166                 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
167                 break;
168
169         case ARMV7M_FPSCR:
170                 /* Floating-point Status and Registers */
171                 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
172                 if (retval != ERROR_OK)
173                         return retval;
174                 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
175                 if (retval != ERROR_OK)
176                         return retval;
177                 LOG_DEBUG("write FPSCR value 0x%" PRIx32, value);
178                 break;
179
180         case ARMV7M_S0 ... ARMV7M_S31:
181                 /* Floating-point Status and Registers */
182                 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
183                 if (retval != ERROR_OK)
184                         return retval;
185                 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
186                 if (retval != ERROR_OK)
187                         return retval;
188                 LOG_DEBUG("write FPU reg S%d  value 0x%" PRIx32,
189                           (int)(num - ARMV7M_S0), value);
190                 break;
191
192         case ARMV7M_PRIMASK:
193         case ARMV7M_BASEPRI:
194         case ARMV7M_FAULTMASK:
195         case ARMV7M_CONTROL:
196                 /* Cortex-M3 packages these four registers as bitfields
197                  * in one Debug Core register.  So say r0 and r2 docs;
198                  * it was removed from r1 docs, but still works.
199                  */
200
201                 adapter->layout->api->read_reg(adapter->handle, 20, &reg);
202
203                 switch (num) {
204                 case ARMV7M_PRIMASK:
205                         buf_set_u32((uint8_t *) &reg, 0, 1, value);
206                         break;
207
208                 case ARMV7M_BASEPRI:
209                         buf_set_u32((uint8_t *) &reg, 8, 8, value);
210                         break;
211
212                 case ARMV7M_FAULTMASK:
213                         buf_set_u32((uint8_t *) &reg, 16, 1, value);
214                         break;
215
216                 case ARMV7M_CONTROL:
217                         buf_set_u32((uint8_t *) &reg, 24, 2, value);
218                         break;
219                 }
220
221                 adapter->layout->api->write_reg(adapter->handle, 20, reg);
222
223                 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
224                 break;
225
226         default:
227                 return ERROR_COMMAND_SYNTAX_ERROR;
228         }
229
230         return ERROR_OK;
231 }
232
233 static int adapter_examine_debug_reason(struct target *target)
234 {
235         if ((target->debug_reason != DBG_REASON_DBGRQ)
236                         && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
237                 target->debug_reason = DBG_REASON_BREAKPOINT;
238         }
239
240         return ERROR_OK;
241 }
242
243 static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)
244 {
245         uint16_t dcrdr;
246         int retval = hl_if->layout->api->read_mem(hl_if->handle,
247                         DCB_DCRDR, 1, sizeof(dcrdr), (uint8_t *)&dcrdr);
248         if (retval == ERROR_OK) {
249             *ctrl = (uint8_t)dcrdr;
250             *value = (uint8_t)(dcrdr >> 8);
251
252             LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
253
254             if (dcrdr & 1) {
255                         /* write ack back to software dcc register
256                          * to signify we have read data */
257                         /* atomically clear just the byte containing the busy bit */
258                         static const uint8_t zero;
259                         retval = hl_if->layout->api->write_mem(hl_if->handle, DCB_DCRDR, 1, 1, &zero);
260                 }
261         }
262         return retval;
263 }
264
265 static int hl_target_request_data(struct target *target,
266         uint32_t size, uint8_t *buffer)
267 {
268         struct hl_interface_s *hl_if = target_to_adapter(target);
269         uint8_t data;
270         uint8_t ctrl;
271         uint32_t i;
272
273         for (i = 0; i < (size * 4); i++) {
274                 int err = hl_dcc_read(hl_if, &data, &ctrl);
275                 if (err != ERROR_OK)
276                         return err;
277
278                 buffer[i] = data;
279         }
280
281         return ERROR_OK;
282 }
283
284 static int hl_handle_target_request(void *priv)
285 {
286         struct target *target = priv;
287         int err;
288
289         if (!target_was_examined(target))
290                 return ERROR_OK;
291         struct hl_interface_s *hl_if = target_to_adapter(target);
292
293         if (!target->dbg_msg_enabled)
294                 return ERROR_OK;
295
296         if (target->state == TARGET_RUNNING) {
297                 uint8_t data;
298                 uint8_t ctrl;
299
300                 err = hl_dcc_read(hl_if, &data, &ctrl);
301                 if (err != ERROR_OK)
302                         return err;
303
304                 /* check if we have data */
305                 if (ctrl & (1 << 0)) {
306                         uint32_t request;
307
308                         /* we assume target is quick enough */
309                         request = data;
310                         err = hl_dcc_read(hl_if, &data, &ctrl);
311                         if (err != ERROR_OK)
312                                 return err;
313
314                         request |= (data << 8);
315                         err = hl_dcc_read(hl_if, &data, &ctrl);
316                         if (err != ERROR_OK)
317                                 return err;
318
319                         request |= (data << 16);
320                         err = hl_dcc_read(hl_if, &data, &ctrl);
321                         if (err != ERROR_OK)
322                                 return err;
323
324                         request |= (data << 24);
325                         target_request(target, request);
326                 }
327         }
328
329         return ERROR_OK;
330 }
331
332 static int adapter_init_arch_info(struct target *target,
333                                        struct cortex_m_common *cortex_m,
334                                        struct jtag_tap *tap)
335 {
336         struct armv7m_common *armv7m;
337
338         LOG_DEBUG("%s", __func__);
339
340         armv7m = &cortex_m->armv7m;
341         armv7m_init_arch_info(target, armv7m);
342
343         armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
344         armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
345
346         armv7m->examine_debug_reason = adapter_examine_debug_reason;
347         armv7m->stlink = true;
348
349         target_register_timer_callback(hl_handle_target_request, 1, 1, target);
350
351         return ERROR_OK;
352 }
353
354 static int adapter_init_target(struct command_context *cmd_ctx,
355                                     struct target *target)
356 {
357         LOG_DEBUG("%s", __func__);
358
359         armv7m_build_reg_cache(target);
360         arm_semihosting_init(target);
361         return ERROR_OK;
362 }
363
364 static int adapter_target_create(struct target *target,
365                 Jim_Interp *interp)
366 {
367         LOG_DEBUG("%s", __func__);
368         struct adiv5_private_config *pc = target->private_config;
369         struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
370         if (!cortex_m)
371                 return ERROR_COMMAND_SYNTAX_ERROR;
372
373         if (pc != NULL && pc->ap_num > 0) {
374                 LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)");
375                 return ERROR_FAIL;
376         }
377
378         adapter_init_arch_info(target, cortex_m, target->tap);
379
380         return ERROR_OK;
381 }
382
383 static int adapter_load_context(struct target *target)
384 {
385         struct armv7m_common *armv7m = target_to_armv7m(target);
386         int num_regs = armv7m->arm.core_cache->num_regs;
387
388         for (int i = 0; i < num_regs; i++) {
389
390                 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
391                 if (!r->valid)
392                         armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
393         }
394
395         return ERROR_OK;
396 }
397
398 static int adapter_debug_entry(struct target *target)
399 {
400         struct hl_interface_s *adapter = target_to_adapter(target);
401         struct armv7m_common *armv7m = target_to_armv7m(target);
402         struct arm *arm = &armv7m->arm;
403         struct reg *r;
404         uint32_t xPSR;
405         int retval;
406
407         /* preserve the DCRDR across halts */
408         retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
409         if (retval != ERROR_OK)
410                 return retval;
411
412         retval = armv7m->examine_debug_reason(target);
413         if (retval != ERROR_OK)
414                 return retval;
415
416         adapter_load_context(target);
417
418         /* make sure we clear the vector catch bit */
419         adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
420
421         r = arm->cpsr;
422         xPSR = buf_get_u32(r->value, 0, 32);
423
424         /* Are we in an exception handler */
425         if (xPSR & 0x1FF) {
426                 armv7m->exception_number = (xPSR & 0x1FF);
427
428                 arm->core_mode = ARM_MODE_HANDLER;
429                 arm->map = armv7m_msp_reg_map;
430         } else {
431                 unsigned control = buf_get_u32(arm->core_cache
432                                 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
433
434                 /* is this thread privileged? */
435                 arm->core_mode = control & 1
436                                 ? ARM_MODE_USER_THREAD
437                                 : ARM_MODE_THREAD;
438
439                 /* which stack is it using? */
440                 if (control & 2)
441                         arm->map = armv7m_psp_reg_map;
442                 else
443                         arm->map = armv7m_msp_reg_map;
444
445                 armv7m->exception_number = 0;
446         }
447
448         LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
449                 arm_mode_name(arm->core_mode),
450                 buf_get_u32(arm->pc->value, 0, 32),
451                 target_state_name(target));
452
453         return retval;
454 }
455
456 static int adapter_poll(struct target *target)
457 {
458         enum target_state state;
459         struct hl_interface_s *adapter = target_to_adapter(target);
460         struct armv7m_common *armv7m = target_to_armv7m(target);
461         enum target_state prev_target_state = target->state;
462
463         state = adapter->layout->api->state(adapter->handle);
464
465         if (state == TARGET_UNKNOWN) {
466                 LOG_ERROR("jtag status contains invalid mode value - communication failure");
467                 return ERROR_TARGET_FAILURE;
468         }
469
470         if (prev_target_state == state)
471                 return ERROR_OK;
472
473         target->state = state;
474
475         if (state == TARGET_HALTED) {
476
477                 int retval = adapter_debug_entry(target);
478                 if (retval != ERROR_OK)
479                         return retval;
480
481                 if (prev_target_state == TARGET_DEBUG_RUNNING) {
482                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
483                 } else {
484                         if (arm_semihosting(target, &retval) != 0)
485                                 return retval;
486
487                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
488                 }
489
490                 LOG_DEBUG("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
491         }
492
493         return ERROR_OK;
494 }
495
496 static int adapter_assert_reset(struct target *target)
497 {
498         int res = ERROR_OK;
499         struct hl_interface_s *adapter = target_to_adapter(target);
500         struct armv7m_common *armv7m = target_to_armv7m(target);
501         bool use_srst_fallback = true;
502
503         LOG_DEBUG("%s", __func__);
504
505         enum reset_types jtag_reset_config = jtag_get_reset_config();
506
507         bool srst_asserted = false;
508
509         if ((jtag_reset_config & RESET_HAS_SRST) &&
510             (jtag_reset_config & RESET_SRST_NO_GATING)) {
511                 jtag_add_reset(0, 1);
512                 res = adapter->layout->api->assert_srst(adapter->handle, 0);
513                 srst_asserted = true;
514         }
515
516         adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
517
518         /* only set vector catch if halt is requested */
519         if (target->reset_halt)
520                 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);
521         else
522                 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
523
524         if (jtag_reset_config & RESET_HAS_SRST) {
525                 if (!srst_asserted) {
526                         jtag_add_reset(0, 1);
527                         res = adapter->layout->api->assert_srst(adapter->handle, 0);
528                 }
529                 if (res == ERROR_COMMAND_NOTFOUND)
530                         LOG_ERROR("Hardware srst not supported, falling back to software reset");
531                 else if (res == ERROR_OK) {
532                         /* hardware srst supported */
533                         use_srst_fallback = false;
534                 }
535         }
536
537         if (use_srst_fallback) {
538                 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
539                 adapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
540         }
541
542         res = adapter->layout->api->reset(adapter->handle);
543
544         if (res != ERROR_OK)
545                 return res;
546
547         /* registers are now invalid */
548         register_cache_invalidate(armv7m->arm.core_cache);
549
550         if (target->reset_halt) {
551                 target->state = TARGET_RESET;
552                 target->debug_reason = DBG_REASON_DBGRQ;
553         } else {
554                 target->state = TARGET_HALTED;
555         }
556
557         return ERROR_OK;
558 }
559
560 static int adapter_deassert_reset(struct target *target)
561 {
562         struct hl_interface_s *adapter = target_to_adapter(target);
563
564         enum reset_types jtag_reset_config = jtag_get_reset_config();
565
566         LOG_DEBUG("%s", __func__);
567
568         if (jtag_reset_config & RESET_HAS_SRST)
569                 adapter->layout->api->assert_srst(adapter->handle, 1);
570
571         /* virtual deassert reset, we need it for the internal
572          * jtag state machine
573          */
574         jtag_add_reset(0, 0);
575
576         target->savedDCRDR = 0;  /* clear both DCC busy bits on initial resume */
577
578         return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);
579 }
580
581 static int adapter_halt(struct target *target)
582 {
583         int res;
584         struct hl_interface_s *adapter = target_to_adapter(target);
585
586         LOG_DEBUG("%s", __func__);
587
588         if (target->state == TARGET_HALTED) {
589                 LOG_DEBUG("target was already halted");
590                 return ERROR_OK;
591         }
592
593         if (target->state == TARGET_UNKNOWN)
594                 LOG_WARNING("target was in unknown state when halt was requested");
595
596         res = adapter->layout->api->halt(adapter->handle);
597
598         if (res != ERROR_OK)
599                 return res;
600
601         target->debug_reason = DBG_REASON_DBGRQ;
602
603         return ERROR_OK;
604 }
605
606 static int adapter_resume(struct target *target, int current,
607                 target_addr_t address, int handle_breakpoints,
608                 int debug_execution)
609 {
610         int res;
611         struct hl_interface_s *adapter = target_to_adapter(target);
612         struct armv7m_common *armv7m = target_to_armv7m(target);
613         uint32_t resume_pc;
614         struct breakpoint *breakpoint = NULL;
615         struct reg *pc;
616
617         LOG_DEBUG("%s %d " TARGET_ADDR_FMT " %d %d", __func__, current,
618                         address, handle_breakpoints, debug_execution);
619
620         if (target->state != TARGET_HALTED) {
621                 LOG_WARNING("target not halted");
622                 return ERROR_TARGET_NOT_HALTED;
623         }
624
625         if (!debug_execution) {
626                 target_free_all_working_areas(target);
627                 cortex_m_enable_breakpoints(target);
628                 cortex_m_enable_watchpoints(target);
629         }
630
631         pc = armv7m->arm.pc;
632         if (!current) {
633                 buf_set_u32(pc->value, 0, 32, address);
634                 pc->dirty = true;
635                 pc->valid = true;
636         }
637
638         if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
639                         && !debug_execution) {
640                 armv7m_maybe_skip_bkpt_inst(target, NULL);
641         }
642
643         resume_pc = buf_get_u32(pc->value, 0, 32);
644
645         /* write any user vector flags */
646         res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
647         if (res != ERROR_OK)
648                 return res;
649
650         armv7m_restore_context(target);
651
652         /* restore savedDCRDR */
653         res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
654         if (res != ERROR_OK)
655                 return res;
656
657         /* registers are now invalid */
658         register_cache_invalidate(armv7m->arm.core_cache);
659
660         /* the front-end may request us not to handle breakpoints */
661         if (handle_breakpoints) {
662                 /* Single step past breakpoint at current address */
663                 breakpoint = breakpoint_find(target, resume_pc);
664                 if (breakpoint) {
665                         LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
666                                         breakpoint->address,
667                                         breakpoint->unique_id);
668                         cortex_m_unset_breakpoint(target, breakpoint);
669
670                         res = adapter->layout->api->step(adapter->handle);
671
672                         if (res != ERROR_OK)
673                                 return res;
674
675                         cortex_m_set_breakpoint(target, breakpoint);
676                 }
677         }
678
679         res = adapter->layout->api->run(adapter->handle);
680
681         if (res != ERROR_OK)
682                 return res;
683
684         target->debug_reason = DBG_REASON_NOTHALTED;
685
686         if (!debug_execution) {
687                 target->state = TARGET_RUNNING;
688                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
689         } else {
690                 target->state = TARGET_DEBUG_RUNNING;
691                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
692         }
693
694         return ERROR_OK;
695 }
696
697 static int adapter_step(struct target *target, int current,
698                 target_addr_t address, int handle_breakpoints)
699 {
700         int res;
701         struct hl_interface_s *adapter = target_to_adapter(target);
702         struct armv7m_common *armv7m = target_to_armv7m(target);
703         struct breakpoint *breakpoint = NULL;
704         struct reg *pc = armv7m->arm.pc;
705         bool bkpt_inst_found = false;
706
707         LOG_DEBUG("%s", __func__);
708
709         if (target->state != TARGET_HALTED) {
710                 LOG_WARNING("target not halted");
711                 return ERROR_TARGET_NOT_HALTED;
712         }
713
714         if (!current) {
715                 buf_set_u32(pc->value, 0, 32, address);
716                 pc->dirty = true;
717                 pc->valid = true;
718         }
719
720         uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
721
722         /* the front-end may request us not to handle breakpoints */
723         if (handle_breakpoints) {
724                 breakpoint = breakpoint_find(target, pc_value);
725                 if (breakpoint)
726                         cortex_m_unset_breakpoint(target, breakpoint);
727         }
728
729         armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
730
731         target->debug_reason = DBG_REASON_SINGLESTEP;
732
733         armv7m_restore_context(target);
734
735         /* restore savedDCRDR */
736         res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
737         if (res != ERROR_OK)
738                 return res;
739
740         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
741
742         res = adapter->layout->api->step(adapter->handle);
743
744         if (res != ERROR_OK)
745                 return res;
746
747         /* registers are now invalid */
748         register_cache_invalidate(armv7m->arm.core_cache);
749
750         if (breakpoint)
751                 cortex_m_set_breakpoint(target, breakpoint);
752
753         adapter_debug_entry(target);
754         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
755
756         LOG_INFO("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
757
758         return ERROR_OK;
759 }
760
761 static int adapter_read_memory(struct target *target, target_addr_t address,
762                 uint32_t size, uint32_t count,
763                 uint8_t *buffer)
764 {
765         struct hl_interface_s *adapter = target_to_adapter(target);
766
767         if (!count || !buffer)
768                 return ERROR_COMMAND_SYNTAX_ERROR;
769
770         LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
771                           __func__, address, size, count);
772
773         return adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);
774 }
775
776 static int adapter_write_memory(struct target *target, target_addr_t address,
777                 uint32_t size, uint32_t count,
778                 const uint8_t *buffer)
779 {
780         struct hl_interface_s *adapter = target_to_adapter(target);
781
782         if (!count || !buffer)
783                 return ERROR_COMMAND_SYNTAX_ERROR;
784
785         LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
786                           __func__, address, size, count);
787
788         return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);
789 }
790
791 static const struct command_registration adapter_command_handlers[] = {
792         {
793                 .chain = arm_command_handlers,
794         },
795         {
796                 .chain = armv7m_trace_command_handlers,
797         },
798         COMMAND_REGISTRATION_DONE
799 };
800
801 struct target_type hla_target = {
802         .name = "hla_target",
803         .deprecated_name = "stm32_stlink",
804
805         .init_target = adapter_init_target,
806         .deinit_target = cortex_m_deinit_target,
807         .target_create = adapter_target_create,
808         .target_jim_configure = adiv5_jim_configure,
809         .examine = cortex_m_examine,
810         .commands = adapter_command_handlers,
811
812         .poll = adapter_poll,
813         .arch_state = armv7m_arch_state,
814
815         .target_request_data = hl_target_request_data,
816         .assert_reset = adapter_assert_reset,
817         .deassert_reset = adapter_deassert_reset,
818
819         .halt = adapter_halt,
820         .resume = adapter_resume,
821         .step = adapter_step,
822
823         .get_gdb_reg_list = armv7m_get_gdb_reg_list,
824
825         .read_memory = adapter_read_memory,
826         .write_memory = adapter_write_memory,
827         .checksum_memory = armv7m_checksum_memory,
828         .blank_check_memory = armv7m_blank_check_memory,
829
830         .run_algorithm = armv7m_run_algorithm,
831         .start_algorithm = armv7m_start_algorithm,
832         .wait_algorithm = armv7m_wait_algorithm,
833
834         .add_breakpoint = cortex_m_add_breakpoint,
835         .remove_breakpoint = cortex_m_remove_breakpoint,
836         .add_watchpoint = cortex_m_add_watchpoint,
837         .remove_watchpoint = cortex_m_remove_watchpoint,
838         .profiling = cortex_m_profiling,
839 };