target: add basic dsp563xx support
[openocd.git] / src / target / dsp563xx.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Mathias Kuester *
3 * mkdorg@users.sourceforge.net *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <helper/jim.h>
25
26 #include "target.h"
27 #include "target_type.h"
28 #include "register.h"
29 #include "dsp563xx.h"
30 #include "dsp563xx_once.h"
31
32 #define DSP563XX_JTAG_INS_LEN 4
33
34 #define JTAG_STATUS_NORMAL 0x01
35 #define JTAG_STATUS_STOPWAIT 0x05
36 #define JTAG_STATUS_BUSY 0x09
37 #define JTAG_STATUS_DEBUG 0x0d
38
39 #define JTAG_INSTR_EXTEST 0x00
40 #define JTAG_INSTR_SAMPLE_PRELOAD 0x01
41 #define JTAG_INSTR_IDCODE 0x02
42 #define JTAG_INSTR_CLAMP 0x03
43 #define JTAG_INSTR_HIZ 0x04
44 #define JTAG_INSTR_ENABLE_ONCE 0x06
45 #define JTAG_INSTR_DEBUG_REQUEST 0x07
46 #define JTAG_INSTR_BYPASS 0x0F
47
48 /* forward declarations */
49 int dsp563xx_target_create(struct target *target, Jim_Interp * interp);
50 int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target);
51
52 int dsp563xx_arch_state(struct target *target);
53 int dsp563xx_poll(struct target *target);
54 int dsp563xx_halt(struct target *target);
55 int dsp563xx_resume(struct target *target, int current, uint32_t address,
56 int handle_breakpoints, int debug_execution);
57 int dsp563xx_step(struct target *target, int current, uint32_t address,
58 int handle_breakpoints);
59
60 int dsp563xx_assert_reset(struct target *target);
61 int dsp563xx_deassert_reset(struct target *target);
62 int dsp563xx_soft_reset_halt(struct target *target);
63
64 /* IR and DR functions */
65 int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out);
66 int dsp563xx_jtag_senddat(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out,
67 int len);
68
69 int dsp563xx_read_memory_p(struct target *target, uint32_t address, uint32_t size,
70 uint32_t count, uint8_t * buffer);
71 int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint32_t size,
72 uint32_t count, uint8_t * buffer);
73
74 #define ASM_REG_R_R0 0x607000
75 #define ASM_REG_R_R1 0x617000
76 #define ASM_REG_R_R2 0x627000
77 #define ASM_REG_R_R3 0x637000
78 #define ASM_REG_R_R4 0x647000
79 #define ASM_REG_R_R5 0x657000
80 #define ASM_REG_R_R6 0x667000
81 #define ASM_REG_R_R7 0x677000
82
83 #define ASM_REG_W_R0 0x60F400
84 #define ASM_REG_W_R1 0x61F400
85 #define ASM_REG_W_R2 0x62F400
86 #define ASM_REG_W_R3 0x63F400
87 #define ASM_REG_W_R4 0x64F400
88 #define ASM_REG_W_R5 0x65F400
89 #define ASM_REG_W_R6 0x66F400
90 #define ASM_REG_W_R7 0x67F400
91
92 #define ASM_REG_R_N0 0x707000
93 #define ASM_REG_R_N1 0x717000
94 #define ASM_REG_R_N2 0x727000
95 #define ASM_REG_R_N3 0x737000
96 #define ASM_REG_R_N4 0x747000
97 #define ASM_REG_R_N5 0x757000
98 #define ASM_REG_R_N6 0x767000
99 #define ASM_REG_R_N7 0x777000
100
101 #define ASM_REG_W_N0 0x70F400
102 #define ASM_REG_W_N1 0x71F400
103 #define ASM_REG_W_N2 0x72F400
104 #define ASM_REG_W_N3 0x73F400
105 #define ASM_REG_W_N4 0x74F400
106 #define ASM_REG_W_N5 0x75F400
107 #define ASM_REG_W_N6 0x76F400
108 #define ASM_REG_W_N7 0x77F400
109
110 #define ASM_REG_R_M0 0x057020 /* control register m[0..7] */
111 #define ASM_REG_R_M1 0x057021
112 #define ASM_REG_R_M2 0x057022
113 #define ASM_REG_R_M3 0x057023
114 #define ASM_REG_R_M4 0x057024
115 #define ASM_REG_R_M5 0x057025
116 #define ASM_REG_R_M6 0x057026
117 #define ASM_REG_R_M7 0x057027
118
119 #define ASM_REG_W_M0 0x05F420
120 #define ASM_REG_W_M1 0x05F421
121 #define ASM_REG_W_M2 0x05F422
122 #define ASM_REG_W_M3 0x05F423
123 #define ASM_REG_W_M4 0x05F424
124 #define ASM_REG_W_M5 0x05F425
125 #define ASM_REG_W_M6 0x05F426
126 #define ASM_REG_W_M7 0x05F427
127
128 #define ASM_REG_R_X0 0x447000
129 #define ASM_REG_R_X1 0x457000
130
131 #define ASM_REG_W_X0 0x44F400
132 #define ASM_REG_W_X1 0x45F400
133
134 #define ASM_REG_R_Y0 0x467000
135 #define ASM_REG_R_Y1 0x477000
136
137 #define ASM_REG_W_Y0 0x46F400
138 #define ASM_REG_W_Y1 0x47F400
139
140 #define ASM_REG_R_A0 0x507000
141 #define ASM_REG_R_A1 0x547000
142 #define ASM_REG_R_A2 0x527000
143
144 #define ASM_REG_W_A0 0x50F400
145 #define ASM_REG_W_A1 0x54F400
146 #define ASM_REG_W_A2 0x52F400
147
148 #define ASM_REG_R_B0 0x517000
149 #define ASM_REG_R_B1 0x557000
150 #define ASM_REG_R_B2 0x537000
151
152 #define ASM_REG_W_B0 0x51F400
153 #define ASM_REG_W_B1 0x55F400
154 #define ASM_REG_W_B2 0x53F400
155
156 #define ASM_REG_R_VBA 0x057030 /* control register */
157 #define ASM_REG_W_VBA 0x05F430
158
159 #define ASM_REG_R_OMR 0x05703A /* control register */
160 #define ASM_REG_W_OMR 0x05F43A
161
162 #define ASM_REG_R_EP 0x05702A
163 #define ASM_REG_W_EP 0x05F42A
164
165 #define ASM_REG_R_SC 0x057031 /* stack counter */
166 #define ASM_REG_W_SC 0x05F431
167
168 #define ASM_REG_R_SZ 0x057038 /* stack size */
169 #define ASM_REG_W_SZ 0x05F438
170
171 #define ASM_REG_R_SR 0x057039 /* control register, status register */
172 #define ASM_REG_W_SR 0x05F439
173
174 #define ASM_REG_R_SP 0x05703B /* control register, stack pointer */
175 #define ASM_REG_W_SP 0x05F43B
176
177 #define ASM_REG_R_SSH 0x05703C /* control register, system stack high */
178 #define ASM_REG_W_SSH 0x05743C
179
180 #define ASM_REG_R_SSL 0x05703D /* control register, system stack low */
181 #define ASM_REG_W_SSL 0x05F43D
182
183 #define ASM_REG_R_LA 0x05703E /* control register, loop address */
184 #define ASM_REG_W_LA 0x05F43E
185
186 #define ASM_REG_R_LC 0x05703F /* control register, loop count */
187 #define ASM_REG_W_LC 0x05F43F
188
189 #define ASM_REG_R_PC 0x000000
190 #define ASM_REG_W_PC 0x000000
191
192 static const struct
193 {
194 unsigned id;
195 char *name;
196 unsigned bits;
197 uint32_t r_cmd;
198 uint32_t w_cmd;
199 } dsp563xx_regs[] =
200 {
201 /* *INDENT-OFF* */
202 {0, "r0", 24, ASM_REG_R_R0, ASM_REG_W_R0},
203 {1, "r1", 24, ASM_REG_R_R1, ASM_REG_W_R1},
204 {2, "r2", 24, ASM_REG_R_R2, ASM_REG_W_R2},
205 {3, "r3", 24, ASM_REG_R_R3, ASM_REG_W_R3},
206 {4, "r4", 24, ASM_REG_R_R4, ASM_REG_W_R4},
207 {5, "r5", 24, ASM_REG_R_R5, ASM_REG_W_R5},
208 {6, "r6", 24, ASM_REG_R_R6, ASM_REG_W_R6},
209 {7, "r7", 24, ASM_REG_R_R7, ASM_REG_W_R7},
210 {8, "n0", 24, ASM_REG_R_N0, ASM_REG_W_N0},
211 {9, "n1", 24, ASM_REG_R_N1, ASM_REG_W_N1},
212 {10, "n2", 24, ASM_REG_R_N2, ASM_REG_W_N2},
213 {11, "n3", 24, ASM_REG_R_N3, ASM_REG_W_N3},
214 {12, "n4", 24, ASM_REG_R_N4, ASM_REG_W_N4},
215 {13, "n5", 24, ASM_REG_R_N5, ASM_REG_W_N5},
216 {14, "n6", 24, ASM_REG_R_N6, ASM_REG_W_N6},
217 {15, "n7", 24, ASM_REG_R_N7, ASM_REG_W_N7},
218 {16, "m0", 24, ASM_REG_R_M0, ASM_REG_W_M0},
219 {17, "m1", 24, ASM_REG_R_M1, ASM_REG_W_M1},
220 {18, "m2", 24, ASM_REG_R_M2, ASM_REG_W_M2},
221 {19, "m3", 24, ASM_REG_R_M3, ASM_REG_W_M3},
222 {20, "m4", 24, ASM_REG_R_M4, ASM_REG_W_M4},
223 {21, "m5", 24, ASM_REG_R_M5, ASM_REG_W_M5},
224 {22, "m6", 24, ASM_REG_R_M6, ASM_REG_W_M6},
225 {23, "m7", 24, ASM_REG_R_M7, ASM_REG_W_M7},
226 {24, "x0", 24, ASM_REG_R_X0, ASM_REG_W_X0},
227 {25, "x1", 24, ASM_REG_R_X1, ASM_REG_W_X1},
228 {26, "y0", 24, ASM_REG_R_Y0, ASM_REG_W_Y0},
229 {27, "y1", 24, ASM_REG_R_Y1, ASM_REG_W_Y1},
230 {28, "a0", 24, ASM_REG_R_A0, ASM_REG_W_A0},
231 {29, "a1", 24, ASM_REG_R_A1, ASM_REG_W_A1},
232 {30, "a2", 8, ASM_REG_R_A2, ASM_REG_W_A2},
233 {31, "b0", 24, ASM_REG_R_B0, ASM_REG_W_B0},
234 {32, "b1", 24, ASM_REG_R_B1, ASM_REG_W_B1},
235 {33, "b2", 8, ASM_REG_R_B2, ASM_REG_W_B2},
236 {34, "omr", 24, ASM_REG_R_OMR, ASM_REG_W_OMR},
237 {35, "vba", 24, ASM_REG_R_VBA, ASM_REG_W_VBA},
238 {36, "ep", 24, ASM_REG_R_EP, ASM_REG_W_EP},
239 {37, "sc", 24, ASM_REG_R_SC, ASM_REG_W_SC},
240 {38, "sz", 24, ASM_REG_R_SZ, ASM_REG_W_SZ},
241 {39, "sr", 24, ASM_REG_R_SR, ASM_REG_W_SR},
242 {40, "sp", 24, ASM_REG_R_SP, ASM_REG_W_SP},
243 {41, "la", 24, ASM_REG_R_LA, ASM_REG_W_LA},
244 {42, "lc", 24, ASM_REG_R_LC, ASM_REG_W_LC},
245 {43, "pc", 24, ASM_REG_R_PC, ASM_REG_W_PC}
246 /* *INDENT-ON* */
247 };
248
249 int dsp563xx_read_core_reg(struct target *target, int num)
250 {
251 uint32_t reg_value;
252 struct dsp563xx_core_reg *dsp563xx_core_reg;
253 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
254
255 if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
256 return ERROR_INVALID_ARGUMENTS;
257
258 dsp563xx_core_reg = dsp563xx->core_cache->reg_list[num].arch_info;
259 reg_value = dsp563xx->core_regs[num];
260 buf_set_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32, reg_value);
261 dsp563xx->core_cache->reg_list[num].valid = 1;
262 dsp563xx->core_cache->reg_list[num].dirty = 0;
263
264 return ERROR_OK;
265 }
266
267 int dsp563xx_write_core_reg(struct target *target, int num)
268 {
269 uint32_t reg_value;
270 struct dsp563xx_core_reg *dsp563xx_core_reg;
271 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
272
273 if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
274 return ERROR_INVALID_ARGUMENTS;
275
276 reg_value = buf_get_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32);
277 dsp563xx_core_reg = dsp563xx->core_cache->reg_list[num].arch_info;
278 dsp563xx->core_regs[num] = reg_value;
279 dsp563xx->core_cache->reg_list[num].valid = 1;
280 dsp563xx->core_cache->reg_list[num].dirty = 0;
281
282 return ERROR_OK;
283 }
284
285 int dsp563xx_target_create(struct target *target, Jim_Interp * interp)
286 {
287 struct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common));
288
289 dsp563xx->jtag_info.tap = target->tap;
290 target->arch_info = dsp563xx;
291 dsp563xx->read_core_reg = dsp563xx_read_core_reg;
292 dsp563xx->write_core_reg = dsp563xx_write_core_reg;
293
294 return ERROR_OK;
295 }
296
297 int dsp563xx_get_core_reg(struct reg *reg)
298 {
299 int retval = 0;
300
301 LOG_DEBUG("%s", __FUNCTION__);
302
303 struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;
304 struct target *target = dsp563xx_reg->target;
305 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
306
307 if (target->state != TARGET_HALTED)
308 {
309 return ERROR_TARGET_NOT_HALTED;
310 }
311
312 retval = dsp563xx->read_core_reg(target, dsp563xx_reg->num);
313
314 return retval;
315 }
316
317 int dsp563xx_set_core_reg(struct reg *reg, uint8_t * buf)
318 {
319 LOG_DEBUG("%s", __FUNCTION__);
320
321 struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;
322 struct target *target = dsp563xx_reg->target;
323 uint32_t value = buf_get_u32(buf, 0, 32);
324
325 if (target->state != TARGET_HALTED)
326 {
327 return ERROR_TARGET_NOT_HALTED;
328 }
329
330 buf_set_u32(reg->value, 0, reg->size, value);
331 reg->dirty = 1;
332 reg->valid = 1;
333
334 return ERROR_OK;
335 }
336
337 int dsp563xx_save_context(struct target *target)
338 {
339 int i;
340 uint32_t data = 0;
341 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
342 struct dsp563xx_core_reg *arch_info;
343
344 for (i = 0; i < DSP563XX_NUMCOREREGS - 1; i++)
345 {
346
347 // if (!dsp563xx->core_cache->reg_list[i].valid)
348 {
349 arch_info = dsp563xx->core_cache->reg_list[i].arch_info;
350 dsp563xx_once_execute_dw_ir(target->tap, arch_info->r_cmd,
351 0xfffffc);
352 dsp563xx_once_execute_sw_ir(target->tap, 0x000000);
353 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR,
354 &data);
355 dsp563xx->core_regs[i] = data;
356 dsp563xx->read_core_reg(target, i);
357 }
358 }
359
360 /* read pc */
361 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABEX, &data);
362 dsp563xx->core_regs[i] = data;
363 dsp563xx->read_core_reg(target, i);
364
365 return ERROR_OK;
366 }
367
368 int dsp563xx_restore_context(struct target *target)
369 {
370 int i;
371 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
372 struct dsp563xx_core_reg *arch_info;
373
374 for (i = 0; i < DSP563XX_NUMCOREREGS - 1; i++)
375 {
376 if (dsp563xx->core_cache->reg_list[i].dirty)
377 {
378 arch_info = dsp563xx->core_cache->reg_list[i].arch_info;
379
380 dsp563xx->write_core_reg(target, i);
381
382 dsp563xx_once_execute_dw_ir(target->tap, arch_info->w_cmd,
383 dsp563xx->core_regs[i]);
384 dsp563xx_once_execute_sw_ir(target->tap, 0x000000);
385 }
386 }
387
388 return ERROR_OK;
389 }
390
391 static const struct reg_arch_type dsp563xx_reg_type = {
392 .get = dsp563xx_get_core_reg,
393 .set = dsp563xx_set_core_reg,
394 };
395
396 int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target)
397 {
398 /* get pointers to arch-specific information */
399 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
400
401 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
402 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
403 struct reg *reg_list = malloc(sizeof(struct reg) * DSP563XX_NUMCOREREGS);
404 struct dsp563xx_core_reg *arch_info =
405 malloc(sizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS);
406 int i;
407
408 LOG_DEBUG("%s", __FUNCTION__);
409
410 /* Build the process context cache */
411 cache->name = "dsp563xx registers";
412 cache->next = NULL;
413 cache->reg_list = reg_list;
414 cache->num_regs = DSP563XX_NUMCOREREGS;
415 (*cache_p) = cache;
416 dsp563xx->core_cache = cache;
417
418 for (i = 0; i < DSP563XX_NUMCOREREGS; i++)
419 {
420 arch_info[i].num = dsp563xx_regs[i].id;
421 arch_info[i].name = dsp563xx_regs[i].name;
422 arch_info[i].size = dsp563xx_regs[i].bits;
423 arch_info[i].r_cmd = dsp563xx_regs[i].r_cmd;
424 arch_info[i].w_cmd = dsp563xx_regs[i].w_cmd;
425 arch_info[i].target = target;
426 arch_info[i].dsp563xx_common = dsp563xx;
427 reg_list[i].name = dsp563xx_regs[i].name;
428 reg_list[i].size = dsp563xx_regs[i].bits;
429 reg_list[i].value = calloc(1, 4);
430 reg_list[i].dirty = 0;
431 reg_list[i].valid = 0;
432 reg_list[i].type = &dsp563xx_reg_type;
433 reg_list[i].arch_info = &arch_info[i];
434 }
435
436 return ERROR_OK;
437 }
438
439 int dsp563xx_arch_state(struct target *target)
440 {
441 LOG_DEBUG("%s", __FUNCTION__);
442 return ERROR_OK;
443 }
444
445 int dsp563xx_jtag_status(struct target *target, uint8_t * status)
446 {
447 uint8_t ir_in;
448
449 ir_in = 0;
450
451 dsp563xx_jtag_sendinstr(target->tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
452 dsp563xx_execute_queue();
453
454 *status = ir_in;
455
456 return ERROR_OK;
457 }
458
459 int dsp563xx_jtag_debug_request(struct target *target)
460 {
461 uint8_t ir_in = 0;
462 uint32_t retry = 0;
463
464 while (ir_in != JTAG_STATUS_DEBUG)
465 {
466 dsp563xx_jtag_sendinstr(target->tap, &ir_in,
467 JTAG_INSTR_DEBUG_REQUEST);
468 dsp563xx_execute_queue();
469 LOG_DEBUG("JTAG CMD 7 res: %02X", ir_in);
470 dsp563xx_jtag_sendinstr(target->tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
471 dsp563xx_execute_queue();
472 LOG_DEBUG("JTAG CMD 6 res: %02X", ir_in);
473
474 if (retry++ == 100)
475 return ERROR_TARGET_FAILURE;
476 }
477
478 if (ir_in != JTAG_STATUS_DEBUG)
479 {
480 return ERROR_TARGET_FAILURE;
481 }
482
483 return ERROR_OK;
484 }
485
486 int dsp563xx_poll(struct target *target)
487 {
488 uint8_t jtag_status;
489 uint32_t once_status;
490
491 dsp563xx_jtag_status(target, &jtag_status);
492
493 if ((jtag_status & 1) != 1)
494 {
495 target->state = TARGET_UNKNOWN;
496 LOG_ERROR
497 ("jtag status contains invalid mode value - communication failure");
498 return ERROR_TARGET_FAILURE;
499 }
500
501 if (jtag_status != JTAG_STATUS_DEBUG)
502 {
503 target->state = TARGET_RUNNING;
504 }
505
506 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR, &once_status);
507
508 if ((once_status & DSP563XX_ONCE_OSCR_DEBUG_M) == DSP563XX_ONCE_OSCR_DEBUG_M)
509 {
510 target->state = TARGET_HALTED;
511
512 }
513
514 return ERROR_OK;
515 }
516
517 int dsp563xx_halt(struct target *target)
518 {
519 uint8_t jtag_status;
520 uint32_t once_status;
521 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
522
523 if (target->state == TARGET_HALTED)
524 {
525 LOG_DEBUG("target was already halted");
526 return ERROR_OK;
527 }
528
529 if (target->state == TARGET_UNKNOWN)
530 {
531 LOG_WARNING("target was in unknown state when halt was requested");
532 }
533
534 // if ( jtag_status != 0x0d )
535 {
536 dsp563xx_jtag_debug_request(target);
537
538 /* store pipeline register */
539 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPILR,
540 &dsp563xx->pipeline_context.once_opilr);
541 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPDBR,
542 &dsp563xx->pipeline_context.once_opdbr);
543
544 dsp563xx_save_context(target);
545
546 dsp563xx_jtag_status(target, &jtag_status);
547 LOG_DEBUG("%02X", jtag_status);
548 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR,
549 &once_status);
550 LOG_DEBUG("%02X", once_status);
551 }
552
553 LOG_DEBUG("target->state: %s", target_state_name(target));
554
555 LOG_DEBUG("%s", __FUNCTION__);
556
557 return ERROR_OK;
558 }
559
560 #define DSP563XX_ASM_CMD_JUMP 0x0AF080
561
562 int dsp563xx_resume(struct target *target, int current, uint32_t address,
563 int handle_breakpoints, int debug_execution)
564 {
565 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
566
567 LOG_DEBUG("%s", __FUNCTION__);
568
569 dsp563xx_restore_context(target);
570
571 if (current)
572 {
573 /* restore pipeline registers and go */
574 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPILR,
575 dsp563xx->pipeline_context.once_opilr);
576 dsp563xx_once_reg_write(target->tap,
577 DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX |
578 DSP563XX_ONCE_OCR_GO,
579 dsp563xx->pipeline_context.once_opdbr);
580 }
581 else
582 {
583 /* set to go register and jump */
584 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR,
585 DSP563XX_ASM_CMD_JUMP);
586 dsp563xx_once_reg_write(target->tap,
587 DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX
588 | DSP563XX_ONCE_OCR_GO, address);
589 }
590
591 target->state = TARGET_RUNNING;
592
593 return ERROR_OK;
594 }
595
596 int dsp563xx_step(struct target *target, int current, uint32_t address,
597 int handle_breakpoints)
598 {
599 uint32_t once_status;
600 uint32_t dr_in, cnt;
601 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
602
603 if (target->state != TARGET_HALTED)
604 {
605 LOG_DEBUG("target was not halted");
606 return ERROR_OK;
607 }
608
609 LOG_DEBUG("%s %08X %08X", __FUNCTION__, current, address);
610
611 dsp563xx_jtag_debug_request(target);
612
613 dsp563xx_restore_context(target);
614
615 /* reset trace mode */
616 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR, 0x000000);
617 /* enable trace mode */
618 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR,
619 DSP563XX_ONCE_OSCR_TME);
620
621 cnt = 0;
622
623 /* on JUMP we need one extra cycle */
624 if (!current)
625 cnt++;
626
627 /* load step counter with N-1 */
628 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OTC, cnt);
629
630 if (current)
631 {
632 /* restore pipeline registers and go */
633 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPILR,
634 dsp563xx->pipeline_context.once_opilr);
635 dsp563xx_once_reg_write(target->tap,
636 DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX |
637 DSP563XX_ONCE_OCR_GO,
638 dsp563xx->pipeline_context.once_opdbr);
639 }
640 else
641 {
642 /* set to go register and jump */
643 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR,
644 DSP563XX_ASM_CMD_JUMP);
645 dsp563xx_once_reg_write(target->tap,
646 DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX
647 | DSP563XX_ONCE_OCR_GO, address);
648 }
649
650 while (1)
651 {
652 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR,
653 &once_status);
654
655 if (once_status & DSP563XX_ONCE_OSCR_TO)
656 {
657 /* store pipeline register */
658 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPILR,
659 &dsp563xx->pipeline_context.
660 once_opilr);
661 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPDBR,
662 &dsp563xx->pipeline_context.
663 once_opdbr);
664
665 dsp563xx_save_context(target);
666
667 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABFR,
668 &dr_in);
669 LOG_DEBUG("%08X", dr_in);
670 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABDR,
671 &dr_in);
672 LOG_DEBUG("%08X", dr_in);
673 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABEX,
674 &dr_in);
675 LOG_DEBUG("%08X", dr_in);
676
677 /* reset trace mode */
678 dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR,
679 0x000000);
680
681 break;
682 }
683 }
684
685 return ERROR_OK;
686 }
687
688 int dsp563xx_assert_reset(struct target *target)
689 {
690 target->state = TARGET_RESET;
691
692 LOG_DEBUG("%s", __FUNCTION__);
693 return ERROR_OK;
694 }
695
696 int dsp563xx_deassert_reset(struct target *target)
697 {
698 target->state = TARGET_RUNNING;
699
700 LOG_DEBUG("%s", __FUNCTION__);
701 return ERROR_OK;
702 }
703
704 int dsp563xx_soft_reset_halt(struct target *target)
705 {
706 LOG_DEBUG("%s", __FUNCTION__);
707 return ERROR_OK;
708 }
709
710 /*
711 * 000000 nop
712 * 46F400 AABBCC move #$aabbcc,y0
713 * 60F400 AABBCC move #$aabbcc,r0
714 * 467000 AABBCC move y0,x:AABBCC
715 * 607000 AABBCC move r0,x:AABBCC
716
717 * 46E000 move x:(r0),y0
718 * 4EE000 move y:(r0),y0
719 * 07E086 move p:(r0),y0
720
721 * 0450B9 move sr,r0
722 * 0446BA move omr,y0
723 * 0446BC move ssh,y0
724 * 0446BD move ssl,y0
725 * 0446BE move la,y0
726 * 0446BF move lc,y0
727 *
728 * 61F000 AABBCC move x:AABBCC,r1
729 * 076190 movem r0,p:(r1)
730 *
731 */
732 int dsp563xx_read_memory_p(struct target *target, uint32_t address,
733 uint32_t size, uint32_t count, uint8_t * buffer)
734 {
735 uint32_t i, x;
736 uint32_t data;
737 uint8_t *b;
738
739 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8"
740 PRIx32, address, size, count);
741
742 if (target->state != TARGET_HALTED)
743 {
744 LOG_WARNING("target not halted");
745 return ERROR_TARGET_NOT_HALTED;
746 }
747
748 x = count;
749
750 for (i = 0; i < x; i++)
751 {
752 dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, address + i);
753 dsp563xx_once_execute_sw_ir_nq(target->tap, 0x07E086);
754 dsp563xx_once_execute_dw_ir_nq(target->tap, 0x467000, 0xfffffc);
755 dsp563xx_execute_queue();
756
757 dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR, &data);
758
759 b = buffer + 4 * i;
760 if (size > 0)
761 *b++ = data >> 0;
762 if (size > 1)
763 *b++ = data >> 8;
764 if (size > 2)
765 *b++ = data >> 16;
766 if (size > 3)
767 *b++ = 0x00;
768 }
769
770 return ERROR_OK;
771 }
772
773 int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint32_t size,
774 uint32_t count, uint8_t * buffer)
775 {
776 uint32_t i, x;
777 uint32_t data;
778 uint8_t *b;
779
780 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8"
781 PRIx32 "", address, size, count);
782
783 if (target->state != TARGET_HALTED)
784 {
785 LOG_WARNING("target not halted");
786 return ERROR_TARGET_NOT_HALTED;
787 }
788
789 x = count;
790
791 for (i = 0; i < x; i++)
792 {
793 b = buffer + 4 * i;
794
795 data = 0;
796 if (size > 0)
797 data = *buffer++;
798 if (size > 1)
799 data |= (*buffer++) << 8;
800 if (size > 2)
801 data |= (*buffer++) << 16;
802 if (size > 3)
803 data |= (*buffer++) << 24;
804
805 // LOG_DEBUG("%08X", data);
806
807 dsp563xx_once_execute_dw_ir_nq(target->tap, 0x61F400, address + i);
808 dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, data);
809 dsp563xx_once_execute_sw_ir_nq(target->tap, 0x076190);
810 dsp563xx_execute_queue();
811 }
812
813 return ERROR_OK;
814 }
815
816 int dsp563xx_jtag_senddat(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out,
817 int len)
818 {
819 return dsp563xx_write_dr_u32(tap, dr_in, dr_out, len, 1);
820 }
821
822 int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out)
823 {
824 return dsp563xx_write_ir_u8(tap, ir_in, ir_out, DSP563XX_JTAG_INS_LEN, 1);
825 }
826
827 /* IR and DR functions */
828 int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out,
829 int ir_len, int rti)
830 {
831 if (NULL == tap)
832 {
833 LOG_ERROR("invalid tap");
834 return ERROR_FAIL;
835 }
836 if (ir_len != tap->ir_length)
837 {
838 LOG_ERROR("invalid ir_len");
839 return ERROR_FAIL;
840 }
841
842 {
843 struct scan_field field[1];
844
845 field[0].tap = tap;
846 field[0].num_bits = tap->ir_length;
847 field[0].out_value = ir_out;
848 field[0].in_value = ir_in;
849 jtag_add_plain_ir_scan(ARRAY_SIZE(field), field,
850 jtag_set_end_state(TAP_IDLE));
851 }
852
853 return ERROR_OK;
854 }
855
856 int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out,
857 int dr_len, int rti)
858 {
859 if (NULL == tap)
860 {
861 LOG_ERROR("invalid tap");
862 return ERROR_FAIL;
863 }
864
865 {
866 struct scan_field field[1];
867
868 field[0].tap = tap;
869 field[0].num_bits = dr_len;
870 field[0].out_value = dr_out;
871 field[0].in_value = dr_in;
872 jtag_add_plain_dr_scan(ARRAY_SIZE(field), field,
873 jtag_set_end_state(TAP_IDLE));
874 }
875
876 return ERROR_OK;
877 }
878
879 int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out,
880 int ir_len, int rti)
881 {
882 if (ir_len > 8)
883 {
884 LOG_ERROR("ir_len overflow, maxium is 8");
885 return ERROR_FAIL;
886 }
887
888 dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);
889
890 return ERROR_OK;
891 }
892
893 int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out,
894 int dr_len, int rti)
895 {
896 if (dr_len > 8)
897 {
898 LOG_ERROR("dr_len overflow, maxium is 8");
899 return ERROR_FAIL;
900 }
901
902 dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti);
903
904 return ERROR_OK;
905 }
906
907 int dsp563xx_write_ir_u16(struct jtag_tap *tap, uint16_t * ir_in, uint16_t ir_out,
908 int ir_len, int rti)
909 {
910 if (ir_len > 16)
911 {
912 LOG_ERROR("ir_len overflow, maxium is 16");
913 return ERROR_FAIL;
914 }
915
916 dsp563xx_write_ir(tap, (uint8_t *) ir_in, (uint8_t *) & ir_out, ir_len, rti);
917
918 return ERROR_OK;
919 }
920
921 int dsp563xx_write_dr_u16(struct jtag_tap *tap, uint16_t * dr_in, uint16_t dr_out,
922 int dr_len, int rti)
923 {
924 if (dr_len > 16)
925 {
926 LOG_ERROR("dr_len overflow, maxium is 16");
927 return ERROR_FAIL;
928 }
929
930 dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) & dr_out, dr_len, rti);
931
932 return ERROR_OK;
933 }
934
935 int dsp563xx_write_ir_u32(struct jtag_tap *tap, uint32_t * ir_in, uint32_t ir_out,
936 int ir_len, int rti)
937 {
938 if (ir_len > 32)
939 {
940 LOG_ERROR("ir_len overflow, maxium is 32");
941 return ERROR_FAIL;
942 }
943
944 dsp563xx_write_ir(tap, (uint8_t *) ir_in, (uint8_t *) & ir_out, ir_len, rti);
945
946 return ERROR_OK;
947 }
948
949 int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out,
950 int dr_len, int rti)
951 {
952 if (dr_len > 32)
953 {
954 LOG_ERROR("dr_len overflow, maxium is 32");
955 return ERROR_FAIL;
956 }
957
958 dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) & dr_out, dr_len, rti);
959
960 return ERROR_OK;
961 }
962
963 int dsp563xx_execute_queue(void)
964 {
965 return jtag_execute_queue();
966 }
967
968 /** Holds methods for DSP563XX targets. */
969 struct target_type dsp563xx_target = {
970 .name = "dsp563xx",
971
972 .poll = dsp563xx_poll,
973 .arch_state = dsp563xx_arch_state,
974
975 .target_request_data = NULL,
976
977 .halt = dsp563xx_halt,
978 .resume = dsp563xx_resume,
979 .step = dsp563xx_step,
980
981 .assert_reset = dsp563xx_assert_reset,
982 .deassert_reset = dsp563xx_deassert_reset,
983 .soft_reset_halt = dsp563xx_soft_reset_halt,
984
985 .read_memory = dsp563xx_read_memory_p,
986 .write_memory = dsp563xx_write_memory_p,
987
988 .target_create = dsp563xx_target_create,
989 .init_target = dsp563xx_init_target,
990 };