1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
7 * Copyright (C) 2008 by David T.L. Wong *
9 * Copyright (C) 2007,2008 Øyvind Harboe *
10 * oyvind.harboe@zylin.com *
12 * Copyright (C) 2011 by Drasko DRASKOVIC *
13 * drasko.draskovic@gmail.com *
14 ***************************************************************************/
22 #include "breakpoints.h"
23 #include "algorithm.h"
26 static const char *mips_isa_strings
[] = {
27 "MIPS32", "MIPS16", "", "MICRO MIPS32",
30 #define MIPS32_GDB_FP_REG 1
34 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
44 { 0, "r0", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
45 { 1, "r1", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
46 { 2, "r2", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
47 { 3, "r3", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
48 { 4, "r4", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
49 { 5, "r5", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
50 { 6, "r6", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
51 { 7, "r7", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
52 { 8, "r8", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
53 { 9, "r9", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
54 { 10, "r10", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 11, "r11", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 12, "r12", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 13, "r13", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 14, "r14", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 15, "r15", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 16, "r16", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 17, "r17", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 18, "r18", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 19, "r19", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 20, "r20", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { 21, "r21", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
66 { 22, "r22", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
67 { 23, "r23", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
68 { 24, "r24", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
69 { 25, "r25", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
70 { 26, "r26", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
71 { 27, "r27", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
72 { 28, "r28", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
73 { 29, "r29", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
74 { 30, "r30", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
75 { 31, "r31", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
76 { 32, "lo", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
77 { 33, "hi", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
79 { MIPS32_REGLIST_FP_INDEX
+ 0, "f0", REG_TYPE_IEEE_DOUBLE
, NULL
,
80 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
81 { MIPS32_REGLIST_FP_INDEX
+ 1, "f1", REG_TYPE_IEEE_DOUBLE
, NULL
,
82 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
83 { MIPS32_REGLIST_FP_INDEX
+ 2, "f2", REG_TYPE_IEEE_DOUBLE
, NULL
,
84 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
85 { MIPS32_REGLIST_FP_INDEX
+ 3, "f3", REG_TYPE_IEEE_DOUBLE
, NULL
,
86 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
87 { MIPS32_REGLIST_FP_INDEX
+ 4, "f4", REG_TYPE_IEEE_DOUBLE
, NULL
,
88 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
89 { MIPS32_REGLIST_FP_INDEX
+ 5, "f5", REG_TYPE_IEEE_DOUBLE
, NULL
,
90 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
91 { MIPS32_REGLIST_FP_INDEX
+ 6, "f6", REG_TYPE_IEEE_DOUBLE
, NULL
,
92 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
93 { MIPS32_REGLIST_FP_INDEX
+ 7, "f7", REG_TYPE_IEEE_DOUBLE
, NULL
,
94 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
95 { MIPS32_REGLIST_FP_INDEX
+ 8, "f8", REG_TYPE_IEEE_DOUBLE
, NULL
,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
97 { MIPS32_REGLIST_FP_INDEX
+ 9, "f9", REG_TYPE_IEEE_DOUBLE
, NULL
,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
99 { MIPS32_REGLIST_FP_INDEX
+ 10, "f10", REG_TYPE_IEEE_DOUBLE
, NULL
,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
101 { MIPS32_REGLIST_FP_INDEX
+ 11, "f11", REG_TYPE_IEEE_DOUBLE
, NULL
,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
103 { MIPS32_REGLIST_FP_INDEX
+ 12, "f12", REG_TYPE_IEEE_DOUBLE
, NULL
,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
105 { MIPS32_REGLIST_FP_INDEX
+ 13, "f13", REG_TYPE_IEEE_DOUBLE
, NULL
,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
107 { MIPS32_REGLIST_FP_INDEX
+ 14, "f14", REG_TYPE_IEEE_DOUBLE
, NULL
,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
109 { MIPS32_REGLIST_FP_INDEX
+ 15, "f15", REG_TYPE_IEEE_DOUBLE
, NULL
,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
111 { MIPS32_REGLIST_FP_INDEX
+ 16, "f16", REG_TYPE_IEEE_DOUBLE
, NULL
,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
113 { MIPS32_REGLIST_FP_INDEX
+ 17, "f17", REG_TYPE_IEEE_DOUBLE
, NULL
,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
115 { MIPS32_REGLIST_FP_INDEX
+ 18, "f18", REG_TYPE_IEEE_DOUBLE
, NULL
,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
117 { MIPS32_REGLIST_FP_INDEX
+ 19, "f19", REG_TYPE_IEEE_DOUBLE
, NULL
,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
119 { MIPS32_REGLIST_FP_INDEX
+ 20, "f20", REG_TYPE_IEEE_DOUBLE
, NULL
,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
121 { MIPS32_REGLIST_FP_INDEX
+ 21, "f21", REG_TYPE_IEEE_DOUBLE
, NULL
,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
123 { MIPS32_REGLIST_FP_INDEX
+ 22, "f22", REG_TYPE_IEEE_DOUBLE
, NULL
,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
125 { MIPS32_REGLIST_FP_INDEX
+ 23, "f23", REG_TYPE_IEEE_DOUBLE
, NULL
,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
127 { MIPS32_REGLIST_FP_INDEX
+ 24, "f24", REG_TYPE_IEEE_DOUBLE
, NULL
,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
129 { MIPS32_REGLIST_FP_INDEX
+ 25, "f25", REG_TYPE_IEEE_DOUBLE
, NULL
,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
131 { MIPS32_REGLIST_FP_INDEX
+ 26, "f26", REG_TYPE_IEEE_DOUBLE
, NULL
,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
133 { MIPS32_REGLIST_FP_INDEX
+ 27, "f27", REG_TYPE_IEEE_DOUBLE
, NULL
,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
135 { MIPS32_REGLIST_FP_INDEX
+ 28, "f28", REG_TYPE_IEEE_DOUBLE
, NULL
,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
137 { MIPS32_REGLIST_FP_INDEX
+ 29, "f29", REG_TYPE_IEEE_DOUBLE
, NULL
,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
139 { MIPS32_REGLIST_FP_INDEX
+ 30, "f30", REG_TYPE_IEEE_DOUBLE
, NULL
,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
141 { MIPS32_REGLIST_FP_INDEX
+ 31, "f31", REG_TYPE_IEEE_DOUBLE
, NULL
,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
144 { MIPS32_REGLIST_FPC_INDEX
+ 0, "fcsr", REG_TYPE_INT
, "float",
145 "org.gnu.gdb.mips.fpu", 0 },
146 { MIPS32_REGLIST_FPC_INDEX
+ 1, "fir", REG_TYPE_INT
, "float",
147 "org.gnu.gdb.mips.fpu", 0 },
149 { MIPS32_REGLIST_C0_STATUS_INDEX
, "status", REG_TYPE_INT
, NULL
,
150 "org.gnu.gdb.mips.cp0", 0 },
151 { MIPS32_REGLIST_C0_BADVADDR_INDEX
, "badvaddr", REG_TYPE_INT
, NULL
,
152 "org.gnu.gdb.mips.cp0", 0 },
153 { MIPS32_REGLIST_C0_CAUSE_INDEX
, "cause", REG_TYPE_INT
, NULL
,
154 "org.gnu.gdb.mips.cp0", 0 },
155 { MIPS32_REGLIST_C0_PC_INDEX
, "pc", REG_TYPE_INT
, NULL
,
156 "org.gnu.gdb.mips.cpu", 0 },
157 { MIPS32_REGLIST_C0_GUESTCTL1_INDEX
, "guestCtl1", REG_TYPE_INT
, NULL
,
158 "org.gnu.gdb.mips.cp0", 0 },
161 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
163 static int mips32_get_core_reg(struct reg
*reg
)
166 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
167 struct target
*target
= mips32_reg
->target
;
168 struct mips32_common
*mips32_target
= target_to_mips32(target
);
170 if (target
->state
!= TARGET_HALTED
)
171 return ERROR_TARGET_NOT_HALTED
;
173 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
178 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
180 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
181 struct target
*target
= mips32_reg
->target
;
185 value
= buf_get_u64(buf
, 0, 64);
187 value
= buf_get_u32(buf
, 0, 32);
189 if (target
->state
!= TARGET_HALTED
)
190 return ERROR_TARGET_NOT_HALTED
;
193 buf_set_u64(reg
->value
, 0, 64, value
);
195 buf_set_u32(reg
->value
, 0, 32, value
);
203 static int mips32_read_core_reg(struct target
*target
, unsigned int num
)
206 uint64_t reg_value
= 0;
208 /* get pointers to arch-specific information */
209 struct mips32_common
*mips32
= target_to_mips32(target
);
211 if (num
>= MIPS32_NUM_REGS
)
212 return ERROR_COMMAND_SYNTAX_ERROR
;
214 if (num
>= MIPS32_REGLIST_C0_INDEX
) {
216 cnum
= num
- MIPS32_REGLIST_C0_INDEX
;
217 reg_value
= mips32
->core_regs
.cp0
[cnum
];
218 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
219 } else if (num
>= MIPS32_REGLIST_FPC_INDEX
) {
221 cnum
= num
- MIPS32_REGLIST_FPC_INDEX
;
222 reg_value
= mips32
->core_regs
.fpcr
[cnum
];
223 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
224 } else if (num
>= MIPS32_REGLIST_FP_INDEX
) {
226 cnum
= num
- MIPS32_REGLIST_FP_INDEX
;
227 reg_value
= mips32
->core_regs
.fpr
[cnum
];
228 buf_set_u64(mips32
->core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
231 cnum
= num
- MIPS32_REGLIST_GP_INDEX
;
232 reg_value
= mips32
->core_regs
.gpr
[cnum
];
233 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
236 mips32
->core_cache
->reg_list
[num
].valid
= true;
237 mips32
->core_cache
->reg_list
[num
].dirty
= false;
239 LOG_DEBUG("read core reg %i value 0x%" PRIx64
"", num
, reg_value
);
244 static int mips32_write_core_reg(struct target
*target
, unsigned int num
)
249 /* get pointers to arch-specific information */
250 struct mips32_common
*mips32
= target_to_mips32(target
);
252 if (num
>= MIPS32_NUM_REGS
)
253 return ERROR_COMMAND_SYNTAX_ERROR
;
255 if (num
>= MIPS32_REGLIST_C0_INDEX
) {
257 cnum
= num
- MIPS32_REGLIST_C0_INDEX
;
258 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
259 mips32
->core_regs
.cp0
[cnum
] = (uint32_t)reg_value
;
260 } else if (num
>= MIPS32_REGLIST_FPC_INDEX
) {
262 cnum
= num
- MIPS32_REGLIST_FPC_INDEX
;
263 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
264 mips32
->core_regs
.fpcr
[cnum
] = (uint32_t)reg_value
;
265 } else if (num
>= MIPS32_REGLIST_FP_INDEX
) {
267 cnum
= num
- MIPS32_REGLIST_FP_INDEX
;
268 reg_value
= buf_get_u64(mips32
->core_cache
->reg_list
[num
].value
, 0, 64);
269 mips32
->core_regs
.fpr
[cnum
] = reg_value
;
272 cnum
= num
- MIPS32_REGLIST_GP_INDEX
;
273 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
274 mips32
->core_regs
.gpr
[cnum
] = (uint32_t)reg_value
;
277 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, reg_value
);
278 mips32
->core_cache
->reg_list
[num
].valid
= true;
279 mips32
->core_cache
->reg_list
[num
].dirty
= false;
284 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
285 int *reg_list_size
, enum target_register_class reg_class
)
287 /* get pointers to arch-specific information */
288 struct mips32_common
*mips32
= target_to_mips32(target
);
291 /* include floating point registers */
292 *reg_list_size
= MIPS32_NUM_REGS
;
293 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
295 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++)
296 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
301 int mips32_save_context(struct target
*target
)
305 /* get pointers to arch-specific information */
306 struct mips32_common
*mips32
= target_to_mips32(target
);
308 /* read core registers */
309 int retval
= mips32_pracc_read_regs(mips32
);
310 if (retval
!= ERROR_OK
) {
311 LOG_ERROR("Could not read core registers from target");
315 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
316 if (!mips32
->core_cache
->reg_list
[i
].valid
)
317 mips32
->read_core_reg(target
, i
);
323 int mips32_restore_context(struct target
*target
)
327 /* get pointers to arch-specific information */
328 struct mips32_common
*mips32
= target_to_mips32(target
);
330 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
331 if (mips32
->core_cache
->reg_list
[i
].dirty
)
332 mips32
->write_core_reg(target
, i
);
335 /* write core regs */
336 mips32_pracc_write_regs(mips32
);
341 int mips32_arch_state(struct target
*target
)
343 struct mips32_common
*mips32
= target_to_mips32(target
);
345 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
346 mips_isa_strings
[mips32
->isa_mode
],
347 debug_reason_name(target
),
348 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32));
353 static const struct reg_arch_type mips32_reg_type
= {
354 .get
= mips32_get_core_reg
,
355 .set
= mips32_set_core_reg
,
358 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
360 /* get pointers to arch-specific information */
361 struct mips32_common
*mips32
= target_to_mips32(target
);
363 int num_regs
= MIPS32_NUM_REGS
;
364 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
365 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
366 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
367 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
368 struct reg_feature
*feature
;
371 /* Build the process context cache */
372 cache
->name
= "mips32 registers";
374 cache
->reg_list
= reg_list
;
375 cache
->num_regs
= num_regs
;
377 mips32
->core_cache
= cache
;
379 for (i
= 0; i
< num_regs
; i
++) {
380 arch_info
[i
].num
= mips32_regs
[i
].id
;
381 arch_info
[i
].target
= target
;
382 arch_info
[i
].mips32_common
= mips32
;
384 reg_list
[i
].name
= mips32_regs
[i
].name
;
385 reg_list
[i
].size
= mips32_regs
[i
].size
? 64 : 32;
387 reg_list
[i
].value
= mips32_regs
[i
].size
? calloc(1, 8) : calloc(1, 4);
388 reg_list
[i
].valid
= false;
389 reg_list
[i
].type
= &mips32_reg_type
;
390 reg_list
[i
].arch_info
= &arch_info
[i
];
392 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
393 if (reg_list
[i
].reg_data_type
)
394 reg_list
[i
].reg_data_type
->type
= mips32_regs
[i
].type
;
396 LOG_ERROR("unable to allocate reg type list");
399 reg_list
[i
].dirty
= false;
401 reg_list
[i
].group
= mips32_regs
[i
].group
;
402 reg_list
[i
].number
= i
;
403 reg_list
[i
].exist
= true;
404 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
406 feature
= calloc(1, sizeof(struct reg_feature
));
408 feature
->name
= mips32_regs
[i
].feature
;
409 reg_list
[i
].feature
= feature
;
411 LOG_ERROR("unable to allocate feature list");
417 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
419 target
->arch_info
= mips32
;
420 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
421 mips32
->fast_data_area
= NULL
;
422 mips32
->isa_imp
= MIPS32_ONLY
; /* default */
424 /* has breakpoint/watchpoint unit been scanned */
425 mips32
->bp_scanned
= 0;
426 mips32
->data_break_list
= NULL
;
428 mips32
->ejtag_info
.tap
= tap
;
429 mips32
->read_core_reg
= mips32_read_core_reg
;
430 mips32
->write_core_reg
= mips32_write_core_reg
;
431 /* if unknown endianness defaults to little endian, 1 */
432 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
433 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
434 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
435 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
436 mips32
->ejtag_info
.config_regs
= 0; /* no config register read */
440 /* run to exit point. return error if exit point was not reached. */
441 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
442 unsigned int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
446 /* This code relies on the target specific resume() and poll()->debug_entry()
447 * sequence to write register values to the processor and the read them back */
448 retval
= target_resume(target
, 0, entry_point
, 0, 1);
449 if (retval
!= ERROR_OK
)
452 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
453 /* If the target fails to halt due to the breakpoint, force a halt */
454 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
455 retval
= target_halt(target
);
456 if (retval
!= ERROR_OK
)
458 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
459 if (retval
!= ERROR_OK
)
461 return ERROR_TARGET_TIMEOUT
;
464 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32);
465 if (exit_point
&& (pc
!= exit_point
)) {
466 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
467 return ERROR_TARGET_TIMEOUT
;
473 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
474 struct mem_param
*mem_params
, int num_reg_params
,
475 struct reg_param
*reg_params
, target_addr_t entry_point
,
476 target_addr_t exit_point
, unsigned int timeout_ms
, void *arch_info
)
478 struct mips32_common
*mips32
= target_to_mips32(target
);
479 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
480 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
482 uint32_t context
[MIPS32_NUM_REGS
];
483 int retval
= ERROR_OK
;
485 LOG_DEBUG("Running algorithm");
487 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
488 * at the exit point */
490 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
491 LOG_ERROR("current target isn't a MIPS32 target");
492 return ERROR_TARGET_INVALID
;
495 if (target
->state
!= TARGET_HALTED
) {
496 LOG_TARGET_ERROR(target
, "not halted (run target algo)");
497 return ERROR_TARGET_NOT_HALTED
;
500 /* refresh core register cache */
501 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
502 if (!mips32
->core_cache
->reg_list
[i
].valid
)
503 mips32
->read_core_reg(target
, i
);
504 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
507 for (int i
= 0; i
< num_mem_params
; i
++) {
508 if (mem_params
[i
].direction
== PARAM_IN
)
510 retval
= target_write_buffer(target
, mem_params
[i
].address
,
511 mem_params
[i
].size
, mem_params
[i
].value
);
512 if (retval
!= ERROR_OK
)
516 for (int i
= 0; i
< num_reg_params
; i
++) {
517 if (reg_params
[i
].direction
== PARAM_IN
)
520 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
523 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
524 return ERROR_COMMAND_SYNTAX_ERROR
;
527 if (reg
->size
!= reg_params
[i
].size
) {
528 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
529 reg_params
[i
].reg_name
);
530 return ERROR_COMMAND_SYNTAX_ERROR
;
533 mips32_set_core_reg(reg
, reg_params
[i
].value
);
536 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
538 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
540 if (retval
!= ERROR_OK
)
543 for (int i
= 0; i
< num_mem_params
; i
++) {
544 if (mem_params
[i
].direction
!= PARAM_OUT
) {
545 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
546 mem_params
[i
].value
);
547 if (retval
!= ERROR_OK
)
552 for (int i
= 0; i
< num_reg_params
; i
++) {
553 if (reg_params
[i
].direction
!= PARAM_OUT
) {
554 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
556 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
557 return ERROR_COMMAND_SYNTAX_ERROR
;
560 if (reg
->size
!= reg_params
[i
].size
) {
561 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
562 reg_params
[i
].reg_name
);
563 return ERROR_COMMAND_SYNTAX_ERROR
;
566 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
570 /* restore everything we saved before */
571 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
573 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
574 if (regvalue
!= context
[i
]) {
575 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
576 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
577 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
579 mips32
->core_cache
->reg_list
[i
].valid
= true;
580 mips32
->core_cache
->reg_list
[i
].dirty
= true;
584 mips32
->isa_mode
= isa_mode
;
589 int mips32_examine(struct target
*target
)
591 struct mips32_common
*mips32
= target_to_mips32(target
);
593 if (!target_was_examined(target
)) {
594 target_set_examined(target
);
596 /* we will configure later */
597 mips32
->bp_scanned
= 0;
598 mips32
->num_inst_bpoints
= 0;
599 mips32
->num_data_bpoints
= 0;
600 mips32
->num_inst_bpoints_avail
= 0;
601 mips32
->num_data_bpoints_avail
= 0;
607 static int mips32_configure_ibs(struct target
*target
)
609 struct mips32_common
*mips32
= target_to_mips32(target
);
610 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
614 /* get number of inst breakpoints */
615 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
616 if (retval
!= ERROR_OK
)
619 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
620 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
621 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
622 sizeof(struct mips32_comparator
));
624 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
625 mips32
->inst_break_list
[i
].reg_address
=
626 ejtag_info
->ejtag_iba0_addr
+
627 (ejtag_info
->ejtag_iba_step_size
* i
);
630 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
634 static int mips32_configure_dbs(struct target
*target
)
636 struct mips32_common
*mips32
= target_to_mips32(target
);
637 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
641 /* get number of data breakpoints */
642 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
643 if (retval
!= ERROR_OK
)
646 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
647 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
648 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
649 sizeof(struct mips32_comparator
));
651 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
652 mips32
->data_break_list
[i
].reg_address
=
653 ejtag_info
->ejtag_dba0_addr
+
654 (ejtag_info
->ejtag_dba_step_size
* i
);
657 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
661 int mips32_configure_break_unit(struct target
*target
)
663 /* get pointers to arch-specific information */
664 struct mips32_common
*mips32
= target_to_mips32(target
);
665 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
669 if (mips32
->bp_scanned
)
672 /* get info about breakpoint support */
673 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
674 if (retval
!= ERROR_OK
)
677 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
678 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
679 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
680 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
681 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
682 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
683 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
685 /* keep debug caps for later use */
686 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
687 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
690 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
691 retval
= mips32_configure_ibs(target
);
692 if (retval
!= ERROR_OK
)
696 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
697 retval
= mips32_configure_dbs(target
);
698 if (retval
!= ERROR_OK
)
702 /* check if target endianness settings matches debug control register */
703 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
704 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
705 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
706 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
707 LOG_WARNING("DCR endianness settings does not match target settings");
709 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
710 mips32
->num_data_bpoints
);
712 mips32
->bp_scanned
= 1;
717 int mips32_enable_interrupts(struct target
*target
, int enable
)
723 /* read debug control register */
724 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
725 if (retval
!= ERROR_OK
)
729 if (!(dcr
& EJTAG_DCR_INTE
)) {
730 /* enable interrupts */
731 dcr
|= EJTAG_DCR_INTE
;
735 if (dcr
& EJTAG_DCR_INTE
) {
736 /* disable interrupts */
737 dcr
&= ~EJTAG_DCR_INTE
;
743 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
744 if (retval
!= ERROR_OK
)
751 /* read processor identification cp0 register */
752 static int mips32_read_c0_prid(struct target
*target
)
754 struct mips32_common
*mips32
= target_to_mips32(target
);
755 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
758 retval
= mips32_cp0_read(ejtag_info
, &mips32
->prid
, 15, 0);
759 if (retval
!= ERROR_OK
) {
760 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
768 * Detect processor type and apply required quirks.
770 * NOTE: The proper detection of certain CPUs can become quite complicated.
771 * Please consult the following Linux kernel code when adding new CPUs:
772 * arch/mips/include/asm/cpu.h
773 * arch/mips/kernel/cpu-probe.c
775 int mips32_cpu_probe(struct target
*target
)
777 struct mips32_common
*mips32
= target_to_mips32(target
);
778 const char *cpu_name
= "unknown";
782 return ERROR_OK
; /* Already probed once, return early. */
784 retval
= mips32_read_c0_prid(target
);
785 if (retval
!= ERROR_OK
)
788 switch (mips32
->prid
& PRID_COMP_MASK
) {
789 case PRID_COMP_INGENIC_E1
:
790 switch (mips32
->prid
& PRID_IMP_MASK
) {
791 case PRID_IMP_XBURST_REV1
:
792 cpu_name
= "Ingenic XBurst rev1";
793 mips32
->cpu_quirks
|= EJTAG_QUIRK_PAD_DRET
;
803 LOG_DEBUG("CPU: %s (PRId %08x)", cpu_name
, mips32
->prid
);
808 /* read config to config3 cp0 registers and log isa implementation */
809 int mips32_read_config_regs(struct target
*target
)
811 struct mips32_common
*mips32
= target_to_mips32(target
);
812 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
814 if (ejtag_info
->config_regs
== 0)
815 for (int i
= 0; i
!= 4; i
++) {
816 int retval
= mips32_cp0_read(ejtag_info
, &ejtag_info
->config
[i
], 16, i
);
817 if (retval
!= ERROR_OK
) {
818 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32
, i
);
819 ejtag_info
->config_regs
= 0;
822 ejtag_info
->config_regs
= i
+ 1;
823 if ((ejtag_info
->config
[i
] & (1 << 31)) == 0)
824 break; /* no more config registers implemented */
827 return ERROR_OK
; /* already successfully read */
829 LOG_DEBUG("read %"PRIu32
" config registers", ejtag_info
->config_regs
);
831 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
) {
832 mips32
->isa_imp
= MIPS32_MIPS16
;
833 LOG_USER("MIPS32 with MIPS16 support implemented");
835 } else if (ejtag_info
->config_regs
>= 4) { /* config3 implemented */
836 unsigned isa_imp
= (ejtag_info
->config
[3] & MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
;
838 mips32
->isa_imp
= MMIPS32_ONLY
;
839 LOG_USER("MICRO MIPS32 only implemented");
841 } else if (isa_imp
!= 0) {
842 mips32
->isa_imp
= MIPS32_MMIPS32
;
843 LOG_USER("MIPS32 and MICRO MIPS32 implemented");
847 if (mips32
->isa_imp
== MIPS32_ONLY
) /* initial default value */
848 LOG_USER("MIPS32 only implemented");
852 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
853 uint32_t count
, uint32_t *checksum
)
855 struct working_area
*crc_algorithm
;
856 struct reg_param reg_params
[2];
857 struct mips32_algorithm mips32_info
;
859 struct mips32_common
*mips32
= target_to_mips32(target
);
860 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
862 /* see contrib/loaders/checksum/mips32.s for src */
863 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
865 uint32_t mips_crc_code
[] = {
866 MIPS32_ADDIU(isa
, 12, 4, 0), /* addiu $t4, $a0, 0 */
867 MIPS32_ADDIU(isa
, 10, 5, 0), /* addiu $t2, $a1, 0 */
868 MIPS32_ADDIU(isa
, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
869 MIPS32_BEQ(isa
, 0, 0, 0x10 << isa
), /* beq $zero, $zero, ncomp */
870 MIPS32_ADDIU(isa
, 11, 0, 0), /* addiu $t3, $zero, 0 */
872 MIPS32_LB(isa
, 5, 0, 12), /* lb $a1, ($t4) */
873 MIPS32_ADDI(isa
, 12, 12, 1), /* addi $t4, $t4, 1 */
874 MIPS32_SLL(isa
, 5, 5, 24), /* sll $a1, $a1, 24 */
875 MIPS32_LUI(isa
, 2, 0x04c1), /* lui $v0, 0x04c1 */
876 MIPS32_XOR(isa
, 4, 4, 5), /* xor $a0, $a0, $a1 */
877 MIPS32_ORI(isa
, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
878 MIPS32_ADDU(isa
, 6, 0, 0), /* addu $a2, $zero, $zero */
880 MIPS32_SLL(isa
, 8, 4, 1), /* sll $t0, $a0, 1 */
881 MIPS32_ADDIU(isa
, 6, 6, 1), /* addiu $a2, $a2, 1 */
882 MIPS32_SLTI(isa
, 4, 4, 0), /* slti $a0, $a0, 0 */
883 MIPS32_XOR(isa
, 9, 8, 7), /* xor $t1, $t0, $a3 */
884 MIPS32_MOVN(isa
, 8, 9, 4), /* movn $t0, $t1, $a0 */
885 MIPS32_SLTI(isa
, 3, 6, 8), /* slti $v1, $a2, 8 */
886 MIPS32_BNE(isa
, 3, 0, NEG16(7 << isa
)), /* bne $v1, $zero, loop */
887 MIPS32_ADDU(isa
, 4, 8, 0), /* addu $a0, $t0, $zero */
889 MIPS32_BNE(isa
, 10, 11, NEG16(16 << isa
)), /* bne $t2, $t3, nbyte */
890 MIPS32_ADDIU(isa
, 11, 11, 1), /* addiu $t3, $t3, 1 */
894 /* make sure we have a working area */
895 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
896 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
898 pracc_swap16_array(ejtag_info
, mips_crc_code
, ARRAY_SIZE(mips_crc_code
));
900 /* convert mips crc code into a buffer in target endianness */
901 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
902 target_buffer_set_u32_array(target
, mips_crc_code_8
,
903 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
905 int retval
= target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
906 if (retval
!= ERROR_OK
)
909 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
910 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
; /* run isa as in debug mode */
912 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
913 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
915 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
916 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
918 unsigned int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
920 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
, crc_algorithm
->address
,
921 crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
, &mips32_info
);
923 if (retval
== ERROR_OK
)
924 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
926 destroy_reg_param(®_params
[0]);
927 destroy_reg_param(®_params
[1]);
929 target_free_working_area(target
, crc_algorithm
);
934 /** Checks whether a memory region is erased. */
935 int mips32_blank_check_memory(struct target
*target
,
936 struct target_memory_check_block
*blocks
, int num_blocks
,
937 uint8_t erased_value
)
939 struct working_area
*erase_check_algorithm
;
940 struct reg_param reg_params
[3];
941 struct mips32_algorithm mips32_info
;
943 struct mips32_common
*mips32
= target_to_mips32(target
);
944 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
946 if (erased_value
!= 0xff) {
947 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
951 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
952 uint32_t erase_check_code
[] = {
954 MIPS32_LB(isa
, 8, 0, 4), /* lb $t0, ($a0) */
955 MIPS32_AND(isa
, 6, 6, 8), /* and $a2, $a2, $t0 */
956 MIPS32_ADDIU(isa
, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
957 MIPS32_BNE(isa
, 5, 0, NEG16(4 << isa
)), /* bne $a1, $zero, nbyte */
958 MIPS32_ADDIU(isa
, 4, 4, 1), /* addiu $a0, $a0, 1 */
959 MIPS32_SDBBP(isa
) /* sdbbp */
962 /* make sure we have a working area */
963 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
964 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
966 pracc_swap16_array(ejtag_info
, erase_check_code
, ARRAY_SIZE(erase_check_code
));
968 /* convert erase check code into a buffer in target endianness */
969 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
970 target_buffer_set_u32_array(target
, erase_check_code_8
,
971 ARRAY_SIZE(erase_check_code
), erase_check_code
);
973 int retval
= target_write_buffer(target
, erase_check_algorithm
->address
,
974 sizeof(erase_check_code
), erase_check_code_8
);
975 if (retval
!= ERROR_OK
)
978 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
979 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
;
981 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
982 buf_set_u32(reg_params
[0].value
, 0, 32, blocks
[0].address
);
984 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
985 buf_set_u32(reg_params
[1].value
, 0, 32, blocks
[0].size
);
987 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
988 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
990 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, erase_check_algorithm
->address
,
991 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4), 10000, &mips32_info
);
993 if (retval
== ERROR_OK
)
994 blocks
[0].result
= buf_get_u32(reg_params
[2].value
, 0, 32);
996 destroy_reg_param(®_params
[0]);
997 destroy_reg_param(®_params
[1]);
998 destroy_reg_param(®_params
[2]);
1001 target_free_working_area(target
, erase_check_algorithm
);
1003 if (retval
!= ERROR_OK
)
1006 return 1; /* only one block has been checked */
1009 static int mips32_verify_pointer(struct command_invocation
*cmd
,
1010 struct mips32_common
*mips32
)
1012 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
1013 command_print(cmd
, "target is not an MIPS32");
1014 return ERROR_TARGET_INVALID
;
1020 * MIPS32 targets expose command interface
1021 * to manipulate CP0 registers
1023 COMMAND_HANDLER(mips32_handle_cp0_command
)
1026 struct target
*target
= get_current_target(CMD_CTX
);
1027 struct mips32_common
*mips32
= target_to_mips32(target
);
1028 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1031 retval
= mips32_verify_pointer(CMD
, mips32
);
1032 if (retval
!= ERROR_OK
)
1035 if (target
->state
!= TARGET_HALTED
) {
1036 command_print(CMD
, "Error: target must be stopped for \"%s\" command", CMD_NAME
);
1037 return ERROR_TARGET_NOT_HALTED
;
1040 /* two or more argument, access a single register/select (write if third argument is given) */
1042 return ERROR_COMMAND_SYNTAX_ERROR
;
1044 uint32_t cp0_reg
, cp0_sel
;
1045 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
1046 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
1048 if (CMD_ARGC
== 2) {
1051 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
1052 if (retval
!= ERROR_OK
) {
1054 "couldn't access reg %" PRIu32
,
1058 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1059 cp0_reg
, cp0_sel
, value
);
1061 } else if (CMD_ARGC
== 3) {
1063 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
1064 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
1065 if (retval
!= ERROR_OK
) {
1067 "couldn't access cp0 reg %" PRIu32
", select %" PRIu32
,
1071 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1072 cp0_reg
, cp0_sel
, value
);
1079 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
1081 struct target
*target
= get_current_target(CMD_CTX
);
1082 struct mips32_common
*mips32
= target_to_mips32(target
);
1083 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1086 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
1087 else if (CMD_ARGC
> 1)
1088 return ERROR_COMMAND_SYNTAX_ERROR
;
1090 command_print(CMD
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
1091 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
1092 ejtag_info
->mode
= 0;
1093 command_print(CMD
, "running in legacy mode");
1095 ejtag_info
->mode
= 1;
1096 command_print(CMD
, "running in fast queued mode");
1102 static const struct command_registration mips32_exec_command_handlers
[] = {
1105 .handler
= mips32_handle_cp0_command
,
1106 .mode
= COMMAND_EXEC
,
1107 .usage
= "regnum select [value]",
1108 .help
= "display/modify cp0 register",
1111 .name
= "scan_delay",
1112 .handler
= mips32_handle_scan_delay_command
,
1113 .mode
= COMMAND_ANY
,
1114 .help
= "display/set scan delay in nano seconds",
1117 COMMAND_REGISTRATION_DONE
1120 const struct command_registration mips32_command_handlers
[] = {
1123 .mode
= COMMAND_ANY
,
1124 .help
= "mips32 command group",
1126 .chain
= mips32_exec_command_handlers
,
1128 COMMAND_REGISTRATION_DONE
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)