]> git.sur5r.net Git - openocd/blob - src/target/dsp563xx.c
warnings: use more 'const' for char *
[openocd] / 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         const 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 };