target: hla: check return value of hl_dcc_read
[fw/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
369         struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
370
371         if (!cortex_m)
372                 return ERROR_COMMAND_SYNTAX_ERROR;
373
374         adapter_init_arch_info(target, cortex_m, target->tap);
375
376         return ERROR_OK;
377 }
378
379 static int adapter_load_context(struct target *target)
380 {
381         struct armv7m_common *armv7m = target_to_armv7m(target);
382         int num_regs = armv7m->arm.core_cache->num_regs;
383
384         for (int i = 0; i < num_regs; i++) {
385
386                 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
387                 if (!r->valid)
388                         armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
389         }
390
391         return ERROR_OK;
392 }
393
394 static int adapter_debug_entry(struct target *target)
395 {
396         struct hl_interface_s *adapter = target_to_adapter(target);
397         struct armv7m_common *armv7m = target_to_armv7m(target);
398         struct arm *arm = &armv7m->arm;
399         struct reg *r;
400         uint32_t xPSR;
401         int retval;
402
403         /* preserve the DCRDR across halts */
404         retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
405         if (retval != ERROR_OK)
406                 return retval;
407
408         retval = armv7m->examine_debug_reason(target);
409         if (retval != ERROR_OK)
410                 return retval;
411
412         adapter_load_context(target);
413
414         /* make sure we clear the vector catch bit */
415         adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
416
417         r = arm->cpsr;
418         xPSR = buf_get_u32(r->value, 0, 32);
419
420         /* Are we in an exception handler */
421         if (xPSR & 0x1FF) {
422                 armv7m->exception_number = (xPSR & 0x1FF);
423
424                 arm->core_mode = ARM_MODE_HANDLER;
425                 arm->map = armv7m_msp_reg_map;
426         } else {
427                 unsigned control = buf_get_u32(arm->core_cache
428                                 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
429
430                 /* is this thread privileged? */
431                 arm->core_mode = control & 1
432                                 ? ARM_MODE_USER_THREAD
433                                 : ARM_MODE_THREAD;
434
435                 /* which stack is it using? */
436                 if (control & 2)
437                         arm->map = armv7m_psp_reg_map;
438                 else
439                         arm->map = armv7m_msp_reg_map;
440
441                 armv7m->exception_number = 0;
442         }
443
444         LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
445                 arm_mode_name(arm->core_mode),
446                 buf_get_u32(arm->pc->value, 0, 32),
447                 target_state_name(target));
448
449         return retval;
450 }
451
452 static int adapter_poll(struct target *target)
453 {
454         enum target_state state;
455         struct hl_interface_s *adapter = target_to_adapter(target);
456         struct armv7m_common *armv7m = target_to_armv7m(target);
457         enum target_state prev_target_state = target->state;
458
459         state = adapter->layout->api->state(adapter->handle);
460
461         if (state == TARGET_UNKNOWN) {
462                 LOG_ERROR("jtag status contains invalid mode value - communication failure");
463                 return ERROR_TARGET_FAILURE;
464         }
465
466         if (prev_target_state == state)
467                 return ERROR_OK;
468
469         target->state = state;
470
471         if (state == TARGET_HALTED) {
472
473                 int retval = adapter_debug_entry(target);
474                 if (retval != ERROR_OK)
475                         return retval;
476
477                 if (prev_target_state == TARGET_DEBUG_RUNNING) {
478                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
479                 } else {
480                         if (arm_semihosting(target, &retval) != 0)
481                                 return retval;
482
483                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
484                 }
485
486                 LOG_DEBUG("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
487         }
488
489         return ERROR_OK;
490 }
491
492 static int adapter_assert_reset(struct target *target)
493 {
494         int res = ERROR_OK;
495         struct hl_interface_s *adapter = target_to_adapter(target);
496         struct armv7m_common *armv7m = target_to_armv7m(target);
497         bool use_srst_fallback = true;
498
499         LOG_DEBUG("%s", __func__);
500
501         enum reset_types jtag_reset_config = jtag_get_reset_config();
502
503         bool srst_asserted = false;
504
505         if ((jtag_reset_config & RESET_HAS_SRST) &&
506             (jtag_reset_config & RESET_SRST_NO_GATING)) {
507                 jtag_add_reset(0, 1);
508                 res = adapter->layout->api->assert_srst(adapter->handle, 0);
509                 srst_asserted = true;
510         }
511
512         adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
513
514         /* only set vector catch if halt is requested */
515         if (target->reset_halt)
516                 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);
517         else
518                 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
519
520         if (jtag_reset_config & RESET_HAS_SRST) {
521                 if (!srst_asserted) {
522                         jtag_add_reset(0, 1);
523                         res = adapter->layout->api->assert_srst(adapter->handle, 0);
524                 }
525                 if (res == ERROR_COMMAND_NOTFOUND)
526                         LOG_ERROR("Hardware srst not supported, falling back to software reset");
527                 else if (res == ERROR_OK) {
528                         /* hardware srst supported */
529                         use_srst_fallback = false;
530                 }
531         }
532
533         if (use_srst_fallback) {
534                 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
535                 adapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
536         }
537
538         res = adapter->layout->api->reset(adapter->handle);
539
540         if (res != ERROR_OK)
541                 return res;
542
543         /* registers are now invalid */
544         register_cache_invalidate(armv7m->arm.core_cache);
545
546         if (target->reset_halt) {
547                 target->state = TARGET_RESET;
548                 target->debug_reason = DBG_REASON_DBGRQ;
549         } else {
550                 target->state = TARGET_HALTED;
551         }
552
553         return ERROR_OK;
554 }
555
556 static int adapter_deassert_reset(struct target *target)
557 {
558         struct hl_interface_s *adapter = target_to_adapter(target);
559
560         enum reset_types jtag_reset_config = jtag_get_reset_config();
561
562         LOG_DEBUG("%s", __func__);
563
564         if (jtag_reset_config & RESET_HAS_SRST)
565                 adapter->layout->api->assert_srst(adapter->handle, 1);
566
567         /* virtual deassert reset, we need it for the internal
568          * jtag state machine
569          */
570         jtag_add_reset(0, 0);
571
572         target->savedDCRDR = 0;  /* clear both DCC busy bits on initial resume */
573
574         return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);
575 }
576
577 static int adapter_halt(struct target *target)
578 {
579         int res;
580         struct hl_interface_s *adapter = target_to_adapter(target);
581
582         LOG_DEBUG("%s", __func__);
583
584         if (target->state == TARGET_HALTED) {
585                 LOG_DEBUG("target was already halted");
586                 return ERROR_OK;
587         }
588
589         if (target->state == TARGET_UNKNOWN)
590                 LOG_WARNING("target was in unknown state when halt was requested");
591
592         res = adapter->layout->api->halt(adapter->handle);
593
594         if (res != ERROR_OK)
595                 return res;
596
597         target->debug_reason = DBG_REASON_DBGRQ;
598
599         return ERROR_OK;
600 }
601
602 static int adapter_resume(struct target *target, int current,
603                 target_addr_t address, int handle_breakpoints,
604                 int debug_execution)
605 {
606         int res;
607         struct hl_interface_s *adapter = target_to_adapter(target);
608         struct armv7m_common *armv7m = target_to_armv7m(target);
609         uint32_t resume_pc;
610         struct breakpoint *breakpoint = NULL;
611         struct reg *pc;
612
613         LOG_DEBUG("%s %d " TARGET_ADDR_FMT " %d %d", __func__, current,
614                         address, handle_breakpoints, debug_execution);
615
616         if (target->state != TARGET_HALTED) {
617                 LOG_WARNING("target not halted");
618                 return ERROR_TARGET_NOT_HALTED;
619         }
620
621         if (!debug_execution) {
622                 target_free_all_working_areas(target);
623                 cortex_m_enable_breakpoints(target);
624                 cortex_m_enable_watchpoints(target);
625         }
626
627         pc = armv7m->arm.pc;
628         if (!current) {
629                 buf_set_u32(pc->value, 0, 32, address);
630                 pc->dirty = true;
631                 pc->valid = true;
632         }
633
634         if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
635                         && !debug_execution) {
636                 armv7m_maybe_skip_bkpt_inst(target, NULL);
637         }
638
639         resume_pc = buf_get_u32(pc->value, 0, 32);
640
641         /* write any user vector flags */
642         res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
643         if (res != ERROR_OK)
644                 return res;
645
646         armv7m_restore_context(target);
647
648         /* restore savedDCRDR */
649         res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
650         if (res != ERROR_OK)
651                 return res;
652
653         /* registers are now invalid */
654         register_cache_invalidate(armv7m->arm.core_cache);
655
656         /* the front-end may request us not to handle breakpoints */
657         if (handle_breakpoints) {
658                 /* Single step past breakpoint at current address */
659                 breakpoint = breakpoint_find(target, resume_pc);
660                 if (breakpoint) {
661                         LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
662                                         breakpoint->address,
663                                         breakpoint->unique_id);
664                         cortex_m_unset_breakpoint(target, breakpoint);
665
666                         res = adapter->layout->api->step(adapter->handle);
667
668                         if (res != ERROR_OK)
669                                 return res;
670
671                         cortex_m_set_breakpoint(target, breakpoint);
672                 }
673         }
674
675         res = adapter->layout->api->run(adapter->handle);
676
677         if (res != ERROR_OK)
678                 return res;
679
680         target->debug_reason = DBG_REASON_NOTHALTED;
681
682         if (!debug_execution) {
683                 target->state = TARGET_RUNNING;
684                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
685         } else {
686                 target->state = TARGET_DEBUG_RUNNING;
687                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
688         }
689
690         return ERROR_OK;
691 }
692
693 static int adapter_step(struct target *target, int current,
694                 target_addr_t address, int handle_breakpoints)
695 {
696         int res;
697         struct hl_interface_s *adapter = target_to_adapter(target);
698         struct armv7m_common *armv7m = target_to_armv7m(target);
699         struct breakpoint *breakpoint = NULL;
700         struct reg *pc = armv7m->arm.pc;
701         bool bkpt_inst_found = false;
702
703         LOG_DEBUG("%s", __func__);
704
705         if (target->state != TARGET_HALTED) {
706                 LOG_WARNING("target not halted");
707                 return ERROR_TARGET_NOT_HALTED;
708         }
709
710         if (!current) {
711                 buf_set_u32(pc->value, 0, 32, address);
712                 pc->dirty = true;
713                 pc->valid = true;
714         }
715
716         uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
717
718         /* the front-end may request us not to handle breakpoints */
719         if (handle_breakpoints) {
720                 breakpoint = breakpoint_find(target, pc_value);
721                 if (breakpoint)
722                         cortex_m_unset_breakpoint(target, breakpoint);
723         }
724
725         armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
726
727         target->debug_reason = DBG_REASON_SINGLESTEP;
728
729         armv7m_restore_context(target);
730
731         /* restore savedDCRDR */
732         res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
733         if (res != ERROR_OK)
734                 return res;
735
736         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
737
738         res = adapter->layout->api->step(adapter->handle);
739
740         if (res != ERROR_OK)
741                 return res;
742
743         /* registers are now invalid */
744         register_cache_invalidate(armv7m->arm.core_cache);
745
746         if (breakpoint)
747                 cortex_m_set_breakpoint(target, breakpoint);
748
749         adapter_debug_entry(target);
750         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
751
752         LOG_INFO("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
753
754         return ERROR_OK;
755 }
756
757 static int adapter_read_memory(struct target *target, target_addr_t address,
758                 uint32_t size, uint32_t count,
759                 uint8_t *buffer)
760 {
761         struct hl_interface_s *adapter = target_to_adapter(target);
762
763         if (!count || !buffer)
764                 return ERROR_COMMAND_SYNTAX_ERROR;
765
766         LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
767                           __func__, address, size, count);
768
769         return adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);
770 }
771
772 static int adapter_write_memory(struct target *target, target_addr_t address,
773                 uint32_t size, uint32_t count,
774                 const uint8_t *buffer)
775 {
776         struct hl_interface_s *adapter = target_to_adapter(target);
777
778         if (!count || !buffer)
779                 return ERROR_COMMAND_SYNTAX_ERROR;
780
781         LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
782                           __func__, address, size, count);
783
784         return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);
785 }
786
787 static const struct command_registration adapter_command_handlers[] = {
788         {
789                 .chain = arm_command_handlers,
790         },
791         {
792                 .chain = armv7m_trace_command_handlers,
793         },
794         COMMAND_REGISTRATION_DONE
795 };
796
797 struct target_type hla_target = {
798         .name = "hla_target",
799         .deprecated_name = "stm32_stlink",
800
801         .init_target = adapter_init_target,
802         .deinit_target = cortex_m_deinit_target,
803         .target_create = adapter_target_create,
804         .examine = cortex_m_examine,
805         .commands = adapter_command_handlers,
806
807         .poll = adapter_poll,
808         .arch_state = armv7m_arch_state,
809
810         .target_request_data = hl_target_request_data,
811         .assert_reset = adapter_assert_reset,
812         .deassert_reset = adapter_deassert_reset,
813
814         .halt = adapter_halt,
815         .resume = adapter_resume,
816         .step = adapter_step,
817
818         .get_gdb_reg_list = armv7m_get_gdb_reg_list,
819
820         .read_memory = adapter_read_memory,
821         .write_memory = adapter_write_memory,
822         .checksum_memory = armv7m_checksum_memory,
823         .blank_check_memory = armv7m_blank_check_memory,
824
825         .run_algorithm = armv7m_run_algorithm,
826         .start_algorithm = armv7m_start_algorithm,
827         .wait_algorithm = armv7m_wait_algorithm,
828
829         .add_breakpoint = cortex_m_add_breakpoint,
830         .remove_breakpoint = cortex_m_remove_breakpoint,
831         .add_watchpoint = cortex_m_add_watchpoint,
832         .remove_watchpoint = cortex_m_remove_watchpoint,
833         .profiling = cortex_m_profiling,
834 };