John McCarthy <jgmcc@magma.ca> pic32mx flash fixups and speedups
[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 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27 #include "log.h"
28 #include "mips32.h"
29 #include "mips32_pracc.h"
30
31 typedef struct {
32 u32 *local_iparam;
33 int num_iparam;
34 u32 *local_oparam;
35 int num_oparam;
36 u32 *code;
37 int code_len;
38 u32 stack[32];
39 int stack_offset;
40 mips_ejtag_t *ejtag_info;
41 } mips32_pracc_context;
42
43 static int wait_for_pracc_rw(mips_ejtag_t *ejtag_info, u32 *ctrl)
44 {
45 u32 ejtag_ctrl;
46
47 while (1)
48 {
49 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
50 ejtag_ctrl = ejtag_info->ejtag_ctrl;
51 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
52 if (ejtag_ctrl & EJTAG_CTRL_PRACC)
53 break;
54 LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
55 return ERROR_JTAG_DEVICE_ERROR;
56 }
57
58 *ctrl = ejtag_ctrl;
59 return ERROR_OK;
60 }
61
62 static int mips32_pracc_exec_read(mips32_pracc_context *ctx, u32 address)
63 {
64 mips_ejtag_t *ejtag_info = ctx->ejtag_info;
65 int offset;
66 u32 ejtag_ctrl, data;
67
68 if ((address >= MIPS32_PRACC_PARAM_IN)
69 && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
70 {
71 offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
72 data = ctx->local_iparam[offset];
73 }
74 else if ((address >= MIPS32_PRACC_PARAM_OUT)
75 && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
76 {
77 offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
78 data = ctx->local_oparam[offset];
79 }
80 else if ((address >= MIPS32_PRACC_TEXT)
81 && (address <= MIPS32_PRACC_TEXT + ctx->code_len*4))
82 {
83 offset = (address - MIPS32_PRACC_TEXT) / 4;
84 data = ctx->code[offset];
85 }
86 else if (address == MIPS32_PRACC_STACK)
87 {
88 /* save to our debug stack */
89 data = ctx->stack[--ctx->stack_offset];
90 }
91 else
92 {
93 /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
94 * to start of debug vector */
95
96 data = 0;
97 LOG_ERROR("Error reading unexpected address");
98 return ERROR_JTAG_DEVICE_ERROR;
99 }
100
101 /* Send the data out */
102 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
103 mips_ejtag_drscan_32(ctx->ejtag_info, &data);
104
105 /* Clear the access pending bit (let the processor eat!) */
106 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
107 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
108 mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
109
110 return ERROR_OK;
111 }
112
113 static int mips32_pracc_exec_write(mips32_pracc_context *ctx, u32 address)
114 {
115 u32 ejtag_ctrl,data;
116 int offset;
117 mips_ejtag_t *ejtag_info = ctx->ejtag_info;
118
119 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
120 mips_ejtag_drscan_32(ctx->ejtag_info, &data);
121
122 /* Clear access pending bit */
123 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
124 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
125 mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
126
127 if ((address >= MIPS32_PRACC_PARAM_IN)
128 && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
129 {
130 offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
131 ctx->local_iparam[offset] = data;
132 }
133 else if ((address >= MIPS32_PRACC_PARAM_OUT )
134 && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
135 {
136 offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
137 ctx->local_oparam[offset] = data;
138 }
139 else if (address == MIPS32_PRACC_STACK)
140 {
141 /* save data onto our stack */
142 ctx->stack[ctx->stack_offset++] = data;
143 }
144 else
145 {
146 LOG_ERROR("Error writing unexpected address");
147 return ERROR_JTAG_DEVICE_ERROR;
148 }
149
150 return ERROR_OK;
151 }
152
153 int mips32_pracc_exec( mips_ejtag_t *ejtag_info, int code_len, u32 *code, int num_param_in, u32 *param_in, int num_param_out, u32 *param_out, int cycle)
154 {
155 u32 ejtag_ctrl;
156 u32 address, data;
157 mips32_pracc_context ctx;
158 int retval;
159 int pass = 0;
160
161 ctx.local_iparam = param_in;
162 ctx.local_oparam = param_out;
163 ctx.num_iparam = num_param_in;
164 ctx.num_oparam = num_param_out;
165 ctx.code = code;
166 ctx.code_len = code_len;
167 ctx.ejtag_info = ejtag_info;
168 ctx.stack_offset = 0;
169
170 while (1)
171 {
172 if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
173 return retval;
174
175 address = data = 0;
176 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
177 mips_ejtag_drscan_32(ejtag_info, &address);
178
179 /* Check for read or write */
180 if (ejtag_ctrl & EJTAG_CTRL_PRNW)
181 {
182 if ((retval = mips32_pracc_exec_write(&ctx, address)) != ERROR_OK)
183 return retval;
184 }
185 else
186 {
187 /* Check to see if its reading at the debug vector. The first pass through
188 * the module is always read at the vector, so the first one we allow. When
189 * the second read from the vector occurs we are done and just exit. */
190 if ((address == MIPS32_PRACC_TEXT) && (pass++))
191 {
192 break;
193 }
194
195 if ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK)
196 return retval;
197 }
198
199 if (cycle == 0)
200 break;
201 }
202
203 /* stack sanity check */
204 if (ctx.stack_offset != 0)
205 {
206 LOG_DEBUG("Pracc Stack not zero");
207 }
208
209 return ERROR_OK;
210 }
211
212 int mips32_pracc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
213 {
214 switch (size)
215 {
216 case 1:
217 return mips32_pracc_read_mem8(ejtag_info, addr, count, (u8*)buf);
218 case 2:
219 return mips32_pracc_read_mem16(ejtag_info, addr, count, (u16*)buf);
220 case 4:
221 if(count==1)
222 return mips32_pracc_read_u32(ejtag_info, addr, (u32*)buf);
223 else
224 return mips32_pracc_read_mem32(ejtag_info, addr, count, (u32*)buf);
225 }
226
227 return ERROR_OK;
228 }
229
230 int mips32_pracc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
231 {
232 u32 code[] = {
233 /* start: */
234 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
235 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
236 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
237 MIPS32_SW(8,0,15), /* sw $8,($15) */
238 MIPS32_SW(9,0,15), /* sw $9,($15) */
239 MIPS32_SW(10,0,15), /* sw $10,($15) */
240 MIPS32_SW(11,0,15), /* sw $11,($15) */
241
242 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
243 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
244 MIPS32_LW(9,0,8), /* $9=mem[$8]; read addr */
245 MIPS32_LW(10,4,8), /* $10=mem[$8+4]; read count */
246 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11=MIPS32_PRACC_PARAM_OUT */
247 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
248 MIPS32_NOP,
249 /* loop: */
250 MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
251 MIPS32_NOP,
252
253 MIPS32_LW(8,0,9), /* lw $8,0($9), Load $8 with the word @mem[$9] */
254 MIPS32_SW(8,0,11), /* sw $8,0($11) */
255
256 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
257 MIPS32_ADDI(9,9,4), /* $1+=4 */
258 MIPS32_ADDI(11,11,4), /* $11+=4 */
259
260 MIPS32_NOP,
261 MIPS32_B(NEG16(9)), /* b loop */
262 MIPS32_NOP,
263 /* end: */
264 MIPS32_LW(11,0,15), /* lw $11,($15) */
265 MIPS32_LW(10,0,15), /* lw $10,($15) */
266 MIPS32_LW(9,0,15), /* lw $9,($15) */
267 MIPS32_LW(8,0,15), /* lw $8,($15) */
268 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
269 MIPS32_NOP,
270 MIPS32_B(NEG16(31)), /* b start */
271 MIPS32_NOP,
272 };
273
274 int retval = ERROR_OK;
275 int blocksize;
276 int bytesread;
277 u32 param_in[2];
278
279 bytesread = 0;
280
281 while (count > 0)
282 {
283 blocksize = count;
284 if (count > 0x400)
285 blocksize = 0x400;
286
287 param_in[0] = addr;
288 param_in[1] = blocksize;
289
290 if ((retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code,
291 sizeof(param_in)/sizeof(param_in[0]), param_in, blocksize, &buf[bytesread], 1)) != ERROR_OK)
292 {
293 return retval;
294 }
295
296 count -= blocksize;
297 addr += blocksize;
298 bytesread += blocksize;
299 }
300
301 return retval;
302 }
303
304 int mips32_pracc_read_u32(mips_ejtag_t *ejtag_info, u32 addr, u32 *buf)
305 {
306 u32 code[] = {
307 /* start: */
308 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
309 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
310 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
311 MIPS32_SW(8,0,15), /* sw $8,($15) */
312 MIPS32_SW(9,0,15), /* sw $9,($15) */
313
314 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
315 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
316 MIPS32_LW(8,0,8), /* $8=mem[$8]; read addr */
317 MIPS32_LUI(9,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $9=MIPS32_PRACC_PARAM_OUT */
318 MIPS32_ORI(9,9,LOWER16(MIPS32_PRACC_PARAM_OUT)),
319
320 MIPS32_LW(8,0,8), /* lw $8,0($8), Load $8 with the word @mem[$8] */
321 MIPS32_SW(8,0,9), /* sw $8,0($9) */
322
323 MIPS32_LW(9,0,15), /* lw $9,($15) */
324 MIPS32_LW(8,0,15), /* lw $8,($15) */
325 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
326 MIPS32_NOP,
327 MIPS32_B(NEG16(17)), /* b start */
328 MIPS32_NOP,
329 };
330
331 int retval = ERROR_OK;
332 u32 param_in[1];
333
334 param_in[0] = addr;
335
336 if ((retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code,
337 sizeof(param_in)/sizeof(param_in[0]), param_in, sizeof(u32), buf, 1)) != ERROR_OK)
338 {
339 return retval;
340 }
341
342 return retval;
343 }
344
345 int mips32_pracc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
346 {
347 u32 code[] = {
348 /* start: */
349 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
350 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
351 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
352 MIPS32_SW(8,0,15), /* sw $8,($15) */
353 MIPS32_SW(9,0,15), /* sw $9,($15) */
354 MIPS32_SW(10,0,15), /* sw $10,($15) */
355 MIPS32_SW(11,0,15), /* sw $11,($15) */
356
357 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
358 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
359 MIPS32_LW(9,0,8), /* $9=mem[$8]; read addr */
360 MIPS32_LW(10,4,8), /* $10=mem[$8+4]; read count */
361 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11=MIPS32_PRACC_PARAM_OUT */
362 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
363 MIPS32_NOP,
364 /* loop: */
365 MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
366 MIPS32_NOP,
367
368 MIPS32_LHU(8,0,9), /* lw $8,0($9), Load $8 with the halfword @mem[$9] */
369 MIPS32_SW(8,0,11), /* sw $8,0($11) */
370
371 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
372 MIPS32_ADDI(9,9,2), /* $9+=2 */
373 MIPS32_ADDI(11,11,4), /* $11+=4 */
374 MIPS32_NOP,
375 MIPS32_B(NEG16(9)), /* b loop */
376 MIPS32_NOP,
377
378 MIPS32_LW(11,0,15), /* lw $11,($15) */
379 MIPS32_LW(10,0,15), /* lw $10,($15) */
380 MIPS32_LW(9,0,15), /* lw $9,($15) */
381 MIPS32_LW(8,0,15), /* lw $8,($15) */
382 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
383 MIPS32_NOP,
384 MIPS32_B(NEG16(31)), /* b start */
385 MIPS32_NOP,
386 };
387
388 // /* TODO remove array */
389 u32 param_out[count];
390 int i;
391
392 // int retval;
393 int blocksize;
394 int bytesread;
395 u32 param_in[2];
396
397 bytesread = 0;
398
399 //while (count > 0)
400 {
401 blocksize = count;
402 if (count > 0x400)
403 blocksize = 0x400;
404
405 param_in[0] = addr;
406 param_in[1] = blocksize;
407
408 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
409 sizeof(param_in)/sizeof(param_in[0]), param_in, count, param_out, 1);
410
411 // count -= blocksize;
412 // addr += blocksize;
413 // bytesread += blocksize;
414 }
415
416 for (i = 0; i < count; i++)
417 {
418 buf[i] = param_out[i];
419 }
420
421 return ERROR_OK;
422 }
423
424 int mips32_pracc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
425 {
426 u32 code[] = {
427 /* start: */
428 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
429 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
430 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
431 MIPS32_SW(8,0,15), /* sw $8,($15) */
432 MIPS32_SW(9,0,15), /* sw $9,($15) */
433 MIPS32_SW(10,0,15), /* sw $10,($15) */
434 MIPS32_SW(11,0,15), /* sw $11,($15) */
435
436 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
437 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
438 MIPS32_LW(9,0,8), /* $9=mem[$8]; read addr */
439 MIPS32_LW(10,4,8), /* $10=mem[$8+4]; read count */
440 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11=MIPS32_PRACC_PARAM_OUT */
441 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
442 MIPS32_NOP,
443 /* loop: */
444 MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
445 MIPS32_NOP,
446
447 MIPS32_LBU(8,0,9), /* lw $8,0($9), Load t4 with the byte @mem[t1] */
448 MIPS32_SW(8,0,11), /* sw $8,0($11) */
449
450 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
451 MIPS32_ADDI(9,9,1), /* $9+=1 */
452 MIPS32_ADDI(11,11,4), /* $11+=4 */
453 MIPS32_NOP,
454 MIPS32_B(NEG16(9)), /* b loop */
455 MIPS32_NOP,
456 /* end: */
457 MIPS32_LW(11,0,15), /* lw $11,($15) */
458 MIPS32_LW(10,0,15), /* lw $10,($15) */
459 MIPS32_LW(9,0,15), /* lw $9,($15) */
460 MIPS32_LW(8,0,15), /* lw $8,($15) */
461 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
462 MIPS32_NOP,
463 MIPS32_B(NEG16(31)), /* b start */
464 MIPS32_NOP,
465 };
466
467 // /* TODO remove array */
468 u32 param_out[count];
469 int i;
470
471 // int retval;
472 int blocksize;
473 int bytesread;
474 u32 param_in[2];
475
476 bytesread = 0;
477
478 // while (count > 0)
479 {
480 blocksize = count;
481 if (count > 0x400)
482 blocksize = 0x400;
483
484 param_in[0] = addr;
485 param_in[1] = blocksize;
486
487 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
488 sizeof(param_in)/sizeof(param_in[0]), param_in, count, param_out, 1);
489
490 // count -= blocksize;
491 // addr += blocksize;
492 // bytesread += blocksize;
493 }
494
495 for (i = 0; i < count; i++)
496 {
497 buf[i] = param_out[i];
498 }
499
500 return ERROR_OK;
501 }
502
503 int mips32_pracc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
504 {
505 switch (size)
506 {
507 case 1:
508 return mips32_pracc_write_mem8(ejtag_info, addr, count, (u8*)buf);
509 case 2:
510 return mips32_pracc_write_mem16(ejtag_info, addr, count,(u16*)buf);
511 case 4:
512 if(count==1)
513 return mips32_pracc_write_u32(ejtag_info, addr, (u32*)buf);
514 else
515 return mips32_pracc_write_mem32(ejtag_info, addr, count, (u32*)buf);
516 }
517
518 return ERROR_OK;
519 }
520
521 int mips32_pracc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
522 {
523 u32 code[] = {
524 /* start: */
525 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
526 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
527 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
528 MIPS32_SW(8,0,15), /* sw $8,($15) */
529 MIPS32_SW(9,0,15), /* sw $9,($15) */
530 MIPS32_SW(10,0,15), /* sw $10,($15) */
531 MIPS32_SW(11,0,15), /* sw $11,($15) */
532
533 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
534 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
535 MIPS32_LW(9,0,8), /* Load write addr to $9 */
536 MIPS32_LW(10,4,8), /* Load write count to $10 */
537 MIPS32_ADDI(8,8,8), /* $8+=8 */
538 MIPS32_NOP,
539 /* loop: */
540 MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
541 MIPS32_NOP,
542
543 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
544 MIPS32_SW(11,0,9), /* sw $11,0($9) */
545
546 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
547 MIPS32_ADDI(9,9,4), /* $9+=4 */
548 MIPS32_ADDI(8,8,4), /* $8+=4 */
549 MIPS32_NOP,
550 MIPS32_B(NEG16(9)), /* b loop */
551 MIPS32_NOP,
552 /* end: */
553 MIPS32_LW(11,0,15), /* lw $11,($15) */
554 MIPS32_LW(10,0,15), /* lw $10,($15) */
555 MIPS32_LW(9,0,15), /* lw $9,($15) */
556 MIPS32_LW(8,0,15), /* lw $8,($15) */
557 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
558 MIPS32_NOP,
559 MIPS32_B(NEG16(30)), /* b start */
560 MIPS32_NOP,
561 };
562
563 /* TODO remove array */
564 u32 param_in[count+2];
565 param_in[0] = addr;
566 param_in[1] = count;
567
568 memcpy(&param_in[2], buf, count * sizeof(u32));
569
570 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
571 sizeof(param_in)/sizeof(param_in[0]),param_in, 0, NULL, 1);
572
573 return ERROR_OK;
574 }
575
576 int mips32_pracc_write_u32(mips_ejtag_t *ejtag_info, u32 addr, u32 *buf)
577 {
578 u32 code[] = {
579 /* start: */
580 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
581 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
582 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
583 MIPS32_SW(8,0,15), /* sw $8,($15) */
584 MIPS32_SW(9,0,15), /* sw $9,($15) */
585
586 MIPS32_LUI(8,UPPER16((MIPS32_PRACC_PARAM_IN+4))), /* $8 = MIPS32_PRACC_PARAM_IN+4 */
587 MIPS32_ORI(8,8,LOWER16((MIPS32_PRACC_PARAM_IN+4))),
588 MIPS32_LW(9,NEG16(4),8), /* Load write addr to $9 */
589
590 MIPS32_LW(8,0,8), /* lw $8,0($8), Load $8 with the word @mem[$8] */
591 MIPS32_SW(8,0,9), /* sw $8,0($9) */
592
593 MIPS32_LW(9,0,15), /* lw $9,($15) */
594 MIPS32_LW(8,0,15), /* lw $8,($15) */
595 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
596 MIPS32_NOP,
597 MIPS32_B(NEG16(15)), /* b start */
598 MIPS32_NOP,
599 };
600
601 /* TODO remove array */
602 u32 param_in[1+1];
603 param_in[0] = addr;
604 param_in[1] = *buf;
605
606 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
607 sizeof(param_in)/sizeof(param_in[0]),param_in, 0, NULL, 1);
608
609 return ERROR_OK;
610 }
611
612 int mips32_pracc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
613 {
614 u32 code[] = {
615 /* start: */
616 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
617 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
618 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
619 MIPS32_SW(8,0,15), /* sw $8,($15) */
620 MIPS32_SW(9,0,15), /* sw $9,($15) */
621 MIPS32_SW(10,0,15), /* sw $10,($15) */
622 MIPS32_SW(11,0,15), /* sw $11,($15) */
623
624 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
625 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
626 MIPS32_LW(9,0,8), /* Load write addr to $9 */
627 MIPS32_LW(10,4,8), /* Load write count to $10 */
628 MIPS32_ADDI(8,8,8), /* $8+=8 */
629 MIPS32_NOP,
630 /* loop: */
631 MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
632 MIPS32_NOP,
633
634 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
635 MIPS32_SH(11,0,9), /* sh $11,0($9) */
636
637 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
638 MIPS32_ADDI(9,9,2), /* $9+=2 */
639 MIPS32_ADDI(8,8,4), /* $8+=4 */
640
641 MIPS32_NOP,
642 MIPS32_B(NEG16(9)), /* b loop */
643 MIPS32_NOP,
644 /* end: */
645 MIPS32_LW(11,0,15), /* lw $11,($15) */
646 MIPS32_LW(10,0,15), /* lw $10,($15) */
647 MIPS32_LW(9,0,15), /* lw $9,($15) */
648 MIPS32_LW(8,0,15), /* lw $8,($15) */
649 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
650 MIPS32_NOP,
651 MIPS32_B(NEG16(30)), /* b start */
652 MIPS32_NOP,
653 };
654
655 /* TODO remove array */
656 u32 param_in[count+2];
657 int i;
658 param_in[0] = addr;
659 param_in[1] = count;
660
661 for (i = 0; i < count; i++)
662 {
663 param_in[i+2] = buf[i];
664 }
665
666 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
667 sizeof(param_in)/sizeof(param_in[0]), param_in, 0, NULL, 1);
668
669 return ERROR_OK;
670 }
671
672 int mips32_pracc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
673 {
674 u32 code[] = {
675 /* start: */
676 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
677 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
678 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
679 MIPS32_SW(8,0,15), /* sw $8,($15) */
680 MIPS32_SW(9,0,15), /* sw $9,($15) */
681 MIPS32_SW(10,0,15), /* sw $10,($15) */
682 MIPS32_SW(11,0,15), /* sw $11,($15) */
683
684 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
685 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
686 MIPS32_LW(9,0,8), /* Load write addr to $9 */
687 MIPS32_LW(10,4,8), /* Load write count to $10 */
688 MIPS32_ADDI(8,8,8), /* $8+=8 */
689 MIPS32_NOP,
690 /* loop: */
691 MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
692 MIPS32_NOP,
693
694 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
695 MIPS32_SB(11,0,9), /* sb $11,0($9) */
696
697 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
698 MIPS32_ADDI(9,9,1), /* $9+=1 */
699 MIPS32_ADDI(8,8,4), /* $8+=4 */
700
701 MIPS32_NOP,
702 MIPS32_B(NEG16(9)), /* b loop */
703 MIPS32_NOP,
704 /* end: */
705 MIPS32_LW(11,0,15), /* lw $11,($15) */
706 MIPS32_LW(10,0,15), /* lw $10,($15) */
707 MIPS32_LW(9,0,15), /* lw $9,($15) */
708 MIPS32_LW(8,0,15), /* lw $8,($15) */
709 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
710 MIPS32_NOP,
711 MIPS32_B(NEG16(30)), /* b start */
712 MIPS32_NOP,
713 };
714
715 /* TODO remove array */
716 u32 param_in[count+2];
717 int retval;
718 int i;
719 param_in[0] = addr;
720 param_in[1] = count;
721
722 for (i = 0; i < count; i++)
723 {
724 param_in[i+2] = buf[i];
725 }
726
727 retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
728 sizeof(param_in)/sizeof(param_in[0]), param_in, 0, NULL, 1);
729
730 return retval;
731 }
732
733 int mips32_pracc_write_regs(mips_ejtag_t *ejtag_info, u32 *regs)
734 {
735 u32 code[] = {
736 /* start: */
737 MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $2 = MIPS32_PRACC_PARAM_IN */
738 MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_IN)),
739 MIPS32_LW(1,1*4,2), /* lw $1,1*4($2) */
740 MIPS32_LW(15,15*4,2), /* lw $15,15*4($2) */
741 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
742 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
743 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
744 MIPS32_SW(1,0,15), /* sw $1,($15) */
745 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $1 = MIPS32_PRACC_PARAM_IN */
746 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_IN)),
747 MIPS32_LW(3,3*4,1), /* lw $3,3*4($1) */
748 MIPS32_LW(4,4*4,1), /* lw $4,4*4($1) */
749 MIPS32_LW(5,5*4,1), /* lw $5,5*4($1) */
750 MIPS32_LW(6,6*4,1), /* lw $6,6*4($1) */
751 MIPS32_LW(7,7*4,1), /* lw $7,7*4($1) */
752 MIPS32_LW(8,8*4,1), /* lw $8,8*4($1) */
753 MIPS32_LW(9,9*4,1), /* lw $9,9*4($1) */
754 MIPS32_LW(10,10*4,1), /* lw $10,10*4($1) */
755 MIPS32_LW(11,11*4,1), /* lw $11,11*4($1) */
756 MIPS32_LW(12,12*4,1), /* lw $12,12*4($1) */
757 MIPS32_LW(13,13*4,1), /* lw $13,13*4($1) */
758 MIPS32_LW(14,14*4,1), /* lw $14,14*4($1) */
759 MIPS32_LW(16,16*4,1), /* lw $16,16*4($1) */
760 MIPS32_LW(17,17*4,1), /* lw $17,17*4($1) */
761 MIPS32_LW(18,18*4,1), /* lw $18,18*4($1) */
762 MIPS32_LW(19,19*4,1), /* lw $19,19*4($1) */
763 MIPS32_LW(20,20*4,1), /* lw $20,20*4($1) */
764 MIPS32_LW(21,21*4,1), /* lw $21,21*4($1) */
765 MIPS32_LW(22,22*4,1), /* lw $22,22*4($1) */
766 MIPS32_LW(23,23*4,1), /* lw $23,23*4($1) */
767 MIPS32_LW(24,24*4,1), /* lw $24,24*4($1) */
768 MIPS32_LW(25,25*4,1), /* lw $25,25*4($1) */
769 MIPS32_LW(26,26*4,1), /* lw $26,26*4($1) */
770 MIPS32_LW(27,27*4,1), /* lw $27,27*4($1) */
771 MIPS32_LW(28,28*4,1), /* lw $28,28*4($1) */
772 MIPS32_LW(29,29*4,1), /* lw $29,29*4($1) */
773 MIPS32_LW(30,30*4,1), /* lw $30,30*4($1) */
774 MIPS32_LW(31,31*4,1), /* lw $31,31*4($1) */
775
776 MIPS32_LW(2,32*4,1), /* lw $2,32*4($1) */
777 MIPS32_MTC0(2,12,0), /* move $2 to status */
778 MIPS32_LW(2,33*4,1), /* lw $2,33*4($1) */
779 MIPS32_MTLO(2), /* move $2 to lo */
780 MIPS32_LW(2,34*4,1), /* lw $2,34*4($1) */
781 MIPS32_MTHI(2), /* move $2 to hi */
782 MIPS32_LW(2,35*4,1), /* lw $2,35*4($1) */
783 MIPS32_MTC0(2,8,0), /* move $2 to badvaddr */
784 MIPS32_LW(2,36*4,1), /* lw $2,36*4($1) */
785 MIPS32_MTC0(2,13,0), /* move $2 to cause*/
786 MIPS32_LW(2,37*4,1), /* lw $2,37*4($1) */
787 MIPS32_MTC0(2,24,0), /* move $2 to pc */
788
789 MIPS32_LW(2,2*4,1), /* lw $2,2*4($1) */
790 MIPS32_LW(1,0,15), /* lw $1,($15) */
791 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
792 MIPS32_NOP,
793 MIPS32_B(NEG16(55)), /* b start */
794 MIPS32_NOP,
795 };
796
797 int retval;
798
799 retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
800 38, regs, 0, NULL, 1);
801
802 return retval;
803 }
804
805 int mips32_pracc_read_regs(mips_ejtag_t *ejtag_info, u32 *regs)
806 {
807 u32 code[] = {
808 /* start: */
809 MIPS32_MTC0(2,31,0), /* move $2 to COP0 DeSave */
810 MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $2 = MIPS32_PRACC_PARAM_OUT */
811 MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_OUT)),
812 MIPS32_SW(0,0*4,2), /* sw $0,0*4($2) */
813 MIPS32_SW(1,1*4,2), /* sw $1,1*4($2) */
814 MIPS32_SW(15,15*4,2), /* sw $15,15*4($2) */
815 MIPS32_MFC0(2,31,0), /* move COP0 DeSave to $2 */
816 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
817 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
818 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
819 MIPS32_SW(1,0,15), /* sw $1,($15) */
820 MIPS32_SW(2,0,15), /* sw $2,($15) */
821 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
822 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
823 MIPS32_SW(2,2*4,1), /* sw $2,2*4($1) */
824 MIPS32_SW(3,3*4,1), /* sw $3,3*4($1) */
825 MIPS32_SW(4,4*4,1), /* sw $4,4*4($1) */
826 MIPS32_SW(5,5*4,1), /* sw $5,5*4($1) */
827 MIPS32_SW(6,6*4,1), /* sw $6,6*4($1) */
828 MIPS32_SW(7,7*4,1), /* sw $7,7*4($1) */
829 MIPS32_SW(8,8*4,1), /* sw $8,8*4($1) */
830 MIPS32_SW(9,9*4,1), /* sw $9,9*4($1) */
831 MIPS32_SW(10,10*4,1), /* sw $10,10*4($1) */
832 MIPS32_SW(11,11*4,1), /* sw $11,11*4($1) */
833 MIPS32_SW(12,12*4,1), /* sw $12,12*4($1) */
834 MIPS32_SW(13,13*4,1), /* sw $13,13*4($1) */
835 MIPS32_SW(14,14*4,1), /* sw $14,14*4($1) */
836 MIPS32_SW(16,16*4,1), /* sw $16,16*4($1) */
837 MIPS32_SW(17,17*4,1), /* sw $17,17*4($1) */
838 MIPS32_SW(18,18*4,1), /* sw $18,18*4($1) */
839 MIPS32_SW(19,19*4,1), /* sw $19,19*4($1) */
840 MIPS32_SW(20,20*4,1), /* sw $20,20*4($1) */
841 MIPS32_SW(21,21*4,1), /* sw $21,21*4($1) */
842 MIPS32_SW(22,22*4,1), /* sw $22,22*4($1) */
843 MIPS32_SW(23,23*4,1), /* sw $23,23*4($1) */
844 MIPS32_SW(24,24*4,1), /* sw $24,24*4($1) */
845 MIPS32_SW(25,25*4,1), /* sw $25,25*4($1) */
846 MIPS32_SW(26,26*4,1), /* sw $26,26*4($1) */
847 MIPS32_SW(27,27*4,1), /* sw $27,27*4($1) */
848 MIPS32_SW(28,28*4,1), /* sw $28,28*4($1) */
849 MIPS32_SW(29,29*4,1), /* sw $29,29*4($1) */
850 MIPS32_SW(30,30*4,1), /* sw $30,30*4($1) */
851 MIPS32_SW(31,31*4,1), /* sw $31,31*4($1) */
852
853 MIPS32_MFC0(2,12,0), /* move status to $2 */
854 MIPS32_SW(2,32*4,1), /* sw $2,32*4($1) */
855 MIPS32_MFLO(2), /* move lo to $2 */
856 MIPS32_SW(2,33*4,1), /* sw $2,33*4($1) */
857 MIPS32_MFHI(2), /* move hi to $2 */
858 MIPS32_SW(2,34*4,1), /* sw $2,34*4($1) */
859 MIPS32_MFC0(2,8,0), /* move badvaddr to $2 */
860 MIPS32_SW(2,35*4,1), /* sw $2,35*4($1) */
861 MIPS32_MFC0(2,13,0), /* move cause to $2 */
862 MIPS32_SW(2,36*4,1), /* sw $2,36*4($1) */
863 MIPS32_MFC0(2,24,0), /* move pc to $2 */
864 MIPS32_SW(2,37*4,1), /* sw $2,37*4($1) */
865
866 MIPS32_LW(2,0,15), /* lw $2,($15) */
867 MIPS32_LW(1,0,15), /* lw $1,($15) */
868 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
869 MIPS32_NOP,
870 MIPS32_B(NEG16(60)), /* b start */
871 MIPS32_NOP,
872 };
873
874 int retval;
875
876 retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
877 0, NULL, 38, regs, 1);
878
879 return retval;
880 }

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)