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