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