Duane Ellis: fix warnings
[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;
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 return retval;
288
289 count -= blocksize;
290 addr += blocksize;
291 bytesread += blocksize;
292 }
293
294 return retval;
295 }
296
297 int mips32_pracc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
298 {
299 u32 code[] = {
300 /* start: */
301 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
302 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
303 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
304 MIPS32_SW(8,0,15), /* sw $8,($15) */
305 MIPS32_SW(9,0,15), /* sw $9,($15) */
306 MIPS32_SW(10,0,15), /* sw $10,($15) */
307 MIPS32_SW(11,0,15), /* sw $10,($15) */
308
309 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
310 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
311 MIPS32_LW(9,0,8), /* $9=mem[$8]; read addr */
312 MIPS32_LW(10,4,8), /* $10=mem[$8+4]; read count */
313 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11=MIPS32_PRACC_PARAM_OUT */
314 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
315 MIPS32_NOP,
316 /* loop: */
317 MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
318 MIPS32_NOP,
319
320 MIPS32_LHU(12,0,9), /* lw $12,0($9), Load $12 with the halfword @mem[$9] */
321 MIPS32_SW(12,0,11), /* sw $12,0($11) */
322
323 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
324 MIPS32_ADDI(9,9,2), /* $9+=2 */
325 MIPS32_ADDI(11,11,4), /* $11+=4 */
326 MIPS32_NOP,
327 MIPS32_B(NEG16(9)), /* b loop */
328 MIPS32_NOP,
329
330 MIPS32_LW(11,0,15), /* sw $11,($15) */
331 MIPS32_LW(10,0,15), /* sw $10,($15) */
332 MIPS32_LW(9,0,15), /* sw $9,($15) */
333 MIPS32_LW(8,0,15), /* sw $8,($15) */
334 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
335 MIPS32_NOP,
336 MIPS32_B(NEG16(31)), /* b start */
337 MIPS32_NOP,
338 };
339
340 // /* TODO remove array */
341 u32 param_out[count];
342 int i;
343
344 // int retval;
345 int blocksize;
346 int bytesread;
347 u32 param_in[2];
348
349 bytesread = 0;
350
351 //while (count > 0)
352 {
353 blocksize = count;
354 if (count > 0x400)
355 blocksize = 0x400;
356
357 param_in[0] = addr;
358 param_in[1] = blocksize;
359
360 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
361 sizeof(param_in)/sizeof(param_in[0]), param_in, count, param_out, 1);
362
363 // count -= blocksize;
364 // addr += blocksize;
365 // bytesread += blocksize;
366 }
367
368 for (i = 0; i < count; i++)
369 {
370 buf[i] = param_out[i];
371 }
372
373 return ERROR_OK;
374 }
375
376 int mips32_pracc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
377 {
378 u32 code[] = {
379 /* start: */
380 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
381 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
382 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
383 MIPS32_SW(8,0,15), /* sw $8,($15) */
384 MIPS32_SW(9,0,15), /* sw $9,($15) */
385 MIPS32_SW(10,0,15), /* sw $10,($15) */
386 MIPS32_SW(11,0,15), /* sw $10,($15) */
387
388 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
389 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
390 MIPS32_LW(9,0,8), /* $9=mem[$8]; read addr */
391 MIPS32_LW(10,4,8), /* $10=mem[$8+4]; read count */
392 MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11=MIPS32_PRACC_PARAM_OUT */
393 MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
394 MIPS32_NOP,
395 /* loop: */
396 MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
397 MIPS32_NOP,
398
399 MIPS32_LBU(12,0,9), /* lw $12,0($9), Load t4 with the byte @mem[t1] */
400 MIPS32_SW(12,0,11), /* sw $12,0($11) */
401
402 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
403 MIPS32_ADDI(9,9,1), /* $9+=1 */
404 MIPS32_ADDI(11,11,4), /* $11+=4 */
405 MIPS32_NOP,
406 MIPS32_B(NEG16(9)), /* b loop */
407 MIPS32_NOP,
408 /* end: */
409 MIPS32_LW(11,0,15), /* sw $11,($15) */
410 MIPS32_LW(10,0,15), /* sw $10,($15) */
411 MIPS32_LW(9,0,15), /* sw $9,($15) */
412 MIPS32_LW(8,0,15), /* sw $8,($15) */
413 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
414 MIPS32_NOP,
415 MIPS32_B(NEG16(31)), /* b start */
416 MIPS32_NOP,
417 };
418
419 // /* TODO remove array */
420 u32 param_out[count];
421 int i;
422
423 // int retval;
424 int blocksize;
425 int bytesread;
426 u32 param_in[2];
427
428 bytesread = 0;
429
430 // while (count > 0)
431 {
432 blocksize = count;
433 if (count > 0x400)
434 blocksize = 0x400;
435
436 param_in[0] = addr;
437 param_in[1] = blocksize;
438
439 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
440 sizeof(param_in)/sizeof(param_in[0]), param_in, count, param_out, 1);
441
442 // count -= blocksize;
443 // addr += blocksize;
444 // bytesread += blocksize;
445 }
446
447 for (i = 0; i < count; i++)
448 {
449 buf[i] = param_out[i];
450 }
451
452 return ERROR_OK;
453 }
454
455 int mips32_pracc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
456 {
457 switch (size)
458 {
459 case 1:
460 return mips32_pracc_write_mem8(ejtag_info, addr, count, (u8*)buf);
461 case 2:
462 return mips32_pracc_write_mem16(ejtag_info, addr, count,(u16*)buf);
463 case 4:
464 return mips32_pracc_write_mem32(ejtag_info, addr, count, (u32*)buf);
465 }
466
467 return ERROR_OK;
468 }
469
470 int mips32_pracc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
471 {
472 u32 code[] = {
473 /* start: */
474 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
475 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
476 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
477 MIPS32_SW(8,0,15), /* sw $8,($15) */
478 MIPS32_SW(9,0,15), /* sw $9,($15) */
479 MIPS32_SW(10,0,15), /* sw $10,($15) */
480 MIPS32_SW(11,0,15), /* sw $10,($15) */
481
482 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
483 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
484 MIPS32_LW(9,0,8), /* Load write addr to $9 */
485 MIPS32_LW(10,4,8), /* Load write count to $10 */
486 MIPS32_ADDI(8,8,8), /* $8+=8 */
487 MIPS32_NOP,
488 /* loop: */
489 MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
490 MIPS32_NOP,
491
492 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
493 MIPS32_SW(11,0,9), /* sw $11,0($9) */
494
495 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
496 MIPS32_ADDI(9,9,4), /* $9+=4 */
497 MIPS32_ADDI(8,8,4), /* $8+=4 */
498 MIPS32_NOP,
499 MIPS32_B(NEG16(9)), /* b loop */
500 MIPS32_NOP,
501 /* end: */
502 MIPS32_LW(11,0,15), /* sw $11,($15) */
503 MIPS32_LW(10,0,15), /* sw $10,($15) */
504 MIPS32_LW(9,0,15), /* sw $9,($15) */
505 MIPS32_LW(8,0,15), /* sw $8,($15) */
506 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
507 MIPS32_NOP,
508 MIPS32_B(NEG16(30)), /* b start */
509 MIPS32_NOP,
510 };
511
512 /* TODO remove array */
513 u32 param_in[count+2];
514 param_in[0] = addr;
515 param_in[1] = count;
516
517 memcpy(&param_in[2], buf, count * sizeof(u32));
518
519 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
520 sizeof(param_in)/sizeof(param_in[0]),param_in, 0, NULL, 1);
521
522 return ERROR_OK;
523 }
524
525 int mips32_pracc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
526 {
527 u32 code[] = {
528 /* start: */
529 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
530 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
531 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
532 MIPS32_SW(8,0,15), /* sw $8,($15) */
533 MIPS32_SW(9,0,15), /* sw $9,($15) */
534 MIPS32_SW(10,0,15), /* sw $10,($15) */
535 MIPS32_SW(11,0,15), /* sw $10,($15) */
536
537 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
538 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
539 MIPS32_LW(9,0,8), /* Load write addr to $9 */
540 MIPS32_LW(10,4,8), /* Load write count to $10 */
541 MIPS32_ADDI(8,8,8), /* $8+=8 */
542 MIPS32_NOP,
543 /* loop: */
544 MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
545 MIPS32_NOP,
546
547 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
548 MIPS32_SH(11,0,9), /* sh $11,0($9) */
549
550 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
551 MIPS32_ADDI(9,9,2), /* $9+=2 */
552 MIPS32_ADDI(8,8,4), /* $8+=4 */
553
554 MIPS32_NOP,
555 MIPS32_B(NEG16(9)), /* b loop */
556 MIPS32_NOP,
557 /* end: */
558 MIPS32_LW(11,0,15), /* sw $11,($15) */
559 MIPS32_LW(10,0,15), /* sw $10,($15) */
560 MIPS32_LW(9,0,15), /* sw $9,($15) */
561 MIPS32_LW(8,0,15), /* sw $8,($15) */
562 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
563 MIPS32_NOP,
564 MIPS32_B(NEG16(30)), /* b start */
565 MIPS32_NOP,
566 };
567
568 /* TODO remove array */
569 u32 param_in[count+2];
570 int i;
571 param_in[0] = addr;
572 param_in[1] = count;
573
574 for (i = 0; i < count; i++)
575 {
576 param_in[i+2] = buf[i];
577 }
578
579 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
580 sizeof(param_in)/sizeof(param_in[0]), param_in, 0, NULL, 1);
581
582 return ERROR_OK;
583 }
584
585 int mips32_pracc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
586 {
587 u32 code[] = {
588 /* start: */
589 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
590 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
591 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
592 MIPS32_SW(8,0,15), /* sw $8,($15) */
593 MIPS32_SW(9,0,15), /* sw $9,($15) */
594 MIPS32_SW(10,0,15), /* sw $10,($15) */
595 MIPS32_SW(11,0,15), /* sw $10,($15) */
596
597 MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
598 MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
599 MIPS32_LW(9,0,8), /* Load write addr to $9 */
600 MIPS32_LW(10,4,8), /* Load write count to $10 */
601 MIPS32_ADDI(8,8,8), /* $8+=8 */
602 MIPS32_NOP,
603 /* loop: */
604 MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
605 MIPS32_NOP,
606
607 MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
608 MIPS32_SB(11,0,9), /* sb $11,0($9) */
609
610 MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
611 MIPS32_ADDI(9,9,1), /* $9+=1 */
612 MIPS32_ADDI(8,8,4), /* $8+=4 */
613
614 MIPS32_NOP,
615 MIPS32_B(NEG16(9)), /* b loop */
616 MIPS32_NOP,
617 /* end: */
618 MIPS32_LW(11,0,15), /* sw $11,($15) */
619 MIPS32_LW(10,0,15), /* sw $10,($15) */
620 MIPS32_LW(9,0,15), /* sw $9,($15) */
621 MIPS32_LW(8,0,15), /* sw $8,($15) */
622 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
623 MIPS32_NOP,
624 MIPS32_B(NEG16(30)), /* b start */
625 MIPS32_NOP,
626 };
627
628 /* TODO remove array */
629 u32 param_in[count+2];
630 int retval;
631 int i;
632 param_in[0] = addr;
633 param_in[1] = count;
634
635 for (i = 0; i < count; i++)
636 {
637 param_in[i+2] = buf[i];
638 }
639
640 retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
641 sizeof(param_in)/sizeof(param_in[0]), param_in, 0, NULL, 1);
642
643 return retval;
644 }
645
646 int mips32_pracc_write_regs(mips_ejtag_t *ejtag_info, u32 *regs)
647 {
648 /* TODO restore all core registers */
649
650 u32 code[] = {
651 /* start: */
652 MIPS32_MTC0(2,31,0), /* move $2 to COP0 DeSave */
653 MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $2 = MIPS32_PRACC_PARAM_IN */
654 MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_IN)),
655 /*MIPS32_LW(0,0*4,2),*/ /* lw $0,0*4($2) */
656 MIPS32_LW(1,1*4,2), /* lw $1,1*4($2) */
657 MIPS32_MFC0(2,31,0), /* move COP0 DeSave to $2 */
658
659 MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */
660 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $1 = MIPS32_PRACC_PARAM_IN */
661 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_IN)),
662 MIPS32_LW(2,2*4,1), /* lw $2,2*4($1) */
663 MIPS32_LW(3,3*4,1), /* lw $3,3*4($1) */
664 MIPS32_LW(4,4*4,1), /* lw $4,4*4($1) */
665 MIPS32_LW(5,5*4,1), /* lw $5,5*4($1) */
666 MIPS32_LW(6,6*4,1), /* lw $6,6*4($1) */
667 MIPS32_LW(7,7*4,1), /* lw $7,7*4($1) */
668 MIPS32_LW(8,8*4,1), /* lw $8,8*4($1) */
669 MIPS32_LW(9,9*4,1), /* lw $9,9*4($1) */
670 MIPS32_LW(10,10*4,1), /* lw $10,10*4($1) */
671 MIPS32_LW(11,11*4,1), /* lw $11,11*4($1) */
672 MIPS32_LW(12,12*4,1), /* lw $12,12*4($1) */
673 MIPS32_LW(13,13*4,1), /* lw $13,13*4($1) */
674 MIPS32_LW(14,14*4,1), /* lw $14,14*4($1) */
675 MIPS32_LW(15,15*4,1), /* lw $15,15*4($1) */
676 MIPS32_LW(16,16*4,1), /* lw $16,16*4($1) */
677 MIPS32_LW(17,17*4,1), /* lw $17,17*4($1) */
678 MIPS32_LW(18,18*4,1), /* lw $18,18*4($1) */
679 MIPS32_LW(19,19*4,1), /* lw $19,19*4($1) */
680 MIPS32_LW(20,20*4,1), /* lw $20,20*4($1) */
681 MIPS32_LW(21,21*4,1), /* lw $21,21*4($1) */
682 MIPS32_LW(22,22*4,1), /* lw $22,22*4($1) */
683 MIPS32_LW(23,23*4,1), /* lw $23,23*4($1) */
684 MIPS32_LW(24,24*4,1), /* lw $24,24*4($1) */
685 MIPS32_LW(25,25*4,1), /* lw $25,25*4($1) */
686 MIPS32_LW(26,26*4,1), /* lw $26,26*4($1) */
687 MIPS32_LW(27,27*4,1), /* lw $27,27*4($1) */
688 MIPS32_LW(28,28*4,1), /* lw $28,28*4($1) */
689 MIPS32_LW(29,29*4,1), /* lw $29,29*4($1) */
690 MIPS32_LW(30,30*4,1), /* lw $30,30*4($1) */
691 MIPS32_LW(31,31*4,1), /* lw $31,31*4($1) */
692
693 MIPS32_MFC0(1,31,0), /* move COP0 DeSave to $1 */
694 MIPS32_NOP,
695 MIPS32_B(NEG16(41)), /* b start */
696 MIPS32_NOP,
697 };
698
699 int retval;
700
701 retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
702 32, regs, 0, NULL, 1);
703
704 return retval;
705 }
706
707 int mips32_pracc_read_regs(mips_ejtag_t *ejtag_info, u32 *regs)
708 {
709 u32 code[] = {
710 /* start: */
711 MIPS32_MTC0(2,31,0), /* move $2 to COP0 DeSave */
712 MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $2 = MIPS32_PRACC_PARAM_OUT */
713 MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_OUT)),
714 MIPS32_SW(0,0*4,2), /* sw $0,0*4($2) */
715 MIPS32_SW(1,1*4,2), /* sw $1,1*4($2) */
716 MIPS32_SW(15,15*4,2), /* sw $15,15*4($2) */
717 MIPS32_MFC0(2,31,0), /* move COP0 DeSave to $2 */
718 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
719 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
720 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
721 MIPS32_SW(1,0,15), /* sw $1,($15) */
722 MIPS32_SW(2,0,15), /* sw $2,($15) */
723 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
724 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
725 MIPS32_SW(2,2*4,1), /* sw $2,2*4($1) */
726 MIPS32_SW(3,3*4,1), /* sw $3,3*4($1) */
727 MIPS32_SW(4,4*4,1), /* sw $4,4*4($1) */
728 MIPS32_SW(5,5*4,1), /* sw $5,5*4($1) */
729 MIPS32_SW(6,6*4,1), /* sw $6,6*4($1) */
730 MIPS32_SW(7,7*4,1), /* sw $7,7*4($1) */
731 MIPS32_SW(8,8*4,1), /* sw $8,8*4($1) */
732 MIPS32_SW(9,9*4,1), /* sw $9,9*4($1) */
733 MIPS32_SW(10,10*4,1), /* sw $10,10*4($1) */
734 MIPS32_SW(11,11*4,1), /* sw $11,11*4($1) */
735 MIPS32_SW(12,12*4,1), /* sw $12,12*4($1) */
736 MIPS32_SW(13,13*4,1), /* sw $13,13*4($1) */
737 MIPS32_SW(14,14*4,1), /* sw $14,14*4($1) */
738 MIPS32_SW(16,16*4,1), /* sw $16,16*4($1) */
739 MIPS32_SW(17,17*4,1), /* sw $17,17*4($1) */
740 MIPS32_SW(18,18*4,1), /* sw $18,18*4($1) */
741 MIPS32_SW(19,19*4,1), /* sw $19,19*4($1) */
742 MIPS32_SW(20,20*4,1), /* sw $20,20*4($1) */
743 MIPS32_SW(21,21*4,1), /* sw $21,21*4($1) */
744 MIPS32_SW(22,22*4,1), /* sw $22,22*4($1) */
745 MIPS32_SW(23,23*4,1), /* sw $23,23*4($1) */
746 MIPS32_SW(24,24*4,1), /* sw $24,24*4($1) */
747 MIPS32_SW(25,25*4,1), /* sw $25,25*4($1) */
748 MIPS32_SW(26,26*4,1), /* sw $26,26*4($1) */
749 MIPS32_SW(27,27*4,1), /* sw $27,27*4($1) */
750 MIPS32_SW(28,28*4,1), /* sw $28,28*4($1) */
751 MIPS32_SW(29,29*4,1), /* sw $29,29*4($1) */
752 MIPS32_SW(30,30*4,1), /* sw $30,30*4($1) */
753 MIPS32_SW(31,31*4,1), /* sw $31,31*4($1) */
754
755 MIPS32_MFC0(2,12,0), /* move status to $2 */
756 MIPS32_SW(2,32*4,1), /* sw $2,32*4($1) */
757 MIPS32_LO(2), /* move lo to $2 */
758 MIPS32_SW(2,33*4,1), /* sw $2,33*4($1) */
759 MIPS32_HI(2), /* move hi to $2 */
760 MIPS32_SW(2,34*4,1), /* sw $2,34*4($1) */
761 MIPS32_MFC0(2,8,0), /* move badvaddr to $2 */
762 MIPS32_SW(2,35*4,1), /* sw $2,35*4($1) */
763 MIPS32_MFC0(2,13,0), /* move cause to $2 */
764 MIPS32_SW(2,36*4,1), /* sw $2,36*4($1) */
765 MIPS32_MFC0(2,24,0), /* move pc to $2 */
766 MIPS32_SW(2,37*4,1), /* sw $2,37*4($1) */
767
768 MIPS32_LW(2,0,15), /* sw $2,($15) */
769 MIPS32_LW(1,0,15), /* sw $1,($15) */
770 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
771 MIPS32_NOP,
772 MIPS32_B(NEG16(60)), /* b start */
773 MIPS32_NOP,
774 };
775
776 int retval;
777
778 retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
779 0, NULL, 38, regs, 1);
780
781 return retval;
782 }

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)