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