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.
 
 
 
 
 
 

681 lines
17 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
  3. * Based on mips_m4k code: *
  4. * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
  5. * Copyright (C) 2008 by David T.L. Wong *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; either version 2 of the License, or *
  10. * (at your option) any later version. *
  11. * *
  12. * This program is distributed in the hope that it will be useful, *
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15. * GNU General Public License for more details. *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with this program; if not, write to the *
  19. * Free Software Foundation, Inc., *
  20. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  21. ***************************************************************************/
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25. #include "jtag/jtag.h"
  26. #include "register.h"
  27. #include "algorithm.h"
  28. #include "target.h"
  29. #include "breakpoints.h"
  30. #include "target_type.h"
  31. #include "avr32_jtag.h"
  32. #include "avr32_mem.h"
  33. #include "avr32_regs.h"
  34. #include "avr32_ap7k.h"
  35. static char* avr32_core_reg_list[] =
  36. {
  37. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
  38. "r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr"
  39. };
  40. static struct avr32_core_reg
  41. avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] =
  42. {
  43. {0, NULL, NULL},
  44. {1, NULL, NULL},
  45. {2, NULL, NULL},
  46. {3, NULL, NULL},
  47. {4, NULL, NULL},
  48. {5, NULL, NULL},
  49. {6, NULL, NULL},
  50. {7, NULL, NULL},
  51. {8, NULL, NULL},
  52. {9, NULL, NULL},
  53. {10, NULL, NULL},
  54. {11, NULL, NULL},
  55. {12, NULL, NULL},
  56. {13, NULL, NULL},
  57. {14, NULL, NULL},
  58. {15, NULL, NULL},
  59. {16, NULL, NULL},
  60. };
  61. static int avr32_read_core_reg(struct target *target, int num);
  62. static int avr32_write_core_reg(struct target *target, int num);
  63. int avr32_ap7k_save_context(struct target *target)
  64. {
  65. int retval, i;
  66. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  67. retval = avr32_jtag_read_regs(&ap7k->jtag, ap7k->core_regs);
  68. if (retval != ERROR_OK)
  69. return retval;
  70. for (i = 0; i < AVR32NUMCOREREGS; i++)
  71. {
  72. if (!ap7k->core_cache->reg_list[i].valid)
  73. {
  74. avr32_read_core_reg(target, i);
  75. }
  76. }
  77. return ERROR_OK;
  78. }
  79. int avr32_ap7k_restore_context(struct target *target)
  80. {
  81. int i;
  82. /* get pointers to arch-specific information */
  83. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  84. for (i = 0; i < AVR32NUMCOREREGS; i++)
  85. {
  86. if (ap7k->core_cache->reg_list[i].dirty)
  87. {
  88. avr32_write_core_reg(target, i);
  89. }
  90. }
  91. /* write core regs */
  92. avr32_jtag_write_regs(&ap7k->jtag, ap7k->core_regs);
  93. return ERROR_OK;
  94. }
  95. static int avr32_read_core_reg(struct target *target, int num)
  96. {
  97. uint32_t reg_value;
  98. /* get pointers to arch-specific information */
  99. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  100. if ((num < 0) || (num >= AVR32NUMCOREREGS))
  101. return ERROR_INVALID_ARGUMENTS;
  102. reg_value = ap7k->core_regs[num];
  103. buf_set_u32(ap7k->core_cache->reg_list[num].value, 0, 32, reg_value);
  104. ap7k->core_cache->reg_list[num].valid = 1;
  105. ap7k->core_cache->reg_list[num].dirty = 0;
  106. return ERROR_OK;
  107. }
  108. static int avr32_write_core_reg(struct target *target, int num)
  109. {
  110. uint32_t reg_value;
  111. /* get pointers to arch-specific information */
  112. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  113. if ((num < 0) || (num >= AVR32NUMCOREREGS))
  114. return ERROR_INVALID_ARGUMENTS;
  115. reg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32);
  116. ap7k->core_regs[num] = reg_value;
  117. LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
  118. ap7k->core_cache->reg_list[num].valid = 1;
  119. ap7k->core_cache->reg_list[num].dirty = 0;
  120. return ERROR_OK;
  121. }
  122. static int avr32_get_core_reg(struct reg *reg)
  123. {
  124. int retval;
  125. struct avr32_core_reg *avr32_reg = reg->arch_info;
  126. struct target *target = avr32_reg->target;
  127. if (target->state != TARGET_HALTED)
  128. {
  129. return ERROR_TARGET_NOT_HALTED;
  130. }
  131. retval = avr32_read_core_reg(target, avr32_reg->num);
  132. return retval;
  133. }
  134. static int avr32_set_core_reg(struct reg *reg, uint8_t *buf)
  135. {
  136. struct avr32_core_reg *avr32_reg = reg->arch_info;
  137. struct target *target = avr32_reg->target;
  138. uint32_t value = buf_get_u32(buf, 0, 32);
  139. if (target->state != TARGET_HALTED)
  140. {
  141. return ERROR_TARGET_NOT_HALTED;
  142. }
  143. buf_set_u32(reg->value, 0, 32, value);
  144. reg->dirty = 1;
  145. reg->valid = 1;
  146. return ERROR_OK;
  147. }
  148. static const struct reg_arch_type avr32_reg_type = {
  149. .get = avr32_get_core_reg,
  150. .set = avr32_set_core_reg,
  151. };
  152. static struct reg_cache *avr32_build_reg_cache(struct target *target)
  153. {
  154. int num_regs = AVR32NUMCOREREGS;
  155. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  156. struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
  157. struct reg_cache *cache = malloc(sizeof(struct reg_cache));
  158. struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
  159. struct avr32_core_reg *arch_info =
  160. malloc(sizeof(struct avr32_core_reg) * num_regs);
  161. int i;
  162. /* Build the process context cache */
  163. cache->name = "avr32 registers";
  164. cache->next = NULL;
  165. cache->reg_list = reg_list;
  166. cache->num_regs = num_regs;
  167. (*cache_p) = cache;
  168. ap7k->core_cache = cache;
  169. for (i = 0; i < num_regs; i++)
  170. {
  171. arch_info[i] = avr32_core_reg_list_arch_info[i];
  172. arch_info[i].target = target;
  173. arch_info[i].avr32_common = ap7k;
  174. reg_list[i].name = avr32_core_reg_list[i];
  175. reg_list[i].size = 32;
  176. reg_list[i].value = calloc(1, 4);
  177. reg_list[i].dirty = 0;
  178. reg_list[i].valid = 0;
  179. reg_list[i].type = &avr32_reg_type;
  180. reg_list[i].arch_info = &arch_info[i];
  181. }
  182. return cache;
  183. }
  184. static int avr32_ap7k_debug_entry(struct target *target)
  185. {
  186. uint32_t dpc, dinst;
  187. int retval;
  188. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  189. retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DPC, &dpc);
  190. if (retval != ERROR_OK)
  191. return retval;
  192. retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DINST, &dinst);
  193. if (retval != ERROR_OK)
  194. return retval;
  195. ap7k->jtag.dpc = dpc;
  196. avr32_ap7k_save_context(target);
  197. return ERROR_OK;
  198. }
  199. static int avr32_ap7k_poll(struct target *target)
  200. {
  201. uint32_t ds;
  202. int retval;
  203. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  204. retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);
  205. if (retval != ERROR_OK)
  206. return retval;
  207. /* check for processor halted */
  208. if (ds & OCDREG_DS_DBA)
  209. {
  210. if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
  211. {
  212. target->state = TARGET_HALTED;
  213. if ((retval = avr32_ap7k_debug_entry(target)) != ERROR_OK)
  214. return retval;
  215. target_call_event_callbacks(target, TARGET_EVENT_HALTED);
  216. }
  217. else if (target->state == TARGET_DEBUG_RUNNING)
  218. {
  219. target->state = TARGET_HALTED;
  220. if ((retval = avr32_ap7k_debug_entry(target)) != ERROR_OK)
  221. return retval;
  222. target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
  223. }
  224. }
  225. else
  226. {
  227. target->state = TARGET_RUNNING;
  228. }
  229. return ERROR_OK;
  230. }
  231. static int avr32_ap7k_halt(struct target *target)
  232. {
  233. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  234. LOG_DEBUG("target->state: %s",
  235. target_state_name(target));
  236. if (target->state == TARGET_HALTED)
  237. {
  238. LOG_DEBUG("target was already halted");
  239. return ERROR_OK;
  240. }
  241. if (target->state == TARGET_UNKNOWN)
  242. {
  243. LOG_WARNING("target was in unknown state when halt was requested");
  244. }
  245. if (target->state == TARGET_RESET)
  246. {
  247. if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
  248. {
  249. LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
  250. return ERROR_TARGET_FAILURE;
  251. }
  252. else
  253. {
  254. target->debug_reason = DBG_REASON_DBGRQ;
  255. return ERROR_OK;
  256. }
  257. }
  258. avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBR);
  259. target->debug_reason = DBG_REASON_DBGRQ;
  260. return ERROR_OK;
  261. }
  262. static int avr32_ap7k_assert_reset(struct target *target)
  263. {
  264. LOG_ERROR("%s: implement me", __func__);
  265. return ERROR_OK;
  266. }
  267. static int avr32_ap7k_deassert_reset(struct target *target)
  268. {
  269. LOG_ERROR("%s: implement me", __func__);
  270. return ERROR_OK;
  271. }
  272. static int avr32_ap7k_soft_reset_halt(struct target *target)
  273. {
  274. LOG_ERROR("%s: implement me", __func__);
  275. return ERROR_OK;
  276. }
  277. static int avr32_ap7k_resume(struct target *target, int current,
  278. uint32_t address, int handle_breakpoints, int debug_execution)
  279. {
  280. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  281. struct breakpoint *breakpoint = NULL;
  282. uint32_t resume_pc;
  283. int retval;
  284. if (target->state != TARGET_HALTED)
  285. {
  286. LOG_WARNING("target not halted");
  287. return ERROR_TARGET_NOT_HALTED;
  288. }
  289. if (!debug_execution)
  290. {
  291. target_free_all_working_areas(target);
  292. /*
  293. avr32_ap7k_enable_breakpoints(target);
  294. avr32_ap7k_enable_watchpoints(target);
  295. */
  296. }
  297. /* current = 1: continue on current pc, otherwise continue at <address> */
  298. if (!current)
  299. {
  300. #if 0
  301. if (retval != ERROR_OK)
  302. return retval;
  303. #endif
  304. }
  305. resume_pc =
  306. buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32);
  307. avr32_ap7k_restore_context(target);
  308. /* the front-end may request us not to handle breakpoints */
  309. if (handle_breakpoints)
  310. {
  311. /* Single step past breakpoint at current address */
  312. if ((breakpoint = breakpoint_find(target, resume_pc)))
  313. {
  314. LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
  315. #if 0
  316. avr32_ap7k_unset_breakpoint(target, breakpoint);
  317. avr32_ap7k_single_step_core(target);
  318. avr32_ap7k_set_breakpoint(target, breakpoint);
  319. #endif
  320. }
  321. }
  322. #if 0
  323. /* enable interrupts if we are running */
  324. avr32_ap7k_enable_interrupts(target, !debug_execution);
  325. /* exit debug mode */
  326. mips_ejtag_exit_debug(ejtag_info);
  327. #endif
  328. retval = avr32_ocd_clearbits(&ap7k->jtag, AVR32_OCDREG_DC,
  329. OCDREG_DC_DBR);
  330. if (retval != ERROR_OK)
  331. return retval;
  332. retval = avr32_jtag_exec(&ap7k->jtag, RETD);
  333. if (retval != ERROR_OK)
  334. return retval;
  335. target->debug_reason = DBG_REASON_NOTHALTED;
  336. /* registers are now invalid */
  337. register_cache_invalidate(ap7k->core_cache);
  338. if (!debug_execution)
  339. {
  340. target->state = TARGET_RUNNING;
  341. target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
  342. LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
  343. }
  344. else
  345. {
  346. target->state = TARGET_DEBUG_RUNNING;
  347. target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
  348. LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
  349. }
  350. return ERROR_OK;
  351. }
  352. static int avr32_ap7k_step(struct target *target, int current,
  353. uint32_t address, int handle_breakpoints)
  354. {
  355. LOG_ERROR("%s: implement me", __func__);
  356. return ERROR_OK;
  357. }
  358. static int avr32_ap7k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
  359. {
  360. LOG_ERROR("%s: implement me", __func__);
  361. return ERROR_OK;
  362. }
  363. static int avr32_ap7k_remove_breakpoint(struct target *target,
  364. struct breakpoint *breakpoint)
  365. {
  366. LOG_ERROR("%s: implement me", __func__);
  367. return ERROR_OK;
  368. }
  369. static int avr32_ap7k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
  370. {
  371. LOG_ERROR("%s: implement me", __func__);
  372. return ERROR_OK;
  373. }
  374. static int avr32_ap7k_remove_watchpoint(struct target *target,
  375. struct watchpoint *watchpoint)
  376. {
  377. LOG_ERROR("%s: implement me", __func__);
  378. return ERROR_OK;
  379. }
  380. static int avr32_ap7k_read_memory(struct target *target, uint32_t address,
  381. uint32_t size, uint32_t count, uint8_t *buffer)
  382. {
  383. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  384. LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
  385. if (target->state != TARGET_HALTED)
  386. {
  387. LOG_WARNING("target not halted");
  388. return ERROR_TARGET_NOT_HALTED;
  389. }
  390. /* sanitize arguments */
  391. if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
  392. return ERROR_INVALID_ARGUMENTS;
  393. if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
  394. return ERROR_TARGET_UNALIGNED_ACCESS;
  395. switch (size)
  396. {
  397. case 4:
  398. return avr32_jtag_read_memory32(&ap7k->jtag, address, count, (uint32_t*)(void *)buffer);
  399. break;
  400. case 2:
  401. return avr32_jtag_read_memory16(&ap7k->jtag, address, count, (uint16_t*)(void *)buffer);
  402. break;
  403. case 1:
  404. return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer);
  405. break;
  406. default:
  407. break;
  408. }
  409. return ERROR_OK;
  410. }
  411. static int avr32_ap7k_write_memory(struct target *target, uint32_t address,
  412. uint32_t size, uint32_t count, const uint8_t *buffer)
  413. {
  414. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  415. LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
  416. if (target->state != TARGET_HALTED)
  417. {
  418. LOG_WARNING("target not halted");
  419. return ERROR_TARGET_NOT_HALTED;
  420. }
  421. /* sanitize arguments */
  422. if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
  423. return ERROR_INVALID_ARGUMENTS;
  424. if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
  425. return ERROR_TARGET_UNALIGNED_ACCESS;
  426. switch (size)
  427. {
  428. case 4:
  429. return avr32_jtag_write_memory32(&ap7k->jtag, address, count, (uint32_t*)(void *)buffer);
  430. break;
  431. case 2:
  432. return avr32_jtag_write_memory16(&ap7k->jtag, address, count, (uint16_t*)(void *)buffer);
  433. break;
  434. case 1:
  435. return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer);
  436. break;
  437. default:
  438. break;
  439. }
  440. return ERROR_OK;
  441. }
  442. static int avr32_ap7k_init_target(struct command_context *cmd_ctx,
  443. struct target *target)
  444. {
  445. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  446. ap7k->jtag.tap = target->tap;
  447. avr32_build_reg_cache(target);
  448. return ERROR_OK;
  449. }
  450. static int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp)
  451. {
  452. struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct
  453. avr32_ap7k_common));
  454. ap7k->common_magic = AP7k_COMMON_MAGIC;
  455. target->arch_info = ap7k;
  456. return ERROR_OK;
  457. }
  458. static int avr32_ap7k_examine(struct target *target)
  459. {
  460. uint32_t devid, ds;
  461. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  462. if (!target_was_examined(target))
  463. {
  464. target_set_examined(target);
  465. avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid);
  466. LOG_INFO("device id: %08x", devid);
  467. avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC,OCDREG_DC_DBE);
  468. avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);
  469. /* check for processor halted */
  470. if (ds & OCDREG_DS_DBA)
  471. {
  472. LOG_INFO("target is halted");
  473. target->state = TARGET_HALTED;
  474. }
  475. else
  476. target->state = TARGET_RUNNING;
  477. }
  478. return ERROR_OK;
  479. }
  480. static int avr32_ap7k_bulk_write_memory(struct target *target, uint32_t address,
  481. uint32_t count, const uint8_t *buffer)
  482. {
  483. LOG_ERROR("%s: implement me", __func__);
  484. return ERROR_OK;
  485. }
  486. int avr32_ap7k_arch_state(struct target *target)
  487. {
  488. struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
  489. LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
  490. debug_reason_name(target), ap7k->jtag.dpc);
  491. return ERROR_OK;
  492. }
  493. int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
  494. {
  495. #if 0
  496. /* get pointers to arch-specific information */
  497. int i;
  498. /* include floating point registers */
  499. *reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS;
  500. *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
  501. for (i = 0; i < AVR32NUMCOREREGS; i++)
  502. {
  503. (*reg_list)[i] = &mips32->core_cache->reg_list[i];
  504. }
  505. /* add dummy floating points regs */
  506. for (i = AVR32NUMCOREREGS; i < (AVR32NUMCOREREGS + AVR32NUMFPREGS); i++)
  507. {
  508. (*reg_list)[i] = &avr32_ap7k_gdb_dummy_fp_reg;
  509. }
  510. #endif
  511. LOG_ERROR("%s: implement me", __func__);
  512. return ERROR_FAIL;
  513. }
  514. struct target_type avr32_ap7k_target =
  515. {
  516. .name = "avr32_ap7k",
  517. .poll = avr32_ap7k_poll,
  518. .arch_state = avr32_ap7k_arch_state,
  519. .target_request_data = NULL,
  520. .halt = avr32_ap7k_halt,
  521. .resume = avr32_ap7k_resume,
  522. .step = avr32_ap7k_step,
  523. .assert_reset = avr32_ap7k_assert_reset,
  524. .deassert_reset = avr32_ap7k_deassert_reset,
  525. .soft_reset_halt = avr32_ap7k_soft_reset_halt,
  526. .get_gdb_reg_list = avr32_ap7k_get_gdb_reg_list,
  527. .read_memory = avr32_ap7k_read_memory,
  528. .write_memory = avr32_ap7k_write_memory,
  529. .bulk_write_memory = avr32_ap7k_bulk_write_memory,
  530. // .checksum_memory = avr32_ap7k_checksum_memory,
  531. // .blank_check_memory = avr32_ap7k_blank_check_memory,
  532. // .run_algorithm = avr32_ap7k_run_algorithm,
  533. .add_breakpoint = avr32_ap7k_add_breakpoint,
  534. .remove_breakpoint = avr32_ap7k_remove_breakpoint,
  535. .add_watchpoint = avr32_ap7k_add_watchpoint,
  536. .remove_watchpoint = avr32_ap7k_remove_watchpoint,
  537. .target_create = avr32_ap7k_target_create,
  538. .init_target = avr32_ap7k_init_target,
  539. .examine = avr32_ap7k_examine,
  540. };