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