MIPS: remove unused arg from mips_ejtag_set_instr
[openocd.git] / src / target / mips32_pracc.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
4 * *
5 * Copyright (C) 2008 by David T.L. Wong *
6 * *
7 * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 ***************************************************************************/
24
25 /*
26 This version has optimized assembly routines for 32 bit operations:
27 - read word
28 - write word
29 - write array of words
30
31 One thing to be aware of is that the MIPS32 cpu will execute the
32 instruction after a branch instruction (one delay slot).
33
34 For example:
35
36 LW $2, ($5 +10)
37 B foo
38 LW $1, ($2 +100)
39
40 The LW $1, ($2 +100) instruction is also executed. If this is
41 not wanted a NOP can be inserted:
42
43 LW $2, ($5 +10)
44 B foo
45 NOP
46 LW $1, ($2 +100)
47
48 or the code can be changed to:
49
50 B foo
51 LW $2, ($5 +10)
52 LW $1, ($2 +100)
53
54 The original code contained NOPs. I have removed these and moved
55 the branches.
56
57 I also moved the PRACC_STACK to 0xFF204000. This allows
58 the use of 16 bits offsets to get pointers to the input
59 and output area relative to the stack. Note that the stack
60 isn't really a stack (the stack pointer is not 'moving')
61 but a FIFO simulated in software.
62
63 These changes result in a 35% speed increase when programming an
64 external flash.
65
66 More improvement could be gained if the registers do no need
67 to be preserved but in that case the routines should be aware
68 OpenOCD is used as a flash programmer or as a debug tool.
69
70 Nico Coesel
71 */
72
73 #ifdef HAVE_CONFIG_H
74 #include "config.h"
75 #endif
76
77 #include "mips32.h"
78 #include "mips32_pracc.h"
79
80 struct mips32_pracc_context
81 {
82 uint32_t *local_iparam;
83 int num_iparam;
84 uint32_t *local_oparam;
85 int num_oparam;
86 const uint32_t *code;
87 int code_len;
88 uint32_t stack[32];
89 int stack_offset;
90 struct mips_ejtag *ejtag_info;
91 };
92
93 static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
94 {
95 uint32_t ejtag_ctrl;
96
97 while (1)
98 {
99 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
100 ejtag_ctrl = ejtag_info->ejtag_ctrl;
101 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
102 if (ejtag_ctrl & EJTAG_CTRL_PRACC)
103 break;
104 LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
105 return ERROR_JTAG_DEVICE_ERROR;
106 }
107
108 *ctrl = ejtag_ctrl;
109 return ERROR_OK;
110 }
111
112 static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t address)
113 {
114 struct mips_ejtag *ejtag_info = ctx->ejtag_info;
115 int offset;
116 uint32_t ejtag_ctrl, data;
117
118 if ((address >= MIPS32_PRACC_PARAM_IN)
119 && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
120 {
121 offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
122 data = ctx->local_iparam[offset];
123 }
124 else if ((address >= MIPS32_PRACC_PARAM_OUT)
125 && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
126 {
127 offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
128 data = ctx->local_oparam[offset];
129 }
130 else if ((address >= MIPS32_PRACC_TEXT)
131 && (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4))
132 {
133 offset = (address - MIPS32_PRACC_TEXT) / 4;
134 data = ctx->code[offset];
135 }
136 else if (address == MIPS32_PRACC_STACK)
137 {
138 /* save to our debug stack */
139 data = ctx->stack[--ctx->stack_offset];
140 }
141 else
142 {
143 /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
144 * to start of debug vector */
145
146 data = 0;
147 LOG_ERROR("Error reading unexpected address 0x%8.8" PRIx32 "", address);
148 return ERROR_JTAG_DEVICE_ERROR;
149 }
150
151 /* Send the data out */
152 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
153 mips_ejtag_drscan_32(ctx->ejtag_info, &data);
154
155 /* Clear the access pending bit (let the processor eat!) */
156 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
157 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
158 mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
159
160 jtag_add_clocks(5);
161 jtag_execute_queue();
162
163 return ERROR_OK;
164 }
165
166 static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t address)
167 {
168 uint32_t ejtag_ctrl,data;
169 int offset;
170 struct mips_ejtag *ejtag_info = ctx->ejtag_info;
171
172 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
173 mips_ejtag_drscan_32(ctx->ejtag_info, &data);
174
175 /* Clear access pending bit */
176 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
177 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
178 mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
179
180 jtag_add_clocks(5);
181 jtag_execute_queue();
182
183 if ((address >= MIPS32_PRACC_PARAM_IN)
184 && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
185 {
186 offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
187 ctx->local_iparam[offset] = data;
188 }
189 else if ((address >= MIPS32_PRACC_PARAM_OUT)
190 && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
191 {
192 offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
193 ctx->local_oparam[offset] = data;
194 }
195 else if (address == MIPS32_PRACC_STACK)
196 {
197 /* save data onto our stack */
198 ctx->stack[ctx->stack_offset++] = data;
199 }
200 else
201 {
202 LOG_ERROR("Error writing unexpected address 0x%8.8" PRIx32 "", address);
203 return ERROR_JTAG_DEVICE_ERROR;
204 }
205
206 return ERROR_OK;
207 }
208
209 int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_t *code,
210 int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle)
211 {
212 uint32_t ejtag_ctrl;
213 uint32_t address, data;
214 struct mips32_pracc_context ctx;
215 int retval;
216 int pass = 0;
217
218 ctx.local_iparam = param_in;
219 ctx.local_oparam = param_out;
220 ctx.num_iparam = num_param_in;
221 ctx.num_oparam = num_param_out;
222 ctx.code = code;
223 ctx.code_len = code_len;
224 ctx.ejtag_info = ejtag_info;
225 ctx.stack_offset = 0;
226
227 while (1)
228 {
229 if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
230 return retval;
231
232 address = data = 0;
233 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
234 mips_ejtag_drscan_32(ejtag_info, &address);
235
236 /* Check for read or write */
237 if (ejtag_ctrl & EJTAG_CTRL_PRNW)
238 {
239 if ((retval = mips32_pracc_exec_write(&ctx, address)) != ERROR_OK)
240 return retval;
241 }
242 else
243 {
244 /* Check to see if its reading at the debug vector. The first pass through
245 * the module is always read at the vector, so the first one we allow. When
246 * the second read from the vector occurs we are done and just exit. */
247 if ((address == MIPS32_PRACC_TEXT) && (pass++))
248 {
249 break;
250 }
251
252 if ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK)
253 return retval;
254 }
255
256 if (cycle == 0)
257 break;
258 }
259
260 /* stack sanity check */
261 if (ctx.stack_offset != 0)
262 {
263 LOG_DEBUG("Pracc Stack not zero");
264 }
265
266 return ERROR_OK;
267 }
268
269 int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
270 {
271 switch (size)
272 {
273 case 1:
274 return mips32_pracc_read_mem8(ejtag_info, addr, count, (uint8_t*)buf);
275 case 2:
276 return mips32_pracc_read_mem16(ejtag_info, addr, count, (uint16_t*)buf);
277 case 4:
278 if (count == 1)
279 return mips32_pracc_read_u32(ejtag_info, addr, (uint32_t*)buf);
280 else
281 return mips32_pracc_read_mem32(ejtag_info, addr, count, (uint32_t*)buf);
282 }
283
284 return ERROR_OK;
285 }
286
287 int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
288 {
289 static const uint32_t code[] = {
290 /* start: */
291 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
292 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
293 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
294 MIPS32_SW(8,0,15), /* sw $8,($15) */
295 MIPS32_SW(9,0,15), /* sw $9,($15) */
296 MIPS32_SW(10,0,15), /* sw $10,($15) */
297 MIPS32_SW(11,0,15), /* sw $11,($15) */
298
299 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
300 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
301 MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */
302 MIPS32_LW(10,4,8), /* $10 = mem[$8 + 4]; read count */
303 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11 = MIPS32_PRACC_PARAM_OUT */
304 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
305 /* loop: */
306 MIPS32_BEQ(0,10,8), /* beq 0, $10, end */
307 MIPS32_NOP,
308
309 MIPS32_LW(8,0,9), /* lw $8,0($9), Load $8 with the word @mem[$9] */
310 MIPS32_SW(8,0,11), /* sw $8,0($11) */
311
312 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
313 MIPS32_ADDI(9,9,4), /* $1 += 4 */
314 MIPS32_ADDI(11,11,4), /* $11 += 4 */
315
316 MIPS32_B(NEG16(8)), /* b loop */
317 MIPS32_NOP,
318 /* end: */
319 MIPS32_LW(11,0,15), /* lw $11,($15) */
320 MIPS32_LW(10,0,15), /* lw $10,($15) */
321 MIPS32_LW(9,0,15), /* lw $9,($15) */
322 MIPS32_LW(8,0,15), /* lw $8,($15) */
323 MIPS32_B(NEG16(27)), /* b start */
324 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
325 };
326
327 int retval = ERROR_OK;
328 int blocksize;
329 int bytesread;
330 uint32_t param_in[2];
331
332 bytesread = 0;
333
334 while (count > 0)
335 {
336 blocksize = count;
337 if (count > 0x400)
338 blocksize = 0x400;
339
340 param_in[0] = addr;
341 param_in[1] = blocksize;
342
343 if ((retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
344 ARRAY_SIZE(param_in), param_in, blocksize, &buf[bytesread], 1)) != ERROR_OK)
345 {
346 return retval;
347 }
348
349 count -= blocksize;
350 addr += blocksize;
351 bytesread += blocksize;
352 }
353
354 return retval;
355 }
356
357 int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
358 {
359 static const uint32_t code[] = {
360 /* start: */
361 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
362 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
363 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
364 MIPS32_SW(8,0,15), /* sw $8,($15) */
365
366 MIPS32_LW(8,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN),15), /* load R8 @ param_in[0] = address */
367
368 MIPS32_LW(8,0,8), /* lw $8,0($8), Load $8 with the word @mem[$8] */
369 MIPS32_SW(8,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_OUT),15), /* store R8 @ param_out[0] */
370
371 MIPS32_LW(8,0,15), /* lw $8,($15) */
372 MIPS32_B(NEG16(9)), /* b start */
373 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
374 };
375
376 int retval = ERROR_OK;
377 uint32_t param_in[1];
378
379 param_in[0] = addr;
380
381 if ((retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
382 ARRAY_SIZE(param_in), param_in, 1, buf, 1)) != ERROR_OK)
383 {
384 return retval;
385 }
386
387 return retval;
388 }
389
390 int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
391 {
392 static const uint32_t code[] = {
393 /* start: */
394 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
395 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
396 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
397 MIPS32_SW(8,0,15), /* sw $8,($15) */
398 MIPS32_SW(9,0,15), /* sw $9,($15) */
399 MIPS32_SW(10,0,15), /* sw $10,($15) */
400 MIPS32_SW(11,0,15), /* sw $11,($15) */
401
402 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
403 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
404 MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */
405 MIPS32_LW(10,4,8), /* $10 = mem[$8 + 4]; read count */
406 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11 = MIPS32_PRACC_PARAM_OUT */
407 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
408 /* loop: */
409 MIPS32_BEQ(0,10,8), /* beq 0, $10, end */
410 MIPS32_NOP,
411
412 MIPS32_LHU(8,0,9), /* lw $8,0($9), Load $8 with the halfword @mem[$9] */
413 MIPS32_SW(8,0,11), /* sw $8,0($11) */
414
415 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
416 MIPS32_ADDI(9,9,2), /* $9 += 2 */
417 MIPS32_ADDI(11,11,4), /* $11 += 4 */
418 MIPS32_B(NEG16(8)), /* b loop */
419 MIPS32_NOP,
420 /* end: */
421 MIPS32_LW(11,0,15), /* lw $11,($15) */
422 MIPS32_LW(10,0,15), /* lw $10,($15) */
423 MIPS32_LW(9,0,15), /* lw $9,($15) */
424 MIPS32_LW(8,0,15), /* lw $8,($15) */
425 MIPS32_B(NEG16(27)), /* b start */
426 MIPS32_MFC0(15,30,0), /* move COP0 DeSave to $15 */
427 };
428
429 /* TODO remove array */
430 uint32_t *param_out = malloc(count * sizeof(uint32_t));
431 int i;
432
433 // int retval;
434 int blocksize;
435 int bytesread;
436 uint32_t param_in[2];
437
438 bytesread = 0;
439
440 //while (count > 0)
441 {
442 blocksize = count;
443 if (count > 0x400)
444 blocksize = 0x400;
445
446 param_in[0] = addr;
447 param_in[1] = blocksize;
448
449 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
450 ARRAY_SIZE(param_in), param_in, count, param_out, 1);
451
452 // count -= blocksize;
453 // addr += blocksize;
454 // bytesread += blocksize;
455 }
456
457 for (i = 0; i < count; i++)
458 {
459 buf[i] = param_out[i];
460 }
461
462 free(param_out);
463
464 return ERROR_OK;
465 }
466
467 int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
468 {
469 static const uint32_t code[] = {
470 /* start: */
471 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
472 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
473 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
474 MIPS32_SW(8,0,15), /* sw $8,($15) */
475 MIPS32_SW(9,0,15), /* sw $9,($15) */
476 MIPS32_SW(10,0,15), /* sw $10,($15) */
477 MIPS32_SW(11,0,15), /* sw $11,($15) */
478
479 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
480 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
481 MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */
482 MIPS32_LW(10,4,8), /* $10 = mem[$8 + 4]; read count */
483 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11 = MIPS32_PRACC_PARAM_OUT */
484 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
485 /* loop: */
486 MIPS32_BEQ(0,10,8), /* beq 0, $10, end */
487 MIPS32_NOP,
488
489 MIPS32_LBU(8,0,9), /* lw $8,0($9), Load t4 with the byte @mem[t1] */
490 MIPS32_SW(8,0,11), /* sw $8,0($11) */
491
492 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
493 MIPS32_ADDI(9,9,1), /* $9 += 1 */
494 MIPS32_ADDI(11,11,4), /* $11 += 4 */
495 MIPS32_B(NEG16(8)), /* b loop */
496 MIPS32_NOP,
497 /* end: */
498 MIPS32_LW(11,0,15), /* lw $11,($15) */
499 MIPS32_LW(10,0,15), /* lw $10,($15) */
500 MIPS32_LW(9,0,15), /* lw $9,($15) */
501 MIPS32_LW(8,0,15), /* lw $8,($15) */
502 MIPS32_B(NEG16(27)), /* b start */
503 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
504 };
505
506 /* TODO remove array */
507 uint32_t *param_out = malloc(count * sizeof(uint32_t));
508 int i;
509
510 // int retval;
511 int blocksize;
512 int bytesread;
513 uint32_t param_in[2];
514
515 bytesread = 0;
516
517 // while (count > 0)
518 {
519 blocksize = count;
520 if (count > 0x400)
521 blocksize = 0x400;
522
523 param_in[0] = addr;
524 param_in[1] = blocksize;
525
526 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
527 ARRAY_SIZE(param_in), param_in, count, param_out, 1);
528
529 // count -= blocksize;
530 // addr += blocksize;
531 // bytesread += blocksize;
532 }
533
534 for (i = 0; i < count; i++)
535 {
536 buf[i] = param_out[i];
537 }
538
539 free(param_out);
540
541 return ERROR_OK;
542 }
543
544 int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
545 {
546 switch (size)
547 {
548 case 1:
549 return mips32_pracc_write_mem8(ejtag_info, addr, count, (uint8_t*)buf);
550 case 2:
551 return mips32_pracc_write_mem16(ejtag_info, addr, count,(uint16_t*)buf);
552 case 4:
553 if (count == 1)
554 return mips32_pracc_write_u32(ejtag_info, addr, (uint32_t*)buf);
555 else
556 return mips32_pracc_write_mem32(ejtag_info, addr, count, (uint32_t*)buf);
557 }
558
559 return ERROR_OK;
560 }
561
562 int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
563 {
564 static const uint32_t code[] = {
565 /* start: */
566 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
567 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
568 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
569 MIPS32_SW(8,0,15), /* sw $8,($15) */
570 MIPS32_SW(9,0,15), /* sw $9,($15) */
571 MIPS32_SW(10,0,15), /* sw $10,($15) */
572 MIPS32_SW(11,0,15), /* sw $11,($15) */
573
574 MIPS32_ADDI(8,15,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)), /* $8= MIPS32_PRACC_PARAM_IN */
575 MIPS32_LW(9,0,8), /* Load write addr to $9 */
576 MIPS32_LW(10,4,8), /* Load write count to $10 */
577 MIPS32_ADDI(8,8,8), /* $8 += 8 beginning of data */
578
579 /* loop: */
580 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
581 MIPS32_SW(11,0,9), /* sw $11,0($9) */
582
583 MIPS32_ADDI(9,9,4), /* $9 += 4 */
584 MIPS32_BNE(10,9,NEG16(4)), /* bne $10, $9, loop */
585 MIPS32_ADDI(8,8,4), /* $8 += 4 */
586
587 /* end: */
588 MIPS32_LW(11,0,15), /* lw $11,($15) */
589 MIPS32_LW(10,0,15), /* lw $10,($15) */
590 MIPS32_LW(9,0,15), /* lw $9,($15) */
591 MIPS32_LW(8,0,15), /* lw $8,($15) */
592 MIPS32_B(NEG16(21)), /* b start */
593 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
594 };
595
596 /* TODO remove array */
597 uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t));
598 param_in[0] = addr;
599 param_in[1] = addr + (count * sizeof(uint32_t)); /* last address */
600
601 memcpy(&param_in[2], buf, count * sizeof(uint32_t));
602
603 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
604 count + 2, param_in, 0, NULL, 1);
605
606 free(param_in);
607
608 return ERROR_OK;
609 }
610
611 int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
612 {
613 static const uint32_t code[] = {
614 /* start: */
615 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
616 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
617 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
618 MIPS32_SW(8,0,15), /* sw $8,($15) */
619 MIPS32_SW(9,0,15), /* sw $9,($15) */
620
621 MIPS32_LW(8,NEG16((MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)-4), 15), /* load R8 @ param_in[1] = data */
622 MIPS32_LW(9,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN), 15), /* load R9 @ param_in[0] = address */
623
624 MIPS32_SW(8,0,9), /* sw $8,0($9) */
625
626 MIPS32_LW(9,0,15), /* lw $9,($15) */
627 MIPS32_LW(8,0,15), /* lw $8,($15) */
628 MIPS32_B(NEG16(11)), /* b start */
629 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
630 };
631
632 /* TODO remove array */
633 uint32_t param_in[1 + 1];
634 param_in[0] = addr;
635 param_in[1] = *buf;
636
637 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
638 ARRAY_SIZE(param_in), param_in, 0, NULL, 1);
639
640 return ERROR_OK;
641 }
642
643 int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
644 {
645 static const uint32_t code[] = {
646 /* start: */
647 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
648 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
649 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
650 MIPS32_SW(8,0,15), /* sw $8,($15) */
651 MIPS32_SW(9,0,15), /* sw $9,($15) */
652 MIPS32_SW(10,0,15), /* sw $10,($15) */
653 MIPS32_SW(11,0,15), /* sw $11,($15) */
654
655 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
656 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
657 MIPS32_LW(9,0,8), /* Load write addr to $9 */
658 MIPS32_LW(10,4,8), /* Load write count to $10 */
659 MIPS32_ADDI(8,8,8), /* $8 += 8 */
660 /* loop: */
661 MIPS32_BEQ(0,10,8), /* beq $0, $10, end */
662 MIPS32_NOP,
663
664 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
665 MIPS32_SH(11,0,9), /* sh $11,0($9) */
666
667 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
668 MIPS32_ADDI(9,9,2), /* $9 += 2 */
669 MIPS32_ADDI(8,8,4), /* $8 += 4 */
670
671 MIPS32_B(NEG16(8)), /* b loop */
672 MIPS32_NOP,
673 /* end: */
674 MIPS32_LW(11,0,15), /* lw $11,($15) */
675 MIPS32_LW(10,0,15), /* lw $10,($15) */
676 MIPS32_LW(9,0,15), /* lw $9,($15) */
677 MIPS32_LW(8,0,15), /* lw $8,($15) */
678 MIPS32_B(NEG16(26)), /* b start */
679 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
680 };
681
682 /* TODO remove array */
683 uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t));
684 int i;
685 param_in[0] = addr;
686 param_in[1] = count;
687
688 for (i = 0; i < count; i++)
689 {
690 param_in[i + 2] = buf[i];
691 }
692
693 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
694 count + 2, param_in, 0, NULL, 1);
695
696 free(param_in);
697
698 return ERROR_OK;
699 }
700
701 int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
702 {
703 static const uint32_t code[] = {
704 /* start: */
705 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
706 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
707 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
708 MIPS32_SW(8,0,15), /* sw $8,($15) */
709 MIPS32_SW(9,0,15), /* sw $9,($15) */
710 MIPS32_SW(10,0,15), /* sw $10,($15) */
711 MIPS32_SW(11,0,15), /* sw $11,($15) */
712
713 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
714 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
715 MIPS32_LW(9,0,8), /* Load write addr to $9 */
716 MIPS32_LW(10,4,8), /* Load write count to $10 */
717 MIPS32_ADDI(8,8,8), /* $8 += 8 */
718 /* loop: */
719 MIPS32_BEQ(0,10,8), /* beq $0, $10, end */
720 MIPS32_NOP,
721
722 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
723 MIPS32_SB(11,0,9), /* sb $11,0($9) */
724
725 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
726 MIPS32_ADDI(9,9,1), /* $9 += 1 */
727 MIPS32_ADDI(8,8,4), /* $8 += 4 */
728
729 MIPS32_B(NEG16(8)), /* b loop */
730 MIPS32_NOP,
731 /* end: */
732 MIPS32_LW(11,0,15), /* lw $11,($15) */
733 MIPS32_LW(10,0,15), /* lw $10,($15) */
734 MIPS32_LW(9,0,15), /* lw $9,($15) */
735 MIPS32_LW(8,0,15), /* lw $8,($15) */
736 MIPS32_B(NEG16(26)), /* b start */
737 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
738 };
739
740 /* TODO remove array */
741 uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t));
742 int retval;
743 int i;
744 param_in[0] = addr;
745 param_in[1] = count;
746
747 for (i = 0; i < count; i++)
748 {
749 param_in[i + 2] = buf[i];
750 }
751
752 retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
753 count + 2, param_in, 0, NULL, 1);
754
755 free(param_in);
756
757 return retval;
758 }
759
760 int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
761 {
762 static const uint32_t code[] = {
763 /* start: */
764 MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $2 = MIPS32_PRACC_PARAM_IN */
765 MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_IN)),
766 MIPS32_LW(1,1*4,2), /* lw $1,1*4($2) */
767 MIPS32_LW(15,15*4,2), /* lw $15,15*4($2) */
768 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
769 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
770 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
771 MIPS32_SW(1,0,15), /* sw $1,($15) */
772 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $1 = MIPS32_PRACC_PARAM_IN */
773 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_IN)),
774 MIPS32_LW(3,3*4,1), /* lw $3,3*4($1) */
775 MIPS32_LW(4,4*4,1), /* lw $4,4*4($1) */
776 MIPS32_LW(5,5*4,1), /* lw $5,5*4($1) */
777 MIPS32_LW(6,6*4,1), /* lw $6,6*4($1) */
778 MIPS32_LW(7,7*4,1), /* lw $7,7*4($1) */
779 MIPS32_LW(8,8*4,1), /* lw $8,8*4($1) */
780 MIPS32_LW(9,9*4,1), /* lw $9,9*4($1) */
781 MIPS32_LW(10,10*4,1), /* lw $10,10*4($1) */
782 MIPS32_LW(11,11*4,1), /* lw $11,11*4($1) */
783 MIPS32_LW(12,12*4,1), /* lw $12,12*4($1) */
784 MIPS32_LW(13,13*4,1), /* lw $13,13*4($1) */
785 MIPS32_LW(14,14*4,1), /* lw $14,14*4($1) */
786 MIPS32_LW(16,16*4,1), /* lw $16,16*4($1) */
787 MIPS32_LW(17,17*4,1), /* lw $17,17*4($1) */
788 MIPS32_LW(18,18*4,1), /* lw $18,18*4($1) */
789 MIPS32_LW(19,19*4,1), /* lw $19,19*4($1) */
790 MIPS32_LW(20,20*4,1), /* lw $20,20*4($1) */
791 MIPS32_LW(21,21*4,1), /* lw $21,21*4($1) */
792 MIPS32_LW(22,22*4,1), /* lw $22,22*4($1) */
793 MIPS32_LW(23,23*4,1), /* lw $23,23*4($1) */
794 MIPS32_LW(24,24*4,1), /* lw $24,24*4($1) */
795 MIPS32_LW(25,25*4,1), /* lw $25,25*4($1) */
796 MIPS32_LW(26,26*4,1), /* lw $26,26*4($1) */
797 MIPS32_LW(27,27*4,1), /* lw $27,27*4($1) */
798 MIPS32_LW(28,28*4,1), /* lw $28,28*4($1) */
799 MIPS32_LW(29,29*4,1), /* lw $29,29*4($1) */
800 MIPS32_LW(30,30*4,1), /* lw $30,30*4($1) */
801 MIPS32_LW(31,31*4,1), /* lw $31,31*4($1) */
802
803 MIPS32_LW(2,32*4,1), /* lw $2,32*4($1) */
804 MIPS32_MTC0(2,12,0), /* move $2 to status */
805 MIPS32_LW(2,33*4,1), /* lw $2,33*4($1) */
806 MIPS32_MTLO(2), /* move $2 to lo */
807 MIPS32_LW(2,34*4,1), /* lw $2,34*4($1) */
808 MIPS32_MTHI(2), /* move $2 to hi */
809 MIPS32_LW(2,35*4,1), /* lw $2,35*4($1) */
810 MIPS32_MTC0(2,8,0), /* move $2 to badvaddr */
811 MIPS32_LW(2,36*4,1), /* lw $2,36*4($1) */
812 MIPS32_MTC0(2,13,0), /* move $2 to cause*/
813 MIPS32_LW(2,37*4,1), /* lw $2,37*4($1) */
814 MIPS32_MTC0(2,24,0), /* move $2 to depc (pc) */
815
816 MIPS32_LW(2,2*4,1), /* lw $2,2*4($1) */
817 MIPS32_LW(1,0,15), /* lw $1,($15) */
818 MIPS32_B(NEG16(53)), /* b start */
819 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
820 };
821
822 int retval;
823
824 retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
825 MIPS32NUMCOREREGS, regs, 0, NULL, 1);
826
827 return retval;
828 }
829
830 int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
831 {
832 static const uint32_t code[] = {
833 /* start: */
834 MIPS32_MTC0(2,31,0), /* move $2 to COP0 DeSave */
835 MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $2 = MIPS32_PRACC_PARAM_OUT */
836 MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_OUT)),
837 MIPS32_SW(0,0*4,2), /* sw $0,0*4($2) */
838 MIPS32_SW(1,1*4,2), /* sw $1,1*4($2) */
839 MIPS32_SW(15,15*4,2), /* sw $15,15*4($2) */
840 MIPS32_MFC0(2,31,0), /* move COP0 DeSave to $2 */
841 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
842 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
843 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
844 MIPS32_SW(1,0,15), /* sw $1,($15) */
845 MIPS32_SW(2,0,15), /* sw $2,($15) */
846 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
847 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
848 MIPS32_SW(2,2*4,1), /* sw $2,2*4($1) */
849 MIPS32_SW(3,3*4,1), /* sw $3,3*4($1) */
850 MIPS32_SW(4,4*4,1), /* sw $4,4*4($1) */
851 MIPS32_SW(5,5*4,1), /* sw $5,5*4($1) */
852 MIPS32_SW(6,6*4,1), /* sw $6,6*4($1) */
853 MIPS32_SW(7,7*4,1), /* sw $7,7*4($1) */
854 MIPS32_SW(8,8*4,1), /* sw $8,8*4($1) */
855 MIPS32_SW(9,9*4,1), /* sw $9,9*4($1) */
856 MIPS32_SW(10,10*4,1), /* sw $10,10*4($1) */
857 MIPS32_SW(11,11*4,1), /* sw $11,11*4($1) */
858 MIPS32_SW(12,12*4,1), /* sw $12,12*4($1) */
859 MIPS32_SW(13,13*4,1), /* sw $13,13*4($1) */
860 MIPS32_SW(14,14*4,1), /* sw $14,14*4($1) */
861 MIPS32_SW(16,16*4,1), /* sw $16,16*4($1) */
862 MIPS32_SW(17,17*4,1), /* sw $17,17*4($1) */
863 MIPS32_SW(18,18*4,1), /* sw $18,18*4($1) */
864 MIPS32_SW(19,19*4,1), /* sw $19,19*4($1) */
865 MIPS32_SW(20,20*4,1), /* sw $20,20*4($1) */
866 MIPS32_SW(21,21*4,1), /* sw $21,21*4($1) */
867 MIPS32_SW(22,22*4,1), /* sw $22,22*4($1) */
868 MIPS32_SW(23,23*4,1), /* sw $23,23*4($1) */
869 MIPS32_SW(24,24*4,1), /* sw $24,24*4($1) */
870 MIPS32_SW(25,25*4,1), /* sw $25,25*4($1) */
871 MIPS32_SW(26,26*4,1), /* sw $26,26*4($1) */
872 MIPS32_SW(27,27*4,1), /* sw $27,27*4($1) */
873 MIPS32_SW(28,28*4,1), /* sw $28,28*4($1) */
874 MIPS32_SW(29,29*4,1), /* sw $29,29*4($1) */
875 MIPS32_SW(30,30*4,1), /* sw $30,30*4($1) */
876 MIPS32_SW(31,31*4,1), /* sw $31,31*4($1) */
877
878 MIPS32_MFC0(2,12,0), /* move status to $2 */
879 MIPS32_SW(2,32*4,1), /* sw $2,32*4($1) */
880 MIPS32_MFLO(2), /* move lo to $2 */
881 MIPS32_SW(2,33*4,1), /* sw $2,33*4($1) */
882 MIPS32_MFHI(2), /* move hi to $2 */
883 MIPS32_SW(2,34*4,1), /* sw $2,34*4($1) */
884 MIPS32_MFC0(2,8,0), /* move badvaddr to $2 */
885 MIPS32_SW(2,35*4,1), /* sw $2,35*4($1) */
886 MIPS32_MFC0(2,13,0), /* move cause to $2 */
887 MIPS32_SW(2,36*4,1), /* sw $2,36*4($1) */
888 MIPS32_MFC0(2,24,0), /* move depc (pc) to $2 */
889 MIPS32_SW(2,37*4,1), /* sw $2,37*4($1) */
890
891 MIPS32_LW(2,0,15), /* lw $2,($15) */
892 MIPS32_LW(1,0,15), /* lw $1,($15) */
893 MIPS32_B(NEG16(58)), /* b start */
894 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
895 };
896
897 int retval;
898
899 retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
900 0, NULL, MIPS32NUMCOREREGS, regs, 1);
901
902 return retval;
903 }
904
905 /* fastdata upload/download requires an initialized working area
906 * to load the download code; it should not be called otherwise
907 * fetch order from the fastdata area
908 * 1. start addr
909 * 2. end addr
910 * 3. data ...
911 */
912 int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source,
913 int write, uint32_t addr, int count, uint32_t *buf)
914 {
915 uint32_t handler_code[] = {
916 /* caution when editing, table is modified below */
917 /* r15 points to the start of this code */
918 MIPS32_SW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15),
919 MIPS32_SW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15),
920 MIPS32_SW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15),
921 MIPS32_SW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15),
922 /* start of fastdata area in t0 */
923 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_FASTDATA_AREA)),
924 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_FASTDATA_AREA)),
925 MIPS32_LW(9,0,8), /* start addr in t1 */
926 MIPS32_LW(10,0,8), /* end addr to t2 */
927 /* loop: */
928 /* 8 */ MIPS32_LW(11,0,0), /* lw t3,[t8 | r9] */
929 /* 9 */ MIPS32_SW(11,0,0), /* sw t3,[r9 | r8] */
930 MIPS32_BNE(10,9,NEG16(3)), /* bne $t2,t1,loop */
931 MIPS32_ADDI(9,9,4), /* addi t1,t1,4 */
932
933 MIPS32_LW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15),
934 MIPS32_LW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15),
935 MIPS32_LW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15),
936 MIPS32_LW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15),
937
938 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_TEXT)),
939 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_TEXT)),
940 MIPS32_JR(15), /* jr start */
941 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
942 };
943
944 uint32_t jmp_code[] = {
945 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
946 /* 1 */ MIPS32_LUI(15,0), /* addr of working area added below */
947 /* 2 */ MIPS32_ORI(15,15,0), /* addr of working area added below */
948 MIPS32_JR(15), /* jump to ram program */
949 MIPS32_NOP,
950 };
951
952 int retval, i;
953 uint32_t val, ejtag_ctrl, address;
954
955 if (source->size < MIPS32_FASTDATA_HANDLER_SIZE)
956 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
957
958 if (write)
959 {
960 handler_code[8] = MIPS32_LW(11,0,8); /* load data from probe at fastdata area */
961 handler_code[9] = MIPS32_SW(11,0,9); /* store data to RAM @ r9 */
962 }
963 else
964 {
965 handler_code[8] = MIPS32_LW(11,0,9); /* load data from RAM @ r9 */
966 handler_code[9] = MIPS32_SW(11,0,8); /* store data to probe at fastdata area */
967 }
968
969 /* write program into RAM */
970 mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code);
971
972 LOG_DEBUG("%s using 0x%.8" PRIx32 " for write handler", __func__, source->address);
973
974 jmp_code[1] |= UPPER16(source->address);
975 jmp_code[2] |= LOWER16(source->address);
976
977 for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++)
978 {
979 if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
980 return retval;
981
982 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
983 mips_ejtag_drscan_32(ejtag_info, &jmp_code[i]);
984
985 /* Clear the access pending bit (let the processor eat!) */
986 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
987 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
988 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
989 }
990
991 if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
992 return retval;
993
994 /* next fetch to dmseg should be in FASTDATA_AREA, check */
995 address = 0;
996 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
997 mips_ejtag_drscan_32(ejtag_info, &address);
998
999 if (address != MIPS32_PRACC_FASTDATA_AREA)
1000 return ERROR_FAIL;
1001
1002 /* Send the load start address */
1003 val = addr;
1004 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
1005 mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
1006
1007 /* Send the load end address */
1008 val = addr + (count - 1) * 4;
1009 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
1010 mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
1011
1012 for (i = 0; i < count; i++)
1013 {
1014 /* Send the data out using fastdata (clears the access pending bit) */
1015 if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write, buf++)) != ERROR_OK)
1016 return retval;
1017 }
1018
1019 if ((retval = jtag_execute_queue()) != ERROR_OK)
1020 {
1021 LOG_ERROR("fastdata load failed");
1022 return retval;
1023 }
1024
1025 if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
1026 return retval;
1027
1028 address = 0;
1029 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
1030 mips_ejtag_drscan_32(ejtag_info, &address);
1031
1032 if (address != MIPS32_PRACC_TEXT)
1033 LOG_ERROR("mini program did not return to start");
1034
1035 return retval;
1036 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)