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

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)