2 * Support for processors implementing MIPS64 instruction set
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>
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
13 * SPDX-License-Identifier: GPL-2.0-or-later
21 #include "mips64_pracc.h"
23 #include "time_support.h"
25 #define STACK_DEPTH 32
28 uint64_t *local_iparam
;
30 uint64_t *local_oparam
;
34 uint64_t stack
[STACK_DEPTH
];
35 unsigned stack_offset
;
36 struct mips_ejtag
*ejtag_info
;
37 } mips64_pracc_context
;
39 static int wait_for_pracc_rw(struct mips_ejtag
*ejtag_info
, uint32_t *ctrl
)
46 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
47 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
;
48 rc
= mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
52 if (ejtag_ctrl
& EJTAG_CTRL_PRACC
)
54 LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
56 return ERROR_JTAG_DEVICE_ERROR
;
64 static int mips64_pracc_exec_read(mips64_pracc_context
*ctx
, uint64_t address
)
66 struct mips_ejtag
*ejtag_info
= ctx
->ejtag_info
;
72 if ((address
>= MIPS64_PRACC_PARAM_IN
)
73 && (address
< MIPS64_PRACC_PARAM_IN
+ ctx
->num_iparam
* MIPS64_PRACC_DATA_STEP
)) {
75 offset
= (address
- MIPS64_PRACC_PARAM_IN
) / MIPS64_PRACC_DATA_STEP
;
77 if (offset
>= MIPS64_PRACC_PARAM_IN_SIZE
) {
78 LOG_ERROR("Error: iparam size exceeds MIPS64_PRACC_PARAM_IN_SIZE");
79 return ERROR_JTAG_DEVICE_ERROR
;
82 if (ctx
->local_iparam
== NULL
) {
83 LOG_ERROR("Error: unexpected reading of input parameter");
84 return ERROR_JTAG_DEVICE_ERROR
;
87 data
= ctx
->local_iparam
[offset
];
88 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
90 } else if ((address
>= MIPS64_PRACC_PARAM_OUT
)
91 && (address
< MIPS64_PRACC_PARAM_OUT
+ ctx
->num_oparam
* MIPS64_PRACC_DATA_STEP
)) {
93 offset
= (address
- MIPS64_PRACC_PARAM_OUT
) / MIPS64_PRACC_DATA_STEP
;
94 if (ctx
->local_oparam
== NULL
) {
95 LOG_ERROR("Error: unexpected reading of output parameter");
96 return ERROR_JTAG_DEVICE_ERROR
;
99 data
= ctx
->local_oparam
[offset
];
100 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
102 } else if ((address
>= MIPS64_PRACC_TEXT
)
103 && (address
< MIPS64_PRACC_TEXT
+ ctx
->code_len
* MIPS64_PRACC_ADDR_STEP
)) {
105 offset
= ((address
& ~7ull) - MIPS64_PRACC_TEXT
) / MIPS64_PRACC_ADDR_STEP
;
106 data
= (uint64_t)ctx
->code
[offset
] << 32;
107 if (offset
+ 1 < ctx
->code_len
)
108 data
|= (uint64_t)ctx
->code
[offset
+ 1];
110 LOG_DEBUG("Running commands %" PRIx64
" at %" PRIx64
, data
,
113 } else if ((address
& ~7llu) == MIPS64_PRACC_STACK
) {
115 /* load from our debug stack */
116 if (ctx
->stack_offset
== 0) {
117 LOG_ERROR("Error reading from stack: stack is empty");
118 return ERROR_JTAG_DEVICE_ERROR
;
121 data
= ctx
->stack
[--ctx
->stack_offset
];
122 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
125 /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
126 * to start of debug vector */
129 LOG_ERROR("Error reading unexpected address %" PRIx64
, address
);
130 return ERROR_JTAG_DEVICE_ERROR
;
133 /* Send the data out */
134 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_DATA
);
135 rc
= mips_ejtag_drscan_64(ctx
->ejtag_info
, &data
);
139 /* Clear the access pending bit (let the processor eat!) */
141 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_PRACC
;
142 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_CONTROL
);
143 rc
= mips_ejtag_drscan_32(ctx
->ejtag_info
, &ejtag_ctrl
);
149 return jtag_execute_queue();
152 static int mips64_pracc_exec_write(mips64_pracc_context
*ctx
, uint64_t address
)
157 struct mips_ejtag
*ejtag_info
= ctx
->ejtag_info
;
160 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_DATA
);
161 rc
= mips_ejtag_drscan_64(ctx
->ejtag_info
, &data
);
165 /* Clear access pending bit */
166 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_PRACC
;
167 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_CONTROL
);
168 rc
= mips_ejtag_drscan_32(ctx
->ejtag_info
, &ejtag_ctrl
);
173 rc
= jtag_execute_queue();
177 LOG_DEBUG("Writing %" PRIx64
" at %" PRIx64
, data
, address
);
179 if ((address
>= MIPS64_PRACC_PARAM_IN
)
180 && (address
< MIPS64_PRACC_PARAM_IN
+ ctx
->num_iparam
* MIPS64_PRACC_DATA_STEP
)) {
181 offset
= (address
- MIPS64_PRACC_PARAM_IN
) / MIPS64_PRACC_DATA_STEP
;
182 if (ctx
->local_iparam
== NULL
) {
183 LOG_ERROR("Error: unexpected writing of input parameter");
184 return ERROR_JTAG_DEVICE_ERROR
;
186 ctx
->local_iparam
[offset
] = data
;
187 } else if ((address
>= MIPS64_PRACC_PARAM_OUT
)
188 && (address
< MIPS64_PRACC_PARAM_OUT
+ ctx
->num_oparam
* MIPS64_PRACC_DATA_STEP
)) {
189 offset
= (address
- MIPS64_PRACC_PARAM_OUT
) / MIPS64_PRACC_DATA_STEP
;
190 if (ctx
->local_oparam
== NULL
) {
191 LOG_ERROR("Error: unexpected writing of output parameter");
192 return ERROR_JTAG_DEVICE_ERROR
;
194 ctx
->local_oparam
[offset
] = data
;
195 } else if (address
== MIPS64_PRACC_STACK
) {
196 /* save data onto our stack */
197 if (ctx
->stack_offset
>= STACK_DEPTH
) {
198 LOG_ERROR("Error: PrAcc stack depth exceeded");
201 ctx
->stack
[ctx
->stack_offset
++] = data
;
203 LOG_ERROR("Error writing unexpected address 0x%" PRIx64
, address
);
204 return ERROR_JTAG_DEVICE_ERROR
;
210 int mips64_pracc_exec(struct mips_ejtag
*ejtag_info
,
211 unsigned code_len
, const uint32_t *code
,
212 unsigned num_param_in
, uint64_t *param_in
,
213 unsigned num_param_out
, uint64_t *param_out
)
216 uint64_t address
= 0, address_prev
= 0, data
;
217 mips64_pracc_context ctx
;
220 bool first_time_call
= true;
223 for (i
= 0; i
< code_len
; i
++)
224 LOG_DEBUG("%08" PRIx32
, code
[i
]);
226 ctx
.local_iparam
= param_in
;
227 ctx
.local_oparam
= param_out
;
228 ctx
.num_iparam
= num_param_in
;
229 ctx
.num_oparam
= num_param_out
;
231 ctx
.code_len
= code_len
;
232 ctx
.ejtag_info
= ejtag_info
;
233 ctx
.stack_offset
= 0;
237 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
238 if (retval
!= ERROR_OK
) {
239 LOG_DEBUG("ERROR wait_for_pracc_rw");
243 address_prev
= address
;
246 address32
= data
= 0;
248 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
249 mips_ejtag_drscan_32(ejtag_info
, &address32
);
250 LOG_DEBUG("-> %08" PRIx32
, address32
);
251 address
= 0xffffffffff200000ull
| address32
;
253 int psz
= (ejtag_ctrl
>> 29) & 3;
254 int address20
= address
& 7;
257 if (address20
!= 7) {
258 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
264 if (address20
!= 0 && address20
!= 4) {
265 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
270 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
274 if (first_time_call
&& address
!= MIPS64_PRACC_TEXT
) {
275 LOG_ERROR("Error reading address " TARGET_ADDR_FMT
" (0x%08llx expected)",
276 address
, MIPS64_PRACC_TEXT
);
277 return ERROR_JTAG_DEVICE_ERROR
;
280 first_time_call
= false;
282 /* Check for read or write */
283 if (ejtag_ctrl
& EJTAG_CTRL_PRNW
) {
284 retval
= mips64_pracc_exec_write(&ctx
, address
);
285 if (retval
!= ERROR_OK
) {
286 printf("ERROR mips64_pracc_exec_write\n");
290 /* Check to see if its reading at the debug vector. The first pass through
291 * the module is always read at the vector, so the first one we allow. When
292 * the second read from the vector occurs we are done and just exit. */
293 if ((address
== MIPS64_PRACC_TEXT
) && (pass
++)) {
294 LOG_DEBUG("@MIPS64_PRACC_TEXT, address_prev=%" PRIx64
, address_prev
);
297 retval
= mips64_pracc_exec_read(&ctx
, address
);
298 if (retval
!= ERROR_OK
) {
299 printf("ERROR mips64_pracc_exec_read\n");
306 /* stack sanity check */
307 if (ctx
.stack_offset
!= 0)
308 LOG_ERROR("Pracc Stack not zero");
313 static int mips64_pracc_read_u64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
316 const uint32_t code
[] = {
317 /* move $15 to COP0 DeSave */
318 MIPS64_DMTC0(15, 31, 0),
319 /* $15 = MIPS64_PRACC_STACK */
320 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
321 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
324 /* load R8 @ param_in[0] = address */
325 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
326 /* ld $8, 0($8), Load $8 with the word @mem[$8] */
329 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
335 /* move COP0 DeSave to $15 */
336 MIPS64_DMFC0(15, 31, 0),
347 uint64_t param_in
[1];
350 LOG_DEBUG("enter mips64_pracc_exec");
351 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
352 ARRAY_SIZE(param_in
), param_in
, 1, (uint64_t *) buf
);
355 static int mips64_pracc_read_mem64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
356 unsigned count
, uint64_t *buf
)
358 int retval
= ERROR_OK
;
360 for (unsigned i
= 0; i
< count
; i
++) {
361 retval
= mips64_pracc_read_u64(ejtag_info
, addr
+ 8*i
, &buf
[i
]);
362 if (retval
!= ERROR_OK
)
368 static int mips64_pracc_read_u32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
371 const uint32_t code
[] = {
372 /* move $15 to COP0 DeSave */
373 MIPS64_DMTC0(15, 31, 0),
374 /* $15 = MIPS64_PRACC_STACK */
375 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
376 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
379 /* load R8 @ param_in[0] = address */
380 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
381 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
384 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
390 /* move COP0 DeSave to $15 */
391 MIPS64_DMFC0(15, 31, 0),
402 int retval
= ERROR_OK
;
403 uint64_t param_in
[1];
404 uint64_t param_out
[1];
408 LOG_DEBUG("enter mips64_pracc_exec");
409 retval
= mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
410 1, param_in
, 1, param_out
);
411 buf
[0] = (uint32_t) param_out
[0];
415 static int mips64_pracc_read_mem32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
416 unsigned count
, uint32_t *buf
)
418 int retval
= ERROR_OK
;
420 for (unsigned i
= 0; i
< count
; i
++) {
421 retval
= mips64_pracc_read_u32(ejtag_info
, addr
+ 4 * i
, &buf
[i
]);
422 if (retval
!= ERROR_OK
)
428 static int mips64_pracc_read_u16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
431 const uint32_t code
[] = {
432 /* move $15 to COP0 DeSave */
433 MIPS64_DMTC0(15, 31, 0),
434 /* $15 = MIPS64_PRACC_STACK */
435 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
436 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
439 /* load R8 @ param_in[0] = address */
440 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
441 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
444 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
450 /* move COP0 DeSave to $15 */
451 MIPS64_DMFC0(15, 31, 0),
463 uint64_t param_in
[1];
464 uint64_t param_out
[1];
468 LOG_DEBUG("enter mips64_pracc_exec");
469 retval
= mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
470 1, param_in
, 1, param_out
);
471 buf
[0] = (uint16_t)param_out
[0];
475 static int mips64_pracc_read_mem16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
476 unsigned count
, uint16_t *buf
)
478 int retval
= ERROR_OK
;
480 for (unsigned i
= 0; i
< count
; i
++) {
481 retval
= mips64_pracc_read_u16(ejtag_info
, addr
+ 2*i
, &buf
[i
]);
482 if (retval
!= ERROR_OK
)
488 static int mips64_pracc_read_u8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
491 const uint32_t code
[] = {
492 /* move $15 to COP0 DeSave */
493 MIPS64_DMTC0(15, 31, 0),
494 /* $15 = MIPS64_PRACC_STACK */
495 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
496 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
499 /* load R8 @ param_in[0] = address */
500 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
501 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
504 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
510 /* move COP0 DeSave to $15 */
511 MIPS64_DMFC0(15, 31, 0),
523 uint64_t param_in
[1];
524 uint64_t param_out
[1];
528 LOG_DEBUG("enter mips64_pracc_exec");
529 retval
= mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
530 1, param_in
, 1, param_out
);
531 buf
[0] = (uint8_t)param_out
[0];
535 static int mips64_pracc_read_mem8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
536 unsigned count
, uint8_t *buf
)
538 int retval
= ERROR_OK
;
540 for (unsigned i
= 0; i
< count
; i
++) {
541 retval
= mips64_pracc_read_u8(ejtag_info
, addr
+ i
, &buf
[i
]);
542 if (retval
!= ERROR_OK
)
548 int mips64_pracc_read_mem(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
549 unsigned size
, unsigned count
, void *buf
)
553 return mips64_pracc_read_mem8(ejtag_info
, addr
, count
, buf
);
555 return mips64_pracc_read_mem16(ejtag_info
, addr
, count
, buf
);
557 return mips64_pracc_read_mem32(ejtag_info
, addr
, count
, buf
);
559 return mips64_pracc_read_mem64(ejtag_info
, addr
, count
, buf
);
564 static int mips64_pracc_write_u64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
567 const uint32_t code
[] = {
568 /* move $15 to COP0 DeSave */
569 MIPS64_DMTC0(15, 31, 0),
570 /* $15 = MIPS64_PRACC_STACK */
571 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
572 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
577 /* load R8 @ param_in[1] = data */
578 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
)-8), 15),
579 /* load R9 @ param_in[0] = address */
580 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
591 /* move COP0 DeSave to $15 */
592 MIPS64_DMFC0(15, 31, 0),
603 /* TODO remove array */
604 uint64_t param_in
[2];
608 LOG_DEBUG("enter mips64_pracc_exec");
609 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
610 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
613 static int mips64_pracc_write_mem64(struct mips_ejtag
*ejtag_info
,
614 uint64_t addr
, unsigned count
, uint64_t *buf
)
616 int retval
= ERROR_OK
;
618 for (unsigned i
= 0; i
< count
; i
++) {
619 retval
= mips64_pracc_write_u64(ejtag_info
, addr
+ 8 * i
, &buf
[i
]);
620 if (retval
!= ERROR_OK
)
626 static int mips64_pracc_write_u32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
629 const uint32_t code
[] = {
630 MIPS64_DMTC0(15, 31, 0),
631 /* move $15 to COP0 DeSave */
632 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
633 /* $15 = MIPS64_PRACC_STACK */
634 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
639 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
) - 8), 15),
640 /* load R8 @ param_in[1] = data */
641 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
642 /* load R9 @ param_in[0] = address */
653 MIPS64_DMFC0(15, 31, 0),
654 /* move COP0 DeSave to $15 */
665 /* TODO remove array */
666 uint64_t param_in
[1 + 1];
670 LOG_DEBUG("enter mips64_pracc_exec");
671 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
672 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
675 static int mips64_pracc_write_mem32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
676 unsigned count
, uint32_t *buf
)
678 int retval
= ERROR_OK
;
680 for (unsigned i
= 0; i
< count
; i
++) {
681 retval
= mips64_pracc_write_u32(ejtag_info
, addr
+ 4 * i
, &buf
[i
]);
682 if (retval
!= ERROR_OK
)
688 static int mips64_pracc_write_u16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
691 const uint32_t code
[] = {
692 /* move $15 to COP0 DeSave */
693 MIPS64_DMTC0(15, 31, 0),
694 /* $15 = MIPS64_PRACC_STACK */
695 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
696 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
701 /* load R8 @ param_in[1] = data */
702 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
) - 8), 15),
703 /* load R9 @ param_in[0] = address */
704 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
714 /* move COP0 DeSave to $15 */
715 MIPS64_DMFC0(15, 31, 0),
726 uint64_t param_in
[2];
730 LOG_DEBUG("enter mips64_pracc_exec");
731 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
732 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
735 static int mips64_pracc_write_mem16(struct mips_ejtag
*ejtag_info
,
736 uint64_t addr
, unsigned count
, uint16_t *buf
)
738 int retval
= ERROR_OK
;
740 for (unsigned i
= 0; i
< count
; i
++) {
741 retval
= mips64_pracc_write_u16(ejtag_info
, addr
+ 2 * i
, &buf
[i
]);
742 if (retval
!= ERROR_OK
)
748 static int mips64_pracc_write_u8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
751 const uint32_t code
[] = {
752 /* move $15 to COP0 DeSave */
753 MIPS64_DMTC0(15, 31, 0),
754 /* $15 = MIPS64_PRACC_STACK */
755 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
756 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
761 /* load R8 @ param_in[1] = data */
762 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
) - 8), 15),
763 /* load R9 @ param_in[0] = address */
764 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
774 /* move COP0 DeSave to $15 */
775 MIPS64_DMFC0(15, 31, 0),
786 /* TODO remove array */
787 uint64_t param_in
[2];
791 LOG_DEBUG("enter mips64_pracc_exec");
792 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
793 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
796 static int mips64_pracc_write_mem8(struct mips_ejtag
*ejtag_info
,
797 uint64_t addr
, unsigned count
, uint8_t *buf
)
799 int retval
= ERROR_OK
;
801 for (unsigned i
= 0; i
< count
; i
++) {
802 retval
= mips64_pracc_write_u8(ejtag_info
, addr
+ i
, &buf
[i
]);
803 if (retval
!= ERROR_OK
)
809 int mips64_pracc_write_mem(struct mips_ejtag
*ejtag_info
,
810 uint64_t addr
, unsigned size
,
811 unsigned count
, void *buf
)
815 return mips64_pracc_write_mem8(ejtag_info
, addr
, count
, buf
);
817 return mips64_pracc_write_mem16(ejtag_info
, addr
, count
, buf
);
819 return mips64_pracc_write_mem32(ejtag_info
, addr
, count
, buf
);
821 return mips64_pracc_write_mem64(ejtag_info
, addr
, count
, buf
);
826 int mips64_pracc_write_regs(struct mips_ejtag
*ejtag_info
, uint64_t *regs
)
828 const uint32_t code
[] = {
829 /* move $2 to COP0 DeSave */
830 MIPS64_DMTC0(2, 31, 0),
831 /* $15 = MIPS64_PRACC_STACK */
832 MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_IN
)),
833 MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_IN
)),
835 MIPS64_LD(1, 1*8, 2),
837 MIPS64_LD(15, 15*8, 2),
839 MIPS64_DMFC0(2, 31, 0),
840 MIPS64_DMTC0(15, 31, 0),
841 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
842 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
844 /* $11 = MIPS64_PRACC_PARAM_OUT */
845 MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_IN
)),
846 MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_IN
)),
847 MIPS64_LD(3, 3*8, 1),
848 MIPS64_LD(4, 4*8, 1),
849 MIPS64_LD(5, 5*8, 1),
850 MIPS64_LD(6, 6*8, 1),
851 MIPS64_LD(7, 7*8, 1),
852 MIPS64_LD(8, 8*8, 1),
853 MIPS64_LD(9, 9*8, 1),
854 MIPS64_LD(10, 10*8, 1),
855 MIPS64_LD(11, 11*8, 1),
856 MIPS64_LD(12, 12*8, 1),
857 MIPS64_LD(13, 13*8, 1),
858 MIPS64_LD(14, 14*8, 1),
859 MIPS64_LD(16, 16*8, 1),
860 MIPS64_LD(17, 17*8, 1),
861 MIPS64_LD(18, 18*8, 1),
862 MIPS64_LD(19, 19*8, 1),
863 MIPS64_LD(20, 20*8, 1),
864 MIPS64_LD(21, 21*8, 1),
865 MIPS64_LD(22, 22*8, 1),
866 MIPS64_LD(23, 23*8, 1),
867 MIPS64_LD(24, 24*8, 1),
868 MIPS64_LD(25, 25*8, 1),
869 MIPS64_LD(26, 26*8, 1),
870 MIPS64_LD(27, 27*8, 1),
871 MIPS64_LD(28, 28*8, 1),
872 MIPS64_LD(29, 29*8, 1),
873 MIPS64_LD(30, 30*8, 1),
874 MIPS64_LD(31, 31*8, 1),
875 MIPS64_LD(2, 32*8, 1),
877 MIPS64_LD(2, 33*8, 1),
879 MIPS64_LD(2, MIPS64_NUM_CORE_REGS
* 8, 1),
880 MIPS64_DMTC0(2, MIPS64_C0_DEPC
, 0),
881 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 2) * 8, 1),
882 MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO0
, 0),
883 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 3) * 8, 1),
884 MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO1
, 0),
885 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 4) * 8, 1),
886 MIPS64_DMTC0(2, MIPS64_C0_CONTEXT
, 0),
887 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 5) * 8, 1),
888 MIPS64_MTC0(2, MIPS64_C0_PAGEMASK
, 0),
889 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 6) * 8, 1),
890 MIPS64_MTC0(2, MIPS64_C0_WIRED
, 0),
891 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 8) * 8, 1),
892 MIPS64_MTC0(2, MIPS64_C0_COUNT
, 0),
893 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 9) * 8, 1),
894 MIPS64_DMTC0(2, MIPS64_C0_ENTRYHI
, 0),
895 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 10) * 8, 1),
896 MIPS64_MTC0(2, MIPS64_C0_COMPARE
, 0),
897 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 11) * 8, 1),
898 MIPS64_MTC0(2, MIPS64_C0_STATUS
, 0),
899 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 12) * 8, 1),
900 MIPS64_MTC0(2, MIPS64_C0_CAUSE
, 0),
901 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 13) * 8, 1),
902 MIPS64_DMTC0(2, MIPS64_C0_EPC
, 0),
903 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 15) * 8, 1),
904 MIPS64_MTC0(2, MIPS64_C0_CONFIG
, 0),
905 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 16) * 8, 1),
906 MIPS64_MTC0(2, MIPS64_C0_LLA
, 0),
907 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 21) * 8, 1),
908 MIPS64_DMTC0(2, MIPS64_C0_XCONTEXT
, 1),
909 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 22) * 8, 1),
910 MIPS64_MTC0(2, MIPS64_C0_MEMCTRL
, 0),
911 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 24) * 8, 1),
912 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 0),
913 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 25) * 8, 1),
914 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 1),
915 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 26) * 8, 1),
916 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 2),
917 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 27) * 8, 1),
918 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 3),
919 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 28) * 8, 1),
920 MIPS64_MTC0(2, MIPS64_C0_ECC
, 0),
921 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 29) * 8, 1),
922 MIPS64_MTC0(2, MIPS64_C0_CACHERR
, 0),
923 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 30) * 8, 1),
924 MIPS64_MTC0(2, MIPS64_C0_TAGLO
, 0),
925 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 31) * 8, 1),
926 MIPS64_MTC0(2, MIPS64_C0_TAGHI
, 0),
927 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 32) * 8, 1),
928 MIPS64_DMTC0(2, MIPS64_C0_DATAHI
, 0),
929 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 33) * 8, 1),
930 MIPS64_DMTC0(2, MIPS64_C0_EEPC
, 0),
931 /* check if FPU is enabled, */
932 MIPS64_MFC0(2, MIPS64_C0_STATUS
, 0),
933 MIPS64_SRL(2, 2, 29),
934 MIPS64_ANDI(2, 2, 1),
935 /* skip FPU registers restoration if not */
936 MIPS64_BEQ(0, 2, 77),
938 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 33) * 8, 1),
939 MIPS64_CTC1(2, MIPS64_C1_FIR
, 0),
940 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 32) * 8, 1),
941 MIPS64_CTC1(2, MIPS64_C1_FCSR
, 0),
942 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 34) * 8, 1),
943 MIPS64_CTC1(2, MIPS64_C1_FCONFIG
, 0),
944 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 35) * 8, 1),
945 MIPS64_CTC1(2, MIPS64_C1_FCCR
, 0),
946 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 36) * 8, 1),
947 MIPS64_CTC1(2, MIPS64_C1_FEXR
, 0),
948 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 37) * 8, 1),
949 MIPS64_CTC1(2, MIPS64_C1_FENR
, 0),
950 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 0) * 8, 1),
951 MIPS64_DMTC1(2, 0, 0),
952 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 1) * 8, 1),
953 MIPS64_DMTC1(2, 1, 0),
954 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 2) * 8, 1),
955 MIPS64_DMTC1(2, 2, 0),
956 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 3) * 8, 1),
957 MIPS64_DMTC1(2, 3, 0),
958 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 4) * 8, 1),
959 MIPS64_DMTC1(2, 4, 0),
960 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 5) * 8, 1),
961 MIPS64_DMTC1(2, 5, 0),
962 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 6) * 8, 1),
963 MIPS64_DMTC1(2, 6, 0),
964 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 7) * 8, 1),
965 MIPS64_DMTC1(2, 7, 0),
966 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 8) * 8, 1),
967 MIPS64_DMTC1(2, 8, 0),
968 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 9) * 8, 1),
969 MIPS64_DMTC1(2, 9, 0),
970 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 10) * 8, 1),
971 MIPS64_DMTC1(2, 10, 0),
972 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 11) * 8, 1),
973 MIPS64_DMTC1(2, 11, 0),
974 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 12) * 8, 1),
975 MIPS64_DMTC1(2, 12, 0),
976 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 13) * 8, 1),
977 MIPS64_DMTC1(2, 13, 0),
978 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 14) * 8, 1),
979 MIPS64_DMTC1(2, 14, 0),
980 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 15) * 8, 1),
981 MIPS64_DMTC1(2, 15, 0),
982 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 16) * 8, 1),
983 MIPS64_DMTC1(2, 16, 0),
984 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 17) * 8, 1),
985 MIPS64_DMTC1(2, 17, 0),
986 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 18) * 8, 1),
987 MIPS64_DMTC1(2, 18, 0),
988 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 19) * 8, 1),
989 MIPS64_DMTC1(2, 19, 0),
990 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 20) * 8, 1),
991 MIPS64_DMTC1(2, 20, 0),
992 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 21) * 8, 1),
993 MIPS64_DMTC1(2, 21, 0),
994 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 22) * 8, 1),
995 MIPS64_DMTC1(2, 22, 0),
996 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 23) * 8, 1),
997 MIPS64_DMTC1(2, 23, 0),
998 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 24) * 8, 1),
999 MIPS64_DMTC1(2, 24, 0),
1000 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 25) * 8, 1),
1001 MIPS64_DMTC1(2, 25, 0),
1002 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 26) * 8, 1),
1003 MIPS64_DMTC1(2, 26, 0),
1004 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 27) * 8, 1),
1005 MIPS64_DMTC1(2, 27, 0),
1006 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 28) * 8, 1),
1007 MIPS64_DMTC1(2, 28, 0),
1008 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 29) * 8, 1),
1009 MIPS64_DMTC1(2, 29, 0),
1010 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 30) * 8, 1),
1011 MIPS64_DMTC1(2, 30, 0),
1012 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 31) * 8, 1),
1013 MIPS64_DMTC1(2, 31, 0),
1014 MIPS64_LD(2, 2 * 8, 1),
1015 MIPS64_LD(1, 0, 15),
1018 MIPS64_B(NEG16(181)),
1019 /* move COP0 DeSave to $15 */
1020 MIPS64_DMFC0(15, 31, 0),
1031 LOG_DEBUG("enter mips64_pracc_exec");
1032 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
1033 MIPS64_NUM_REGS
, regs
, 0, NULL
);
1036 int mips64_pracc_read_regs(struct mips_ejtag
*ejtag_info
, uint64_t *regs
)
1038 const uint32_t code
[] = {
1039 /* move $2 to COP0 DeSave */
1040 MIPS64_DMTC0(2, 31, 0),
1041 /* $2 = MIPS64_PRACC_PARAM_OUT */
1042 MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_OUT
)),
1043 MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_OUT
)),
1044 /* sd $0, 0*8($2) */
1045 MIPS64_SD(0, 0*8, 2),
1046 /* sd $1, 1*8($2) */
1047 MIPS64_SD(1, 1*8, 2),
1048 /* sd $15, 15*8($2) */
1049 MIPS64_SD(15, 15*8, 2),
1050 /* move COP0 DeSave to $2 */
1051 MIPS64_DMFC0(2, 31, 0),
1052 /* move $15 to COP0 DeSave */
1053 MIPS64_DMTC0(15, 31, 0),
1054 /* $15 = MIPS64_PRACC_STACK */
1055 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
1056 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
1058 MIPS64_SD(1, 0, 15),
1060 MIPS64_SD(2, 0, 15),
1061 /* $1 = MIPS64_PRACC_PARAM_OUT */
1062 MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_OUT
)),
1063 MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_OUT
)),
1064 MIPS64_SD(2, 2 * 8, 1),
1065 MIPS64_SD(3, 3 * 8, 1),
1066 MIPS64_SD(4, 4 * 8, 1),
1067 MIPS64_SD(5, 5 * 8, 1),
1068 MIPS64_SD(6, 6 * 8, 1),
1069 MIPS64_SD(7, 7 * 8, 1),
1070 MIPS64_SD(8, 8 * 8, 1),
1071 MIPS64_SD(9, 9 * 8, 1),
1072 MIPS64_SD(10, 10 * 8, 1),
1073 MIPS64_SD(11, 11 * 8, 1),
1074 MIPS64_SD(12, 12 * 8, 1),
1075 MIPS64_SD(13, 13 * 8, 1),
1076 MIPS64_SD(14, 14 * 8, 1),
1077 MIPS64_SD(16, 16 * 8, 1),
1078 MIPS64_SD(17, 17 * 8, 1),
1079 MIPS64_SD(18, 18 * 8, 1),
1080 MIPS64_SD(19, 19 * 8, 1),
1081 MIPS64_SD(20, 20 * 8, 1),
1082 MIPS64_SD(21, 21 * 8, 1),
1083 MIPS64_SD(22, 22 * 8, 1),
1084 MIPS64_SD(23, 23 * 8, 1),
1085 MIPS64_SD(24, 24 * 8, 1),
1086 MIPS64_SD(25, 25 * 8, 1),
1087 MIPS64_SD(26, 26 * 8, 1),
1088 MIPS64_SD(27, 27 * 8, 1),
1089 MIPS64_SD(28, 28 * 8, 1),
1090 MIPS64_SD(29, 29 * 8, 1),
1091 MIPS64_SD(30, 30 * 8, 1),
1092 MIPS64_SD(31, 31 * 8, 1),
1094 MIPS64_SD(2, 32 * 8, 1),
1096 MIPS64_SD(2, 33 * 8, 1),
1097 MIPS64_DMFC0(2, MIPS64_C0_DEPC
, 0),
1098 MIPS64_SD(2, MIPS64_NUM_CORE_REGS
* 8, 1),
1099 MIPS64_DMFC0(2, MIPS64_C0_RANDOM
, 0),
1100 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 1) * 8, 1),
1101 MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO0
, 0),
1102 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 2) * 8, 1),
1103 MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO1
, 0),
1104 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 3) * 8, 1),
1105 MIPS64_DMFC0(2, MIPS64_C0_CONTEXT
, 0),
1106 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 4) * 8, 1),
1107 MIPS64_MFC0(2, MIPS64_C0_PAGEMASK
, 0),
1108 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 5) * 8, 1),
1109 MIPS64_MFC0(2, MIPS64_C0_WIRED
, 0),
1110 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 6) * 8, 1),
1111 MIPS64_DMFC0(2, MIPS64_C0_BADVADDR
, 0),
1112 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 7) * 8, 1),
1113 MIPS64_MFC0(2, MIPS64_C0_COUNT
, 0),
1114 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 8) * 8, 1),
1115 MIPS64_DMFC0(2, MIPS64_C0_ENTRYHI
, 0),
1116 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 9) * 8, 1),
1117 MIPS64_MFC0(2, MIPS64_C0_COMPARE
, 0),
1118 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 10) * 8, 1),
1119 MIPS64_MFC0(2, MIPS64_C0_STATUS
, 0),
1120 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 11) * 8, 1),
1121 MIPS64_MFC0(2, MIPS64_C0_CAUSE
, 0),
1122 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 12) * 8, 1),
1123 MIPS64_DMFC0(2, MIPS64_C0_EPC
, 0),
1124 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 13) * 8, 1),
1125 MIPS64_MFC0(2, MIPS64_C0_PRID
, 0),
1126 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 14) * 8, 1),
1127 MIPS64_MFC0(2, MIPS64_C0_CONFIG
, 0),
1128 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 15) * 8, 1),
1129 MIPS64_MFC0(2, MIPS64_C0_LLA
, 0),
1130 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 16) * 8, 1),
1131 MIPS64_DMFC0(2, MIPS64_C0_XCONTEXT
, 1),
1132 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 21) * 8, 1),
1133 MIPS64_MFC0(2, MIPS64_C0_MEMCTRL
, 0),
1134 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 22) * 8, 1),
1135 MIPS64_MFC0(2, MIPS64_C0_DEBUG
, 0),
1136 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 23) * 8, 1),
1137 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 0),
1138 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 24) * 8, 1),
1139 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 1),
1140 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 25) * 8, 1),
1141 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 2),
1142 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 26) * 8, 1),
1143 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 3),
1144 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 27) * 8, 1),
1145 MIPS64_MFC0(2, MIPS64_C0_ECC
, 0),
1146 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 28) * 8, 1),
1147 MIPS64_MFC0(2, MIPS64_C0_CACHERR
, 0),
1148 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 29) * 8, 1),
1149 MIPS64_MFC0(2, MIPS64_C0_TAGLO
, 0),
1150 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 30) * 8, 1),
1151 MIPS64_MFC0(2, MIPS64_C0_TAGHI
, 0),
1152 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 31) * 8, 1),
1153 MIPS64_DMFC0(2, MIPS64_C0_DATAHI
, 0),
1154 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 32) * 8, 1),
1155 MIPS64_DMFC0(2, MIPS64_C0_EEPC
, 0),
1156 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 33) * 8, 1),
1157 /* check if FPU is enabled, */
1158 MIPS64_MFC0(2, MIPS64_C0_STATUS
, 0),
1159 MIPS64_SRL(2, 2, 29),
1160 MIPS64_ANDI(2, 2, 1),
1161 /* skip FPU registers dump if not */
1162 MIPS64_BEQ(0, 2, 77),
1164 MIPS64_CFC1(2, MIPS64_C1_FIR
, 0),
1165 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 33) * 8, 1),
1166 MIPS64_CFC1(2, MIPS64_C1_FCSR
, 0),
1167 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 32) * 8, 1),
1168 MIPS64_CFC1(2, MIPS64_C1_FCONFIG
, 0),
1169 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 34) * 8, 1),
1170 MIPS64_CFC1(2, MIPS64_C1_FCCR
, 0),
1171 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 35) * 8, 1),
1172 MIPS64_CFC1(2, MIPS64_C1_FEXR
, 0),
1173 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 36) * 8, 1),
1174 MIPS64_CFC1(2, MIPS64_C1_FENR
, 0),
1175 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 37) * 8, 1),
1176 MIPS64_DMFC1(2, 0, 0),
1177 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 0) * 8, 1),
1178 MIPS64_DMFC1(2, 1, 0),
1179 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 1) * 8, 1),
1180 MIPS64_DMFC1(2, 2, 0),
1181 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 2) * 8, 1),
1182 MIPS64_DMFC1(2, 3, 0),
1183 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 3) * 8, 1),
1184 MIPS64_DMFC1(2, 4, 0),
1185 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 4) * 8, 1),
1186 MIPS64_DMFC1(2, 5, 0),
1187 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 5) * 8, 1),
1188 MIPS64_DMFC1(2, 6, 0),
1189 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 6) * 8, 1),
1190 MIPS64_DMFC1(2, 7, 0),
1191 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 7) * 8, 1),
1192 MIPS64_DMFC1(2, 8, 0),
1193 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 8) * 8, 1),
1194 MIPS64_DMFC1(2, 9, 0),
1195 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 9) * 8, 1),
1196 MIPS64_DMFC1(2, 10, 0),
1197 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 10) * 8, 1),
1198 MIPS64_DMFC1(2, 11, 0),
1199 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 11) * 8, 1),
1200 MIPS64_DMFC1(2, 12, 0),
1201 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 12) * 8, 1),
1202 MIPS64_DMFC1(2, 13, 0),
1203 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 13) * 8, 1),
1204 MIPS64_DMFC1(2, 14, 0),
1205 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 14) * 8, 1),
1206 MIPS64_DMFC1(2, 15, 0),
1207 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 15) * 8, 1),
1208 MIPS64_DMFC1(2, 16, 0),
1209 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 16) * 8, 1),
1210 MIPS64_DMFC1(2, 17, 0),
1211 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 17) * 8, 1),
1212 MIPS64_DMFC1(2, 18, 0),
1213 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 18) * 8, 1),
1214 MIPS64_DMFC1(2, 19, 0),
1215 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 19) * 8, 1),
1216 MIPS64_DMFC1(2, 20, 0),
1217 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 20) * 8, 1),
1218 MIPS64_DMFC1(2, 21, 0),
1219 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 21) * 8, 1),
1220 MIPS64_DMFC1(2, 22, 0),
1221 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 22) * 8, 1),
1222 MIPS64_DMFC1(2, 23, 0),
1223 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 23) * 8, 1),
1224 MIPS64_DMFC1(2, 24, 0),
1225 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 24) * 8, 1),
1226 MIPS64_DMFC1(2, 25, 0),
1227 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 25) * 8, 1),
1228 MIPS64_DMFC1(2, 26, 0),
1229 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 26) * 8, 1),
1230 MIPS64_DMFC1(2, 27, 0),
1231 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 27) * 8, 1),
1232 MIPS64_DMFC1(2, 28, 0),
1233 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 28) * 8, 1),
1234 MIPS64_DMFC1(2, 29, 0),
1235 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 29) * 8, 1),
1236 MIPS64_DMFC1(2, 30, 0),
1237 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 30) * 8, 1),
1238 MIPS64_DMFC1(2, 31, 0),
1239 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 31) * 8, 1),
1240 MIPS64_LD(2, 0, 15),
1241 MIPS64_LD(1, 0, 15),
1244 MIPS64_B(NEG16(192)),
1245 /* move COP0 DeSave to $15 */
1246 MIPS64_DMFC0(15, 31, 0),
1257 LOG_DEBUG("enter mips64_pracc_exec");
1258 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
1259 0, NULL
, MIPS64_NUM_REGS
, regs
);
1262 /* fastdata upload/download requires an initialized working area
1263 * to load the download code; it should not be called otherwise
1264 * fetch order from the fastdata area
1269 int mips64_pracc_fastdata_xfer(struct mips_ejtag
*ejtag_info
,
1270 struct working_area
*source
,
1271 bool write_t
, uint64_t addr
,
1272 unsigned count
, uint64_t *buf
)
1274 uint32_t handler_code
[] = {
1275 /* caution when editing, table is modified below */
1276 /* r15 points to the start of this code */
1277 MIPS64_SD(8, MIPS64_FASTDATA_HANDLER_SIZE
- 8, 15),
1278 MIPS64_SD(9, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 2, 15),
1279 MIPS64_SD(10, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 3, 15),
1280 MIPS64_SD(11, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 4, 15),
1281 /* start of fastdata area in t0 */
1282 MIPS64_LUI(8, UPPER16(MIPS64_PRACC_FASTDATA_AREA
)),
1283 MIPS64_ORI(8, 8, LOWER16(MIPS64_PRACC_FASTDATA_AREA
)),
1284 /* start addr in t1 */
1286 /* end addr to t2 */
1287 MIPS64_LD(10, 0, 8),
1290 /* lw t3,[t8 | r9] */
1291 /* 8 */ MIPS64_LD(11, 0, 0),
1292 /* sw t3,[r9 | r8] */
1293 /* 9 */ MIPS64_SD(11, 0, 0),
1294 /* bne $t2,t1,loop */
1295 MIPS64_BNE(10, 9, NEG16(3)),
1297 MIPS64_DADDIU(9, 9, 8),
1299 MIPS64_LD(8, MIPS64_FASTDATA_HANDLER_SIZE
- 8, 15),
1300 MIPS64_LD(9, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 2, 15),
1301 MIPS64_LD(10, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 3, 15),
1302 MIPS64_LD(11, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 4, 15),
1304 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_TEXT
)),
1305 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_TEXT
)),
1308 /* move COP0 DeSave to $15 */
1309 MIPS64_DMFC0(15, 31, 0),
1312 uint32_t jmp_code
[] = {
1313 /* addr of working area added below */
1314 /* 0 */ MIPS64_LUI(15, 0),
1315 /* addr of working area added below */
1316 /* 1 */ MIPS64_ORI(15, 15, 0),
1317 /* jump to ram program */
1324 uint32_t ejtag_ctrl
, address32
;
1325 uint64_t address
, val
;
1327 if (source
->size
< MIPS64_FASTDATA_HANDLER_SIZE
)
1328 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1331 /* load data from probe at fastdata area */
1332 handler_code
[8] = MIPS64_LD(11, 0, 8);
1333 /* store data to RAM @ r9 */
1334 handler_code
[9] = MIPS64_SD(11, 0, 9);
1336 /* load data from RAM @ r9 */
1337 handler_code
[8] = MIPS64_LD(11, 0, 9);
1338 /* store data to probe at fastdata area */
1339 handler_code
[9] = MIPS64_SD(11, 0, 8);
1342 /* write program into RAM */
1343 if (write_t
!= ejtag_info
->fast_access_save
) {
1344 mips64_pracc_write_mem(ejtag_info
, source
->address
, 4,
1345 ARRAY_SIZE(handler_code
), handler_code
);
1346 /* save previous operation to speed to any consecutive read/writes */
1347 ejtag_info
->fast_access_save
= write_t
;
1350 LOG_DEBUG("%s using " TARGET_ADDR_FMT
" for write handler", __func__
,
1352 LOG_DEBUG("daddiu: %08" PRIx32
, handler_code
[11]);
1354 jmp_code
[0] |= UPPER16(source
->address
);
1355 jmp_code
[1] |= LOWER16(source
->address
);
1356 mips64_pracc_exec(ejtag_info
,
1357 ARRAY_SIZE(jmp_code
), jmp_code
,
1360 /* next fetch to dmseg should be in FASTDATA_AREA, check */
1363 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
1364 retval
= mips_ejtag_drscan_32(ejtag_info
, &address32
);
1365 if (retval
!= ERROR_OK
)
1367 address
= 0xffffffffff200000ull
| address32
;
1368 if ((address
& ~7ull) != MIPS64_PRACC_FASTDATA_AREA
) {
1369 LOG_ERROR("! @MIPS64_PRACC_FASTDATA_AREA (" TARGET_ADDR_FMT
")", address
);
1372 /* Send the load start address */
1374 LOG_DEBUG("start: " TARGET_ADDR_FMT
, val
);
1375 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_FASTDATA
);
1376 mips64_ejtag_fastdata_scan(ejtag_info
, 1, &val
);
1378 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
1379 if (retval
!= ERROR_OK
)
1382 /* Send the load end address */
1383 val
= addr
+ (count
- 1) * 8;
1384 LOG_DEBUG("stop: " TARGET_ADDR_FMT
, val
);
1385 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_FASTDATA
);
1386 mips64_ejtag_fastdata_scan(ejtag_info
, 1, &val
);
1388 /* like in legacy code */
1389 unsigned num_clocks
= 0;
1390 if (ejtag_info
->mode
!= 0)
1391 num_clocks
= ((uint64_t)(ejtag_info
->scan_delay
) * jtag_get_speed_khz() + 500000) / 1000000;
1392 LOG_DEBUG("num_clocks=%d", num_clocks
);
1393 for (i
= 0; i
< count
; i
++) {
1394 jtag_add_clocks(num_clocks
);
1395 retval
= mips64_ejtag_fastdata_scan(ejtag_info
, write_t
, buf
++);
1396 if (retval
!= ERROR_OK
) {
1397 LOG_ERROR("mips64_ejtag_fastdata_scan failed");
1402 retval
= jtag_execute_queue();
1403 if (retval
!= ERROR_OK
) {
1404 LOG_ERROR("jtag_execute_queue failed");
1408 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
1409 if (retval
!= ERROR_OK
) {
1410 LOG_ERROR("wait_for_pracc_rw failed");
1415 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
1416 retval
= mips_ejtag_drscan_32(ejtag_info
, &address32
);
1417 if (retval
!= ERROR_OK
) {
1418 LOG_ERROR("mips_ejtag_drscan_32 failed");
1422 address
= 0xffffffffff200000ull
| address32
;
1423 if ((address
& ~7ull) != MIPS64_PRACC_TEXT
)
1424 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)