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

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)