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
20 #if BUILD_TARGET64 == 1
23 #include "mips64_pracc.h"
25 #include "time_support.h"
27 #define STACK_DEPTH 32
30 uint64_t *local_iparam
;
32 uint64_t *local_oparam
;
36 uint64_t stack
[STACK_DEPTH
];
37 unsigned stack_offset
;
38 struct mips_ejtag
*ejtag_info
;
39 } mips64_pracc_context
;
41 static int wait_for_pracc_rw(struct mips_ejtag
*ejtag_info
, uint32_t *ctrl
)
48 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
49 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
;
50 rc
= mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
54 if (ejtag_ctrl
& EJTAG_CTRL_PRACC
)
56 LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
58 return ERROR_JTAG_DEVICE_ERROR
;
66 static int mips64_pracc_exec_read(mips64_pracc_context
*ctx
, uint64_t address
)
68 struct mips_ejtag
*ejtag_info
= ctx
->ejtag_info
;
74 if ((address
>= MIPS64_PRACC_PARAM_IN
)
75 && (address
< MIPS64_PRACC_PARAM_IN
+ ctx
->num_iparam
* MIPS64_PRACC_DATA_STEP
)) {
77 offset
= (address
- MIPS64_PRACC_PARAM_IN
) / MIPS64_PRACC_DATA_STEP
;
79 if (offset
>= MIPS64_PRACC_PARAM_IN_SIZE
) {
80 LOG_ERROR("Error: iparam size exceeds MIPS64_PRACC_PARAM_IN_SIZE");
81 return ERROR_JTAG_DEVICE_ERROR
;
84 if (ctx
->local_iparam
== NULL
) {
85 LOG_ERROR("Error: unexpected reading of input parameter");
86 return ERROR_JTAG_DEVICE_ERROR
;
89 data
= ctx
->local_iparam
[offset
];
90 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
92 } else if ((address
>= MIPS64_PRACC_PARAM_OUT
)
93 && (address
< MIPS64_PRACC_PARAM_OUT
+ ctx
->num_oparam
* MIPS64_PRACC_DATA_STEP
)) {
95 offset
= (address
- MIPS64_PRACC_PARAM_OUT
) / MIPS64_PRACC_DATA_STEP
;
96 if (ctx
->local_oparam
== NULL
) {
97 LOG_ERROR("Error: unexpected reading of output parameter");
98 return ERROR_JTAG_DEVICE_ERROR
;
101 data
= ctx
->local_oparam
[offset
];
102 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
104 } else if ((address
>= MIPS64_PRACC_TEXT
)
105 && (address
< MIPS64_PRACC_TEXT
+ ctx
->code_len
* MIPS64_PRACC_ADDR_STEP
)) {
107 offset
= ((address
& ~7ull) - MIPS64_PRACC_TEXT
) / MIPS64_PRACC_ADDR_STEP
;
108 data
= (uint64_t)ctx
->code
[offset
] << 32;
109 if (offset
+ 1 < ctx
->code_len
)
110 data
|= (uint64_t)ctx
->code
[offset
+ 1];
112 LOG_DEBUG("Running commands %" PRIx64
" at %" PRIx64
, data
,
115 } else if ((address
& ~7llu) == MIPS64_PRACC_STACK
) {
117 /* load from our debug stack */
118 if (ctx
->stack_offset
== 0) {
119 LOG_ERROR("Error reading from stack: stack is empty");
120 return ERROR_JTAG_DEVICE_ERROR
;
123 data
= ctx
->stack
[--ctx
->stack_offset
];
124 LOG_DEBUG("Reading %" PRIx64
" at %" PRIx64
, data
, address
);
127 /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
128 * to start of debug vector */
131 LOG_ERROR("Error reading unexpected address %" PRIx64
, address
);
132 return ERROR_JTAG_DEVICE_ERROR
;
135 /* Send the data out */
136 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_DATA
);
137 rc
= mips_ejtag_drscan_64(ctx
->ejtag_info
, &data
);
141 /* Clear the access pending bit (let the processor eat!) */
143 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_PRACC
;
144 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_CONTROL
);
145 rc
= mips_ejtag_drscan_32(ctx
->ejtag_info
, &ejtag_ctrl
);
151 return jtag_execute_queue();
154 static int mips64_pracc_exec_write(mips64_pracc_context
*ctx
, uint64_t address
)
159 struct mips_ejtag
*ejtag_info
= ctx
->ejtag_info
;
162 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_DATA
);
163 rc
= mips_ejtag_drscan_64(ctx
->ejtag_info
, &data
);
167 /* Clear access pending bit */
168 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_PRACC
;
169 mips_ejtag_set_instr(ctx
->ejtag_info
, EJTAG_INST_CONTROL
);
170 rc
= mips_ejtag_drscan_32(ctx
->ejtag_info
, &ejtag_ctrl
);
175 rc
= jtag_execute_queue();
179 LOG_DEBUG("Writing %" PRIx64
" at %" PRIx64
, data
, address
);
181 if ((address
>= MIPS64_PRACC_PARAM_IN
)
182 && (address
< MIPS64_PRACC_PARAM_IN
+ ctx
->num_iparam
* MIPS64_PRACC_DATA_STEP
)) {
183 offset
= (address
- MIPS64_PRACC_PARAM_IN
) / MIPS64_PRACC_DATA_STEP
;
184 if (ctx
->local_iparam
== NULL
) {
185 LOG_ERROR("Error: unexpected writing of input parameter");
186 return ERROR_JTAG_DEVICE_ERROR
;
188 ctx
->local_iparam
[offset
] = data
;
189 } else if ((address
>= MIPS64_PRACC_PARAM_OUT
)
190 && (address
< MIPS64_PRACC_PARAM_OUT
+ ctx
->num_oparam
* MIPS64_PRACC_DATA_STEP
)) {
191 offset
= (address
- MIPS64_PRACC_PARAM_OUT
) / MIPS64_PRACC_DATA_STEP
;
192 if (ctx
->local_oparam
== NULL
) {
193 LOG_ERROR("Error: unexpected writing of output parameter");
194 return ERROR_JTAG_DEVICE_ERROR
;
196 ctx
->local_oparam
[offset
] = data
;
197 } else if (address
== MIPS64_PRACC_STACK
) {
198 /* save data onto our stack */
199 if (ctx
->stack_offset
>= STACK_DEPTH
) {
200 LOG_ERROR("Error: PrAcc stack depth exceeded");
203 ctx
->stack
[ctx
->stack_offset
++] = data
;
205 LOG_ERROR("Error writing unexpected address 0x%" PRIx64
, address
);
206 return ERROR_JTAG_DEVICE_ERROR
;
212 int mips64_pracc_exec(struct mips_ejtag
*ejtag_info
,
213 unsigned code_len
, const uint32_t *code
,
214 unsigned num_param_in
, uint64_t *param_in
,
215 unsigned num_param_out
, uint64_t *param_out
)
218 uint64_t address
= 0, address_prev
= 0, data
;
219 mips64_pracc_context ctx
;
222 bool first_time_call
= true;
225 for (i
= 0; i
< code_len
; i
++)
226 LOG_DEBUG("%08x", code
[i
]);
228 ctx
.local_iparam
= param_in
;
229 ctx
.local_oparam
= param_out
;
230 ctx
.num_iparam
= num_param_in
;
231 ctx
.num_oparam
= num_param_out
;
233 ctx
.code_len
= code_len
;
234 ctx
.ejtag_info
= ejtag_info
;
235 ctx
.stack_offset
= 0;
239 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
240 if (retval
!= ERROR_OK
) {
241 LOG_DEBUG("ERROR wait_for_pracc_rw");
245 address_prev
= address
;
248 address32
= data
= 0;
250 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
251 mips_ejtag_drscan_32(ejtag_info
, &address32
);
252 LOG_DEBUG("-> %08x", address32
);
253 address
= 0xffffffffff200000ull
| address32
;
255 int psz
= (ejtag_ctrl
>> 29) & 3;
256 int address20
= address
& 7;
259 if (address20
!= 7) {
260 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
266 if (address20
!= 0 && address20
!= 4) {
267 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
272 LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz
, address20
);
276 if (first_time_call
&& address
!= MIPS64_PRACC_TEXT
) {
277 LOG_ERROR("Error reading address " TARGET_ADDR_FMT
" (0x%08llx expected)",
278 address
, MIPS64_PRACC_TEXT
);
279 return ERROR_JTAG_DEVICE_ERROR
;
282 first_time_call
= false;
284 /* Check for read or write */
285 if (ejtag_ctrl
& EJTAG_CTRL_PRNW
) {
286 retval
= mips64_pracc_exec_write(&ctx
, address
);
287 if (retval
!= ERROR_OK
) {
288 printf("ERROR mips64_pracc_exec_write\n");
292 /* Check to see if its reading at the debug vector. The first pass through
293 * the module is always read at the vector, so the first one we allow. When
294 * the second read from the vector occurs we are done and just exit. */
295 if ((address
== MIPS64_PRACC_TEXT
) && (pass
++)) {
296 LOG_DEBUG("@MIPS64_PRACC_TEXT, address_prev=%" PRIx64
, address_prev
);
299 retval
= mips64_pracc_exec_read(&ctx
, address
);
300 if (retval
!= ERROR_OK
) {
301 printf("ERROR mips64_pracc_exec_read\n");
308 /* stack sanity check */
309 if (ctx
.stack_offset
!= 0)
310 LOG_ERROR("Pracc Stack not zero");
315 static int mips64_pracc_read_u64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
318 const uint32_t code
[] = {
319 /* move $15 to COP0 DeSave */
320 MIPS64_DMTC0(15, 31, 0),
321 /* $15 = MIPS64_PRACC_STACK */
322 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
323 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
326 /* load R8 @ param_in[0] = address */
327 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
328 /* ld $8, 0($8), Load $8 with the word @mem[$8] */
331 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
337 /* move COP0 DeSave to $15 */
338 MIPS64_DMFC0(15, 31, 0),
349 uint64_t param_in
[1];
352 LOG_DEBUG("enter mips64_pracc_exec");
353 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
354 ARRAY_SIZE(param_in
), param_in
, 1, (uint64_t *) buf
);
357 static int mips64_pracc_read_mem64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
358 unsigned count
, uint64_t *buf
)
360 int retval
= ERROR_OK
;
362 for (unsigned i
= 0; i
< count
; i
++) {
363 retval
= mips64_pracc_read_u64(ejtag_info
, addr
+ 8*i
, &buf
[i
]);
364 if (retval
!= ERROR_OK
)
370 static int mips64_pracc_read_u32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
373 const uint32_t code
[] = {
374 /* move $15 to COP0 DeSave */
375 MIPS64_DMTC0(15, 31, 0),
376 /* $15 = MIPS64_PRACC_STACK */
377 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
378 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
381 /* load R8 @ param_in[0] = address */
382 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
383 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
386 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
392 /* move COP0 DeSave to $15 */
393 MIPS64_DMFC0(15, 31, 0),
404 int retval
= ERROR_OK
;
405 uint64_t param_in
[1];
406 uint64_t param_out
[1];
410 LOG_DEBUG("enter mips64_pracc_exec");
411 retval
= mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
412 1, param_in
, 1, param_out
);
413 buf
[0] = (uint32_t) param_out
[0];
417 static int mips64_pracc_read_mem32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
418 unsigned count
, uint32_t *buf
)
420 int retval
= ERROR_OK
;
422 for (unsigned i
= 0; i
< count
; i
++) {
423 retval
= mips64_pracc_read_u32(ejtag_info
, addr
+ 4 * i
, &buf
[i
]);
424 if (retval
!= ERROR_OK
)
430 static int mips64_pracc_read_u16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
433 const uint32_t code
[] = {
434 /* move $15 to COP0 DeSave */
435 MIPS64_DMTC0(15, 31, 0),
436 /* $15 = MIPS64_PRACC_STACK */
437 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
438 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
441 /* load R8 @ param_in[0] = address */
442 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
443 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
446 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
452 /* move COP0 DeSave to $15 */
453 MIPS64_DMFC0(15, 31, 0),
465 uint64_t param_in
[1];
466 uint64_t param_out
[1];
470 LOG_DEBUG("enter mips64_pracc_exec");
471 retval
= mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
472 1, param_in
, 1, param_out
);
473 buf
[0] = (uint16_t)param_out
[0];
477 static int mips64_pracc_read_mem16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
478 unsigned count
, uint16_t *buf
)
480 int retval
= ERROR_OK
;
482 for (unsigned i
= 0; i
< count
; i
++) {
483 retval
= mips64_pracc_read_u16(ejtag_info
, addr
+ 2*i
, &buf
[i
]);
484 if (retval
!= ERROR_OK
)
490 static int mips64_pracc_read_u8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
493 const uint32_t code
[] = {
494 /* move $15 to COP0 DeSave */
495 MIPS64_DMTC0(15, 31, 0),
496 /* $15 = MIPS64_PRACC_STACK */
497 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
498 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
501 /* load R8 @ param_in[0] = address */
502 MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
503 /* lw $8, 0($8), Load $8 with the word @mem[$8] */
506 MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_OUT
), 15),
512 /* move COP0 DeSave to $15 */
513 MIPS64_DMFC0(15, 31, 0),
525 uint64_t param_in
[1];
526 uint64_t param_out
[1];
530 LOG_DEBUG("enter mips64_pracc_exec");
531 retval
= mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
532 1, param_in
, 1, param_out
);
533 buf
[0] = (uint8_t)param_out
[0];
537 static int mips64_pracc_read_mem8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
538 unsigned count
, uint8_t *buf
)
540 int retval
= ERROR_OK
;
542 for (unsigned i
= 0; i
< count
; i
++) {
543 retval
= mips64_pracc_read_u8(ejtag_info
, addr
+ i
, &buf
[i
]);
544 if (retval
!= ERROR_OK
)
550 int mips64_pracc_read_mem(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
551 unsigned size
, unsigned count
, void *buf
)
555 return mips64_pracc_read_mem8(ejtag_info
, addr
, count
, buf
);
557 return mips64_pracc_read_mem16(ejtag_info
, addr
, count
, buf
);
559 return mips64_pracc_read_mem32(ejtag_info
, addr
, count
, buf
);
561 return mips64_pracc_read_mem64(ejtag_info
, addr
, count
, buf
);
566 static int mips64_pracc_write_u64(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
569 const uint32_t code
[] = {
570 /* move $15 to COP0 DeSave */
571 MIPS64_DMTC0(15, 31, 0),
572 /* $15 = MIPS64_PRACC_STACK */
573 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
574 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
579 /* load R8 @ param_in[1] = data */
580 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
)-8), 15),
581 /* load R9 @ param_in[0] = address */
582 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
593 /* move COP0 DeSave to $15 */
594 MIPS64_DMFC0(15, 31, 0),
605 /* TODO remove array */
606 uint64_t param_in
[2];
610 LOG_DEBUG("enter mips64_pracc_exec");
611 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
612 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
615 static int mips64_pracc_write_mem64(struct mips_ejtag
*ejtag_info
,
616 uint64_t addr
, unsigned count
, uint64_t *buf
)
618 int retval
= ERROR_OK
;
620 for (unsigned i
= 0; i
< count
; i
++) {
621 retval
= mips64_pracc_write_u64(ejtag_info
, addr
+ 8 * i
, &buf
[i
]);
622 if (retval
!= ERROR_OK
)
628 static int mips64_pracc_write_u32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
631 const uint32_t code
[] = {
632 MIPS64_DMTC0(15, 31, 0),
633 /* move $15 to COP0 DeSave */
634 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
635 /* $15 = MIPS64_PRACC_STACK */
636 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
641 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
) - 8), 15),
642 /* load R8 @ param_in[1] = data */
643 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
644 /* load R9 @ param_in[0] = address */
655 MIPS64_DMFC0(15, 31, 0),
656 /* move COP0 DeSave to $15 */
667 /* TODO remove array */
668 uint64_t param_in
[1 + 1];
672 LOG_DEBUG("enter mips64_pracc_exec");
673 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
674 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
677 static int mips64_pracc_write_mem32(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
678 unsigned count
, uint32_t *buf
)
680 int retval
= ERROR_OK
;
682 for (unsigned i
= 0; i
< count
; i
++) {
683 retval
= mips64_pracc_write_u32(ejtag_info
, addr
+ 4 * i
, &buf
[i
]);
684 if (retval
!= ERROR_OK
)
690 static int mips64_pracc_write_u16(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
693 const uint32_t code
[] = {
694 /* move $15 to COP0 DeSave */
695 MIPS64_DMTC0(15, 31, 0),
696 /* $15 = MIPS64_PRACC_STACK */
697 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
698 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
703 /* load R8 @ param_in[1] = data */
704 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
) - 8), 15),
705 /* load R9 @ param_in[0] = address */
706 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
716 /* move COP0 DeSave to $15 */
717 MIPS64_DMFC0(15, 31, 0),
728 uint64_t param_in
[2];
732 LOG_DEBUG("enter mips64_pracc_exec");
733 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
734 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
737 static int mips64_pracc_write_mem16(struct mips_ejtag
*ejtag_info
,
738 uint64_t addr
, unsigned count
, uint16_t *buf
)
740 int retval
= ERROR_OK
;
742 for (unsigned i
= 0; i
< count
; i
++) {
743 retval
= mips64_pracc_write_u16(ejtag_info
, addr
+ 2 * i
, &buf
[i
]);
744 if (retval
!= ERROR_OK
)
750 static int mips64_pracc_write_u8(struct mips_ejtag
*ejtag_info
, uint64_t addr
,
753 const uint32_t code
[] = {
754 /* move $15 to COP0 DeSave */
755 MIPS64_DMTC0(15, 31, 0),
756 /* $15 = MIPS64_PRACC_STACK */
757 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
758 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
763 /* load R8 @ param_in[1] = data */
764 MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
) - 8), 15),
765 /* load R9 @ param_in[0] = address */
766 MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK
-MIPS64_PRACC_PARAM_IN
), 15),
776 /* move COP0 DeSave to $15 */
777 MIPS64_DMFC0(15, 31, 0),
788 /* TODO remove array */
789 uint64_t param_in
[2];
793 LOG_DEBUG("enter mips64_pracc_exec");
794 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
795 ARRAY_SIZE(param_in
), param_in
, 0, NULL
);
798 static int mips64_pracc_write_mem8(struct mips_ejtag
*ejtag_info
,
799 uint64_t addr
, unsigned count
, uint8_t *buf
)
801 int retval
= ERROR_OK
;
803 for (unsigned i
= 0; i
< count
; i
++) {
804 retval
= mips64_pracc_write_u8(ejtag_info
, addr
+ i
, &buf
[i
]);
805 if (retval
!= ERROR_OK
)
811 int mips64_pracc_write_mem(struct mips_ejtag
*ejtag_info
,
812 uint64_t addr
, unsigned size
,
813 unsigned count
, void *buf
)
817 return mips64_pracc_write_mem8(ejtag_info
, addr
, count
, buf
);
819 return mips64_pracc_write_mem16(ejtag_info
, addr
, count
, buf
);
821 return mips64_pracc_write_mem32(ejtag_info
, addr
, count
, buf
);
823 return mips64_pracc_write_mem64(ejtag_info
, addr
, count
, buf
);
828 int mips64_pracc_write_regs(struct mips_ejtag
*ejtag_info
, uint64_t *regs
)
830 const uint32_t code
[] = {
831 /* move $2 to COP0 DeSave */
832 MIPS64_DMTC0(2, 31, 0),
833 /* $15 = MIPS64_PRACC_STACK */
834 MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_IN
)),
835 MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_IN
)),
837 MIPS64_LD(1, 1*8, 2),
839 MIPS64_LD(15, 15*8, 2),
841 MIPS64_DMFC0(2, 31, 0),
842 MIPS64_DMTC0(15, 31, 0),
843 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
844 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
846 /* $11 = MIPS64_PRACC_PARAM_OUT */
847 MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_IN
)),
848 MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_IN
)),
849 MIPS64_LD(3, 3*8, 1),
850 MIPS64_LD(4, 4*8, 1),
851 MIPS64_LD(5, 5*8, 1),
852 MIPS64_LD(6, 6*8, 1),
853 MIPS64_LD(7, 7*8, 1),
854 MIPS64_LD(8, 8*8, 1),
855 MIPS64_LD(9, 9*8, 1),
856 MIPS64_LD(10, 10*8, 1),
857 MIPS64_LD(11, 11*8, 1),
858 MIPS64_LD(12, 12*8, 1),
859 MIPS64_LD(13, 13*8, 1),
860 MIPS64_LD(14, 14*8, 1),
861 MIPS64_LD(16, 16*8, 1),
862 MIPS64_LD(17, 17*8, 1),
863 MIPS64_LD(18, 18*8, 1),
864 MIPS64_LD(19, 19*8, 1),
865 MIPS64_LD(20, 20*8, 1),
866 MIPS64_LD(21, 21*8, 1),
867 MIPS64_LD(22, 22*8, 1),
868 MIPS64_LD(23, 23*8, 1),
869 MIPS64_LD(24, 24*8, 1),
870 MIPS64_LD(25, 25*8, 1),
871 MIPS64_LD(26, 26*8, 1),
872 MIPS64_LD(27, 27*8, 1),
873 MIPS64_LD(28, 28*8, 1),
874 MIPS64_LD(29, 29*8, 1),
875 MIPS64_LD(30, 30*8, 1),
876 MIPS64_LD(31, 31*8, 1),
877 MIPS64_LD(2, 32*8, 1),
879 MIPS64_LD(2, 33*8, 1),
881 MIPS64_LD(2, MIPS64_NUM_CORE_REGS
* 8, 1),
882 MIPS64_DMTC0(2, MIPS64_C0_DEPC
, 0),
883 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 2) * 8, 1),
884 MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO0
, 0),
885 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 3) * 8, 1),
886 MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO1
, 0),
887 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 4) * 8, 1),
888 MIPS64_DMTC0(2, MIPS64_C0_CONTEXT
, 0),
889 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 5) * 8, 1),
890 MIPS64_MTC0(2, MIPS64_C0_PAGEMASK
, 0),
891 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 6) * 8, 1),
892 MIPS64_MTC0(2, MIPS64_C0_WIRED
, 0),
893 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 8) * 8, 1),
894 MIPS64_MTC0(2, MIPS64_C0_COUNT
, 0),
895 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 9) * 8, 1),
896 MIPS64_DMTC0(2, MIPS64_C0_ENTRYHI
, 0),
897 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 10) * 8, 1),
898 MIPS64_MTC0(2, MIPS64_C0_COMPARE
, 0),
899 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 11) * 8, 1),
900 MIPS64_MTC0(2, MIPS64_C0_STATUS
, 0),
901 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 12) * 8, 1),
902 MIPS64_MTC0(2, MIPS64_C0_CAUSE
, 0),
903 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 13) * 8, 1),
904 MIPS64_DMTC0(2, MIPS64_C0_EPC
, 0),
905 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 15) * 8, 1),
906 MIPS64_MTC0(2, MIPS64_C0_CONFIG
, 0),
907 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 16) * 8, 1),
908 MIPS64_MTC0(2, MIPS64_C0_LLA
, 0),
909 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 21) * 8, 1),
910 MIPS64_DMTC0(2, MIPS64_C0_XCONTEXT
, 1),
911 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 22) * 8, 1),
912 MIPS64_MTC0(2, MIPS64_C0_MEMCTRL
, 0),
913 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 24) * 8, 1),
914 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 0),
915 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 25) * 8, 1),
916 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 1),
917 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 26) * 8, 1),
918 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 2),
919 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 27) * 8, 1),
920 MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT
, 3),
921 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 28) * 8, 1),
922 MIPS64_MTC0(2, MIPS64_C0_ECC
, 0),
923 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 29) * 8, 1),
924 MIPS64_MTC0(2, MIPS64_C0_CACHERR
, 0),
925 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 30) * 8, 1),
926 MIPS64_MTC0(2, MIPS64_C0_TAGLO
, 0),
927 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 31) * 8, 1),
928 MIPS64_MTC0(2, MIPS64_C0_TAGHI
, 0),
929 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 32) * 8, 1),
930 MIPS64_DMTC0(2, MIPS64_C0_DATAHI
, 0),
931 MIPS64_LD(2, (MIPS64_NUM_CORE_REGS
+ 33) * 8, 1),
932 MIPS64_DMTC0(2, MIPS64_C0_EEPC
, 0),
933 /* check if FPU is enabled, */
934 MIPS64_MFC0(2, MIPS64_C0_STATUS
, 0),
935 MIPS64_SRL(2, 2, 29),
936 MIPS64_ANDI(2, 2, 1),
937 /* skip FPU registers restoration if not */
938 MIPS64_BEQ(0, 2, 77),
940 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 33) * 8, 1),
941 MIPS64_CTC1(2, MIPS64_C1_FIR
, 0),
942 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 32) * 8, 1),
943 MIPS64_CTC1(2, MIPS64_C1_FCSR
, 0),
944 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 34) * 8, 1),
945 MIPS64_CTC1(2, MIPS64_C1_FCONFIG
, 0),
946 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 35) * 8, 1),
947 MIPS64_CTC1(2, MIPS64_C1_FCCR
, 0),
948 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 36) * 8, 1),
949 MIPS64_CTC1(2, MIPS64_C1_FEXR
, 0),
950 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 37) * 8, 1),
951 MIPS64_CTC1(2, MIPS64_C1_FENR
, 0),
952 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 0) * 8, 1),
953 MIPS64_DMTC1(2, 0, 0),
954 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 1) * 8, 1),
955 MIPS64_DMTC1(2, 1, 0),
956 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 2) * 8, 1),
957 MIPS64_DMTC1(2, 2, 0),
958 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 3) * 8, 1),
959 MIPS64_DMTC1(2, 3, 0),
960 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 4) * 8, 1),
961 MIPS64_DMTC1(2, 4, 0),
962 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 5) * 8, 1),
963 MIPS64_DMTC1(2, 5, 0),
964 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 6) * 8, 1),
965 MIPS64_DMTC1(2, 6, 0),
966 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 7) * 8, 1),
967 MIPS64_DMTC1(2, 7, 0),
968 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 8) * 8, 1),
969 MIPS64_DMTC1(2, 8, 0),
970 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 9) * 8, 1),
971 MIPS64_DMTC1(2, 9, 0),
972 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 10) * 8, 1),
973 MIPS64_DMTC1(2, 10, 0),
974 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 11) * 8, 1),
975 MIPS64_DMTC1(2, 11, 0),
976 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 12) * 8, 1),
977 MIPS64_DMTC1(2, 12, 0),
978 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 13) * 8, 1),
979 MIPS64_DMTC1(2, 13, 0),
980 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 14) * 8, 1),
981 MIPS64_DMTC1(2, 14, 0),
982 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 15) * 8, 1),
983 MIPS64_DMTC1(2, 15, 0),
984 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 16) * 8, 1),
985 MIPS64_DMTC1(2, 16, 0),
986 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 17) * 8, 1),
987 MIPS64_DMTC1(2, 17, 0),
988 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 18) * 8, 1),
989 MIPS64_DMTC1(2, 18, 0),
990 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 19) * 8, 1),
991 MIPS64_DMTC1(2, 19, 0),
992 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 20) * 8, 1),
993 MIPS64_DMTC1(2, 20, 0),
994 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 21) * 8, 1),
995 MIPS64_DMTC1(2, 21, 0),
996 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 22) * 8, 1),
997 MIPS64_DMTC1(2, 22, 0),
998 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 23) * 8, 1),
999 MIPS64_DMTC1(2, 23, 0),
1000 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 24) * 8, 1),
1001 MIPS64_DMTC1(2, 24, 0),
1002 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 25) * 8, 1),
1003 MIPS64_DMTC1(2, 25, 0),
1004 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 26) * 8, 1),
1005 MIPS64_DMTC1(2, 26, 0),
1006 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 27) * 8, 1),
1007 MIPS64_DMTC1(2, 27, 0),
1008 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 28) * 8, 1),
1009 MIPS64_DMTC1(2, 28, 0),
1010 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 29) * 8, 1),
1011 MIPS64_DMTC1(2, 29, 0),
1012 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 30) * 8, 1),
1013 MIPS64_DMTC1(2, 30, 0),
1014 MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS
+ 31) * 8, 1),
1015 MIPS64_DMTC1(2, 31, 0),
1016 MIPS64_LD(2, 2 * 8, 1),
1017 MIPS64_LD(1, 0, 15),
1020 MIPS64_B(NEG16(181)),
1021 /* move COP0 DeSave to $15 */
1022 MIPS64_DMFC0(15, 31, 0),
1033 LOG_DEBUG("enter mips64_pracc_exec");
1034 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
1035 MIPS64_NUM_REGS
, regs
, 0, NULL
);
1038 int mips64_pracc_read_regs(struct mips_ejtag
*ejtag_info
, uint64_t *regs
)
1040 const uint32_t code
[] = {
1041 /* move $2 to COP0 DeSave */
1042 MIPS64_DMTC0(2, 31, 0),
1043 /* $2 = MIPS64_PRACC_PARAM_OUT */
1044 MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_OUT
)),
1045 MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_OUT
)),
1046 /* sd $0, 0*8($2) */
1047 MIPS64_SD(0, 0*8, 2),
1048 /* sd $1, 1*8($2) */
1049 MIPS64_SD(1, 1*8, 2),
1050 /* sd $15, 15*8($2) */
1051 MIPS64_SD(15, 15*8, 2),
1052 /* move COP0 DeSave to $2 */
1053 MIPS64_DMFC0(2, 31, 0),
1054 /* move $15 to COP0 DeSave */
1055 MIPS64_DMTC0(15, 31, 0),
1056 /* $15 = MIPS64_PRACC_STACK */
1057 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)),
1058 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
1060 MIPS64_SD(1, 0, 15),
1062 MIPS64_SD(2, 0, 15),
1063 /* $1 = MIPS64_PRACC_PARAM_OUT */
1064 MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_OUT
)),
1065 MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_OUT
)),
1066 MIPS64_SD(2, 2 * 8, 1),
1067 MIPS64_SD(3, 3 * 8, 1),
1068 MIPS64_SD(4, 4 * 8, 1),
1069 MIPS64_SD(5, 5 * 8, 1),
1070 MIPS64_SD(6, 6 * 8, 1),
1071 MIPS64_SD(7, 7 * 8, 1),
1072 MIPS64_SD(8, 8 * 8, 1),
1073 MIPS64_SD(9, 9 * 8, 1),
1074 MIPS64_SD(10, 10 * 8, 1),
1075 MIPS64_SD(11, 11 * 8, 1),
1076 MIPS64_SD(12, 12 * 8, 1),
1077 MIPS64_SD(13, 13 * 8, 1),
1078 MIPS64_SD(14, 14 * 8, 1),
1079 MIPS64_SD(16, 16 * 8, 1),
1080 MIPS64_SD(17, 17 * 8, 1),
1081 MIPS64_SD(18, 18 * 8, 1),
1082 MIPS64_SD(19, 19 * 8, 1),
1083 MIPS64_SD(20, 20 * 8, 1),
1084 MIPS64_SD(21, 21 * 8, 1),
1085 MIPS64_SD(22, 22 * 8, 1),
1086 MIPS64_SD(23, 23 * 8, 1),
1087 MIPS64_SD(24, 24 * 8, 1),
1088 MIPS64_SD(25, 25 * 8, 1),
1089 MIPS64_SD(26, 26 * 8, 1),
1090 MIPS64_SD(27, 27 * 8, 1),
1091 MIPS64_SD(28, 28 * 8, 1),
1092 MIPS64_SD(29, 29 * 8, 1),
1093 MIPS64_SD(30, 30 * 8, 1),
1094 MIPS64_SD(31, 31 * 8, 1),
1096 MIPS64_SD(2, 32 * 8, 1),
1098 MIPS64_SD(2, 33 * 8, 1),
1099 MIPS64_DMFC0(2, MIPS64_C0_DEPC
, 0),
1100 MIPS64_SD(2, MIPS64_NUM_CORE_REGS
* 8, 1),
1101 MIPS64_DMFC0(2, MIPS64_C0_RANDOM
, 0),
1102 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 1) * 8, 1),
1103 MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO0
, 0),
1104 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 2) * 8, 1),
1105 MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO1
, 0),
1106 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 3) * 8, 1),
1107 MIPS64_DMFC0(2, MIPS64_C0_CONTEXT
, 0),
1108 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 4) * 8, 1),
1109 MIPS64_MFC0(2, MIPS64_C0_PAGEMASK
, 0),
1110 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 5) * 8, 1),
1111 MIPS64_MFC0(2, MIPS64_C0_WIRED
, 0),
1112 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 6) * 8, 1),
1113 MIPS64_DMFC0(2, MIPS64_C0_BADVADDR
, 0),
1114 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 7) * 8, 1),
1115 MIPS64_MFC0(2, MIPS64_C0_COUNT
, 0),
1116 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 8) * 8, 1),
1117 MIPS64_DMFC0(2, MIPS64_C0_ENTRYHI
, 0),
1118 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 9) * 8, 1),
1119 MIPS64_MFC0(2, MIPS64_C0_COMPARE
, 0),
1120 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 10) * 8, 1),
1121 MIPS64_MFC0(2, MIPS64_C0_STATUS
, 0),
1122 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 11) * 8, 1),
1123 MIPS64_MFC0(2, MIPS64_C0_CAUSE
, 0),
1124 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 12) * 8, 1),
1125 MIPS64_DMFC0(2, MIPS64_C0_EPC
, 0),
1126 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 13) * 8, 1),
1127 MIPS64_MFC0(2, MIPS64_C0_PRID
, 0),
1128 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 14) * 8, 1),
1129 MIPS64_MFC0(2, MIPS64_C0_CONFIG
, 0),
1130 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 15) * 8, 1),
1131 MIPS64_MFC0(2, MIPS64_C0_LLA
, 0),
1132 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 16) * 8, 1),
1133 MIPS64_DMFC0(2, MIPS64_C0_XCONTEXT
, 1),
1134 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 21) * 8, 1),
1135 MIPS64_MFC0(2, MIPS64_C0_MEMCTRL
, 0),
1136 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 22) * 8, 1),
1137 MIPS64_MFC0(2, MIPS64_C0_DEBUG
, 0),
1138 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 23) * 8, 1),
1139 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 0),
1140 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 24) * 8, 1),
1141 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 1),
1142 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 25) * 8, 1),
1143 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 2),
1144 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 26) * 8, 1),
1145 MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT
, 3),
1146 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 27) * 8, 1),
1147 MIPS64_MFC0(2, MIPS64_C0_ECC
, 0),
1148 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 28) * 8, 1),
1149 MIPS64_MFC0(2, MIPS64_C0_CACHERR
, 0),
1150 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 29) * 8, 1),
1151 MIPS64_MFC0(2, MIPS64_C0_TAGLO
, 0),
1152 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 30) * 8, 1),
1153 MIPS64_MFC0(2, MIPS64_C0_TAGHI
, 0),
1154 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 31) * 8, 1),
1155 MIPS64_DMFC0(2, MIPS64_C0_DATAHI
, 0),
1156 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 32) * 8, 1),
1157 MIPS64_DMFC0(2, MIPS64_C0_EEPC
, 0),
1158 MIPS64_SD(2, (MIPS64_NUM_CORE_REGS
+ 33) * 8, 1),
1159 /* check if FPU is enabled, */
1160 MIPS64_MFC0(2, MIPS64_C0_STATUS
, 0),
1161 MIPS64_SRL(2, 2, 29),
1162 MIPS64_ANDI(2, 2, 1),
1163 /* skip FPU registers dump if not */
1164 MIPS64_BEQ(0, 2, 77),
1166 MIPS64_CFC1(2, MIPS64_C1_FIR
, 0),
1167 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 33) * 8, 1),
1168 MIPS64_CFC1(2, MIPS64_C1_FCSR
, 0),
1169 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 32) * 8, 1),
1170 MIPS64_CFC1(2, MIPS64_C1_FCONFIG
, 0),
1171 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 34) * 8, 1),
1172 MIPS64_CFC1(2, MIPS64_C1_FCCR
, 0),
1173 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 35) * 8, 1),
1174 MIPS64_CFC1(2, MIPS64_C1_FEXR
, 0),
1175 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 36) * 8, 1),
1176 MIPS64_CFC1(2, MIPS64_C1_FENR
, 0),
1177 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 37) * 8, 1),
1178 MIPS64_DMFC1(2, 0, 0),
1179 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 0) * 8, 1),
1180 MIPS64_DMFC1(2, 1, 0),
1181 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 1) * 8, 1),
1182 MIPS64_DMFC1(2, 2, 0),
1183 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 2) * 8, 1),
1184 MIPS64_DMFC1(2, 3, 0),
1185 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 3) * 8, 1),
1186 MIPS64_DMFC1(2, 4, 0),
1187 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 4) * 8, 1),
1188 MIPS64_DMFC1(2, 5, 0),
1189 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 5) * 8, 1),
1190 MIPS64_DMFC1(2, 6, 0),
1191 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 6) * 8, 1),
1192 MIPS64_DMFC1(2, 7, 0),
1193 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 7) * 8, 1),
1194 MIPS64_DMFC1(2, 8, 0),
1195 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 8) * 8, 1),
1196 MIPS64_DMFC1(2, 9, 0),
1197 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 9) * 8, 1),
1198 MIPS64_DMFC1(2, 10, 0),
1199 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 10) * 8, 1),
1200 MIPS64_DMFC1(2, 11, 0),
1201 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 11) * 8, 1),
1202 MIPS64_DMFC1(2, 12, 0),
1203 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 12) * 8, 1),
1204 MIPS64_DMFC1(2, 13, 0),
1205 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 13) * 8, 1),
1206 MIPS64_DMFC1(2, 14, 0),
1207 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 14) * 8, 1),
1208 MIPS64_DMFC1(2, 15, 0),
1209 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 15) * 8, 1),
1210 MIPS64_DMFC1(2, 16, 0),
1211 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 16) * 8, 1),
1212 MIPS64_DMFC1(2, 17, 0),
1213 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 17) * 8, 1),
1214 MIPS64_DMFC1(2, 18, 0),
1215 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 18) * 8, 1),
1216 MIPS64_DMFC1(2, 19, 0),
1217 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 19) * 8, 1),
1218 MIPS64_DMFC1(2, 20, 0),
1219 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 20) * 8, 1),
1220 MIPS64_DMFC1(2, 21, 0),
1221 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 21) * 8, 1),
1222 MIPS64_DMFC1(2, 22, 0),
1223 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 22) * 8, 1),
1224 MIPS64_DMFC1(2, 23, 0),
1225 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 23) * 8, 1),
1226 MIPS64_DMFC1(2, 24, 0),
1227 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 24) * 8, 1),
1228 MIPS64_DMFC1(2, 25, 0),
1229 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 25) * 8, 1),
1230 MIPS64_DMFC1(2, 26, 0),
1231 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 26) * 8, 1),
1232 MIPS64_DMFC1(2, 27, 0),
1233 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 27) * 8, 1),
1234 MIPS64_DMFC1(2, 28, 0),
1235 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 28) * 8, 1),
1236 MIPS64_DMFC1(2, 29, 0),
1237 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 29) * 8, 1),
1238 MIPS64_DMFC1(2, 30, 0),
1239 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 30) * 8, 1),
1240 MIPS64_DMFC1(2, 31, 0),
1241 MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS
+ 31) * 8, 1),
1242 MIPS64_LD(2, 0, 15),
1243 MIPS64_LD(1, 0, 15),
1246 MIPS64_B(NEG16(192)),
1247 /* move COP0 DeSave to $15 */
1248 MIPS64_DMFC0(15, 31, 0),
1259 LOG_DEBUG("enter mips64_pracc_exec");
1260 return mips64_pracc_exec(ejtag_info
, ARRAY_SIZE(code
), code
,
1261 0, NULL
, MIPS64_NUM_REGS
, regs
);
1264 /* fastdata upload/download requires an initialized working area
1265 * to load the download code; it should not be called otherwise
1266 * fetch order from the fastdata area
1271 int mips64_pracc_fastdata_xfer(struct mips_ejtag
*ejtag_info
,
1272 struct working_area
*source
,
1273 bool write_t
, uint64_t addr
,
1274 unsigned count
, uint64_t *buf
)
1276 uint32_t handler_code
[] = {
1277 /* caution when editing, table is modified below */
1278 /* r15 points to the start of this code */
1279 MIPS64_SD(8, MIPS64_FASTDATA_HANDLER_SIZE
- 8, 15),
1280 MIPS64_SD(9, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 2, 15),
1281 MIPS64_SD(10, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 3, 15),
1282 MIPS64_SD(11, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 4, 15),
1283 /* start of fastdata area in t0 */
1284 MIPS64_LUI(8, UPPER16(MIPS64_PRACC_FASTDATA_AREA
)),
1285 MIPS64_ORI(8, 8, LOWER16(MIPS64_PRACC_FASTDATA_AREA
)),
1286 /* start addr in t1 */
1288 /* end addr to t2 */
1289 MIPS64_LD(10, 0, 8),
1292 /* lw t3,[t8 | r9] */
1293 /* 8 */ MIPS64_LD(11, 0, 0),
1294 /* sw t3,[r9 | r8] */
1295 /* 9 */ MIPS64_SD(11, 0, 0),
1296 /* bne $t2,t1,loop */
1297 MIPS64_BNE(10, 9, NEG16(3)),
1299 MIPS64_DADDIU(9, 9, 8),
1301 MIPS64_LD(8, MIPS64_FASTDATA_HANDLER_SIZE
- 8, 15),
1302 MIPS64_LD(9, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 2, 15),
1303 MIPS64_LD(10, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 3, 15),
1304 MIPS64_LD(11, MIPS64_FASTDATA_HANDLER_SIZE
- 8 * 4, 15),
1306 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_TEXT
)),
1307 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_TEXT
)),
1310 /* move COP0 DeSave to $15 */
1311 MIPS64_DMFC0(15, 31, 0),
1314 uint32_t jmp_code
[] = {
1315 /* addr of working area added below */
1316 /* 0 */ MIPS64_LUI(15, 0),
1317 /* addr of working area added below */
1318 /* 1 */ MIPS64_ORI(15, 15, 0),
1319 /* jump to ram program */
1326 uint32_t ejtag_ctrl
, address32
;
1327 uint64_t address
, val
;
1329 if (source
->size
< MIPS64_FASTDATA_HANDLER_SIZE
)
1330 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1333 /* load data from probe at fastdata area */
1334 handler_code
[8] = MIPS64_LD(11, 0, 8);
1335 /* store data to RAM @ r9 */
1336 handler_code
[9] = MIPS64_SD(11, 0, 9);
1338 /* load data from RAM @ r9 */
1339 handler_code
[8] = MIPS64_LD(11, 0, 9);
1340 /* store data to probe at fastdata area */
1341 handler_code
[9] = MIPS64_SD(11, 0, 8);
1344 /* write program into RAM */
1345 if (write_t
!= ejtag_info
->fast_access_save
) {
1346 mips64_pracc_write_mem(ejtag_info
, source
->address
, 4,
1347 ARRAY_SIZE(handler_code
), handler_code
);
1348 /* save previous operation to speed to any consecutive read/writes */
1349 ejtag_info
->fast_access_save
= write_t
;
1352 LOG_DEBUG("%s using " TARGET_ADDR_FMT
" for write handler", __func__
,
1354 LOG_DEBUG("daddiu: %08x", handler_code
[11]);
1356 jmp_code
[0] |= UPPER16(source
->address
);
1357 jmp_code
[1] |= LOWER16(source
->address
);
1358 mips64_pracc_exec(ejtag_info
,
1359 ARRAY_SIZE(jmp_code
), jmp_code
,
1362 /* next fetch to dmseg should be in FASTDATA_AREA, check */
1365 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
1366 retval
= mips_ejtag_drscan_32(ejtag_info
, &address32
);
1367 if (retval
!= ERROR_OK
)
1369 address
= 0xffffffffff200000ull
| address32
;
1370 if ((address
& ~7ull) != MIPS64_PRACC_FASTDATA_AREA
) {
1371 LOG_ERROR("! @MIPS64_PRACC_FASTDATA_AREA (" TARGET_ADDR_FMT
")", address
);
1374 /* Send the load start address */
1376 LOG_DEBUG("start: " TARGET_ADDR_FMT
, val
);
1377 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_FASTDATA
);
1378 mips64_ejtag_fastdata_scan(ejtag_info
, 1, &val
);
1380 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
1381 if (retval
!= ERROR_OK
)
1384 /* Send the load end address */
1385 val
= addr
+ (count
- 1) * 8;
1386 LOG_DEBUG("stop: " TARGET_ADDR_FMT
, val
);
1387 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_FASTDATA
);
1388 mips64_ejtag_fastdata_scan(ejtag_info
, 1, &val
);
1390 /* like in legacy code */
1391 unsigned num_clocks
= 0;
1392 if (ejtag_info
->mode
!= 0)
1393 num_clocks
= ((uint64_t)(ejtag_info
->scan_delay
) * jtag_get_speed_khz() + 500000) / 1000000;
1394 LOG_DEBUG("num_clocks=%d", num_clocks
);
1395 for (i
= 0; i
< count
; i
++) {
1396 jtag_add_clocks(num_clocks
);
1397 retval
= mips64_ejtag_fastdata_scan(ejtag_info
, write_t
, buf
++);
1398 if (retval
!= ERROR_OK
) {
1399 LOG_ERROR("mips64_ejtag_fastdata_scan failed");
1404 retval
= jtag_execute_queue();
1405 if (retval
!= ERROR_OK
) {
1406 LOG_ERROR("jtag_execute_queue failed");
1410 retval
= wait_for_pracc_rw(ejtag_info
, &ejtag_ctrl
);
1411 if (retval
!= ERROR_OK
) {
1412 LOG_ERROR("wait_for_pracc_rw failed");
1417 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
1418 retval
= mips_ejtag_drscan_32(ejtag_info
, &address32
);
1419 if (retval
!= ERROR_OK
) {
1420 LOG_ERROR("mips_ejtag_drscan_32 failed");
1424 address
= 0xffffffffff200000ull
| address32
;
1425 if ((address
& ~7ull) != MIPS64_PRACC_TEXT
)
1426 LOG_ERROR("mini program did not return to start");
1431 #endif /* BUILD_TARGET64 */
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)