jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / mips64_pracc.c
1 /*
2 * Support for processors implementing MIPS64 instruction set
3 *
4 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
5 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
6 * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
7 *
8 * Based on the work of:
9 * Copyright (C) 2008 by Spencer Oliver
10 * Copyright (C) 2008 by David T.L. Wong
11 * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include "mips64.h"
21 #include "mips64_pracc.h"
22
23 #include <helper/time_support.h>
24 #include <jtag/adapter.h>
25
26 #define STACK_DEPTH 32
27
28 struct mips64_pracc_context {
29 uint64_t *local_iparam;
30 unsigned num_iparam;
31 uint64_t *local_oparam;
32 unsigned num_oparam;
33 const uint32_t *code;
34 unsigned code_len;
35 uint64_t stack[STACK_DEPTH];
36 unsigned stack_offset;
37 struct mips_ejtag *ejtag_info;
38 };
39
40 static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
41 {
42 uint32_t ejtag_ctrl;
43 int nt = 5;
44 int rc;
45
46 while (1) {
47 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
48 ejtag_ctrl = ejtag_info->ejtag_ctrl;
49 rc = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
50 if (rc != ERROR_OK)
51 return rc;
52
53 if (ejtag_ctrl & EJTAG_CTRL_PRACC)
54 break;
55 LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
56 if (nt == 0)
57 return ERROR_JTAG_DEVICE_ERROR;
58 nt--;
59 }
60
61 *ctrl = ejtag_ctrl;
62 return ERROR_OK;
63 }
64
65 static int mips64_pracc_exec_read(struct mips64_pracc_context *ctx, uint64_t address)
66 {
67 struct mips_ejtag *ejtag_info = ctx->ejtag_info;
68 unsigned offset;
69 uint32_t ejtag_ctrl;
70 uint64_t data;
71 int rc;
72
73 if ((address >= MIPS64_PRACC_PARAM_IN)
74 && (address < MIPS64_PRACC_PARAM_IN + ctx->num_iparam * MIPS64_PRACC_DATA_STEP)) {
75
76 offset = (address - MIPS64_PRACC_PARAM_IN) / MIPS64_PRACC_DATA_STEP;
77
78 if (offset >= MIPS64_PRACC_PARAM_IN_SIZE) {
79 LOG_ERROR("Error: iparam size exceeds MIPS64_PRACC_PARAM_IN_SIZE");
80 return ERROR_JTAG_DEVICE_ERROR;
81 }
82
83 if (!ctx->local_iparam) {
84 LOG_ERROR("Error: unexpected reading of input parameter");
85 return ERROR_JTAG_DEVICE_ERROR;
86 }
87
88 data = ctx->local_iparam[offset];
89 LOG_DEBUG("Reading %" PRIx64 " at %" PRIx64, data, address);
90
91 } else if ((address >= MIPS64_PRACC_PARAM_OUT)
92 && (address < MIPS64_PRACC_PARAM_OUT + ctx->num_oparam * MIPS64_PRACC_DATA_STEP)) {
93
94 offset = (address - MIPS64_PRACC_PARAM_OUT) / MIPS64_PRACC_DATA_STEP;
95 if (!ctx->local_oparam) {
96 LOG_ERROR("Error: unexpected reading of output parameter");
97 return ERROR_JTAG_DEVICE_ERROR;
98 }
99
100 data = ctx->local_oparam[offset];
101 LOG_DEBUG("Reading %" PRIx64 " at %" PRIx64, data, address);
102
103 } else if ((address >= MIPS64_PRACC_TEXT)
104 && (address < MIPS64_PRACC_TEXT + ctx->code_len * MIPS64_PRACC_ADDR_STEP)) {
105
106 offset = ((address & ~7ull) - MIPS64_PRACC_TEXT) / MIPS64_PRACC_ADDR_STEP;
107 data = (uint64_t)ctx->code[offset] << 32;
108 if (offset + 1 < ctx->code_len)
109 data |= (uint64_t)ctx->code[offset + 1];
110
111 LOG_DEBUG("Running commands %" PRIx64 " at %" PRIx64, data,
112 address);
113
114 } else if ((address & ~7llu) == MIPS64_PRACC_STACK) {
115
116 /* load from our debug stack */
117 if (ctx->stack_offset == 0) {
118 LOG_ERROR("Error reading from stack: stack is empty");
119 return ERROR_JTAG_DEVICE_ERROR;
120 }
121
122 data = ctx->stack[--ctx->stack_offset];
123 LOG_DEBUG("Reading %" PRIx64 " at %" PRIx64, data, address);
124
125 } else {
126 /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
127 * to start of debug vector */
128
129 data = 0;
130 LOG_ERROR("Error reading unexpected address %" PRIx64, address);
131 return ERROR_JTAG_DEVICE_ERROR;
132 }
133
134 /* Send the data out */
135 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
136 rc = mips_ejtag_drscan_64(ctx->ejtag_info, &data);
137 if (rc != ERROR_OK)
138 return rc;
139
140 /* Clear the access pending bit (let the processor eat!) */
141
142 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
143 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
144 rc = mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
145 if (rc != ERROR_OK)
146 return rc;
147
148 jtag_add_clocks(5);
149
150 return jtag_execute_queue();
151 }
152
153 static int mips64_pracc_exec_write(struct mips64_pracc_context *ctx, uint64_t address)
154 {
155 uint32_t ejtag_ctrl;
156 uint64_t data;
157 unsigned offset;
158 struct mips_ejtag *ejtag_info = ctx->ejtag_info;
159 int rc;
160
161 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
162 rc = mips_ejtag_drscan_64(ctx->ejtag_info, &data);
163 if (rc != ERROR_OK)
164 return rc;
165
166 /* Clear access pending bit */
167 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
168 mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
169 rc = mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
170 if (rc != ERROR_OK)
171 return rc;
172
173 jtag_add_clocks(5);
174 rc = jtag_execute_queue();
175 if (rc != ERROR_OK)
176 return rc;
177
178 LOG_DEBUG("Writing %" PRIx64 " at %" PRIx64, data, address);
179
180 if ((address >= MIPS64_PRACC_PARAM_IN)
181 && (address < MIPS64_PRACC_PARAM_IN + ctx->num_iparam * MIPS64_PRACC_DATA_STEP)) {
182 offset = (address - MIPS64_PRACC_PARAM_IN) / MIPS64_PRACC_DATA_STEP;
183 if (!ctx->local_iparam) {
184 LOG_ERROR("Error: unexpected writing of input parameter");
185 return ERROR_JTAG_DEVICE_ERROR;
186 }
187 ctx->local_iparam[offset] = data;
188 } else if ((address >= MIPS64_PRACC_PARAM_OUT)
189 && (address < MIPS64_PRACC_PARAM_OUT + ctx->num_oparam * MIPS64_PRACC_DATA_STEP)) {
190 offset = (address - MIPS64_PRACC_PARAM_OUT) / MIPS64_PRACC_DATA_STEP;
191 if (!ctx->local_oparam) {
192 LOG_ERROR("Error: unexpected writing of output parameter");
193 return ERROR_JTAG_DEVICE_ERROR;
194 }
195 ctx->local_oparam[offset] = data;
196 } else if (address == MIPS64_PRACC_STACK) {
197 /* save data onto our stack */
198 if (ctx->stack_offset >= STACK_DEPTH) {
199 LOG_ERROR("Error: PrAcc stack depth exceeded");
200 return ERROR_FAIL;
201 }
202 ctx->stack[ctx->stack_offset++] = data;
203 } else {
204 LOG_ERROR("Error writing unexpected address 0x%" PRIx64, address);
205 return ERROR_JTAG_DEVICE_ERROR;
206 }
207
208 return ERROR_OK;
209 }
210
211 int mips64_pracc_exec(struct mips_ejtag *ejtag_info,
212 unsigned code_len, const uint32_t *code,
213 unsigned num_param_in, uint64_t *param_in,
214 unsigned num_param_out, uint64_t *param_out)
215 {
216 uint32_t ejtag_ctrl;
217 uint64_t address = 0, address_prev = 0;
218 struct mips64_pracc_context ctx;
219 int retval;
220 int pass = 0;
221 bool first_time_call = true;
222 unsigned i;
223
224 for (i = 0; i < code_len; i++)
225 LOG_DEBUG("%08" PRIx32, code[i]);
226
227 ctx.local_iparam = param_in;
228 ctx.local_oparam = param_out;
229 ctx.num_iparam = num_param_in;
230 ctx.num_oparam = num_param_out;
231 ctx.code = code;
232 ctx.code_len = code_len;
233 ctx.ejtag_info = ejtag_info;
234 ctx.stack_offset = 0;
235
236 while (true) {
237 uint32_t address32;
238 retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
239 if (retval != ERROR_OK) {
240 LOG_DEBUG("ERROR wait_for_pracc_rw");
241 return retval;
242 }
243 if (pass)
244 address_prev = address;
245 else
246 address_prev = 0;
247 address32 = 0;
248
249 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
250 mips_ejtag_drscan_32(ejtag_info, &address32);
251 LOG_DEBUG("-> %08" PRIx32, address32);
252 address = 0xffffffffff200000ull | address32;
253
254 int psz = (ejtag_ctrl >> 29) & 3;
255 int address20 = address & 7;
256 switch (psz) {
257 case 3:
258 if (address20 != 7) {
259 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz, address20);
260 return ERROR_FAIL;
261 }
262 address &= ~7ull;
263 break;
264 case 2:
265 if (address20 != 0 && address20 != 4) {
266 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz, address20);
267 return ERROR_FAIL;
268 }
269 break;
270 default:
271 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz, address20);
272 return ERROR_FAIL;
273 }
274
275 if (first_time_call && address != MIPS64_PRACC_TEXT) {
276 LOG_ERROR("Error reading address " TARGET_ADDR_FMT " (0x%08llx expected)",
277 address, MIPS64_PRACC_TEXT);
278 return ERROR_JTAG_DEVICE_ERROR;
279 }
280
281 first_time_call = false;
282
283 /* Check for read or write */
284 if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
285 retval = mips64_pracc_exec_write(&ctx, address);
286 if (retval != ERROR_OK) {
287 LOG_ERROR("mips64_pracc_exec_write() failed");
288 return retval;
289 }
290 } else {
291 /* Check to see if its reading at the debug vector. The first pass through
292 * the module is always read at the vector, so the first one we allow. When
293 * the second read from the vector occurs we are done and just exit. */
294 if ((address == MIPS64_PRACC_TEXT) && (pass++)) {
295 LOG_DEBUG("@MIPS64_PRACC_TEXT, address_prev=%" PRIx64, address_prev);
296 break;
297 }
298 retval = mips64_pracc_exec_read(&ctx, address);
299 if (retval != ERROR_OK) {
300 LOG_ERROR("mips64_pracc_exec_read() failed");
301 return retval;
302 }
303
304 }
305 }
306
307 /* stack sanity check */
308 if (ctx.stack_offset != 0)
309 LOG_ERROR("Pracc Stack not zero");
310
311 return ERROR_OK;
312 }
313
314 static int mips64_pracc_read_u64(struct mips_ejtag *ejtag_info, uint64_t addr,
315 uint64_t *buf)
316 {
317 const uint32_t code[] = {
318 /* move $15 to COP0 DeSave */
319 MIPS64_DMTC0(15, 31, 0),
320 /* $15 = MIPS64_PRACC_STACK */
321 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
322 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
323 /* sd $8, ($15) */
324 MIPS64_SD(8, 0, 15),
325 /* load R8 @ param_in[0] = address */
326 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
327 /* ld $8, 0($8), Load $8 with the word @mem[$8] */
328 MIPS64_LD(8, 0, 8),
329 /* sd $8, 0($15) */
330 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),
331 /* ld $8, ($15) */
332 MIPS64_LD(8, 0, 15),
333 MIPS64_SYNC,
334 /* b start */
335 MIPS64_B(NEG16(10)),
336 /* move COP0 DeSave to $15 */
337 MIPS64_DMFC0(15, 31, 0),
338 MIPS64_NOP,
339 MIPS64_NOP,
340 MIPS64_NOP,
341 MIPS64_NOP,
342 MIPS64_NOP,
343 MIPS64_NOP,
344 MIPS64_NOP,
345 MIPS64_NOP,
346 };
347
348 uint64_t param_in[1];
349 param_in[0] = addr;
350
351 LOG_DEBUG("enter mips64_pracc_exec");
352 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
353 ARRAY_SIZE(param_in), param_in, 1, (uint64_t *) buf);
354 }
355
356 static int mips64_pracc_read_mem64(struct mips_ejtag *ejtag_info, uint64_t addr,
357 unsigned count, uint64_t *buf)
358 {
359 int retval = ERROR_OK;
360
361 for (unsigned i = 0; i < count; i++) {
362 retval = mips64_pracc_read_u64(ejtag_info, addr + 8*i, &buf[i]);
363 if (retval != ERROR_OK)
364 return retval;
365 }
366 return retval;
367 }
368
369 static int mips64_pracc_read_u32(struct mips_ejtag *ejtag_info, uint64_t addr,
370 uint32_t *buf)
371 {
372 const uint32_t code[] = {
373 /* move $15 to COP0 DeSave */
374 MIPS64_DMTC0(15, 31, 0),
375 /* $15 = MIPS64_PRACC_STACK */
376 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
377 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
378 /* sd $8, ($15) */
379 MIPS64_SD(8, 0, 15),
380 /* load R8 @ param_in[0] = address */
381 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
382 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
383 MIPS64_LW(8, 0, 8),
384 /* sd $8, 0($9) */
385 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),
386 /* ld $8, ($15) */
387 MIPS64_LD(8, 0, 15),
388 MIPS64_SYNC,
389 /* b start */
390 MIPS64_B(NEG16(10)),
391 /* move COP0 DeSave to $15 */
392 MIPS64_DMFC0(15, 31, 0),
393 MIPS64_NOP,
394 MIPS64_NOP,
395 MIPS64_NOP,
396 MIPS64_NOP,
397 MIPS64_NOP,
398 MIPS64_NOP,
399 MIPS64_NOP,
400 MIPS64_NOP,
401 };
402
403 int retval = ERROR_OK;
404 uint64_t param_in[1];
405 uint64_t param_out[1];
406
407 param_in[0] = addr;
408
409 LOG_DEBUG("enter mips64_pracc_exec");
410 retval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
411 1, param_in, 1, param_out);
412 buf[0] = (uint32_t) param_out[0];
413 return retval;
414 }
415
416 static int mips64_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint64_t addr,
417 unsigned count, uint32_t *buf)
418 {
419 int retval = ERROR_OK;
420
421 for (unsigned i = 0; i < count; i++) {
422 retval = mips64_pracc_read_u32(ejtag_info, addr + 4 * i, &buf[i]);
423 if (retval != ERROR_OK)
424 return retval;
425 }
426 return retval;
427 }
428
429 static int mips64_pracc_read_u16(struct mips_ejtag *ejtag_info, uint64_t addr,
430 uint16_t *buf)
431 {
432 const uint32_t code[] = {
433 /* move $15 to COP0 DeSave */
434 MIPS64_DMTC0(15, 31, 0),
435 /* $15 = MIPS64_PRACC_STACK */
436 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
437 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
438 /* sd $8, ($15) */
439 MIPS64_SD(8, 0, 15),
440 /* load R8 @ param_in[0] = address */
441 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
442 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
443 MIPS64_LHU(8, 0, 8),
444 /* sd $8, 0($9) */
445 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),
446 /* ld $8, ($15) */
447 MIPS64_LD(8, 0, 15),
448 MIPS64_SYNC,
449 /* b start */
450 MIPS64_B(NEG16(10)),
451 /* move COP0 DeSave to $15 */
452 MIPS64_DMFC0(15, 31, 0),
453 MIPS64_NOP,
454 MIPS64_NOP,
455 MIPS64_NOP,
456 MIPS64_NOP,
457 MIPS64_NOP,
458 MIPS64_NOP,
459 MIPS64_NOP,
460 MIPS64_NOP,
461 };
462
463 int retval;
464 uint64_t param_in[1];
465 uint64_t param_out[1];
466
467 param_in[0] = addr;
468
469 LOG_DEBUG("enter mips64_pracc_exec");
470 retval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
471 1, param_in, 1, param_out);
472 buf[0] = (uint16_t)param_out[0];
473 return retval;
474 }
475
476 static int mips64_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint64_t addr,
477 unsigned count, uint16_t *buf)
478 {
479 int retval = ERROR_OK;
480
481 for (unsigned i = 0; i < count; i++) {
482 retval = mips64_pracc_read_u16(ejtag_info, addr + 2*i, &buf[i]);
483 if (retval != ERROR_OK)
484 return retval;
485 }
486 return retval;
487 }
488
489 static int mips64_pracc_read_u8(struct mips_ejtag *ejtag_info, uint64_t addr,
490 uint8_t *buf)
491 {
492 const uint32_t code[] = {
493 /* move $15 to COP0 DeSave */
494 MIPS64_DMTC0(15, 31, 0),
495 /* $15 = MIPS64_PRACC_STACK */
496 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
497 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
498 /* sd $8, ($15) */
499 MIPS64_SD(8, 0, 15),
500 /* load R8 @ param_in[0] = address */
501 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
502 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
503 MIPS64_LBU(8, 0, 8),
504 /* sd $8, 0($9) */
505 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),
506 /* ld $8, ($15) */
507 MIPS64_LD(8, 0, 15),
508 MIPS64_SYNC,
509 /* b start */
510 MIPS64_B(NEG16(10)),
511 /* move COP0 DeSave to $15 */
512 MIPS64_DMFC0(15, 31, 0),
513 MIPS64_NOP,
514 MIPS64_NOP,
515 MIPS64_NOP,
516 MIPS64_NOP,
517 MIPS64_NOP,
518 MIPS64_NOP,
519 MIPS64_NOP,
520 MIPS64_NOP,
521 };
522
523 int retval;
524 uint64_t param_in[1];
525 uint64_t param_out[1];
526
527 param_in[0] = addr;
528
529 LOG_DEBUG("enter mips64_pracc_exec");
530 retval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
531 1, param_in, 1, param_out);
532 buf[0] = (uint8_t)param_out[0];
533 return retval;
534 }
535
536 static int mips64_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint64_t addr,
537 unsigned count, uint8_t *buf)
538 {
539 int retval = ERROR_OK;
540
541 for (unsigned i = 0; i < count; i++) {
542 retval = mips64_pracc_read_u8(ejtag_info, addr + i, &buf[i]);
543 if (retval != ERROR_OK)
544 return retval;
545 }
546 return retval;
547 }
548
549 int mips64_pracc_read_mem(struct mips_ejtag *ejtag_info, uint64_t addr,
550 unsigned size, unsigned count, void *buf)
551 {
552 switch (size) {
553 case 1:
554 return mips64_pracc_read_mem8(ejtag_info, addr, count, buf);
555 case 2:
556 return mips64_pracc_read_mem16(ejtag_info, addr, count, buf);
557 case 4:
558 return mips64_pracc_read_mem32(ejtag_info, addr, count, buf);
559 case 8:
560 return mips64_pracc_read_mem64(ejtag_info, addr, count, buf);
561 }
562 return ERROR_FAIL;
563 }
564
565 static int mips64_pracc_write_u64(struct mips_ejtag *ejtag_info, uint64_t addr,
566 uint64_t *buf)
567 {
568 const uint32_t code[] = {
569 /* move $15 to COP0 DeSave */
570 MIPS64_DMTC0(15, 31, 0),
571 /* $15 = MIPS64_PRACC_STACK */
572 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
573 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
574 /* sd $8, ($15) */
575 MIPS64_SD(8, 0, 15),
576 /* sd $9, ($15) */
577 MIPS64_SD(9, 0, 15),
578 /* load R8 @ param_in[1] = data */
579 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN)-8), 15),
580 /* load R9 @ param_in[0] = address */
581 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
582 /* sd $8, 0($9) */
583 MIPS64_SD(8, 0, 9),
584 MIPS64_SYNCI(9, 0),
585 /* ld $9, ($15) */
586 MIPS64_LD(9, 0, 15),
587 /* ld $8, ($15) */
588 MIPS64_LD(8, 0, 15),
589 MIPS64_SYNC,
590 /* b start */
591 MIPS64_B(NEG16(13)),
592 /* move COP0 DeSave to $15 */
593 MIPS64_DMFC0(15, 31, 0),
594 MIPS64_NOP,
595 MIPS64_NOP,
596 MIPS64_NOP,
597 MIPS64_NOP,
598 MIPS64_NOP,
599 MIPS64_NOP,
600 MIPS64_NOP,
601 MIPS64_NOP,
602 };
603
604 /* TODO remove array */
605 uint64_t param_in[2];
606 param_in[0] = addr;
607 param_in[1] = *buf;
608
609 LOG_DEBUG("enter mips64_pracc_exec");
610 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
611 ARRAY_SIZE(param_in), param_in, 0, NULL);
612 }
613
614 static int mips64_pracc_write_mem64(struct mips_ejtag *ejtag_info,
615 uint64_t addr, unsigned count, uint64_t *buf)
616 {
617 int retval = ERROR_OK;
618
619 for (unsigned i = 0; i < count; i++) {
620 retval = mips64_pracc_write_u64(ejtag_info, addr + 8 * i, &buf[i]);
621 if (retval != ERROR_OK)
622 return retval;
623 }
624 return retval;
625 }
626
627 static int mips64_pracc_write_u32(struct mips_ejtag *ejtag_info, uint64_t addr,
628 uint32_t *buf)
629 {
630 const uint32_t code[] = {
631 MIPS64_DMTC0(15, 31, 0),
632 /* move $15 to COP0 DeSave */
633 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
634 /* $15 = MIPS64_PRACC_STACK */
635 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
636 MIPS64_SD(8, 0, 15),
637 /* sd $8, ($15) */
638 MIPS64_SD(9, 0, 15),
639 /* sd $9, ($15) */
640 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15),
641 /* load R8 @ param_in[1] = data */
642 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
643 /* load R9 @ param_in[0] = address */
644 MIPS64_SW(8, 0, 9),
645 /* sw $8, 0($9) */
646 MIPS64_SYNCI(9, 0),
647 MIPS64_LD(9, 0, 15),
648 /* ld $9, ($15) */
649 MIPS64_LD(8, 0, 15),
650 /* ld $8, ($15) */
651 MIPS64_SYNC,
652 MIPS64_B(NEG16(13)),
653 /* b start */
654 MIPS64_DMFC0(15, 31, 0),
655 /* move COP0 DeSave to $15 */
656 MIPS64_NOP,
657 MIPS64_NOP,
658 MIPS64_NOP,
659 MIPS64_NOP,
660 MIPS64_NOP,
661 MIPS64_NOP,
662 MIPS64_NOP,
663 MIPS64_NOP,
664 };
665
666 /* TODO remove array */
667 uint64_t param_in[1 + 1];
668 param_in[0] = addr;
669 param_in[1] = *buf;
670
671 LOG_DEBUG("enter mips64_pracc_exec");
672 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
673 ARRAY_SIZE(param_in), param_in, 0, NULL);
674 }
675
676 static int mips64_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint64_t addr,
677 unsigned count, uint32_t *buf)
678 {
679 int retval = ERROR_OK;
680
681 for (unsigned i = 0; i < count; i++) {
682 retval = mips64_pracc_write_u32(ejtag_info, addr + 4 * i, &buf[i]);
683 if (retval != ERROR_OK)
684 return retval;
685 }
686 return retval;
687 }
688
689 static int mips64_pracc_write_u16(struct mips_ejtag *ejtag_info, uint64_t addr,
690 uint16_t *buf)
691 {
692 const uint32_t code[] = {
693 /* move $15 to COP0 DeSave */
694 MIPS64_DMTC0(15, 31, 0),
695 /* $15 = MIPS64_PRACC_STACK */
696 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
697 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
698 /* sd $8, ($15) */
699 MIPS64_SD(8, 0, 15),
700 /* sd $9, ($15) */
701 MIPS64_SD(9, 0, 15),
702 /* load R8 @ param_in[1] = data */
703 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15),
704 /* load R9 @ param_in[0] = address */
705 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
706 /* sh $8, 0($9) */
707 MIPS64_SH(8, 0, 9),
708 /* ld $9, ($15) */
709 MIPS64_LD(9, 0, 15),
710 /* ld $8, ($15) */
711 MIPS64_LD(8, 0, 15),
712 MIPS64_SYNC,
713 /* b start */
714 MIPS64_B(NEG16(12)),
715 /* move COP0 DeSave to $15 */
716 MIPS64_DMFC0(15, 31, 0),
717 MIPS64_NOP,
718 MIPS64_NOP,
719 MIPS64_NOP,
720 MIPS64_NOP,
721 MIPS64_NOP,
722 MIPS64_NOP,
723 MIPS64_NOP,
724 MIPS64_NOP,
725 };
726
727 uint64_t param_in[2];
728 param_in[0] = addr;
729 param_in[1] = *buf;
730
731 LOG_DEBUG("enter mips64_pracc_exec");
732 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
733 ARRAY_SIZE(param_in), param_in, 0, NULL);
734 }
735
736 static int mips64_pracc_write_mem16(struct mips_ejtag *ejtag_info,
737 uint64_t addr, unsigned count, uint16_t *buf)
738 {
739 int retval = ERROR_OK;
740
741 for (unsigned i = 0; i < count; i++) {
742 retval = mips64_pracc_write_u16(ejtag_info, addr + 2 * i, &buf[i]);
743 if (retval != ERROR_OK)
744 return retval;
745 }
746 return retval;
747 }
748
749 static int mips64_pracc_write_u8(struct mips_ejtag *ejtag_info, uint64_t addr,
750 uint8_t *buf)
751 {
752 const uint32_t code[] = {
753 /* move $15 to COP0 DeSave */
754 MIPS64_DMTC0(15, 31, 0),
755 /* $15 = MIPS64_PRACC_STACK */
756 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
757 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
758 /* sd $8, ($15) */
759 MIPS64_SD(8, 0, 15),
760 /* sd $9, ($15) */
761 MIPS64_SD(9, 0, 15),
762 /* load R8 @ param_in[1] = data */
763 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15),
764 /* load R9 @ param_in[0] = address */
765 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),
766 /* sh $8, 0($9) */
767 MIPS64_SB(8, 0, 9),
768 /* ld $9, ($15) */
769 MIPS64_LD(9, 0, 15),
770 /* ld $8, ($15) */
771 MIPS64_LD(8, 0, 15),
772 MIPS64_SYNC,
773 /* b start */
774 MIPS64_B(NEG16(12)),
775 /* move COP0 DeSave to $15 */
776 MIPS64_DMFC0(15, 31, 0),
777 MIPS64_NOP,
778 MIPS64_NOP,
779 MIPS64_NOP,
780 MIPS64_NOP,
781 MIPS64_NOP,
782 MIPS64_NOP,
783 MIPS64_NOP,
784 MIPS64_NOP,
785 };
786
787 /* TODO remove array */
788 uint64_t param_in[2];
789 param_in[0] = addr;
790 param_in[1] = *buf;
791
792 LOG_DEBUG("enter mips64_pracc_exec");
793 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
794 ARRAY_SIZE(param_in), param_in, 0, NULL);
795 }
796
797 static int mips64_pracc_write_mem8(struct mips_ejtag *ejtag_info,
798 uint64_t addr, unsigned count, uint8_t *buf)
799 {
800 int retval = ERROR_OK;
801
802 for (unsigned i = 0; i < count; i++) {
803 retval = mips64_pracc_write_u8(ejtag_info, addr + i, &buf[i]);
804 if (retval != ERROR_OK)
805 return retval;
806 }
807 return retval;
808 }
809
810 int mips64_pracc_write_mem(struct mips_ejtag *ejtag_info,
811 uint64_t addr, unsigned size,
812 unsigned count, void *buf)
813 {
814 switch (size) {
815 case 1:
816 return mips64_pracc_write_mem8(ejtag_info, addr, count, buf);
817 case 2:
818 return mips64_pracc_write_mem16(ejtag_info, addr, count, buf);
819 case 4:
820 return mips64_pracc_write_mem32(ejtag_info, addr, count, buf);
821 case 8:
822 return mips64_pracc_write_mem64(ejtag_info, addr, count, buf);
823 }
824 return ERROR_FAIL;
825 }
826
827 int mips64_pracc_write_regs(struct mips_ejtag *ejtag_info, uint64_t *regs)
828 {
829 const uint32_t code[] = {
830 /* move $2 to COP0 DeSave */
831 MIPS64_DMTC0(2, 31, 0),
832 /* $15 = MIPS64_PRACC_STACK */
833 MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_IN)),
834 MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_IN)),
835 /* sd $0, 0*8($2) */
836 MIPS64_LD(1, 1*8, 2),
837 /* sd $1, 1*8($2) */
838 MIPS64_LD(15, 15*8, 2),
839 /* sd $11, ($15) */
840 MIPS64_DMFC0(2, 31, 0),
841 MIPS64_DMTC0(15, 31, 0),
842 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
843 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
844 MIPS64_SD(1, 0, 15),
845 /* $11 = MIPS64_PRACC_PARAM_OUT */
846 MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_IN)),
847 MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_IN)),
848 MIPS64_LD(3, 3*8, 1),
849 MIPS64_LD(4, 4*8, 1),
850 MIPS64_LD(5, 5*8, 1),
851 MIPS64_LD(6, 6*8, 1),
852 MIPS64_LD(7, 7*8, 1),
853 MIPS64_LD(8, 8*8, 1),
854 MIPS64_LD(9, 9*8, 1),
855 MIPS64_LD(10, 10*8, 1),
856 MIPS64_LD(11, 11*8, 1),
857 MIPS64_LD(12, 12*8, 1),
858 MIPS64_LD(13, 13*8, 1),
859 MIPS64_LD(14, 14*8, 1),
860 MIPS64_LD(16, 16*8, 1),
861 MIPS64_LD(17, 17*8, 1),
862 MIPS64_LD(18, 18*8, 1),
863 MIPS64_LD(19, 19*8, 1),
864 MIPS64_LD(20, 20*8, 1),
865 MIPS64_LD(21, 21*8, 1),
866 MIPS64_LD(22, 22*8, 1),
867 MIPS64_LD(23, 23*8, 1),
868 MIPS64_LD(24, 24*8, 1),
869 MIPS64_LD(25, 25*8, 1),
870 MIPS64_LD(26, 26*8, 1),
871 MIPS64_LD(27, 27*8, 1),
872 MIPS64_LD(28, 28*8, 1),
873 MIPS64_LD(29, 29*8, 1),
874 MIPS64_LD(30, 30*8, 1),
875 MIPS64_LD(31, 31*8, 1),
876 MIPS64_LD(2, 32*8, 1),
877 MIPS64_MTLO(2),
878 MIPS64_LD(2, 33*8, 1),
879 MIPS64_MTHI(2),
880 MIPS64_LD(2, MIPS64_NUM_CORE_REGS * 8, 1),
881 MIPS64_DMTC0(2, MIPS64_C0_DEPC, 0),
882 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 2) * 8, 1),
883 MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO0, 0),
884 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 3) * 8, 1),
885 MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO1, 0),
886 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 4) * 8, 1),
887 MIPS64_DMTC0(2, MIPS64_C0_CONTEXT, 0),
888 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 5) * 8, 1),
889 MIPS64_MTC0(2, MIPS64_C0_PAGEMASK, 0),
890 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 6) * 8, 1),
891 MIPS64_MTC0(2, MIPS64_C0_WIRED, 0),
892 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 8) * 8, 1),
893 MIPS64_MTC0(2, MIPS64_C0_COUNT, 0),
894 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 9) * 8, 1),
895 MIPS64_DMTC0(2, MIPS64_C0_ENTRYHI, 0),
896 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 10) * 8, 1),
897 MIPS64_MTC0(2, MIPS64_C0_COMPARE, 0),
898 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 11) * 8, 1),
899 MIPS64_MTC0(2, MIPS64_C0_STATUS, 0),
900 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 12) * 8, 1),
901 MIPS64_MTC0(2, MIPS64_C0_CAUSE, 0),
902 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 13) * 8, 1),
903 MIPS64_DMTC0(2, MIPS64_C0_EPC, 0),
904 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 15) * 8, 1),
905 MIPS64_MTC0(2, MIPS64_C0_CONFIG, 0),
906 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 16) * 8, 1),
907 MIPS64_MTC0(2, MIPS64_C0_LLA, 0),
908 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 21) * 8, 1),
909 MIPS64_DMTC0(2, MIPS64_C0_XCONTEXT, 1),
910 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 22) * 8, 1),
911 MIPS64_MTC0(2, MIPS64_C0_MEMCTRL, 0),
912 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 24) * 8, 1),
913 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 0),
914 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 25) * 8, 1),
915 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 1),
916 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 26) * 8, 1),
917 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 2),
918 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 27) * 8, 1),
919 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 3),
920 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 28) * 8, 1),
921 MIPS64_MTC0(2, MIPS64_C0_ECC, 0),
922 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 29) * 8, 1),
923 MIPS64_MTC0(2, MIPS64_C0_CACHERR, 0),
924 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 30) * 8, 1),
925 MIPS64_MTC0(2, MIPS64_C0_TAGLO, 0),
926 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 31) * 8, 1),
927 MIPS64_MTC0(2, MIPS64_C0_TAGHI, 0),
928 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 32) * 8, 1),
929 MIPS64_DMTC0(2, MIPS64_C0_DATAHI, 0),
930 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 33) * 8, 1),
931 MIPS64_DMTC0(2, MIPS64_C0_EEPC, 0),
932 /* check if FPU is enabled, */
933 MIPS64_MFC0(2, MIPS64_C0_STATUS, 0),
934 MIPS64_SRL(2, 2, 29),
935 MIPS64_ANDI(2, 2, 1),
936 /* skip FPU registers restoration if not */
937 MIPS64_BEQ(0, 2, 77),
938 MIPS64_NOP,
939 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 33) * 8, 1),
940 MIPS64_CTC1(2, MIPS64_C1_FIR, 0),
941 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 32) * 8, 1),
942 MIPS64_CTC1(2, MIPS64_C1_FCSR, 0),
943 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 34) * 8, 1),
944 MIPS64_CTC1(2, MIPS64_C1_FCONFIG, 0),
945 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 35) * 8, 1),
946 MIPS64_CTC1(2, MIPS64_C1_FCCR, 0),
947 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 36) * 8, 1),
948 MIPS64_CTC1(2, MIPS64_C1_FEXR, 0),
949 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 37) * 8, 1),
950 MIPS64_CTC1(2, MIPS64_C1_FENR, 0),
951 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 0) * 8, 1),
952 MIPS64_DMTC1(2, 0, 0),
953 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 1) * 8, 1),
954 MIPS64_DMTC1(2, 1, 0),
955 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 2) * 8, 1),
956 MIPS64_DMTC1(2, 2, 0),
957 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 3) * 8, 1),
958 MIPS64_DMTC1(2, 3, 0),
959 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 4) * 8, 1),
960 MIPS64_DMTC1(2, 4, 0),
961 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 5) * 8, 1),
962 MIPS64_DMTC1(2, 5, 0),
963 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 6) * 8, 1),
964 MIPS64_DMTC1(2, 6, 0),
965 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 7) * 8, 1),
966 MIPS64_DMTC1(2, 7, 0),
967 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 8) * 8, 1),
968 MIPS64_DMTC1(2, 8, 0),
969 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 9) * 8, 1),
970 MIPS64_DMTC1(2, 9, 0),
971 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 10) * 8, 1),
972 MIPS64_DMTC1(2, 10, 0),
973 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 11) * 8, 1),
974 MIPS64_DMTC1(2, 11, 0),
975 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 12) * 8, 1),
976 MIPS64_DMTC1(2, 12, 0),
977 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 13) * 8, 1),
978 MIPS64_DMTC1(2, 13, 0),
979 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 14) * 8, 1),
980 MIPS64_DMTC1(2, 14, 0),
981 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 15) * 8, 1),
982 MIPS64_DMTC1(2, 15, 0),
983 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 16) * 8, 1),
984 MIPS64_DMTC1(2, 16, 0),
985 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 17) * 8, 1),
986 MIPS64_DMTC1(2, 17, 0),
987 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 18) * 8, 1),
988 MIPS64_DMTC1(2, 18, 0),
989 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 19) * 8, 1),
990 MIPS64_DMTC1(2, 19, 0),
991 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 20) * 8, 1),
992 MIPS64_DMTC1(2, 20, 0),
993 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 21) * 8, 1),
994 MIPS64_DMTC1(2, 21, 0),
995 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 22) * 8, 1),
996 MIPS64_DMTC1(2, 22, 0),
997 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 23) * 8, 1),
998 MIPS64_DMTC1(2, 23, 0),
999 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 24) * 8, 1),
1000 MIPS64_DMTC1(2, 24, 0),
1001 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 25) * 8, 1),
1002 MIPS64_DMTC1(2, 25, 0),
1003 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 26) * 8, 1),
1004 MIPS64_DMTC1(2, 26, 0),
1005 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 27) * 8, 1),
1006 MIPS64_DMTC1(2, 27, 0),
1007 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 28) * 8, 1),
1008 MIPS64_DMTC1(2, 28, 0),
1009 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 29) * 8, 1),
1010 MIPS64_DMTC1(2, 29, 0),
1011 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 30) * 8, 1),
1012 MIPS64_DMTC1(2, 30, 0),
1013 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 31) * 8, 1),
1014 MIPS64_DMTC1(2, 31, 0),
1015 MIPS64_LD(2, 2 * 8, 1),
1016 MIPS64_LD(1, 0, 15),
1017 MIPS64_SYNC,
1018 /* b start */
1019 MIPS64_B(NEG16(181)),
1020 /* move COP0 DeSave to $15 */
1021 MIPS64_DMFC0(15, 31, 0),
1022 MIPS64_NOP,
1023 MIPS64_NOP,
1024 MIPS64_NOP,
1025 MIPS64_NOP,
1026 MIPS64_NOP,
1027 MIPS64_NOP,
1028 MIPS64_NOP,
1029 MIPS64_NOP,
1030 };
1031
1032 LOG_DEBUG("enter mips64_pracc_exec");
1033 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
1034 MIPS64_NUM_REGS, regs, 0, NULL);
1035 }
1036
1037 int mips64_pracc_read_regs(struct mips_ejtag *ejtag_info, uint64_t *regs)
1038 {
1039 const uint32_t code[] = {
1040 /* move $2 to COP0 DeSave */
1041 MIPS64_DMTC0(2, 31, 0),
1042 /* $2 = MIPS64_PRACC_PARAM_OUT */
1043 MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_OUT)),
1044 MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_OUT)),
1045 /* sd $0, 0*8($2) */
1046 MIPS64_SD(0, 0*8, 2),
1047 /* sd $1, 1*8($2) */
1048 MIPS64_SD(1, 1*8, 2),
1049 /* sd $15, 15*8($2) */
1050 MIPS64_SD(15, 15*8, 2),
1051 /* move COP0 DeSave to $2 */
1052 MIPS64_DMFC0(2, 31, 0),
1053 /* move $15 to COP0 DeSave */
1054 MIPS64_DMTC0(15, 31, 0),
1055 /* $15 = MIPS64_PRACC_STACK */
1056 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),
1057 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
1058 /* sd $1, ($15) */
1059 MIPS64_SD(1, 0, 15),
1060 /* sd $2, ($15) */
1061 MIPS64_SD(2, 0, 15),
1062 /* $1 = MIPS64_PRACC_PARAM_OUT */
1063 MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_OUT)),
1064 MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_OUT)),
1065 MIPS64_SD(2, 2 * 8, 1),
1066 MIPS64_SD(3, 3 * 8, 1),
1067 MIPS64_SD(4, 4 * 8, 1),
1068 MIPS64_SD(5, 5 * 8, 1),
1069 MIPS64_SD(6, 6 * 8, 1),
1070 MIPS64_SD(7, 7 * 8, 1),
1071 MIPS64_SD(8, 8 * 8, 1),
1072 MIPS64_SD(9, 9 * 8, 1),
1073 MIPS64_SD(10, 10 * 8, 1),
1074 MIPS64_SD(11, 11 * 8, 1),
1075 MIPS64_SD(12, 12 * 8, 1),
1076 MIPS64_SD(13, 13 * 8, 1),
1077 MIPS64_SD(14, 14 * 8, 1),
1078 MIPS64_SD(16, 16 * 8, 1),
1079 MIPS64_SD(17, 17 * 8, 1),
1080 MIPS64_SD(18, 18 * 8, 1),
1081 MIPS64_SD(19, 19 * 8, 1),
1082 MIPS64_SD(20, 20 * 8, 1),
1083 MIPS64_SD(21, 21 * 8, 1),
1084 MIPS64_SD(22, 22 * 8, 1),
1085 MIPS64_SD(23, 23 * 8, 1),
1086 MIPS64_SD(24, 24 * 8, 1),
1087 MIPS64_SD(25, 25 * 8, 1),
1088 MIPS64_SD(26, 26 * 8, 1),
1089 MIPS64_SD(27, 27 * 8, 1),
1090 MIPS64_SD(28, 28 * 8, 1),
1091 MIPS64_SD(29, 29 * 8, 1),
1092 MIPS64_SD(30, 30 * 8, 1),
1093 MIPS64_SD(31, 31 * 8, 1),
1094 MIPS64_MFLO(2),
1095 MIPS64_SD(2, 32 * 8, 1),
1096 MIPS64_MFHI(2),
1097 MIPS64_SD(2, 33 * 8, 1),
1098 MIPS64_DMFC0(2, MIPS64_C0_DEPC, 0),
1099 MIPS64_SD(2, MIPS64_NUM_CORE_REGS * 8, 1),
1100 MIPS64_DMFC0(2, MIPS64_C0_RANDOM, 0),
1101 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 1) * 8, 1),
1102 MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO0, 0),
1103 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 2) * 8, 1),
1104 MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO1, 0),
1105 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 3) * 8, 1),
1106 MIPS64_DMFC0(2, MIPS64_C0_CONTEXT, 0),
1107 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 4) * 8, 1),
1108 MIPS64_MFC0(2, MIPS64_C0_PAGEMASK, 0),
1109 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 5) * 8, 1),
1110 MIPS64_MFC0(2, MIPS64_C0_WIRED, 0),
1111 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 6) * 8, 1),
1112 MIPS64_DMFC0(2, MIPS64_C0_BADVADDR, 0),
1113 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 7) * 8, 1),
1114 MIPS64_MFC0(2, MIPS64_C0_COUNT, 0),
1115 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 8) * 8, 1),
1116 MIPS64_DMFC0(2, MIPS64_C0_ENTRYHI, 0),
1117 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 9) * 8, 1),
1118 MIPS64_MFC0(2, MIPS64_C0_COMPARE, 0),
1119 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 10) * 8, 1),
1120 MIPS64_MFC0(2, MIPS64_C0_STATUS, 0),
1121 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 11) * 8, 1),
1122 MIPS64_MFC0(2, MIPS64_C0_CAUSE, 0),
1123 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 12) * 8, 1),
1124 MIPS64_DMFC0(2, MIPS64_C0_EPC, 0),
1125 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 13) * 8, 1),
1126 MIPS64_MFC0(2, MIPS64_C0_PRID, 0),
1127 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 14) * 8, 1),
1128 MIPS64_MFC0(2, MIPS64_C0_CONFIG, 0),
1129 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 15) * 8, 1),
1130 MIPS64_MFC0(2, MIPS64_C0_LLA, 0),
1131 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 16) * 8, 1),
1132 MIPS64_DMFC0(2, MIPS64_C0_XCONTEXT, 1),
1133 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 21) * 8, 1),
1134 MIPS64_MFC0(2, MIPS64_C0_MEMCTRL, 0),
1135 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 22) * 8, 1),
1136 MIPS64_MFC0(2, MIPS64_C0_DEBUG, 0),
1137 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 23) * 8, 1),
1138 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 0),
1139 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 24) * 8, 1),
1140 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 1),
1141 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 25) * 8, 1),
1142 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 2),
1143 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 26) * 8, 1),
1144 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 3),
1145 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 27) * 8, 1),
1146 MIPS64_MFC0(2, MIPS64_C0_ECC, 0),
1147 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 28) * 8, 1),
1148 MIPS64_MFC0(2, MIPS64_C0_CACHERR, 0),
1149 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 29) * 8, 1),
1150 MIPS64_MFC0(2, MIPS64_C0_TAGLO, 0),
1151 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 30) * 8, 1),
1152 MIPS64_MFC0(2, MIPS64_C0_TAGHI, 0),
1153 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 31) * 8, 1),
1154 MIPS64_DMFC0(2, MIPS64_C0_DATAHI, 0),
1155 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 32) * 8, 1),
1156 MIPS64_DMFC0(2, MIPS64_C0_EEPC, 0),
1157 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 33) * 8, 1),
1158 /* check if FPU is enabled, */
1159 MIPS64_MFC0(2, MIPS64_C0_STATUS, 0),
1160 MIPS64_SRL(2, 2, 29),
1161 MIPS64_ANDI(2, 2, 1),
1162 /* skip FPU registers dump if not */
1163 MIPS64_BEQ(0, 2, 77),
1164 MIPS64_NOP,
1165 MIPS64_CFC1(2, MIPS64_C1_FIR, 0),
1166 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 33) * 8, 1),
1167 MIPS64_CFC1(2, MIPS64_C1_FCSR, 0),
1168 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 32) * 8, 1),
1169 MIPS64_CFC1(2, MIPS64_C1_FCONFIG, 0),
1170 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 34) * 8, 1),
1171 MIPS64_CFC1(2, MIPS64_C1_FCCR, 0),
1172 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 35) * 8, 1),
1173 MIPS64_CFC1(2, MIPS64_C1_FEXR, 0),
1174 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 36) * 8, 1),
1175 MIPS64_CFC1(2, MIPS64_C1_FENR, 0),
1176 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 37) * 8, 1),
1177 MIPS64_DMFC1(2, 0, 0),
1178 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 0) * 8, 1),
1179 MIPS64_DMFC1(2, 1, 0),
1180 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 1) * 8, 1),
1181 MIPS64_DMFC1(2, 2, 0),
1182 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 2) * 8, 1),
1183 MIPS64_DMFC1(2, 3, 0),
1184 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 3) * 8, 1),
1185 MIPS64_DMFC1(2, 4, 0),
1186 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 4) * 8, 1),
1187 MIPS64_DMFC1(2, 5, 0),
1188 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 5) * 8, 1),
1189 MIPS64_DMFC1(2, 6, 0),
1190 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 6) * 8, 1),
1191 MIPS64_DMFC1(2, 7, 0),
1192 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 7) * 8, 1),
1193 MIPS64_DMFC1(2, 8, 0),
1194 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 8) * 8, 1),
1195 MIPS64_DMFC1(2, 9, 0),
1196 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 9) * 8, 1),
1197 MIPS64_DMFC1(2, 10, 0),
1198 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 10) * 8, 1),
1199 MIPS64_DMFC1(2, 11, 0),
1200 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 11) * 8, 1),
1201 MIPS64_DMFC1(2, 12, 0),
1202 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 12) * 8, 1),
1203 MIPS64_DMFC1(2, 13, 0),
1204 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 13) * 8, 1),
1205 MIPS64_DMFC1(2, 14, 0),
1206 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 14) * 8, 1),
1207 MIPS64_DMFC1(2, 15, 0),
1208 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 15) * 8, 1),
1209 MIPS64_DMFC1(2, 16, 0),
1210 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 16) * 8, 1),
1211 MIPS64_DMFC1(2, 17, 0),
1212 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 17) * 8, 1),
1213 MIPS64_DMFC1(2, 18, 0),
1214 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 18) * 8, 1),
1215 MIPS64_DMFC1(2, 19, 0),
1216 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 19) * 8, 1),
1217 MIPS64_DMFC1(2, 20, 0),
1218 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 20) * 8, 1),
1219 MIPS64_DMFC1(2, 21, 0),
1220 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 21) * 8, 1),
1221 MIPS64_DMFC1(2, 22, 0),
1222 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 22) * 8, 1),
1223 MIPS64_DMFC1(2, 23, 0),
1224 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 23) * 8, 1),
1225 MIPS64_DMFC1(2, 24, 0),
1226 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 24) * 8, 1),
1227 MIPS64_DMFC1(2, 25, 0),
1228 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 25) * 8, 1),
1229 MIPS64_DMFC1(2, 26, 0),
1230 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 26) * 8, 1),
1231 MIPS64_DMFC1(2, 27, 0),
1232 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 27) * 8, 1),
1233 MIPS64_DMFC1(2, 28, 0),
1234 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 28) * 8, 1),
1235 MIPS64_DMFC1(2, 29, 0),
1236 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 29) * 8, 1),
1237 MIPS64_DMFC1(2, 30, 0),
1238 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 30) * 8, 1),
1239 MIPS64_DMFC1(2, 31, 0),
1240 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 31) * 8, 1),
1241 MIPS64_LD(2, 0, 15),
1242 MIPS64_LD(1, 0, 15),
1243 MIPS64_SYNC,
1244 /* b start */
1245 MIPS64_B(NEG16(192)),
1246 /* move COP0 DeSave to $15 */
1247 MIPS64_DMFC0(15, 31, 0),
1248 MIPS64_NOP,
1249 MIPS64_NOP,
1250 MIPS64_NOP,
1251 MIPS64_NOP,
1252 MIPS64_NOP,
1253 MIPS64_NOP,
1254 MIPS64_NOP,
1255 MIPS64_NOP,
1256 };
1257
1258 LOG_DEBUG("enter mips64_pracc_exec");
1259 return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
1260 0, NULL, MIPS64_NUM_REGS, regs);
1261 }
1262
1263 /* fastdata upload/download requires an initialized working area
1264 * to load the download code; it should not be called otherwise
1265 * fetch order from the fastdata area
1266 * 1. start addr
1267 * 2. end addr
1268 * 3. data ...
1269 */
1270 int mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info,
1271 struct working_area *source,
1272 bool write_t, uint64_t addr,
1273 unsigned count, uint64_t *buf)
1274 {
1275 uint32_t handler_code[] = {
1276 /* caution when editing, table is modified below */
1277 /* r15 points to the start of this code */
1278 MIPS64_SD(8, MIPS64_FASTDATA_HANDLER_SIZE - 8, 15),
1279 MIPS64_SD(9, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 2, 15),
1280 MIPS64_SD(10, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 3, 15),
1281 MIPS64_SD(11, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 4, 15),
1282 /* start of fastdata area in t0 */
1283 MIPS64_LUI(8, UPPER16(MIPS64_PRACC_FASTDATA_AREA)),
1284 MIPS64_ORI(8, 8, LOWER16(MIPS64_PRACC_FASTDATA_AREA)),
1285 /* start addr in t1 */
1286 MIPS64_LD(9, 0, 8),
1287 /* end addr to t2 */
1288 MIPS64_LD(10, 0, 8),
1289
1290 /* loop: */
1291 /* lw t3,[t8 | r9] */
1292 /* 8 */ MIPS64_LD(11, 0, 0),
1293 /* sw t3,[r9 | r8] */
1294 /* 9 */ MIPS64_SD(11, 0, 0),
1295 /* bne $t2,t1,loop */
1296 MIPS64_BNE(10, 9, NEG16(3)),
1297 /* addi t1,t1,4 */
1298 MIPS64_DADDIU(9, 9, 8),
1299
1300 MIPS64_LD(8, MIPS64_FASTDATA_HANDLER_SIZE - 8, 15),
1301 MIPS64_LD(9, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 2, 15),
1302 MIPS64_LD(10, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 3, 15),
1303 MIPS64_LD(11, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 4, 15),
1304
1305 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_TEXT)),
1306 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_TEXT)),
1307 /* jr start */
1308 MIPS64_JR(15),
1309 /* move COP0 DeSave to $15 */
1310 MIPS64_DMFC0(15, 31, 0),
1311 };
1312
1313 uint32_t jmp_code[] = {
1314 /* addr of working area added below */
1315 /* 0 */ MIPS64_LUI(15, 0),
1316 /* addr of working area added below */
1317 /* 1 */ MIPS64_ORI(15, 15, 0),
1318 /* jump to ram program */
1319 MIPS64_JR(15),
1320 MIPS64_NOP,
1321 };
1322
1323 int retval;
1324 unsigned i;
1325 uint32_t ejtag_ctrl, address32;
1326 uint64_t address, val;
1327
1328 if (source->size < MIPS64_FASTDATA_HANDLER_SIZE)
1329 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1330
1331 if (write_t) {
1332 /* load data from probe at fastdata area */
1333 handler_code[8] = MIPS64_LD(11, 0, 8);
1334 /* store data to RAM @ r9 */
1335 handler_code[9] = MIPS64_SD(11, 0, 9);
1336 } else {
1337 /* load data from RAM @ r9 */
1338 handler_code[8] = MIPS64_LD(11, 0, 9);
1339 /* store data to probe at fastdata area */
1340 handler_code[9] = MIPS64_SD(11, 0, 8);
1341 }
1342
1343 /* write program into RAM */
1344 if (write_t != ejtag_info->fast_access_save) {
1345 mips64_pracc_write_mem(ejtag_info, source->address, 4,
1346 ARRAY_SIZE(handler_code), handler_code);
1347 /* save previous operation to speed to any consecutive read/writes */
1348 ejtag_info->fast_access_save = write_t;
1349 }
1350
1351 LOG_DEBUG("%s using " TARGET_ADDR_FMT " for write handler", __func__,
1352 source->address);
1353 LOG_DEBUG("daddiu: %08" PRIx32, handler_code[11]);
1354
1355 jmp_code[0] |= UPPER16(source->address);
1356 jmp_code[1] |= LOWER16(source->address);
1357 mips64_pracc_exec(ejtag_info,
1358 ARRAY_SIZE(jmp_code), jmp_code,
1359 0, NULL, 0, NULL);
1360
1361 /* next fetch to dmseg should be in FASTDATA_AREA, check */
1362 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
1363 retval = mips_ejtag_drscan_32(ejtag_info, &address32);
1364 if (retval != ERROR_OK)
1365 return retval;
1366 address = 0xffffffffff200000ull | address32;
1367 if ((address & ~7ull) != MIPS64_PRACC_FASTDATA_AREA) {
1368 LOG_ERROR("! @MIPS64_PRACC_FASTDATA_AREA (" TARGET_ADDR_FMT ")", address);
1369 return ERROR_FAIL;
1370 }
1371 /* Send the load start address */
1372 val = addr;
1373 LOG_DEBUG("start: " TARGET_ADDR_FMT, val);
1374 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
1375 mips64_ejtag_fastdata_scan(ejtag_info, 1, &val);
1376
1377 retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
1378 if (retval != ERROR_OK)
1379 return retval;
1380
1381 /* Send the load end address */
1382 val = addr + (count - 1) * 8;
1383 LOG_DEBUG("stop: " TARGET_ADDR_FMT, val);
1384 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
1385 mips64_ejtag_fastdata_scan(ejtag_info, 1, &val);
1386
1387 /* like in legacy code */
1388 unsigned num_clocks = 0;
1389 if (ejtag_info->mode != 0)
1390 num_clocks = ((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000;
1391 LOG_DEBUG("num_clocks=%d", num_clocks);
1392 for (i = 0; i < count; i++) {
1393 jtag_add_clocks(num_clocks);
1394 retval = mips64_ejtag_fastdata_scan(ejtag_info, write_t, buf++);
1395 if (retval != ERROR_OK) {
1396 LOG_ERROR("mips64_ejtag_fastdata_scan failed");
1397 return retval;
1398 }
1399 }
1400
1401 retval = jtag_execute_queue();
1402 if (retval != ERROR_OK) {
1403 LOG_ERROR("jtag_execute_queue failed");
1404 return retval;
1405 }
1406
1407 retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
1408 if (retval != ERROR_OK) {
1409 LOG_ERROR("wait_for_pracc_rw failed");
1410 return retval;
1411 }
1412
1413 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
1414 retval = mips_ejtag_drscan_32(ejtag_info, &address32);
1415 if (retval != ERROR_OK) {
1416 LOG_ERROR("mips_ejtag_drscan_32 failed");
1417 return retval;
1418 }
1419
1420 address = 0xffffffffff200000ull | address32;
1421 if ((address & ~7ull) != MIPS64_PRACC_TEXT)
1422 LOG_ERROR("mini program did not return to start");
1423
1424 return retval;
1425 }

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)