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

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)