armv7m_trace: get rid of the old tpiu code
[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/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/hla/hla_transport.h"
31 #include "jtag/hla/hla_interface.h"
32 #include "jtag/hla/hla_layout.h"
33 #include "register.h"
34 #include "algorithm.h"
35 #include "target.h"
36 #include "breakpoints.h"
37 #include "target_type.h"
38 #include "armv7m.h"
39 #include "cortex_m.h"
40 #include "arm_semihosting.h"
41 #include "target_request.h"
42 #include <rtt/rtt.h>
43
44 #define savedDCRDR  dbgbase  /* FIXME: using target->dbgbase to preserve DCRDR */
45
46 #define ARMV7M_SCS_DCRSR        DCB_DCRSR
47 #define ARMV7M_SCS_DCRDR        DCB_DCRDR
48
49 static inline struct hl_interface_s *target_to_adapter(struct target *target)
50 {
51         return target->tap->priv;
52 }
53
54 static int adapter_load_core_reg_u32(struct target *target,
55                 uint32_t regsel, uint32_t *value)
56 {
57         struct hl_interface_s *adapter = target_to_adapter(target);
58         return adapter->layout->api->read_reg(adapter->handle, regsel, value);
59 }
60
61 static int adapter_store_core_reg_u32(struct target *target,
62                 uint32_t regsel, uint32_t value)
63 {
64         struct hl_interface_s *adapter = target_to_adapter(target);
65         return adapter->layout->api->write_reg(adapter->handle, regsel, value);
66 }
67
68 static int adapter_examine_debug_reason(struct target *target)
69 {
70         if ((target->debug_reason != DBG_REASON_DBGRQ)
71                         && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
72                 target->debug_reason = DBG_REASON_BREAKPOINT;
73         }
74
75         return ERROR_OK;
76 }
77
78 static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)
79 {
80         uint16_t dcrdr;
81         int retval = hl_if->layout->api->read_mem(hl_if->handle,
82                         DCB_DCRDR, 1, sizeof(dcrdr), (uint8_t *)&dcrdr);
83         if (retval == ERROR_OK) {
84             *ctrl = (uint8_t)dcrdr;
85             *value = (uint8_t)(dcrdr >> 8);
86
87             LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
88
89             if (dcrdr & 1) {
90                         /* write ack back to software dcc register
91                          * to signify we have read data */
92                         /* atomically clear just the byte containing the busy bit */
93                         static const uint8_t zero;
94                         retval = hl_if->layout->api->write_mem(hl_if->handle, DCB_DCRDR, 1, 1, &zero);
95                 }
96         }
97         return retval;
98 }
99
100 static int hl_target_request_data(struct target *target,
101         uint32_t size, uint8_t *buffer)
102 {
103         struct hl_interface_s *hl_if = target_to_adapter(target);
104         uint8_t data;
105         uint8_t ctrl;
106         uint32_t i;
107
108         for (i = 0; i < (size * 4); i++) {
109                 int err = hl_dcc_read(hl_if, &data, &ctrl);
110                 if (err != ERROR_OK)
111                         return err;
112
113                 buffer[i] = data;
114         }
115
116         return ERROR_OK;
117 }
118
119 static int hl_handle_target_request(void *priv)
120 {
121         struct target *target = priv;
122         int err;
123
124         if (!target_was_examined(target))
125                 return ERROR_OK;
126         struct hl_interface_s *hl_if = target_to_adapter(target);
127
128         if (!target->dbg_msg_enabled)
129                 return ERROR_OK;
130
131         if (target->state == TARGET_RUNNING) {
132                 uint8_t data;
133                 uint8_t ctrl;
134
135                 err = hl_dcc_read(hl_if, &data, &ctrl);
136                 if (err != ERROR_OK)
137                         return err;
138
139                 /* check if we have data */
140                 if (ctrl & (1 << 0)) {
141                         uint32_t request;
142
143                         /* we assume target is quick enough */
144                         request = data;
145                         err = hl_dcc_read(hl_if, &data, &ctrl);
146                         if (err != ERROR_OK)
147                                 return err;
148
149                         request |= (data << 8);
150                         err = hl_dcc_read(hl_if, &data, &ctrl);
151                         if (err != ERROR_OK)
152                                 return err;
153
154                         request |= (data << 16);
155                         err = hl_dcc_read(hl_if, &data, &ctrl);
156                         if (err != ERROR_OK)
157                                 return err;
158
159                         request |= (data << 24);
160                         target_request(target, request);
161                 }
162         }
163
164         return ERROR_OK;
165 }
166
167 static int adapter_init_arch_info(struct target *target,
168                                        struct cortex_m_common *cortex_m,
169                                        struct jtag_tap *tap)
170 {
171         struct armv7m_common *armv7m;
172
173         LOG_DEBUG("%s", __func__);
174
175         armv7m = &cortex_m->armv7m;
176         armv7m_init_arch_info(target, armv7m);
177
178         armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
179         armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
180
181         armv7m->examine_debug_reason = adapter_examine_debug_reason;
182         armv7m->stlink = true;
183
184         target_register_timer_callback(hl_handle_target_request, 1,
185                 TARGET_TIMER_TYPE_PERIODIC, target);
186
187         return ERROR_OK;
188 }
189
190 static int adapter_init_target(struct command_context *cmd_ctx,
191                                     struct target *target)
192 {
193         LOG_DEBUG("%s", __func__);
194
195         armv7m_build_reg_cache(target);
196         arm_semihosting_init(target);
197         return ERROR_OK;
198 }
199
200 static int adapter_target_create(struct target *target,
201                 Jim_Interp *interp)
202 {
203         LOG_DEBUG("%s", __func__);
204         struct adiv5_private_config *pc = target->private_config;
205         if (pc != NULL && pc->ap_num > 0) {
206                 LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)");
207                 return ERROR_COMMAND_SYNTAX_ERROR;
208         }
209
210         struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
211         if (cortex_m == NULL) {
212                 LOG_ERROR("No memory creating target");
213                 return ERROR_FAIL;
214         }
215
216         adapter_init_arch_info(target, cortex_m, target->tap);
217
218         return ERROR_OK;
219 }
220
221 static int adapter_load_context(struct target *target)
222 {
223         struct armv7m_common *armv7m = target_to_armv7m(target);
224         int num_regs = armv7m->arm.core_cache->num_regs;
225
226         for (int i = 0; i < num_regs; i++) {
227
228                 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
229                 if (!r->valid)
230                         armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
231         }
232
233         return ERROR_OK;
234 }
235
236 static int adapter_debug_entry(struct target *target)
237 {
238         struct hl_interface_s *adapter = target_to_adapter(target);
239         struct armv7m_common *armv7m = target_to_armv7m(target);
240         struct arm *arm = &armv7m->arm;
241         struct reg *r;
242         uint32_t xPSR;
243         int retval;
244
245         /* preserve the DCRDR across halts */
246         retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
247         if (retval != ERROR_OK)
248                 return retval;
249
250         retval = armv7m->examine_debug_reason(target);
251         if (retval != ERROR_OK)
252                 return retval;
253
254         adapter_load_context(target);
255
256         /* make sure we clear the vector catch bit */
257         adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
258
259         r = arm->cpsr;
260         xPSR = buf_get_u32(r->value, 0, 32);
261
262         /* Are we in an exception handler */
263         if (xPSR & 0x1FF) {
264                 armv7m->exception_number = (xPSR & 0x1FF);
265
266                 arm->core_mode = ARM_MODE_HANDLER;
267                 arm->map = armv7m_msp_reg_map;
268         } else {
269                 unsigned control = buf_get_u32(arm->core_cache
270                                 ->reg_list[ARMV7M_CONTROL].value, 0, 3);
271
272                 /* is this thread privileged? */
273                 arm->core_mode = control & 1
274                                 ? ARM_MODE_USER_THREAD
275                                 : ARM_MODE_THREAD;
276
277                 /* which stack is it using? */
278                 if (control & 2)
279                         arm->map = armv7m_psp_reg_map;
280                 else
281                         arm->map = armv7m_msp_reg_map;
282
283                 armv7m->exception_number = 0;
284         }
285
286         LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
287                 arm_mode_name(arm->core_mode),
288                 buf_get_u32(arm->pc->value, 0, 32),
289                 target_state_name(target));
290
291         return retval;
292 }
293
294 static int adapter_poll(struct target *target)
295 {
296         enum target_state state;
297         struct hl_interface_s *adapter = target_to_adapter(target);
298         struct armv7m_common *armv7m = target_to_armv7m(target);
299         enum target_state prev_target_state = target->state;
300
301         state = adapter->layout->api->state(adapter->handle);
302
303         if (state == TARGET_UNKNOWN) {
304                 LOG_ERROR("jtag status contains invalid mode value - communication failure");
305                 return ERROR_TARGET_FAILURE;
306         }
307
308         if (prev_target_state == state)
309                 return ERROR_OK;
310
311         if (prev_target_state == TARGET_DEBUG_RUNNING && state == TARGET_RUNNING)
312                 return ERROR_OK;
313
314         target->state = state;
315
316         if (state == TARGET_HALTED) {
317
318                 int retval = adapter_debug_entry(target);
319                 if (retval != ERROR_OK)
320                         return retval;
321
322                 if (prev_target_state == TARGET_DEBUG_RUNNING) {
323                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
324                 } else {
325                         if (arm_semihosting(target, &retval) != 0)
326                                 return retval;
327
328                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
329                 }
330
331                 LOG_DEBUG("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
332         }
333
334         return ERROR_OK;
335 }
336
337 static int hl_assert_reset(struct target *target)
338 {
339         int res = ERROR_OK;
340         struct hl_interface_s *adapter = target_to_adapter(target);
341         struct armv7m_common *armv7m = target_to_armv7m(target);
342         bool use_srst_fallback = true;
343
344         LOG_DEBUG("%s", __func__);
345
346         enum reset_types jtag_reset_config = jtag_get_reset_config();
347
348         bool srst_asserted = false;
349
350         if ((jtag_reset_config & RESET_HAS_SRST) &&
351             (jtag_reset_config & RESET_SRST_NO_GATING)) {
352                 res = adapter_assert_reset();
353                 srst_asserted = true;
354         }
355
356         adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
357
358         /* only set vector catch if halt is requested */
359         if (target->reset_halt)
360                 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);
361         else
362                 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
363
364         if (jtag_reset_config & RESET_HAS_SRST) {
365                 if (!srst_asserted) {
366                         res = adapter_assert_reset();
367                 }
368                 if (res == ERROR_COMMAND_NOTFOUND)
369                         LOG_ERROR("Hardware srst not supported, falling back to software reset");
370                 else if (res == ERROR_OK) {
371                         /* hardware srst supported */
372                         use_srst_fallback = false;
373                 }
374         }
375
376         if (use_srst_fallback) {
377                 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
378                 adapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
379         }
380
381         res = adapter->layout->api->reset(adapter->handle);
382
383         if (res != ERROR_OK)
384                 return res;
385
386         /* registers are now invalid */
387         register_cache_invalidate(armv7m->arm.core_cache);
388
389         if (target->reset_halt) {
390                 target->state = TARGET_RESET;
391                 target->debug_reason = DBG_REASON_DBGRQ;
392         } else {
393                 target->state = TARGET_HALTED;
394         }
395
396         return ERROR_OK;
397 }
398
399 static int hl_deassert_reset(struct target *target)
400 {
401         enum reset_types jtag_reset_config = jtag_get_reset_config();
402
403         LOG_DEBUG("%s", __func__);
404
405         if (jtag_reset_config & RESET_HAS_SRST)
406                 adapter_deassert_reset();
407
408         target->savedDCRDR = 0;  /* clear both DCC busy bits on initial resume */
409
410         return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);
411 }
412
413 static int adapter_halt(struct target *target)
414 {
415         int res;
416         struct hl_interface_s *adapter = target_to_adapter(target);
417
418         LOG_DEBUG("%s", __func__);
419
420         if (target->state == TARGET_HALTED) {
421                 LOG_DEBUG("target was already halted");
422                 return ERROR_OK;
423         }
424
425         if (target->state == TARGET_UNKNOWN)
426                 LOG_WARNING("target was in unknown state when halt was requested");
427
428         res = adapter->layout->api->halt(adapter->handle);
429
430         if (res != ERROR_OK)
431                 return res;
432
433         target->debug_reason = DBG_REASON_DBGRQ;
434
435         return ERROR_OK;
436 }
437
438 static int adapter_resume(struct target *target, int current,
439                 target_addr_t address, int handle_breakpoints,
440                 int debug_execution)
441 {
442         int res;
443         struct hl_interface_s *adapter = target_to_adapter(target);
444         struct armv7m_common *armv7m = target_to_armv7m(target);
445         uint32_t resume_pc;
446         struct breakpoint *breakpoint = NULL;
447         struct reg *pc;
448
449         LOG_DEBUG("%s %d " TARGET_ADDR_FMT " %d %d", __func__, current,
450                         address, handle_breakpoints, debug_execution);
451
452         if (target->state != TARGET_HALTED) {
453                 LOG_WARNING("target not halted");
454                 return ERROR_TARGET_NOT_HALTED;
455         }
456
457         if (!debug_execution) {
458                 target_free_all_working_areas(target);
459                 cortex_m_enable_breakpoints(target);
460                 cortex_m_enable_watchpoints(target);
461         }
462
463         pc = armv7m->arm.pc;
464         if (!current) {
465                 buf_set_u32(pc->value, 0, 32, address);
466                 pc->dirty = true;
467                 pc->valid = true;
468         }
469
470         if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
471                         && !debug_execution) {
472                 armv7m_maybe_skip_bkpt_inst(target, NULL);
473         }
474
475         resume_pc = buf_get_u32(pc->value, 0, 32);
476
477         /* write any user vector flags */
478         res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
479         if (res != ERROR_OK)
480                 return res;
481
482         armv7m_restore_context(target);
483
484         /* restore savedDCRDR */
485         res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
486         if (res != ERROR_OK)
487                 return res;
488
489         /* registers are now invalid */
490         register_cache_invalidate(armv7m->arm.core_cache);
491
492         /* the front-end may request us not to handle breakpoints */
493         if (handle_breakpoints) {
494                 /* Single step past breakpoint at current address */
495                 breakpoint = breakpoint_find(target, resume_pc);
496                 if (breakpoint) {
497                         LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
498                                         breakpoint->address,
499                                         breakpoint->unique_id);
500                         cortex_m_unset_breakpoint(target, breakpoint);
501
502                         res = adapter->layout->api->step(adapter->handle);
503
504                         if (res != ERROR_OK)
505                                 return res;
506
507                         cortex_m_set_breakpoint(target, breakpoint);
508                 }
509         }
510
511         res = adapter->layout->api->run(adapter->handle);
512
513         if (res != ERROR_OK)
514                 return res;
515
516         target->debug_reason = DBG_REASON_NOTHALTED;
517
518         if (!debug_execution) {
519                 target->state = TARGET_RUNNING;
520                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
521         } else {
522                 target->state = TARGET_DEBUG_RUNNING;
523                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
524         }
525
526         return ERROR_OK;
527 }
528
529 static int adapter_step(struct target *target, int current,
530                 target_addr_t address, int handle_breakpoints)
531 {
532         int res;
533         struct hl_interface_s *adapter = target_to_adapter(target);
534         struct armv7m_common *armv7m = target_to_armv7m(target);
535         struct breakpoint *breakpoint = NULL;
536         struct reg *pc = armv7m->arm.pc;
537         bool bkpt_inst_found = false;
538
539         LOG_DEBUG("%s", __func__);
540
541         if (target->state != TARGET_HALTED) {
542                 LOG_WARNING("target not halted");
543                 return ERROR_TARGET_NOT_HALTED;
544         }
545
546         if (!current) {
547                 buf_set_u32(pc->value, 0, 32, address);
548                 pc->dirty = true;
549                 pc->valid = true;
550         }
551
552         uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
553
554         /* the front-end may request us not to handle breakpoints */
555         if (handle_breakpoints) {
556                 breakpoint = breakpoint_find(target, pc_value);
557                 if (breakpoint)
558                         cortex_m_unset_breakpoint(target, breakpoint);
559         }
560
561         armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
562
563         target->debug_reason = DBG_REASON_SINGLESTEP;
564
565         armv7m_restore_context(target);
566
567         /* restore savedDCRDR */
568         res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
569         if (res != ERROR_OK)
570                 return res;
571
572         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
573
574         res = adapter->layout->api->step(adapter->handle);
575
576         if (res != ERROR_OK)
577                 return res;
578
579         /* registers are now invalid */
580         register_cache_invalidate(armv7m->arm.core_cache);
581
582         if (breakpoint)
583                 cortex_m_set_breakpoint(target, breakpoint);
584
585         adapter_debug_entry(target);
586         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
587
588         LOG_INFO("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
589
590         return ERROR_OK;
591 }
592
593 static int adapter_read_memory(struct target *target, target_addr_t address,
594                 uint32_t size, uint32_t count,
595                 uint8_t *buffer)
596 {
597         struct hl_interface_s *adapter = target_to_adapter(target);
598
599         if (!count || !buffer)
600                 return ERROR_COMMAND_SYNTAX_ERROR;
601
602         LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
603                           __func__, address, size, count);
604
605         return adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);
606 }
607
608 static int adapter_write_memory(struct target *target, target_addr_t address,
609                 uint32_t size, uint32_t count,
610                 const uint8_t *buffer)
611 {
612         struct hl_interface_s *adapter = target_to_adapter(target);
613
614         if (!count || !buffer)
615                 return ERROR_COMMAND_SYNTAX_ERROR;
616
617         LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
618                           __func__, address, size, count);
619
620         return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);
621 }
622
623 static const struct command_registration adapter_command_handlers[] = {
624         {
625                 .chain = arm_command_handlers,
626         },
627         {
628                 .chain = armv7m_trace_command_handlers,
629         },
630         {
631                 .chain = rtt_target_command_handlers,
632         },
633         /* START_DEPRECATED_TPIU */
634         {
635                 .chain = arm_tpiu_deprecated_command_handlers,
636         },
637         /* END_DEPRECATED_TPIU */
638         COMMAND_REGISTRATION_DONE
639 };
640
641 struct target_type hla_target = {
642         .name = "hla_target",
643         .deprecated_name = "stm32_stlink",
644
645         .init_target = adapter_init_target,
646         .deinit_target = cortex_m_deinit_target,
647         .target_create = adapter_target_create,
648         .target_jim_configure = adiv5_jim_configure,
649         .examine = cortex_m_examine,
650         .commands = adapter_command_handlers,
651
652         .poll = adapter_poll,
653         .arch_state = armv7m_arch_state,
654
655         .target_request_data = hl_target_request_data,
656         .assert_reset = hl_assert_reset,
657         .deassert_reset = hl_deassert_reset,
658
659         .halt = adapter_halt,
660         .resume = adapter_resume,
661         .step = adapter_step,
662
663         .get_gdb_arch = arm_get_gdb_arch,
664         .get_gdb_reg_list = armv7m_get_gdb_reg_list,
665
666         .read_memory = adapter_read_memory,
667         .write_memory = adapter_write_memory,
668         .checksum_memory = armv7m_checksum_memory,
669         .blank_check_memory = armv7m_blank_check_memory,
670
671         .run_algorithm = armv7m_run_algorithm,
672         .start_algorithm = armv7m_start_algorithm,
673         .wait_algorithm = armv7m_wait_algorithm,
674
675         .add_breakpoint = cortex_m_add_breakpoint,
676         .remove_breakpoint = cortex_m_remove_breakpoint,
677         .add_watchpoint = cortex_m_add_watchpoint,
678         .remove_watchpoint = cortex_m_remove_watchpoint,
679         .profiling = cortex_m_profiling,
680 };