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 mips32_pracc_read_regs(mips32
);
311 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
312 if (!mips32
->core_cache
->reg_list
[i
].valid
)
313 mips32
->read_core_reg(target
, i
);
319 int mips32_restore_context(struct target
*target
)
323 /* get pointers to arch-specific information */
324 struct mips32_common
*mips32
= target_to_mips32(target
);
326 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
327 if (mips32
->core_cache
->reg_list
[i
].dirty
)
328 mips32
->write_core_reg(target
, i
);
331 /* write core regs */
332 mips32_pracc_write_regs(mips32
);
337 int mips32_arch_state(struct target
*target
)
339 struct mips32_common
*mips32
= target_to_mips32(target
);
341 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
342 mips_isa_strings
[mips32
->isa_mode
],
343 debug_reason_name(target
),
344 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32));
349 static const struct reg_arch_type mips32_reg_type
= {
350 .get
= mips32_get_core_reg
,
351 .set
= mips32_set_core_reg
,
354 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
356 /* get pointers to arch-specific information */
357 struct mips32_common
*mips32
= target_to_mips32(target
);
359 int num_regs
= MIPS32_NUM_REGS
;
360 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
361 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
362 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
363 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
364 struct reg_feature
*feature
;
367 /* Build the process context cache */
368 cache
->name
= "mips32 registers";
370 cache
->reg_list
= reg_list
;
371 cache
->num_regs
= num_regs
;
373 mips32
->core_cache
= cache
;
375 for (i
= 0; i
< num_regs
; i
++) {
376 arch_info
[i
].num
= mips32_regs
[i
].id
;
377 arch_info
[i
].target
= target
;
378 arch_info
[i
].mips32_common
= mips32
;
380 reg_list
[i
].name
= mips32_regs
[i
].name
;
381 reg_list
[i
].size
= mips32_regs
[i
].size
? 64 : 32;
383 reg_list
[i
].value
= mips32_regs
[i
].size
? calloc(1, 8) : calloc(1, 4);
384 reg_list
[i
].valid
= false;
385 reg_list
[i
].type
= &mips32_reg_type
;
386 reg_list
[i
].arch_info
= &arch_info
[i
];
388 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
389 if (reg_list
[i
].reg_data_type
)
390 reg_list
[i
].reg_data_type
->type
= mips32_regs
[i
].type
;
392 LOG_ERROR("unable to allocate reg type list");
395 reg_list
[i
].dirty
= false;
397 reg_list
[i
].group
= mips32_regs
[i
].group
;
398 reg_list
[i
].number
= i
;
399 reg_list
[i
].exist
= true;
400 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
402 feature
= calloc(1, sizeof(struct reg_feature
));
404 feature
->name
= mips32_regs
[i
].feature
;
405 reg_list
[i
].feature
= feature
;
407 LOG_ERROR("unable to allocate feature list");
413 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
415 target
->arch_info
= mips32
;
416 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
417 mips32
->fast_data_area
= NULL
;
418 mips32
->isa_imp
= MIPS32_ONLY
; /* default */
420 /* has breakpoint/watchpoint unit been scanned */
421 mips32
->bp_scanned
= 0;
422 mips32
->data_break_list
= NULL
;
424 mips32
->ejtag_info
.tap
= tap
;
425 mips32
->read_core_reg
= mips32_read_core_reg
;
426 mips32
->write_core_reg
= mips32_write_core_reg
;
427 /* if unknown endianness defaults to little endian, 1 */
428 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
429 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
430 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
431 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
432 mips32
->ejtag_info
.config_regs
= 0; /* no config register read */
436 /* run to exit point. return error if exit point was not reached. */
437 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
438 unsigned int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
442 /* This code relies on the target specific resume() and poll()->debug_entry()
443 * sequence to write register values to the processor and the read them back */
444 retval
= target_resume(target
, 0, entry_point
, 0, 1);
445 if (retval
!= ERROR_OK
)
448 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
449 /* If the target fails to halt due to the breakpoint, force a halt */
450 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
451 retval
= target_halt(target
);
452 if (retval
!= ERROR_OK
)
454 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
455 if (retval
!= ERROR_OK
)
457 return ERROR_TARGET_TIMEOUT
;
460 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32);
461 if (exit_point
&& (pc
!= exit_point
)) {
462 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
463 return ERROR_TARGET_TIMEOUT
;
469 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
470 struct mem_param
*mem_params
, int num_reg_params
,
471 struct reg_param
*reg_params
, target_addr_t entry_point
,
472 target_addr_t exit_point
, unsigned int timeout_ms
, void *arch_info
)
474 struct mips32_common
*mips32
= target_to_mips32(target
);
475 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
476 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
478 uint32_t context
[MIPS32_NUM_REGS
];
479 int retval
= ERROR_OK
;
481 LOG_DEBUG("Running algorithm");
483 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
484 * at the exit point */
486 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
487 LOG_ERROR("current target isn't a MIPS32 target");
488 return ERROR_TARGET_INVALID
;
491 if (target
->state
!= TARGET_HALTED
) {
492 LOG_TARGET_ERROR(target
, "not halted (run target algo)");
493 return ERROR_TARGET_NOT_HALTED
;
496 /* refresh core register cache */
497 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
498 if (!mips32
->core_cache
->reg_list
[i
].valid
)
499 mips32
->read_core_reg(target
, i
);
500 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
503 for (int i
= 0; i
< num_mem_params
; i
++) {
504 if (mem_params
[i
].direction
== PARAM_IN
)
506 retval
= target_write_buffer(target
, mem_params
[i
].address
,
507 mem_params
[i
].size
, mem_params
[i
].value
);
508 if (retval
!= ERROR_OK
)
512 for (int i
= 0; i
< num_reg_params
; i
++) {
513 if (reg_params
[i
].direction
== PARAM_IN
)
516 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
519 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
520 return ERROR_COMMAND_SYNTAX_ERROR
;
523 if (reg
->size
!= reg_params
[i
].size
) {
524 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
525 reg_params
[i
].reg_name
);
526 return ERROR_COMMAND_SYNTAX_ERROR
;
529 mips32_set_core_reg(reg
, reg_params
[i
].value
);
532 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
534 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
536 if (retval
!= ERROR_OK
)
539 for (int i
= 0; i
< num_mem_params
; i
++) {
540 if (mem_params
[i
].direction
!= PARAM_OUT
) {
541 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
542 mem_params
[i
].value
);
543 if (retval
!= ERROR_OK
)
548 for (int i
= 0; i
< num_reg_params
; i
++) {
549 if (reg_params
[i
].direction
!= PARAM_OUT
) {
550 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
552 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
553 return ERROR_COMMAND_SYNTAX_ERROR
;
556 if (reg
->size
!= reg_params
[i
].size
) {
557 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
558 reg_params
[i
].reg_name
);
559 return ERROR_COMMAND_SYNTAX_ERROR
;
562 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
566 /* restore everything we saved before */
567 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
569 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
570 if (regvalue
!= context
[i
]) {
571 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
572 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
573 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
575 mips32
->core_cache
->reg_list
[i
].valid
= true;
576 mips32
->core_cache
->reg_list
[i
].dirty
= true;
580 mips32
->isa_mode
= isa_mode
;
585 int mips32_examine(struct target
*target
)
587 struct mips32_common
*mips32
= target_to_mips32(target
);
589 if (!target_was_examined(target
)) {
590 target_set_examined(target
);
592 /* we will configure later */
593 mips32
->bp_scanned
= 0;
594 mips32
->num_inst_bpoints
= 0;
595 mips32
->num_data_bpoints
= 0;
596 mips32
->num_inst_bpoints_avail
= 0;
597 mips32
->num_data_bpoints_avail
= 0;
603 static int mips32_configure_ibs(struct target
*target
)
605 struct mips32_common
*mips32
= target_to_mips32(target
);
606 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
610 /* get number of inst breakpoints */
611 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
612 if (retval
!= ERROR_OK
)
615 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
616 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
617 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
618 sizeof(struct mips32_comparator
));
620 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
621 mips32
->inst_break_list
[i
].reg_address
=
622 ejtag_info
->ejtag_iba0_addr
+
623 (ejtag_info
->ejtag_iba_step_size
* i
);
626 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
630 static int mips32_configure_dbs(struct target
*target
)
632 struct mips32_common
*mips32
= target_to_mips32(target
);
633 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
637 /* get number of data breakpoints */
638 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
639 if (retval
!= ERROR_OK
)
642 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
643 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
644 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
645 sizeof(struct mips32_comparator
));
647 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
648 mips32
->data_break_list
[i
].reg_address
=
649 ejtag_info
->ejtag_dba0_addr
+
650 (ejtag_info
->ejtag_dba_step_size
* i
);
653 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
657 int mips32_configure_break_unit(struct target
*target
)
659 /* get pointers to arch-specific information */
660 struct mips32_common
*mips32
= target_to_mips32(target
);
661 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
665 if (mips32
->bp_scanned
)
668 /* get info about breakpoint support */
669 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
670 if (retval
!= ERROR_OK
)
673 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
674 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
675 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
676 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
677 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
678 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
679 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
681 /* keep debug caps for later use */
682 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
683 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
686 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
687 retval
= mips32_configure_ibs(target
);
688 if (retval
!= ERROR_OK
)
692 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
693 retval
= mips32_configure_dbs(target
);
694 if (retval
!= ERROR_OK
)
698 /* check if target endianness settings matches debug control register */
699 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
700 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
701 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
702 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
703 LOG_WARNING("DCR endianness settings does not match target settings");
705 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
706 mips32
->num_data_bpoints
);
708 mips32
->bp_scanned
= 1;
713 int mips32_enable_interrupts(struct target
*target
, int enable
)
719 /* read debug control register */
720 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
721 if (retval
!= ERROR_OK
)
725 if (!(dcr
& EJTAG_DCR_INTE
)) {
726 /* enable interrupts */
727 dcr
|= EJTAG_DCR_INTE
;
731 if (dcr
& EJTAG_DCR_INTE
) {
732 /* disable interrupts */
733 dcr
&= ~EJTAG_DCR_INTE
;
739 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
740 if (retval
!= ERROR_OK
)
747 /* read processor identification cp0 register */
748 static int mips32_read_c0_prid(struct target
*target
)
750 struct mips32_common
*mips32
= target_to_mips32(target
);
751 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
754 retval
= mips32_cp0_read(ejtag_info
, &mips32
->prid
, 15, 0);
755 if (retval
!= ERROR_OK
) {
756 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
764 * Detect processor type and apply required quirks.
766 * NOTE: The proper detection of certain CPUs can become quite complicated.
767 * Please consult the following Linux kernel code when adding new CPUs:
768 * arch/mips/include/asm/cpu.h
769 * arch/mips/kernel/cpu-probe.c
771 int mips32_cpu_probe(struct target
*target
)
773 struct mips32_common
*mips32
= target_to_mips32(target
);
774 const char *cpu_name
= "unknown";
778 return ERROR_OK
; /* Already probed once, return early. */
780 retval
= mips32_read_c0_prid(target
);
781 if (retval
!= ERROR_OK
)
784 switch (mips32
->prid
& PRID_COMP_MASK
) {
785 case PRID_COMP_INGENIC_E1
:
786 switch (mips32
->prid
& PRID_IMP_MASK
) {
787 case PRID_IMP_XBURST_REV1
:
788 cpu_name
= "Ingenic XBurst rev1";
789 mips32
->cpu_quirks
|= EJTAG_QUIRK_PAD_DRET
;
799 LOG_DEBUG("CPU: %s (PRId %08x)", cpu_name
, mips32
->prid
);
804 /* read config to config3 cp0 registers and log isa implementation */
805 int mips32_read_config_regs(struct target
*target
)
807 struct mips32_common
*mips32
= target_to_mips32(target
);
808 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
810 if (ejtag_info
->config_regs
== 0)
811 for (int i
= 0; i
!= 4; i
++) {
812 int retval
= mips32_cp0_read(ejtag_info
, &ejtag_info
->config
[i
], 16, i
);
813 if (retval
!= ERROR_OK
) {
814 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32
, i
);
815 ejtag_info
->config_regs
= 0;
818 ejtag_info
->config_regs
= i
+ 1;
819 if ((ejtag_info
->config
[i
] & (1 << 31)) == 0)
820 break; /* no more config registers implemented */
823 return ERROR_OK
; /* already successfully read */
825 LOG_DEBUG("read %"PRIu32
" config registers", ejtag_info
->config_regs
);
827 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
) {
828 mips32
->isa_imp
= MIPS32_MIPS16
;
829 LOG_USER("MIPS32 with MIPS16 support implemented");
831 } else if (ejtag_info
->config_regs
>= 4) { /* config3 implemented */
832 unsigned isa_imp
= (ejtag_info
->config
[3] & MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
;
834 mips32
->isa_imp
= MMIPS32_ONLY
;
835 LOG_USER("MICRO MIPS32 only implemented");
837 } else if (isa_imp
!= 0) {
838 mips32
->isa_imp
= MIPS32_MMIPS32
;
839 LOG_USER("MIPS32 and MICRO MIPS32 implemented");
843 if (mips32
->isa_imp
== MIPS32_ONLY
) /* initial default value */
844 LOG_USER("MIPS32 only implemented");
848 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
849 uint32_t count
, uint32_t *checksum
)
851 struct working_area
*crc_algorithm
;
852 struct reg_param reg_params
[2];
853 struct mips32_algorithm mips32_info
;
855 struct mips32_common
*mips32
= target_to_mips32(target
);
856 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
858 /* see contrib/loaders/checksum/mips32.s for src */
859 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
861 uint32_t mips_crc_code
[] = {
862 MIPS32_ADDIU(isa
, 12, 4, 0), /* addiu $t4, $a0, 0 */
863 MIPS32_ADDIU(isa
, 10, 5, 0), /* addiu $t2, $a1, 0 */
864 MIPS32_ADDIU(isa
, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
865 MIPS32_BEQ(isa
, 0, 0, 0x10 << isa
), /* beq $zero, $zero, ncomp */
866 MIPS32_ADDIU(isa
, 11, 0, 0), /* addiu $t3, $zero, 0 */
868 MIPS32_LB(isa
, 5, 0, 12), /* lb $a1, ($t4) */
869 MIPS32_ADDI(isa
, 12, 12, 1), /* addi $t4, $t4, 1 */
870 MIPS32_SLL(isa
, 5, 5, 24), /* sll $a1, $a1, 24 */
871 MIPS32_LUI(isa
, 2, 0x04c1), /* lui $v0, 0x04c1 */
872 MIPS32_XOR(isa
, 4, 4, 5), /* xor $a0, $a0, $a1 */
873 MIPS32_ORI(isa
, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
874 MIPS32_ADDU(isa
, 6, 0, 0), /* addu $a2, $zero, $zero */
876 MIPS32_SLL(isa
, 8, 4, 1), /* sll $t0, $a0, 1 */
877 MIPS32_ADDIU(isa
, 6, 6, 1), /* addiu $a2, $a2, 1 */
878 MIPS32_SLTI(isa
, 4, 4, 0), /* slti $a0, $a0, 0 */
879 MIPS32_XOR(isa
, 9, 8, 7), /* xor $t1, $t0, $a3 */
880 MIPS32_MOVN(isa
, 8, 9, 4), /* movn $t0, $t1, $a0 */
881 MIPS32_SLTI(isa
, 3, 6, 8), /* slti $v1, $a2, 8 */
882 MIPS32_BNE(isa
, 3, 0, NEG16(7 << isa
)), /* bne $v1, $zero, loop */
883 MIPS32_ADDU(isa
, 4, 8, 0), /* addu $a0, $t0, $zero */
885 MIPS32_BNE(isa
, 10, 11, NEG16(16 << isa
)), /* bne $t2, $t3, nbyte */
886 MIPS32_ADDIU(isa
, 11, 11, 1), /* addiu $t3, $t3, 1 */
890 /* make sure we have a working area */
891 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
892 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
894 pracc_swap16_array(ejtag_info
, mips_crc_code
, ARRAY_SIZE(mips_crc_code
));
896 /* convert mips crc code into a buffer in target endianness */
897 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
898 target_buffer_set_u32_array(target
, mips_crc_code_8
,
899 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
901 int retval
= target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
902 if (retval
!= ERROR_OK
)
905 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
906 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
; /* run isa as in debug mode */
908 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
909 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
911 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
912 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
914 unsigned int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
916 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
, crc_algorithm
->address
,
917 crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
, &mips32_info
);
919 if (retval
== ERROR_OK
)
920 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
922 destroy_reg_param(®_params
[0]);
923 destroy_reg_param(®_params
[1]);
925 target_free_working_area(target
, crc_algorithm
);
930 /** Checks whether a memory region is erased. */
931 int mips32_blank_check_memory(struct target
*target
,
932 struct target_memory_check_block
*blocks
, int num_blocks
,
933 uint8_t erased_value
)
935 struct working_area
*erase_check_algorithm
;
936 struct reg_param reg_params
[3];
937 struct mips32_algorithm mips32_info
;
939 struct mips32_common
*mips32
= target_to_mips32(target
);
940 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
942 if (erased_value
!= 0xff) {
943 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
947 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
948 uint32_t erase_check_code
[] = {
950 MIPS32_LB(isa
, 8, 0, 4), /* lb $t0, ($a0) */
951 MIPS32_AND(isa
, 6, 6, 8), /* and $a2, $a2, $t0 */
952 MIPS32_ADDIU(isa
, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
953 MIPS32_BNE(isa
, 5, 0, NEG16(4 << isa
)), /* bne $a1, $zero, nbyte */
954 MIPS32_ADDIU(isa
, 4, 4, 1), /* addiu $a0, $a0, 1 */
955 MIPS32_SDBBP(isa
) /* sdbbp */
958 /* make sure we have a working area */
959 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
960 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
962 pracc_swap16_array(ejtag_info
, erase_check_code
, ARRAY_SIZE(erase_check_code
));
964 /* convert erase check code into a buffer in target endianness */
965 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
966 target_buffer_set_u32_array(target
, erase_check_code_8
,
967 ARRAY_SIZE(erase_check_code
), erase_check_code
);
969 int retval
= target_write_buffer(target
, erase_check_algorithm
->address
,
970 sizeof(erase_check_code
), erase_check_code_8
);
971 if (retval
!= ERROR_OK
)
974 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
975 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
;
977 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
978 buf_set_u32(reg_params
[0].value
, 0, 32, blocks
[0].address
);
980 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
981 buf_set_u32(reg_params
[1].value
, 0, 32, blocks
[0].size
);
983 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
984 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
986 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, erase_check_algorithm
->address
,
987 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4), 10000, &mips32_info
);
989 if (retval
== ERROR_OK
)
990 blocks
[0].result
= buf_get_u32(reg_params
[2].value
, 0, 32);
992 destroy_reg_param(®_params
[0]);
993 destroy_reg_param(®_params
[1]);
994 destroy_reg_param(®_params
[2]);
997 target_free_working_area(target
, erase_check_algorithm
);
999 if (retval
!= ERROR_OK
)
1002 return 1; /* only one block has been checked */
1005 static int mips32_verify_pointer(struct command_invocation
*cmd
,
1006 struct mips32_common
*mips32
)
1008 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
1009 command_print(cmd
, "target is not an MIPS32");
1010 return ERROR_TARGET_INVALID
;
1016 * MIPS32 targets expose command interface
1017 * to manipulate CP0 registers
1019 COMMAND_HANDLER(mips32_handle_cp0_command
)
1022 struct target
*target
= get_current_target(CMD_CTX
);
1023 struct mips32_common
*mips32
= target_to_mips32(target
);
1024 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1027 retval
= mips32_verify_pointer(CMD
, mips32
);
1028 if (retval
!= ERROR_OK
)
1031 if (target
->state
!= TARGET_HALTED
) {
1032 command_print(CMD
, "Error: target must be stopped for \"%s\" command", CMD_NAME
);
1033 return ERROR_TARGET_NOT_HALTED
;
1036 /* two or more argument, access a single register/select (write if third argument is given) */
1038 return ERROR_COMMAND_SYNTAX_ERROR
;
1040 uint32_t cp0_reg
, cp0_sel
;
1041 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
1042 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
1044 if (CMD_ARGC
== 2) {
1047 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
1048 if (retval
!= ERROR_OK
) {
1050 "couldn't access reg %" PRIu32
,
1054 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1055 cp0_reg
, cp0_sel
, value
);
1057 } else if (CMD_ARGC
== 3) {
1059 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
1060 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
1061 if (retval
!= ERROR_OK
) {
1063 "couldn't access cp0 reg %" PRIu32
", select %" PRIu32
,
1067 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1068 cp0_reg
, cp0_sel
, value
);
1075 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
1077 struct target
*target
= get_current_target(CMD_CTX
);
1078 struct mips32_common
*mips32
= target_to_mips32(target
);
1079 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1082 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
1083 else if (CMD_ARGC
> 1)
1084 return ERROR_COMMAND_SYNTAX_ERROR
;
1086 command_print(CMD
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
1087 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
1088 ejtag_info
->mode
= 0;
1089 command_print(CMD
, "running in legacy mode");
1091 ejtag_info
->mode
= 1;
1092 command_print(CMD
, "running in fast queued mode");
1098 static const struct command_registration mips32_exec_command_handlers
[] = {
1101 .handler
= mips32_handle_cp0_command
,
1102 .mode
= COMMAND_EXEC
,
1103 .usage
= "regnum select [value]",
1104 .help
= "display/modify cp0 register",
1107 .name
= "scan_delay",
1108 .handler
= mips32_handle_scan_delay_command
,
1109 .mode
= COMMAND_ANY
,
1110 .help
= "display/set scan delay in nano seconds",
1113 COMMAND_REGISTRATION_DONE
1116 const struct command_registration mips32_command_handlers
[] = {
1119 .mode
= COMMAND_ANY
,
1120 .help
= "mips32 command group",
1122 .chain
= mips32_exec_command_handlers
,
1124 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)