You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

680 lines
18 KiB

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