1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 * Support for processors implementing MIPS64 instruction set
6 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
7 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
8 * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
10 * Based on the work of:
11 * Copyright (C) 2008 by Spencer Oliver
12 * Copyright (C) 2008 by David T.L. Wong
13 * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
21 #include "mips64_pracc.h"
23 #include <helper/time_support.h>
24 #include <jtag/adapter.h>
26 #define STACK_DEPTH 32
28 struct mips64_pracc_context
{
29 uint64_t *local_iparam
;
31 uint64_t *local_oparam
;
35 uint64_t stack
[STACK_DEPTH
];
36 unsigned stack_offset
;
37 struct mips_ejtag
*ejtag_info
;
40 static int wait_for_pracc_rw(struct mips_ejtag
*ejtag_info
, uint32_t *ctrl
)
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
);
53 if (ejtag_ctrl
& EJTAG_CTRL_PRACC
)
55 LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
57 return ERROR_JTAG_DEVICE_ERROR
;
65 static int mips64_pracc_exec_read(struct mips64_pracc_context
*ctx
, uint64_t address
)
67 struct mips_ejtag
*ejtag_info
= ctx
->ejtag_info
;
73 if ((address
>= MIPS64_PRACC_PARAM_IN
)
74 && (address
< MIPS64_PRACC_PARAM_IN
+ ctx
->num_iparam
* MIPS64_PRACC_DATA_STEP
)) {
76 offset
= (address
- MIPS64_PRACC_PARAM_IN
) / MIPS64_PRACC_DATA_STEP
;
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
;
83 if (!ctx
->local_iparam
) {
84 LOG_ERROR("Error: unexpected reading of input parameter");
85 return ERROR_JTAG_DEVICE_ERROR
;
88 data
= ctx
->local_iparam
[offset
];
89 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
91 } else if ((address
>= MIPS64_PRACC_PARAM_OUT
)
92 && (address
< MIPS64_PRACC_PARAM_OUT
+ ctx
->num_oparam
* MIPS64_PRACC_DATA_STEP
)) {
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
;
100 data
= ctx
->local_oparam
[offset
];
101 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
103 } else if ((address
>= MIPS64_PRACC_TEXT
)
104 && (address
< MIPS64_PRACC_TEXT
+ ctx
->code_len
* MIPS64_PRACC_ADDR_STEP
)) {
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];
111 LOG_DEBUG("Running commands %" PRIx64
" at %" PRIx64
, data
,
114 } else if ((address
& ~7llu) == MIPS64_PRACC_STACK
) {
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
;
122 data
= ctx
->stack
[--ctx
->stack_offset
];
123 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
126 /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
127 * to start of debug vector */
130 LOG_ERROR("Error reading unexpected address %" PRIx64
, address
);
131 return ERROR_JTAG_DEVICE_ERROR
;
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
);
140 /* Clear the access pending bit (let the processor eat!) */
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
);
150 return jtag_execute_queue();
153 static int mips64_pracc_exec_write(struct mips64_pracc_context
*ctx
, uint64_t address
)
158 struct mips_ejtag
*ejtag_info
= ctx
->ejtag_info
;
161 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_DATA
);
162 rc
= mips_ejtag_drscan_64(ctx
->ejtag_info
, &data
);
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
);
174 rc
= jtag_execute_queue();
178 LOG_DEBUG("Writing %" PRIx64
" at %" PRIx64
, data
, address
);
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
;
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
;
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");
202 ctx
->stack
[ctx
->stack_offset
++] = data
;
204 LOG_ERROR("Error writing unexpected address 0x%" PRIx64
, address
);
205 return ERROR_JTAG_DEVICE_ERROR
;
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
)
217 uint64_t address
= 0, address_prev
= 0;
218 struct mips64_pracc_context ctx
;
221 bool first_time_call
= true;
224 for (i
= 0; i
< code_len
; i
++)
225 LOG_DEBUG("%08" PRIx32
, code
[i
]);
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
;
232 ctx
.code_len
= code_len
;
233 ctx
.ejtag_info
= ejtag_info
;
234 ctx
.stack_offset
= 0;
238 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
239 if (retval
!= ERROR_OK
) {
240 LOG_DEBUG("ERROR wait_for_pracc_rw");
244 address_prev
= address
;
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
;
254 int psz
= (ejtag_ctrl
>> 29) & 3;
255 int address20
= address
& 7;
258 if (address20
!= 7) {
259 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
265 if (address20
!= 0 && address20
!= 4) {
266 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
271 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
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
;
281 first_time_call
= false;
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");
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
);
298 retval
= mips64_pracc_exec_read(&ctx
, address
);
299 if (retval
!= ERROR_OK
) {
300 LOG_ERROR("mips64_pracc_exec_read() failed");
307 /* stack sanity check */
308 if (ctx
.stack_offset
!= 0)
309 LOG_ERROR("Pracc Stack not zero");
314 static int mips64_pracc_read_u64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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] */
330 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
336 /* move COP0 DeSave to $15 */
337 MIPS64_DMFC0(15, 31, 0),
348 uint64_t param_in
[1];
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
);
356 static int mips64_pracc_read_mem64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
357 unsigned count
, uint64_t *buf
)
359 int retval
= ERROR_OK
;
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
)
369 static int mips64_pracc_read_u32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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] */
385 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
391 /* move COP0 DeSave to $15 */
392 MIPS64_DMFC0(15, 31, 0),
403 int retval
= ERROR_OK
;
404 uint64_t param_in
[1];
405 uint64_t param_out
[1];
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];
416 static int mips64_pracc_read_mem32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
417 unsigned count
, uint32_t *buf
)
419 int retval
= ERROR_OK
;
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
)
429 static int mips64_pracc_read_u16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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] */
445 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
451 /* move COP0 DeSave to $15 */
452 MIPS64_DMFC0(15, 31, 0),
464 uint64_t param_in
[1];
465 uint64_t param_out
[1];
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];
476 static int mips64_pracc_read_mem16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
477 unsigned count
, uint16_t *buf
)
479 int retval
= ERROR_OK
;
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
)
489 static int mips64_pracc_read_u8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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] */
505 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
511 /* move COP0 DeSave to $15 */
512 MIPS64_DMFC0(15, 31, 0),
524 uint64_t param_in
[1];
525 uint64_t param_out
[1];
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];
536 static int mips64_pracc_read_mem8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
537 unsigned count
, uint8_t *buf
)
539 int retval
= ERROR_OK
;
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
)
549 int mips64_pracc_read_mem(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
550 unsigned size
, unsigned count
, void *buf
)
554 return mips64_pracc_read_mem8(ejtag_info
, addr
, count
, buf
);
556 return mips64_pracc_read_mem16(ejtag_info
, addr
, count
, buf
);
558 return mips64_pracc_read_mem32(ejtag_info
, addr
, count
, buf
);
560 return mips64_pracc_read_mem64(ejtag_info
, addr
, count
, buf
);
565 static int mips64_pracc_write_u64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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),
592 /* move COP0 DeSave to $15 */
593 MIPS64_DMFC0(15, 31, 0),
604 /* TODO remove array */
605 uint64_t param_in
[2];
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
);
614 static int mips64_pracc_write_mem64(struct mips_ejtag
*ejtag_info
,
615 uint64_t addr
, unsigned count
, uint64_t *buf
)
617 int retval
= ERROR_OK
;
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
)
627 static int mips64_pracc_write_u32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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 */
654 MIPS64_DMFC0(15, 31, 0),
655 /* move COP0 DeSave to $15 */
666 /* TODO remove array */
667 uint64_t param_in
[1 + 1];
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
);
676 static int mips64_pracc_write_mem32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
677 unsigned count
, uint32_t *buf
)
679 int retval
= ERROR_OK
;
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
)
689 static int mips64_pracc_write_u16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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),
715 /* move COP0 DeSave to $15 */
716 MIPS64_DMFC0(15, 31, 0),
727 uint64_t param_in
[2];
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
);
736 static int mips64_pracc_write_mem16(struct mips_ejtag
*ejtag_info
,
737 uint64_t addr
, unsigned count
, uint16_t *buf
)
739 int retval
= ERROR_OK
;
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
)
749 static int mips64_pracc_write_u8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
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
)),
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),
775 /* move COP0 DeSave to $15 */
776 MIPS64_DMFC0(15, 31, 0),
787 /* TODO remove array */
788 uint64_t param_in
[2];
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
);
797 static int mips64_pracc_write_mem8(struct mips_ejtag
*ejtag_info
,
798 uint64_t addr
, unsigned count
, uint8_t *buf
)
800 int retval
= ERROR_OK
;
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
)
810 int mips64_pracc_write_mem(struct mips_ejtag
*ejtag_info
,
811 uint64_t addr
, unsigned size
,
812 unsigned count
, void *buf
)
816 return mips64_pracc_write_mem8(ejtag_info
, addr
, count
, buf
);
818 return mips64_pracc_write_mem16(ejtag_info
, addr
, count
, buf
);
820 return mips64_pracc_write_mem32(ejtag_info
, addr
, count
, buf
);
822 return mips64_pracc_write_mem64(ejtag_info
, addr
, count
, buf
);
827 int mips64_pracc_write_regs(struct mips_ejtag
*ejtag_info
, uint64_t *regs
)
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
)),
836 MIPS64_LD(1, 1*8, 2),
838 MIPS64_LD(15, 15*8, 2),
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
)),
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),
878 MIPS64_LD(2, 33*8, 1),
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),
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),
1019 MIPS64_B(NEG16(181)),
1020 /* move COP0 DeSave to $15 */
1021 MIPS64_DMFC0(15, 31, 0),
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
);
1037 int mips64_pracc_read_regs(struct mips_ejtag
*ejtag_info
, uint64_t *regs
)
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
)),
1059 MIPS64_SD(1, 0, 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),
1095 MIPS64_SD(2, 32 * 8, 1),
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),
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),
1245 MIPS64_B(NEG16(192)),
1246 /* move COP0 DeSave to $15 */
1247 MIPS64_DMFC0(15, 31, 0),
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
);
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
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
)
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 */
1287 /* end addr to t2 */
1288 MIPS64_LD(10, 0, 8),
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)),
1298 MIPS64_DADDIU(9, 9, 8),
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),
1305 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_TEXT
)),
1306 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_TEXT
)),
1309 /* move COP0 DeSave to $15 */
1310 MIPS64_DMFC0(15, 31, 0),
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 */
1325 uint32_t ejtag_ctrl
, address32
;
1326 uint64_t address
, val
;
1328 if (source
->size
< MIPS64_FASTDATA_HANDLER_SIZE
)
1329 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
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);
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);
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
;
1351 LOG_DEBUG("%s using " TARGET_ADDR_FMT
" for write handler", __func__
,
1353 LOG_DEBUG("daddiu: %08" PRIx32
, handler_code
[11]);
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
,
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
)
1366 address
= 0xffffffffff200000ull
| address32
;
1367 if ((address
& ~7ull) != MIPS64_PRACC_FASTDATA_AREA
) {
1368 LOG_ERROR("! @MIPS64_PRACC_FASTDATA_AREA (" TARGET_ADDR_FMT
")", address
);
1371 /* Send the load start address */
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
);
1377 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
1378 if (retval
!= ERROR_OK
)
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
);
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");
1401 retval
= jtag_execute_queue();
1402 if (retval
!= ERROR_OK
) {
1403 LOG_ERROR("jtag_execute_queue failed");
1407 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
1408 if (retval
!= ERROR_OK
) {
1409 LOG_ERROR("wait_for_pracc_rw failed");
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");
1420 address
= 0xffffffffff200000ull
| address32
;
1421 if ((address
& ~7ull) != MIPS64_PRACC_TEXT
)
1422 LOG_ERROR("mini program did not return to start");
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)