target/mips32: optimize pracc access
[openocd.git] / src / target / mips32.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
6 * *
7 * Copyright (C) 2008 by David T.L. Wong *
8 * *
9 * Copyright (C) 2007,2008 Øyvind Harboe *
10 * oyvind.harboe@zylin.com *
11 * *
12 * Copyright (C) 2011 by Drasko DRASKOVIC *
13 * drasko.draskovic@gmail.com *
14 ***************************************************************************/
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include "mips32.h"
21 #include "mips_cpu.h"
22 #include "breakpoints.h"
23 #include "algorithm.h"
24 #include "register.h"
25
26 static const char *mips_isa_strings[] = {
27 "MIPS32", "MIPS16", "", "MICRO MIPS32",
28 };
29
30 #define MIPS32_GDB_FP_REG 1
31
32 /*
33 * GDB registers
34 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
35 */
36 static const struct {
37 unsigned id;
38 const char *name;
39 enum reg_type type;
40 const char *group;
41 const char *feature;
42 int size;
43 } mips32_regs[] = {
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 },
78
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 },
143
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 },
148
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 },
159 };
160
161 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
162
163
164 static int mips32_get_core_reg(struct reg *reg)
165 {
166 int retval;
167 struct mips32_core_reg *mips32_reg = reg->arch_info;
168 struct target *target = mips32_reg->target;
169 struct mips32_common *mips32_target = target_to_mips32(target);
170
171 if (target->state != TARGET_HALTED)
172 return ERROR_TARGET_NOT_HALTED;
173
174 retval = mips32_target->read_core_reg(target, mips32_reg->num);
175
176 return retval;
177 }
178
179 static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
180 {
181 struct mips32_core_reg *mips32_reg = reg->arch_info;
182 struct target *target = mips32_reg->target;
183 uint64_t value;
184
185 if (reg->size == 64)
186 value = buf_get_u64(buf, 0, 64);
187 else
188 value = buf_get_u32(buf, 0, 32);
189
190 if (target->state != TARGET_HALTED)
191 return ERROR_TARGET_NOT_HALTED;
192
193 if (reg->size == 64)
194 buf_set_u64(reg->value, 0, 64, value);
195 else
196 buf_set_u32(reg->value, 0, 32, value);
197
198 reg->dirty = true;
199 reg->valid = true;
200
201 return ERROR_OK;
202 }
203
204 static int mips32_read_core_reg(struct target *target, unsigned int num)
205 {
206 unsigned int cnum;
207 uint64_t reg_value = 0;
208
209 /* get pointers to arch-specific information */
210 struct mips32_common *mips32 = target_to_mips32(target);
211
212 if (num >= MIPS32_NUM_REGS)
213 return ERROR_COMMAND_SYNTAX_ERROR;
214
215 if (num >= MIPS32_REGLIST_C0_INDEX) {
216 /* CP0 */
217 cnum = num - MIPS32_REGLIST_C0_INDEX;
218 reg_value = mips32->core_regs.cp0[cnum];
219 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
220 } else if (num >= MIPS32_REGLIST_FPC_INDEX) {
221 /* FPCR */
222 cnum = num - MIPS32_REGLIST_FPC_INDEX;
223 reg_value = mips32->core_regs.fpcr[cnum];
224 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
225 } else if (num >= MIPS32_REGLIST_FP_INDEX) {
226 /* FPR */
227 cnum = num - MIPS32_REGLIST_FP_INDEX;
228 reg_value = mips32->core_regs.fpr[cnum];
229 buf_set_u64(mips32->core_cache->reg_list[num].value, 0, 64, reg_value);
230 } else {
231 /* GPR */
232 cnum = num - MIPS32_REGLIST_GP_INDEX;
233 reg_value = mips32->core_regs.gpr[cnum];
234 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
235 }
236
237 mips32->core_cache->reg_list[num].valid = true;
238 mips32->core_cache->reg_list[num].dirty = false;
239
240 LOG_DEBUG("read core reg %i value 0x%" PRIx64 "", num, reg_value);
241
242 return ERROR_OK;
243 }
244
245 static int mips32_write_core_reg(struct target *target, unsigned int num)
246 {
247 unsigned int cnum;
248 uint64_t reg_value;
249
250 /* get pointers to arch-specific information */
251 struct mips32_common *mips32 = target_to_mips32(target);
252
253 if (num >= MIPS32_NUM_REGS)
254 return ERROR_COMMAND_SYNTAX_ERROR;
255
256 if (num >= MIPS32_REGLIST_C0_INDEX) {
257 /* CP0 */
258 cnum = num - MIPS32_REGLIST_C0_INDEX;
259 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
260 mips32->core_regs.cp0[cnum] = (uint32_t)reg_value;
261 } else if (num >= MIPS32_REGLIST_FPC_INDEX) {
262 /* FPCR */
263 cnum = num - MIPS32_REGLIST_FPC_INDEX;
264 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
265 mips32->core_regs.fpcr[cnum] = (uint32_t)reg_value;
266 } else if (num >= MIPS32_REGLIST_FP_INDEX) {
267 /* FPR */
268 cnum = num - MIPS32_REGLIST_FP_INDEX;
269 reg_value = buf_get_u64(mips32->core_cache->reg_list[num].value, 0, 64);
270 mips32->core_regs.fpr[cnum] = reg_value;
271 } else {
272 /* GPR */
273 cnum = num - MIPS32_REGLIST_GP_INDEX;
274 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
275 mips32->core_regs.gpr[cnum] = (uint32_t)reg_value;
276 }
277
278 LOG_DEBUG("write core reg %i value 0x%" PRIx64 "", num, reg_value);
279 mips32->core_cache->reg_list[num].valid = true;
280 mips32->core_cache->reg_list[num].dirty = false;
281
282 return ERROR_OK;
283 }
284
285 int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
286 int *reg_list_size, enum target_register_class reg_class)
287 {
288 /* get pointers to arch-specific information */
289 struct mips32_common *mips32 = target_to_mips32(target);
290 unsigned int i;
291
292 /* include floating point registers */
293 *reg_list_size = MIPS32_NUM_REGS;
294 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
295
296 for (i = 0; i < MIPS32_NUM_REGS; i++)
297 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
298
299 return ERROR_OK;
300 }
301
302 int mips32_save_context(struct target *target)
303 {
304 unsigned int i;
305
306 /* get pointers to arch-specific information */
307 struct mips32_common *mips32 = target_to_mips32(target);
308
309 /* read core registers */
310 int retval = mips32_pracc_read_regs(mips32);
311 if (retval != ERROR_OK) {
312 LOG_ERROR("Could not read core registers from target");
313 return retval;
314 }
315
316 for (i = 0; i < MIPS32_NUM_REGS; i++) {
317 if (!mips32->core_cache->reg_list[i].valid)
318 mips32->read_core_reg(target, i);
319 }
320
321 return ERROR_OK;
322 }
323
324 int mips32_restore_context(struct target *target)
325 {
326 unsigned int i;
327
328 /* get pointers to arch-specific information */
329 struct mips32_common *mips32 = target_to_mips32(target);
330
331 for (i = 0; i < MIPS32_NUM_REGS; i++) {
332 if (mips32->core_cache->reg_list[i].dirty)
333 mips32->write_core_reg(target, i);
334 }
335
336 /* write core regs */
337 return mips32_pracc_write_regs(mips32);
338 }
339
340 int mips32_arch_state(struct target *target)
341 {
342 struct mips32_common *mips32 = target_to_mips32(target);
343
344 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
345 mips_isa_strings[mips32->isa_mode],
346 debug_reason_name(target),
347 buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32));
348
349 return ERROR_OK;
350 }
351
352 static const struct reg_arch_type mips32_reg_type = {
353 .get = mips32_get_core_reg,
354 .set = mips32_set_core_reg,
355 };
356
357 struct reg_cache *mips32_build_reg_cache(struct target *target)
358 {
359 /* get pointers to arch-specific information */
360 struct mips32_common *mips32 = target_to_mips32(target);
361
362 int num_regs = MIPS32_NUM_REGS;
363 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
364 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
365 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
366 struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
367 struct reg_feature *feature;
368 int i;
369
370 /* Build the process context cache */
371 cache->name = "mips32 registers";
372 cache->next = NULL;
373 cache->reg_list = reg_list;
374 cache->num_regs = num_regs;
375 (*cache_p) = cache;
376 mips32->core_cache = cache;
377
378 for (i = 0; i < num_regs; i++) {
379 arch_info[i].num = mips32_regs[i].id;
380 arch_info[i].target = target;
381 arch_info[i].mips32_common = mips32;
382
383 reg_list[i].name = mips32_regs[i].name;
384 reg_list[i].size = mips32_regs[i].size ? 64 : 32;
385
386 reg_list[i].value = mips32_regs[i].size ? calloc(1, 8) : calloc(1, 4);
387 reg_list[i].valid = false;
388 reg_list[i].type = &mips32_reg_type;
389 reg_list[i].arch_info = &arch_info[i];
390
391 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
392 if (reg_list[i].reg_data_type)
393 reg_list[i].reg_data_type->type = mips32_regs[i].type;
394 else
395 LOG_ERROR("unable to allocate reg type list");
396
397
398 reg_list[i].dirty = false;
399
400 reg_list[i].group = mips32_regs[i].group;
401 reg_list[i].number = i;
402 reg_list[i].exist = true;
403 reg_list[i].caller_save = true; /* gdb defaults to true */
404
405 feature = calloc(1, sizeof(struct reg_feature));
406 if (feature) {
407 feature->name = mips32_regs[i].feature;
408 reg_list[i].feature = feature;
409 } else
410 LOG_ERROR("unable to allocate feature list");
411 }
412
413 return cache;
414 }
415
416 int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)
417 {
418 target->arch_info = mips32;
419 mips32->common_magic = MIPS32_COMMON_MAGIC;
420 mips32->fast_data_area = NULL;
421 mips32->isa_imp = MIPS32_ONLY; /* default */
422
423 /* has breakpoint/watchpoint unit been scanned */
424 mips32->bp_scanned = 0;
425 mips32->data_break_list = NULL;
426
427 mips32->ejtag_info.tap = tap;
428 mips32->read_core_reg = mips32_read_core_reg;
429 mips32->write_core_reg = mips32_write_core_reg;
430 /* if unknown endianness defaults to little endian, 1 */
431 mips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1;
432 mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE;
433 mips32->ejtag_info.mode = 0; /* Initial default value */
434 mips32->ejtag_info.isa = 0; /* isa on debug mips32, updated by poll function */
435 mips32->ejtag_info.config_regs = 0; /* no config register read */
436 return ERROR_OK;
437 }
438
439 /* run to exit point. return error if exit point was not reached. */
440 static int mips32_run_and_wait(struct target *target, target_addr_t entry_point,
441 unsigned int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32)
442 {
443 uint32_t pc;
444 int retval;
445 /* This code relies on the target specific resume() and poll()->debug_entry()
446 * sequence to write register values to the processor and the read them back */
447 retval = target_resume(target, 0, entry_point, 0, 1);
448 if (retval != ERROR_OK)
449 return retval;
450
451 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
452 /* If the target fails to halt due to the breakpoint, force a halt */
453 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
454 retval = target_halt(target);
455 if (retval != ERROR_OK)
456 return retval;
457 retval = target_wait_state(target, TARGET_HALTED, 500);
458 if (retval != ERROR_OK)
459 return retval;
460 return ERROR_TARGET_TIMEOUT;
461 }
462
463 pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32);
464 if (exit_point && (pc != exit_point)) {
465 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
466 return ERROR_TARGET_TIMEOUT;
467 }
468
469 return ERROR_OK;
470 }
471
472 int mips32_run_algorithm(struct target *target, int num_mem_params,
473 struct mem_param *mem_params, int num_reg_params,
474 struct reg_param *reg_params, target_addr_t entry_point,
475 target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
476 {
477 struct mips32_common *mips32 = target_to_mips32(target);
478 struct mips32_algorithm *mips32_algorithm_info = arch_info;
479 enum mips32_isa_mode isa_mode = mips32->isa_mode;
480
481 uint32_t context[MIPS32_NUM_REGS];
482 int retval = ERROR_OK;
483
484 LOG_DEBUG("Running algorithm");
485
486 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
487 * at the exit point */
488
489 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
490 LOG_ERROR("current target isn't a MIPS32 target");
491 return ERROR_TARGET_INVALID;
492 }
493
494 if (target->state != TARGET_HALTED) {
495 LOG_TARGET_ERROR(target, "not halted (run target algo)");
496 return ERROR_TARGET_NOT_HALTED;
497 }
498
499 /* refresh core register cache */
500 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
501 if (!mips32->core_cache->reg_list[i].valid)
502 mips32->read_core_reg(target, i);
503 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
504 }
505
506 for (int i = 0; i < num_mem_params; i++) {
507 if (mem_params[i].direction == PARAM_IN)
508 continue;
509 retval = target_write_buffer(target, mem_params[i].address,
510 mem_params[i].size, mem_params[i].value);
511 if (retval != ERROR_OK)
512 return retval;
513 }
514
515 for (int i = 0; i < num_reg_params; i++) {
516 if (reg_params[i].direction == PARAM_IN)
517 continue;
518
519 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);
520
521 if (!reg) {
522 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
523 return ERROR_COMMAND_SYNTAX_ERROR;
524 }
525
526 if (reg->size != reg_params[i].size) {
527 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
528 reg_params[i].reg_name);
529 return ERROR_COMMAND_SYNTAX_ERROR;
530 }
531
532 mips32_set_core_reg(reg, reg_params[i].value);
533 }
534
535 mips32->isa_mode = mips32_algorithm_info->isa_mode;
536
537 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
538
539 if (retval != ERROR_OK)
540 return retval;
541
542 for (int i = 0; i < num_mem_params; i++) {
543 if (mem_params[i].direction != PARAM_OUT) {
544 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
545 mem_params[i].value);
546 if (retval != ERROR_OK)
547 return retval;
548 }
549 }
550
551 for (int i = 0; i < num_reg_params; i++) {
552 if (reg_params[i].direction != PARAM_OUT) {
553 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);
554 if (!reg) {
555 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
556 return ERROR_COMMAND_SYNTAX_ERROR;
557 }
558
559 if (reg->size != reg_params[i].size) {
560 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
561 reg_params[i].reg_name);
562 return ERROR_COMMAND_SYNTAX_ERROR;
563 }
564
565 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
566 }
567 }
568
569 /* restore everything we saved before */
570 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
571 uint32_t regvalue;
572 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
573 if (regvalue != context[i]) {
574 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
575 mips32->core_cache->reg_list[i].name, context[i]);
576 buf_set_u32(mips32->core_cache->reg_list[i].value,
577 0, 32, context[i]);
578 mips32->core_cache->reg_list[i].valid = true;
579 mips32->core_cache->reg_list[i].dirty = true;
580 }
581 }
582
583 mips32->isa_mode = isa_mode;
584
585 return ERROR_OK;
586 }
587
588 int mips32_examine(struct target *target)
589 {
590 struct mips32_common *mips32 = target_to_mips32(target);
591
592 if (!target_was_examined(target)) {
593 target_set_examined(target);
594
595 /* we will configure later */
596 mips32->bp_scanned = 0;
597 mips32->num_inst_bpoints = 0;
598 mips32->num_data_bpoints = 0;
599 mips32->num_inst_bpoints_avail = 0;
600 mips32->num_data_bpoints_avail = 0;
601 }
602
603 return ERROR_OK;
604 }
605
606 static int mips32_configure_ibs(struct target *target)
607 {
608 struct mips32_common *mips32 = target_to_mips32(target);
609 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
610 int retval, i;
611 uint32_t bpinfo;
612
613 /* get number of inst breakpoints */
614 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
615 if (retval != ERROR_OK)
616 return retval;
617
618 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
619 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
620 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
621 sizeof(struct mips32_comparator));
622
623 for (i = 0; i < mips32->num_inst_bpoints; i++)
624 mips32->inst_break_list[i].reg_address =
625 ejtag_info->ejtag_iba0_addr +
626 (ejtag_info->ejtag_iba_step_size * i);
627
628 /* clear IBIS reg */
629 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
630 return retval;
631 }
632
633 static int mips32_configure_dbs(struct target *target)
634 {
635 struct mips32_common *mips32 = target_to_mips32(target);
636 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
637 int retval, i;
638 uint32_t bpinfo;
639
640 /* get number of data breakpoints */
641 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
642 if (retval != ERROR_OK)
643 return retval;
644
645 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
646 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
647 mips32->data_break_list = calloc(mips32->num_data_bpoints,
648 sizeof(struct mips32_comparator));
649
650 for (i = 0; i < mips32->num_data_bpoints; i++)
651 mips32->data_break_list[i].reg_address =
652 ejtag_info->ejtag_dba0_addr +
653 (ejtag_info->ejtag_dba_step_size * i);
654
655 /* clear DBIS reg */
656 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
657 return retval;
658 }
659
660 int mips32_configure_break_unit(struct target *target)
661 {
662 /* get pointers to arch-specific information */
663 struct mips32_common *mips32 = target_to_mips32(target);
664 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
665 int retval;
666 uint32_t dcr;
667
668 if (mips32->bp_scanned)
669 return ERROR_OK;
670
671 /* get info about breakpoint support */
672 retval = target_read_u32(target, EJTAG_DCR, &dcr);
673 if (retval != ERROR_OK)
674 return retval;
675
676 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
677 if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
678 ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;
679 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))
680 ejtag_info->debug_caps |= EJTAG_DCR_IB;
681 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))
682 ejtag_info->debug_caps |= EJTAG_DCR_DB;
683 } else
684 /* keep debug caps for later use */
685 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
686 | EJTAG_DCR_IB | EJTAG_DCR_DB);
687
688
689 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
690 retval = mips32_configure_ibs(target);
691 if (retval != ERROR_OK)
692 return retval;
693 }
694
695 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
696 retval = mips32_configure_dbs(target);
697 if (retval != ERROR_OK)
698 return retval;
699 }
700
701 /* check if target endianness settings matches debug control register */
702 if (((ejtag_info->debug_caps & EJTAG_DCR_ENM)
703 && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
704 (!(ejtag_info->debug_caps & EJTAG_DCR_ENM)
705 && (target->endianness == TARGET_BIG_ENDIAN)))
706 LOG_WARNING("DCR endianness settings does not match target settings");
707
708 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
709 mips32->num_data_bpoints);
710
711 mips32->bp_scanned = 1;
712
713 return ERROR_OK;
714 }
715
716 int mips32_enable_interrupts(struct target *target, int enable)
717 {
718 int retval;
719 int update = 0;
720 uint32_t dcr;
721
722 /* read debug control register */
723 retval = target_read_u32(target, EJTAG_DCR, &dcr);
724 if (retval != ERROR_OK)
725 return retval;
726
727 if (enable) {
728 if (!(dcr & EJTAG_DCR_INTE)) {
729 /* enable interrupts */
730 dcr |= EJTAG_DCR_INTE;
731 update = 1;
732 }
733 } else {
734 if (dcr & EJTAG_DCR_INTE) {
735 /* disable interrupts */
736 dcr &= ~EJTAG_DCR_INTE;
737 update = 1;
738 }
739 }
740
741 if (update) {
742 retval = target_write_u32(target, EJTAG_DCR, dcr);
743 if (retval != ERROR_OK)
744 return retval;
745 }
746
747 return ERROR_OK;
748 }
749
750 /* read processor identification cp0 register */
751 static int mips32_read_c0_prid(struct target *target)
752 {
753 struct mips32_common *mips32 = target_to_mips32(target);
754 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
755 int retval;
756
757 retval = mips32_cp0_read(ejtag_info, &mips32->prid, 15, 0);
758 if (retval != ERROR_OK) {
759 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
760 mips32->prid = 0;
761 }
762
763 return retval;
764 }
765
766 /**
767 * mips32_find_cpu_by_prid - Find CPU information by processor ID.
768 * @param[in] prid: Processor ID of the CPU.
769 *
770 * @brief This function looks up the CPU entry in the mips32_cpu_entry array based on the provided
771 * processor ID. It also handles special cases like AMD/Alchemy CPUs that use Company Options
772 * instead of Processor IDs.
773 *
774 * @return Pointer to the corresponding cpu_entry struct, or the 'unknown' entry if not found.
775 */
776 static const struct cpu_entry *mips32_find_cpu_by_prid(uint32_t prid)
777 {
778 /* AMD/Alchemy CPU uses Company Options instead of Processor ID.
779 * Therefore an extra transform step for prid to map it to an assigned ID,
780 */
781 if ((prid & PRID_COMP_MASK) == PRID_COMP_ALCHEMY) {
782 /* Clears Processor ID field, then put Company Option field to its place */
783 prid = (prid & 0xFFFF00FF) | ((prid & 0xFF000000) >> 16);
784 }
785
786 /* Mask out Company Option */
787 prid &= 0x00FFFFFF;
788
789 for (unsigned int i = 0; i < MIPS32_NUM_CPU_ENTRIES; i++) {
790 const struct cpu_entry *entry = &mips32_cpu_entry[i];
791 if ((entry->prid & MIPS32_CORE_MASK) <= prid && prid <= entry->prid)
792 return entry;
793 }
794
795 /* If nothing matched, then return unknown entry */
796 return &mips32_cpu_entry[MIPS32_NUM_CPU_ENTRIES - 1];
797 }
798
799 static bool mips32_cpu_is_lexra(struct mips_ejtag *ejtag_info)
800 {
801 return (ejtag_info->prid & PRID_COMP_MASK) == PRID_COMP_LEXRA;
802 }
803
804 static int mips32_cpu_get_release(struct mips_ejtag *ejtag_info)
805 {
806 return (ejtag_info->config[0] & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;
807 }
808
809 /**
810 * mips32_cpu_support_sync - Checks CPU supports ordering
811 * @param[in] ejtag_info: MIPS EJTAG information structure.
812 *
813 * @brief MIPS ISA implemented on Lexra CPUs is MIPS-I, similar to R3000,
814 * which does not have the SYNC instruction alone with unaligned
815 * load/store instructions.
816 *
817 * @returns true if current CPU supports sync instruction(CPU is not Lexra)
818 */
819 bool mips32_cpu_support_sync(struct mips_ejtag *ejtag_info)
820 {
821 return !mips32_cpu_is_lexra(ejtag_info);
822 }
823
824 /**
825 * mips32_cpu_support_hazard_barrier - Checks CPU supports hazard barrier
826 * @param[in] ejtag_info: MIPS EJTAG information structure.
827 *
828 * @brief hazard barrier instructions EHB and *.HB was introduced to MIPS from release 2.
829 *
830 * @returns true if current CPU supports hazard barrier(release > 1)
831 */
832 bool mips32_cpu_support_hazard_barrier(struct mips_ejtag *ejtag_info)
833 {
834 return mips32_cpu_get_release(ejtag_info) > MIPS32_RELEASE_1;
835 }
836
837 /**
838 * mips32_cpu_probe - Detects processor type and applies necessary quirks.
839 * @param[in] target: The target CPU to probe.
840 *
841 * @brief This function probes the CPU, reads its PRID (Processor ID), and determines the CPU type.
842 * It applies any quirks necessary for specific processor types.
843 *
844 * NOTE: The proper detection of certain CPUs can become quite complicated.
845 * Please consult the following Linux kernel code when adding new CPUs:
846 * arch/mips/include/asm/cpu.h
847 * arch/mips/kernel/cpu-probe.c
848 *
849 * @return ERROR_OK on success; error code on failure.
850 */
851 int mips32_cpu_probe(struct target *target)
852 {
853 struct mips32_common *mips32 = target_to_mips32(target);
854 int retval;
855
856 if (mips32->prid)
857 return ERROR_OK; /* Already probed once, return early. */
858
859 retval = mips32_read_c0_prid(target);
860 if (retval != ERROR_OK)
861 return retval;
862
863 const struct cpu_entry *entry = mips32_find_cpu_by_prid(mips32->prid);
864
865 switch (mips32->prid & PRID_COMP_MASK) {
866 case PRID_COMP_INGENIC_E1:
867 switch (mips32->prid & PRID_IMP_MASK) {
868 case PRID_IMP_XBURST_REV1:
869 mips32->cpu_quirks |= EJTAG_QUIRK_PAD_DRET;
870 break;
871 default:
872 break;
873 }
874 break;
875
876 /* Determine which CP0 registers are available in the current processor core */
877 case PRID_COMP_MTI:
878 switch (entry->prid & PRID_IMP_MASK) {
879 case PRID_IMP_MAPTIV_UC:
880 mips32->cp0_mask = MIPS_CP0_MAPTIV_UC;
881 break;
882 case PRID_IMP_MAPTIV_UP:
883 case PRID_IMP_M5150:
884 mips32->cp0_mask = MIPS_CP0_MAPTIV_UP;
885 break;
886 case PRID_IMP_IAPTIV:
887 case PRID_IMP_IAPTIV_CM:
888 mips32->cp0_mask = MIPS_CP0_IAPTIV;
889 break;
890 default:
891 /* CP0 mask should be the same as MK4 by default */
892 mips32->cp0_mask = MIPS_CP0_MK4;
893 break;
894 }
895
896 default:
897 break;
898 }
899
900 mips32->cpu_info = entry;
901 LOG_DEBUG("CPU: %s (PRId %08x)", entry->cpu_name, mips32->prid);
902
903 return ERROR_OK;
904 }
905
906 /* reads dsp implementation info from CP0 Config3 register {DSPP, DSPREV}*/
907 static void mips32_read_config_dsp(struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
908 {
909 uint32_t dsp_present = ((ejtag_info->config[3] & MIPS32_CONFIG3_DSPP_MASK) >> MIPS32_CONFIG3_DSPP_SHIFT);
910 if (dsp_present) {
911 mips32->dsp_imp = ((ejtag_info->config[3] & MIPS32_CONFIG3_DSPREV_MASK) >> MIPS32_CONFIG3_DSPREV_SHIFT) + 1;
912 LOG_USER("DSP implemented: %s, rev %d", "yes", mips32->dsp_imp);
913 } else {
914 LOG_USER("DSP implemented: %s", "no");
915 }
916 }
917
918 /* read fpu implementation info from CP0 Config1 register {CU1, FP}*/
919 static int mips32_read_config_fpu(struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
920 {
921 int retval;
922 uint32_t fp_imp = (ejtag_info->config[1] & MIPS32_CONFIG1_FP_MASK) >> MIPS32_CONFIG1_FP_SHIFT;
923 char buf[60] = {0};
924 if (!fp_imp) {
925 LOG_USER("FPU implemented: %s", "no");
926 mips32->fp_imp = MIPS32_FP_IMP_NONE;
927 return ERROR_OK;
928 }
929 uint32_t status_value;
930 bool status_fr, status_cu1;
931
932 retval = mips32_cp0_read(ejtag_info, &status_value, MIPS32_C0_STATUS, 0);
933 if (retval != ERROR_OK) {
934 LOG_ERROR("Failed to read cp0 status register");
935 return retval;
936 }
937
938 status_fr = (status_value >> MIPS32_CP0_STATUS_FR_SHIFT) & 0x1;
939 status_cu1 = (status_value >> MIPS32_CP0_STATUS_CU1_SHIFT) & 0x1;
940 if (status_cu1) {
941 /* TODO: read fpu(cp1) config register for current operating mode.
942 * Now its set to 32 bits by default. */
943 snprintf(buf, sizeof(buf), "yes");
944 fp_imp = MIPS32_FP_IMP_32;
945 } else {
946 snprintf(buf, sizeof(buf), "yes, disabled");
947 fp_imp = MIPS32_FP_IMP_UNKNOWN;
948 }
949
950 mips32->fpu_in_64bit = status_fr;
951 mips32->fpu_enabled = status_cu1;
952
953 LOG_USER("FPU implemented: %s", buf);
954 mips32->fp_imp = fp_imp;
955
956 return ERROR_OK;
957 }
958
959 /**
960 * mips32_read_config_fdc - Read Fast Debug Channel configuration
961 * @param[in,out] mips32: MIPS32 common structure
962 * @param[in] ejtag_info: EJTAG information structure
963 * @param[in] dcr: Device Configuration Register value
964 *
965 * @brief Checks if the current target implements the Common Device Memory Map (CDMM) and Fast Debug Channel (FDC).
966 *
967 * This function examines the configuration registers and the Device Configuration Register (DCR) to determine
968 * if the current MIPS32 target supports the Common Device Memory Map (CDMM) and the Fast Debug Channel (FDC).
969 * If supported, it sets the corresponding flags in the MIPS32 common structure. \n
970 *
971 * NOTE:These are defined on MD00090, page 67 and MD00047F, page 82, respectively.
972 * MIPS Documents are pretty much all available online,
973 * it should pop up first when you search "MDxxxxx"
974 */
975 static void mips32_read_config_fdc(struct mips32_common *mips32, struct mips_ejtag *ejtag_info, uint32_t dcr)
976 {
977 if (((ejtag_info->config[3] & MIPS32_CONFIG3_CDMM_MASK) != 0) && ((dcr & EJTAG_DCR_FDC) != 0)) {
978 mips32->fdc = 1;
979 mips32->semihosting = 1;
980 } else {
981 mips32->fdc = 0;
982 mips32->semihosting = 0;
983 }
984 }
985
986 /* read config to config3 cp0 registers and log isa implementation */
987 int mips32_read_config_regs(struct target *target)
988 {
989 struct mips32_common *mips32 = target_to_mips32(target);
990 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
991 char buf[60] = {0};
992 int retval;
993
994 if (ejtag_info->config_regs == 0)
995 for (int i = 0; i != 4; i++) {
996 retval = mips32_cp0_read(ejtag_info, &ejtag_info->config[i], 16, i);
997 if (retval != ERROR_OK) {
998 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32, i);
999 ejtag_info->config_regs = 0;
1000 return retval;
1001 }
1002 ejtag_info->config_regs = i + 1;
1003 if ((ejtag_info->config[i] & (1 << 31)) == 0)
1004 break; /* no more config registers implemented */
1005 }
1006 else
1007 return ERROR_OK; /* already successfully read */
1008
1009 LOG_DEBUG("read %"PRIu32" config registers", ejtag_info->config_regs);
1010
1011 mips32->isa_rel = (ejtag_info->config[0] & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;
1012 snprintf(buf, sizeof(buf), ", release %s(AR=%d)",
1013 mips32->isa_rel == MIPS32_RELEASE_1 ? "1"
1014 : mips32->isa_rel == MIPS32_RELEASE_2 ? "2"
1015 : mips32->isa_rel == MIPS32_RELEASE_6 ? "6"
1016 : "unknown", mips32->isa_rel);
1017
1018 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
1019 mips32->isa_imp = MIPS32_MIPS16;
1020 LOG_USER("ISA implemented: %s%s", "MIPS32, MIPS16", buf);
1021 } else if (ejtag_info->config_regs >= 4) { /* config3 implemented */
1022 unsigned isa_imp = (ejtag_info->config[3] & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT;
1023 if (isa_imp == 1) {
1024 mips32->isa_imp = MMIPS32_ONLY;
1025 LOG_USER("ISA implemented: %s%s", "microMIPS32", buf);
1026
1027 } else if (isa_imp != 0) {
1028 mips32->isa_imp = MIPS32_MMIPS32;
1029 LOG_USER("ISA implemented: %s%s", "MIPS32, microMIPS32", buf);
1030 }
1031 } else if (mips32->isa_imp == MIPS32_ONLY) {
1032 /* initial default value */
1033 LOG_USER("ISA implemented: %s%s", "MIPS32", buf);
1034 }
1035
1036 /* Retrieve DSP info */
1037 mips32_read_config_dsp(mips32, ejtag_info);
1038
1039 /* Retrieve if Float Point CoProcessor Implemented */
1040 retval = mips32_read_config_fpu(mips32, ejtag_info);
1041 if (retval != ERROR_OK) {
1042 LOG_ERROR("fpu info is not available, error while reading cp0 status");
1043 mips32->fp_imp = MIPS32_FP_IMP_NONE;
1044 return retval;
1045 }
1046
1047 uint32_t dcr;
1048
1049 retval = target_read_u32(target, EJTAG_DCR, &dcr);
1050 if (retval != ERROR_OK) {
1051 LOG_ERROR("failed to read EJTAG_DCR register");
1052 return retval;
1053 }
1054
1055 /* Determine if FDC and CDMM are implemented for this core */
1056 mips32_read_config_fdc(mips32, ejtag_info, dcr);
1057
1058 return ERROR_OK;
1059 }
1060
1061 int mips32_checksum_memory(struct target *target, target_addr_t address,
1062 uint32_t count, uint32_t *checksum)
1063 {
1064 struct working_area *crc_algorithm;
1065 struct reg_param reg_params[2];
1066 struct mips32_algorithm mips32_info;
1067
1068 struct mips32_common *mips32 = target_to_mips32(target);
1069 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1070
1071 /* see contrib/loaders/checksum/mips32.s for src */
1072 uint32_t isa = ejtag_info->isa ? 1 : 0;
1073
1074 uint32_t mips_crc_code[] = {
1075 MIPS32_ADDIU(isa, 12, 4, 0), /* addiu $t4, $a0, 0 */
1076 MIPS32_ADDIU(isa, 10, 5, 0), /* addiu $t2, $a1, 0 */
1077 MIPS32_ADDIU(isa, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
1078 MIPS32_BEQ(isa, 0, 0, 0x10 << isa), /* beq $zero, $zero, ncomp */
1079 MIPS32_ADDIU(isa, 11, 0, 0), /* addiu $t3, $zero, 0 */
1080 /* nbyte: */
1081 MIPS32_LB(isa, 5, 0, 12), /* lb $a1, ($t4) */
1082 MIPS32_ADDI(isa, 12, 12, 1), /* addi $t4, $t4, 1 */
1083 MIPS32_SLL(isa, 5, 5, 24), /* sll $a1, $a1, 24 */
1084 MIPS32_LUI(isa, 2, 0x04c1), /* lui $v0, 0x04c1 */
1085 MIPS32_XOR(isa, 4, 4, 5), /* xor $a0, $a0, $a1 */
1086 MIPS32_ORI(isa, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
1087 MIPS32_ADDU(isa, 6, 0, 0), /* addu $a2, $zero, $zero */
1088 /* loop */
1089 MIPS32_SLL(isa, 8, 4, 1), /* sll $t0, $a0, 1 */
1090 MIPS32_ADDIU(isa, 6, 6, 1), /* addiu $a2, $a2, 1 */
1091 MIPS32_SLTI(isa, 4, 4, 0), /* slti $a0, $a0, 0 */
1092 MIPS32_XOR(isa, 9, 8, 7), /* xor $t1, $t0, $a3 */
1093 MIPS32_MOVN(isa, 8, 9, 4), /* movn $t0, $t1, $a0 */
1094 MIPS32_SLTI(isa, 3, 6, 8), /* slti $v1, $a2, 8 */
1095 MIPS32_BNE(isa, 3, 0, NEG16(7 << isa)), /* bne $v1, $zero, loop */
1096 MIPS32_ADDU(isa, 4, 8, 0), /* addu $a0, $t0, $zero */
1097 /* ncomp */
1098 MIPS32_BNE(isa, 10, 11, NEG16(16 << isa)), /* bne $t2, $t3, nbyte */
1099 MIPS32_ADDIU(isa, 11, 11, 1), /* addiu $t3, $t3, 1 */
1100 MIPS32_SDBBP(isa),
1101 };
1102
1103 /* make sure we have a working area */
1104 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
1105 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1106
1107 pracc_swap16_array(ejtag_info, mips_crc_code, ARRAY_SIZE(mips_crc_code));
1108
1109 /* convert mips crc code into a buffer in target endianness */
1110 uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
1111 target_buffer_set_u32_array(target, mips_crc_code_8,
1112 ARRAY_SIZE(mips_crc_code), mips_crc_code);
1113
1114 int retval = target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
1115 if (retval != ERROR_OK)
1116 return retval;
1117
1118 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
1119 mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32; /* run isa as in debug mode */
1120
1121 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
1122 buf_set_u32(reg_params[0].value, 0, 32, address);
1123
1124 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
1125 buf_set_u32(reg_params[1].value, 0, 32, count);
1126
1127 unsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));
1128
1129 retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
1130 crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout, &mips32_info);
1131
1132 if (retval == ERROR_OK)
1133 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
1134
1135 destroy_reg_param(&reg_params[0]);
1136 destroy_reg_param(&reg_params[1]);
1137
1138 target_free_working_area(target, crc_algorithm);
1139
1140 return retval;
1141 }
1142
1143 /** Checks whether a memory region is erased. */
1144 int mips32_blank_check_memory(struct target *target,
1145 struct target_memory_check_block *blocks, int num_blocks,
1146 uint8_t erased_value)
1147 {
1148 struct working_area *erase_check_algorithm;
1149 struct reg_param reg_params[3];
1150 struct mips32_algorithm mips32_info;
1151
1152 struct mips32_common *mips32 = target_to_mips32(target);
1153 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1154
1155 if (erased_value != 0xff) {
1156 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for MIPS32",
1157 erased_value);
1158 return ERROR_FAIL;
1159 }
1160 uint32_t isa = ejtag_info->isa ? 1 : 0;
1161 uint32_t erase_check_code[] = {
1162 /* nbyte: */
1163 MIPS32_LB(isa, 8, 0, 4), /* lb $t0, ($a0) */
1164 MIPS32_AND(isa, 6, 6, 8), /* and $a2, $a2, $t0 */
1165 MIPS32_ADDIU(isa, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
1166 MIPS32_BNE(isa, 5, 0, NEG16(4 << isa)), /* bne $a1, $zero, nbyte */
1167 MIPS32_ADDIU(isa, 4, 4, 1), /* addiu $a0, $a0, 1 */
1168 MIPS32_SDBBP(isa) /* sdbbp */
1169 };
1170
1171 /* make sure we have a working area */
1172 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
1173 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1174
1175 pracc_swap16_array(ejtag_info, erase_check_code, ARRAY_SIZE(erase_check_code));
1176
1177 /* convert erase check code into a buffer in target endianness */
1178 uint8_t erase_check_code_8[sizeof(erase_check_code)];
1179 target_buffer_set_u32_array(target, erase_check_code_8,
1180 ARRAY_SIZE(erase_check_code), erase_check_code);
1181
1182 int retval = target_write_buffer(target, erase_check_algorithm->address,
1183 sizeof(erase_check_code), erase_check_code_8);
1184 if (retval != ERROR_OK)
1185 goto cleanup;
1186
1187 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
1188 mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;
1189
1190 init_reg_param(&reg_params[0], "r4", 32, PARAM_OUT);
1191 buf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);
1192
1193 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
1194 buf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);
1195
1196 init_reg_param(&reg_params[2], "r6", 32, PARAM_IN_OUT);
1197 buf_set_u32(reg_params[2].value, 0, 32, erased_value);
1198
1199 retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
1200 erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);
1201
1202 if (retval == ERROR_OK)
1203 blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
1204
1205 destroy_reg_param(&reg_params[0]);
1206 destroy_reg_param(&reg_params[1]);
1207 destroy_reg_param(&reg_params[2]);
1208
1209 cleanup:
1210 target_free_working_area(target, erase_check_algorithm);
1211
1212 if (retval != ERROR_OK)
1213 return retval;
1214
1215 return 1; /* only one block has been checked */
1216 }
1217
1218 static int mips32_verify_pointer(struct command_invocation *cmd,
1219 struct mips32_common *mips32)
1220 {
1221 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
1222 command_print(cmd, "target is not an MIPS32");
1223 return ERROR_TARGET_INVALID;
1224 }
1225 return ERROR_OK;
1226 }
1227
1228 /**
1229 * mips32_read_config_mmu - Reads MMU configuration and logs relevant information.
1230 * @param[in] ejtag_info: EJTAG interface information.
1231 *
1232 * @brief Reads the MMU configuration from the CP0 register and calculates the number of TLB entries,
1233 * ways, and sets. Handles different MMU types like VTLB only, root RPU/Fixed, and VTLB and FTLB.
1234 *
1235 * @return ERROR_OK on success; error code on failure.
1236 */
1237 static int mips32_read_config_mmu(struct mips_ejtag *ejtag_info)
1238 {
1239 uint32_t config4, tlb_entries = 0, ways = 0, sets = 0;
1240 uint32_t config0 = ejtag_info->config[0];
1241 uint32_t config1 = ejtag_info->config[1];
1242 uint32_t config3 = ejtag_info->config[3];
1243 uint32_t mmu_type = (config0 >> 7) & 7;
1244 uint32_t vz_present = (config3 & BIT(23));
1245
1246 int retval = mips32_cp0_read(ejtag_info, &config4, 16, 4);
1247 if (retval != ERROR_OK)
1248 return retval;
1249
1250 /* mmu type = 1: VTLB only (Note: Does not account for Config4.ExtVTLB)
1251 * mmu type = 3: root RPU/Fixed (Note: Only valid with VZ ASE)
1252 * mmu type = 4: VTLB and FTLB
1253 */
1254 if ((mmu_type == 1 || mmu_type == 4) || (mmu_type == 3 && vz_present)) {
1255 tlb_entries = (uint32_t)(((config1 >> 25) & 0x3f) + 1);
1256 if (mmu_type == 4) {
1257 /* Release 6 definition for Config4[0:15] (MD01251, page 243) */
1258 /* The FTLB ways field is defined as [2, 3, 4, 5, 6, 7, 8, ...0 (reserved)] */
1259 int index = ((config4 >> 4) & 0xf);
1260 ways = index > 6 ? 0 : index + 2;
1261
1262 /* The FTLB sets field is defined as [1, 2, 4, 8, ..., 16384, 32768] (powers of 2) */
1263 index = (config4 & 0xf);
1264 sets = 1 << index;
1265 tlb_entries = tlb_entries + (ways * sets);
1266 }
1267 }
1268 LOG_USER("TLB Entries: %d (%d ways, %d sets per way)", tlb_entries, ways, sets);
1269
1270 return ERROR_OK;
1271 }
1272
1273 /**
1274 * mips32_cp0_find_register_by_name - Find CP0 register by its name.
1275 * @param[in] cp0_mask: Mask to filter out irrelevant registers.
1276 * @param[in] reg_name: Name of the register to find.
1277 *
1278 * @brief This function iterates through mips32_cp0_regs to find a register
1279 * matching reg_name, considering cp0_mask to filter out registers
1280 * not relevant for the current core.
1281 *
1282 * @return Pointer to the found register, or NULL if not found.
1283 */
1284 static const struct mips32_cp0 *mips32_cp0_find_register_by_name(uint32_t cp0_mask, const char *reg_name)
1285 {
1286 if (reg_name)
1287 for (unsigned int i = 0; i < MIPS32NUMCP0REGS; i++) {
1288 if ((mips32_cp0_regs[i].core & cp0_mask) == 0)
1289 continue;
1290
1291 if (strcmp(mips32_cp0_regs[i].name, reg_name) == 0)
1292 return &mips32_cp0_regs[i];
1293 }
1294 return NULL;
1295 }
1296
1297 /**
1298 * mips32_cp0_get_all_regs - Print all CP0 registers and their values.
1299 * @param[in] cmd: Command invocation context.
1300 * @param[in] ejtag_info: EJTAG interface information.
1301 * @param[in] cp0_mask: Mask to identify relevant registers.
1302 *
1303 * @brief Iterates over all CP0 registers, reads their values, and prints them.
1304 * Only considers registers relevant to the current core, as defined by cp0_mask.
1305 *
1306 * @return ERROR_OK on success; error code on failure.
1307 */
1308 static int mips32_cp0_get_all_regs(struct command_invocation *cmd, struct mips_ejtag *ejtag_info, uint32_t cp0_mask)
1309 {
1310 uint32_t value;
1311
1312 for (unsigned int i = 0; i < MIPS32NUMCP0REGS; i++) {
1313 /* Register name not valid for this core */
1314 if ((mips32_cp0_regs[i].core & cp0_mask) == 0)
1315 continue;
1316
1317 int retval = mips32_cp0_read(ejtag_info, &value, mips32_cp0_regs[i].reg, mips32_cp0_regs[i].sel);
1318 if (retval != ERROR_OK) {
1319 command_print(CMD, "Error: couldn't access reg %s", mips32_cp0_regs[i].name);
1320 return retval;
1321 }
1322
1323 command_print(CMD, "%*s: 0x%8.8" PRIx32, 14, mips32_cp0_regs[i].name, value);
1324 }
1325 return ERROR_OK;
1326 }
1327
1328 /**
1329 * mips32_cp0_get_reg_by_name - Read and print a CP0 register's value by name.
1330 * @param[in] cmd: Command invocation context.
1331 * @param[in] ejtag_info: EJTAG interface information.
1332 * @param[in] cp0_mask: Mask to identify relevant registers.
1333 *
1334 * @brief Finds a CP0 register by name, reads its value, and prints it.
1335 * Handles error scenarios like register not found or read failure.
1336 *
1337 * @return ERROR_OK on success; error code on failure.
1338 */
1339 static int mips32_cp0_get_reg_by_name(struct command_invocation *cmd, struct mips_ejtag *ejtag_info, uint32_t cp0_mask)
1340 {
1341 const struct mips32_cp0 *cp0_regs = mips32_cp0_find_register_by_name(cp0_mask, CMD_ARGV[0]);
1342 if (!cp0_regs) {
1343 command_print(CMD, "Error: Register '%s' not found", CMD_ARGV[0]);
1344 return ERROR_COMMAND_ARGUMENT_INVALID;
1345 }
1346
1347 uint32_t value;
1348 int retval = mips32_cp0_read(ejtag_info, &value, cp0_regs->reg, cp0_regs->sel);
1349 if (retval != ERROR_OK) {
1350 command_print(CMD, "Error: Encounter an Error while reading cp0 reg %d sel %d",
1351 cp0_regs->reg, cp0_regs->sel);
1352 return retval;
1353 }
1354
1355 command_print(CMD, "0x%8.8" PRIx32, value);
1356 return ERROR_OK;
1357 }
1358
1359 /**
1360 * mips32_cp0_get_reg_by_number - Read and print a CP0 register's value by number.
1361 * @param[in] cmd: Command invocation context.
1362 * @param[in] ejtag_info: EJTAG interface information.
1363 *
1364 * @brief Reads a specific CP0 register (identified by number and selection) and prints its value.
1365 * The register number and selection are parsed from the command arguments.
1366 *
1367 * @return ERROR_OK on success; error code on failure.
1368 */
1369 static int mips32_cp0_get_reg_by_number(struct command_invocation *cmd, struct mips_ejtag *ejtag_info)
1370 {
1371 uint32_t cp0_reg, cp0_sel, value;
1372 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
1373 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
1374
1375 int retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
1376 if (retval != ERROR_OK) {
1377 command_print(CMD,
1378 "Error: couldn't access reg %" PRIu32,
1379 cp0_reg);
1380 return retval;
1381 }
1382
1383 command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
1384 cp0_reg, cp0_sel, value);
1385 return ERROR_OK;
1386 }
1387
1388 /**
1389 * mips32_cp0_set_reg_by_name - Write to a CP0 register identified by name.
1390 * @param[in] cmd: Command invocation context.
1391 * @param[in] mips32: Common MIPS32 data structure.
1392 * @param[in] ejtag_info: EJTAG interface information.
1393 *
1394 * @brief Writes a value to a CP0 register specified by name. Updates internal
1395 * cache if specific registers (STATUS, CAUSE, DEPC, GUESTCTL1) are modified.
1396 *
1397 * @return ERROR_OK on success; error code on failure.
1398 */
1399 static int mips32_cp0_set_reg_by_name(struct command_invocation *cmd,
1400 struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
1401 {
1402 const struct mips32_cp0 *cp0_regs = mips32_cp0_find_register_by_name(mips32->cp0_mask, CMD_ARGV[0]);
1403 if (!cp0_regs) {
1404 command_print(CMD, "Error: Register '%s' not found", CMD_ARGV[0]);
1405 return ERROR_COMMAND_ARGUMENT_INVALID;
1406 }
1407
1408
1409 uint32_t value;
1410 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1411
1412 if (cp0_regs->reg == MIPS32_C0_STATUS && cp0_regs->sel == 0) {
1413 /* Update cached Status register if user is writing to Status */
1414 mips32->core_regs.cp0[MIPS32_REG_C0_STATUS_INDEX] = value;
1415 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_STATUS_INDEX].dirty = 1;
1416 } else if (cp0_regs->reg == MIPS32_C0_CAUSE && cp0_regs->sel == 0) {
1417 /* Update register cache with new value if its Cause */
1418 mips32->core_regs.cp0[MIPS32_REG_C0_CAUSE_INDEX] = value;
1419 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_CAUSE_INDEX].dirty = 1;
1420 } else if (cp0_regs->reg == MIPS32_C0_DEPC && cp0_regs->sel == 0) {
1421 /* Update cached PC if its DEPC */
1422 mips32->core_regs.cp0[MIPS32_REG_C0_PC_INDEX] = value;
1423 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = 1;
1424 } else if (cp0_regs->reg == MIPS32_C0_GUESTCTL1 && cp0_regs->sel == 4) {
1425 /* Update cached guestCtl1 */
1426 mips32->core_regs.cp0[MIPS32_REG_C0_GUESTCTL1_INDEX] = value;
1427 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_GUESTCTL1_INDEX].dirty = 1;
1428 }
1429
1430 int retval = mips32_cp0_write(ejtag_info, value,
1431 cp0_regs->reg,
1432 cp0_regs->sel);
1433 if (retval != ERROR_OK) {
1434 command_print(CMD, "Error: Encounter an Error while writing to cp0 reg %d, sel %d",
1435 cp0_regs->reg, cp0_regs->sel);
1436 return retval;
1437 }
1438
1439 command_print(CMD, "cp0 reg %s (%u, select %u: %8.8" PRIx32 ")",
1440 CMD_ARGV[0], cp0_regs->reg, cp0_regs->sel, value);
1441 return ERROR_OK;
1442 }
1443
1444 /**
1445 * mips32_cp0_set_reg_by_number - Write to a CP0 register identified by number.
1446 * @param[in] cmd: Command invocation context.
1447 * @param[in] mips32: Common MIPS32 data structure.
1448 * @param[in] ejtag_info: EJTAG interface information.
1449 *
1450 * @brief Writes a value to a CP0 register specified by number and selection.
1451 * Handles special cases like updating the internal cache for certain registers.
1452 *
1453 * @return ERROR_OK on success; error code on failure.
1454 */
1455 static int mips32_cp0_set_reg_by_number(struct command_invocation *cmd,
1456 struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
1457 {
1458 uint32_t cp0_reg, cp0_sel, value;
1459 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
1460 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
1461 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1462
1463 if (cp0_reg == MIPS32_C0_STATUS && cp0_sel == 0) {
1464 /* Update cached status register if user is writing to Status register */
1465 mips32->core_regs.cp0[MIPS32_REG_C0_STATUS_INDEX] = value;
1466 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_STATUS_INDEX].dirty = 1;
1467 } else if (cp0_reg == MIPS32_C0_CAUSE && cp0_sel == 0) {
1468 /* Update register cache with new value if its Cause register */
1469 mips32->core_regs.cp0[MIPS32_REG_C0_CAUSE_INDEX] = value;
1470 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_CAUSE_INDEX].dirty = 1;
1471 } else if (cp0_reg == MIPS32_C0_DEPC && cp0_sel == 0) {
1472 /* Update cached PC if its DEPC */
1473 mips32->core_regs.cp0[MIPS32_REG_C0_PC_INDEX] = value;
1474 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = 1;
1475 } else if (cp0_reg == MIPS32_C0_GUESTCTL1 && cp0_sel == 4) {
1476 /* Update cached guestCtl1, too */
1477 mips32->core_regs.cp0[MIPS32_REG_C0_GUESTCTL1_INDEX] = value;
1478 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_GUESTCTL1_INDEX].dirty = 1;
1479 }
1480
1481 int retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
1482 if (retval != ERROR_OK) {
1483 command_print(CMD,
1484 "Error: couldn't access cp0 reg %" PRIu32 ", select %" PRIu32,
1485 cp0_reg, cp0_sel);
1486 return retval;
1487 }
1488
1489 command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
1490 cp0_reg, cp0_sel, value);
1491 return ERROR_OK;
1492 }
1493
1494 /**
1495 * mips32_handle_cp0_command - Handle commands related to CP0 registers.
1496 * @cmd: Command invocation context.
1497 *
1498 * Orchestrates different operations on CP0 registers based on the command arguments.
1499 * Supports operations like reading all registers, reading/writing a specific register
1500 * by name or number.
1501 *
1502 * Return: ERROR_OK on success; error code on failure.
1503 */
1504 COMMAND_HANDLER(mips32_handle_cp0_command)
1505 {
1506 int retval, tmp;
1507 struct target *target = get_current_target(CMD_CTX);
1508 struct mips32_common *mips32 = target_to_mips32(target);
1509 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1510
1511
1512 retval = mips32_verify_pointer(CMD, mips32);
1513 if (retval != ERROR_OK)
1514 return retval;
1515
1516 if (target->state != TARGET_HALTED) {
1517 command_print(CMD, "Error: target must be stopped for \"%s\" command", CMD_NAME);
1518 return ERROR_TARGET_NOT_HALTED;
1519 }
1520
1521 switch (CMD_ARGC) {
1522 case 0: /* No arg => print out all cp0 regs */
1523 retval = mips32_cp0_get_all_regs(CMD, ejtag_info, mips32->cp0_mask);
1524 break;
1525 case 1: /* 1 arg => get cp0 #reg/#sel value by name */
1526 retval = mips32_cp0_get_reg_by_name(CMD, ejtag_info, mips32->cp0_mask);
1527 break;
1528 case 2: /* 2 args => get cp0 reg/sel value or set value by name */
1529 tmp = *CMD_ARGV[0];
1530 if (isdigit(tmp)) /* starts from number then args are #reg and #sel */
1531 retval = mips32_cp0_get_reg_by_number(CMD, ejtag_info);
1532 else /* or set value by register name */
1533 retval = mips32_cp0_set_reg_by_name(CMD, mips32, ejtag_info);
1534
1535 break;
1536 case 3: /* 3 args => set cp0 reg/sel value*/
1537 retval = mips32_cp0_set_reg_by_number(CMD, mips32, ejtag_info);
1538 break;
1539 default: /* Other argc => err */
1540 retval = ERROR_COMMAND_SYNTAX_ERROR;
1541 break;
1542 }
1543
1544 return retval;
1545 }
1546
1547 /**
1548 * mips32_handle_cpuinfo_command - Handles the 'cpuinfo' command.
1549 * @param[in] cmd: Command invocation context.
1550 *
1551 * @brief Executes the 'cpuinfo' command which displays detailed information about the current CPU core.
1552 * This includes core type, vendor, instruction set, cache size, and other relevant details.
1553 *
1554 * @return ERROR_OK on success; error code on failure.
1555 */
1556 COMMAND_HANDLER(mips32_handle_cpuinfo_command)
1557 {
1558 int retval;
1559 struct target *target = get_current_target(CMD_CTX);
1560 struct mips32_common *mips32 = target_to_mips32(target);
1561 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1562
1563 uint32_t prid = mips32->prid; /* cp0 PRID - 15, 0 */
1564 uint32_t config0 = ejtag_info->config[0]; /* cp0 config - 16, 0 */
1565 uint32_t config1 = ejtag_info->config[1]; /* cp0 config - 16, 1 */
1566 uint32_t config3 = ejtag_info->config[3]; /* cp0 config - 16, 3 */
1567
1568 /* Following configs are not read during probe */
1569 uint32_t config5; /* cp0 config - 16, 5 */
1570
1571 /* No args for now */
1572 if (CMD_ARGC != 0)
1573 return ERROR_COMMAND_SYNTAX_ERROR;
1574
1575 if (target->state != TARGET_HALTED) {
1576 command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
1577 return ERROR_TARGET_NOT_HALTED;
1578 }
1579
1580 retval = mips32_cp0_read(ejtag_info, &config5, 16, 5);
1581 if (retval != ERROR_OK)
1582 return retval;
1583
1584 /* Determine Core info */
1585 const struct cpu_entry *entry = mips32->cpu_info;
1586 /* Display Core Type info */
1587 command_print(CMD, "CPU Core: %s", entry->cpu_name);
1588
1589 /* Display Core Vendor ID if it's unknown */
1590 if (entry == &mips32_cpu_entry[MIPS32_NUM_CPU_ENTRIES - 1])
1591 command_print(CMD, "Vendor: Unknown CPU vendor code %x.", ((prid & 0x00ffff00) >> 16));
1592 else
1593 command_print(CMD, "Vendor: %s", entry->vendor);
1594
1595 /* If MIPS release 2 or above, then get exception base info */
1596 enum mips32_isa_rel ar = mips32->isa_rel;
1597 if (ar > MIPS32_RELEASE_1) { /* release 2 and above */
1598 uint32_t ebase;
1599 retval = mips32_cp0_read(ejtag_info, &ebase, 15, 1);
1600 if (retval != ERROR_OK)
1601 return retval;
1602
1603 command_print(CMD, "Current CPU ID: %d", (ebase & 0x1ff));
1604 } else {
1605 command_print(CMD, "Current CPU ID: 0");
1606 }
1607
1608 char *instr;
1609 switch ((config3 & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT) {
1610 case 0:
1611 instr = "MIPS32";
1612 break;
1613 case 1:
1614 instr = "microMIPS";
1615 break;
1616 case 2:
1617 instr = "MIPS32 (at reset) and microMIPS";
1618 break;
1619 case 3:
1620 instr = "microMIPS (at reset) and MIPS32";
1621 break;
1622 }
1623
1624 /* Display Instruction Set Info */
1625 command_print(CMD, "Instr set: %s", instr);
1626 command_print(CMD, "Instr rel: %s",
1627 ar == MIPS32_RELEASE_1 ? "1"
1628 : ar == MIPS32_RELEASE_2 ? "2"
1629 : ar == MIPS32_RELEASE_6 ? "6"
1630 : "unknown");
1631 command_print(CMD, "PRId: %x", prid);
1632 /* Some of MIPS CPU Revisions(for M74K) can be seen on MD00541, page 26 */
1633 uint32_t rev = prid & 0x000000ff;
1634 command_print(CMD, "RTL Rev: %d.%d.%d", (rev & 0xE0), (rev & 0x1C), (rev & 0x3));
1635
1636 command_print(CMD, "Max Number of Instr Breakpoints: %d", mips32->num_inst_bpoints);
1637 command_print(CMD, "Max Number of Data Breakpoints: %d", mips32->num_data_bpoints);
1638
1639 /* MMU Support */
1640 uint32_t mmu_type = (config0 >> 7) & 7; /* MMU Type Info */
1641 char *mmu;
1642 switch (mmu_type) {
1643 case MIPS32_MMU_TLB:
1644 mmu = "TLB";
1645 break;
1646 case MIPS32_MMU_BAT:
1647 mmu = "BAT";
1648 break;
1649 case MIPS32_MMU_FIXED:
1650 mmu = "FIXED";
1651 break;
1652 case MIPS32_MMU_DUAL_VTLB_FTLB:
1653 mmu = "DUAL VAR/FIXED";
1654 break;
1655 default:
1656 mmu = "Unknown";
1657 }
1658 command_print(CMD, "MMU Type: %s", mmu);
1659
1660 retval = mips32_read_config_mmu(ejtag_info);
1661 if (retval != ERROR_OK)
1662 return retval;
1663
1664 /* Definitions of I/D Cache Sizes are available on MD01251, page 224~226 */
1665 int index;
1666 uint32_t ways, sets, bpl;
1667
1668 /* Determine Instr Cache Size */
1669 /* Ways mapping = [1, 2, 3, 4, 5, 6, 7, 8] */
1670 ways = ((config1 >> MIPS32_CFG1_IASHIFT) & 7);
1671
1672 /* Sets per way = [64, 128, 256, 512, 1024, 2048, 4096, 32] */
1673 index = ((config1 >> MIPS32_CFG1_ISSHIFT) & 7);
1674 sets = index == 7 ? 32 : 32 << (index + 1);
1675
1676 /* Bytes per line = [0, 4, 8, 16, 32, 64, 128, Reserved] */
1677 index = ((config1 >> MIPS32_CFG1_ILSHIFT) & 7);
1678 bpl = index == 0 ? 0 : 4 << (index - 1);
1679 command_print(CMD, "Instr Cache: %d (%d ways, %d lines, %d byte per line)", ways * sets * bpl, ways, sets, bpl);
1680
1681 /* Determine data cache size, same as above */
1682 ways = ((config1 >> MIPS32_CFG1_DASHIFT) & 7);
1683
1684 index = ((config1 >> MIPS32_CFG1_DSSHIFT) & 7);
1685 sets = index == 7 ? 32 : 32 << (index + 1);
1686
1687 index = ((config1 >> MIPS32_CFG1_DLSHIFT) & 7);
1688 bpl = index == 0 ? 0 : 4 << (index - 1);
1689 command_print(CMD, " Data Cache: %d (%d ways, %d lines, %d byte per line)", ways * sets * bpl, ways, sets, bpl);
1690
1691 /* does the core hava FPU*/
1692 mips32_read_config_fpu(mips32, ejtag_info);
1693
1694 /* does the core support a DSP */
1695 mips32_read_config_dsp(mips32, ejtag_info);
1696
1697 /* VZ module */
1698 uint32_t vzase = (config3 & BIT(23));
1699 if (vzase)
1700 command_print(CMD, "VZ implemented: yes");
1701 else
1702 command_print(CMD, "VZ implemented: no");
1703
1704 /* multithreading */
1705 uint32_t mtase = (config3 & BIT(2));
1706 if (mtase) {
1707 command_print(CMD, "MT implemented: yes");
1708
1709 /* Get VPE and Thread info */
1710 uint32_t tcbind;
1711 uint32_t mvpconf0;
1712
1713 /* Read tcbind register */
1714 retval = mips32_cp0_read(ejtag_info, &tcbind, 2, 2);
1715 if (retval != ERROR_OK)
1716 return retval;
1717
1718 command_print(CMD, " | Current VPE: %d", (tcbind & 0xf));
1719 command_print(CMD, " | Current TC: %d", ((tcbind >> 21) & 0xff));
1720
1721 /* Read mvpconf0 register */
1722 retval = mips32_cp0_read(ejtag_info, &mvpconf0, 0, 2);
1723 if (retval != ERROR_OK)
1724 return retval;
1725
1726 command_print(CMD, " | Total TC: %d", (mvpconf0 & 0xf) + 1);
1727 command_print(CMD, " | Total VPE: %d", ((mvpconf0 >> 10) & 0xf) + 1);
1728 } else {
1729 command_print(CMD, "MT implemented: no");
1730 }
1731
1732 /* MIPS SIMD Architecture (MSA) */
1733 uint32_t msa = (config3 & BIT(28));
1734 command_print(CMD, "MSA implemented: %s", msa ? "yes" : "no");
1735
1736 /* Move To/From High COP0 (MTHC0/MFHC0) instructions are implemented.
1737 * Implicates current ISA release >= 5.*/
1738 uint32_t mvh = (config5 & BIT(5));
1739 command_print(CMD, "MVH implemented: %s", mvh ? "yes" : "no");
1740
1741 /* Common Device Memory Map implemented? */
1742 uint32_t cdmm = (config3 & BIT(3));
1743 command_print(CMD, "CDMM implemented: %s", cdmm ? "yes" : "no");
1744
1745 return ERROR_OK;
1746 }
1747
1748 /**
1749 * mips32_handle_ejtag_reg_command - Handler commands related to EJTAG
1750 * @param[in] cmd: Command invocation context
1751 *
1752 * @brief Prints all EJTAG Registers including DCR features.
1753 *
1754 * @return ERROR_OK on success; error code on failure.
1755 */
1756 COMMAND_HANDLER(mips32_handle_ejtag_reg_command)
1757 {
1758 struct target *target = get_current_target(CMD_CTX);
1759 struct mips32_common *mips32 = target_to_mips32(target);
1760 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1761
1762 uint32_t ejtag_ctrl;
1763 uint32_t dcr;
1764 int retval;
1765
1766 retval = mips_ejtag_get_idcode(ejtag_info);
1767 if (retval != ERROR_OK)
1768 command_print(CMD, "Error: Encounter an Error while getting idcode");
1769 else
1770 command_print(CMD, " idcode: 0x%8.8" PRIx32, ejtag_info->idcode);
1771
1772 retval = mips_ejtag_get_impcode(ejtag_info);
1773 if (retval != ERROR_OK)
1774 command_print(CMD, "Error: Encounter an Error while getting impcode");
1775 else
1776 command_print(CMD, " impcode: 0x%8.8" PRIx32, ejtag_info->impcode);
1777
1778 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
1779 ejtag_ctrl = ejtag_info->ejtag_ctrl;
1780 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
1781 if (retval != ERROR_OK)
1782 command_print(CMD, "Error: Encounter an Error while executing drscan reading EJTAG Control register");
1783 else
1784 command_print(CMD, "ejtag control: 0x%8.8" PRIx32, ejtag_ctrl);
1785
1786 ejtag_main_print_imp(ejtag_info);
1787
1788 /* Display current DCR */
1789 retval = target_read_u32(target, EJTAG_DCR, &dcr);
1790 if (retval != ERROR_OK)
1791 command_print(CMD, "Error: Encounter an Error while reading Debug Control Register");
1792 else
1793 command_print(CMD, " DCR: 0x%8.8" PRIx32, dcr);
1794
1795 for (unsigned int i = 0; i < EJTAG_DCR_ENTRIES; i++) {
1796 if (dcr & BIT(dcr_features[i].bit))
1797 command_print(CMD, "%s supported", dcr_features[i].name);
1798 }
1799
1800 return ERROR_OK;
1801 }
1802
1803 /**
1804 * mips32_handle_scan_delay_command - Handler command for changing scan delay
1805 * @param[in] cmd: Command invocation context
1806 *
1807 * @brief Changes current scan mode between legacy and fast queued mode.
1808 *
1809 * @return ERROR_OK on success; error code on failure.
1810 */
1811 COMMAND_HANDLER(mips32_handle_scan_delay_command)
1812 {
1813 struct target *target = get_current_target(CMD_CTX);
1814 struct mips32_common *mips32 = target_to_mips32(target);
1815 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1816
1817 if (CMD_ARGC == 1)
1818 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
1819 else if (CMD_ARGC > 1)
1820 return ERROR_COMMAND_SYNTAX_ERROR;
1821
1822 command_print(CMD, "scan delay: %d nsec", ejtag_info->scan_delay);
1823 if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
1824 ejtag_info->mode = 0;
1825 command_print(CMD, "running in legacy mode");
1826 } else {
1827 ejtag_info->mode = 1;
1828 command_print(CMD, "running in fast queued mode");
1829 }
1830
1831 return ERROR_OK;
1832 }
1833
1834 static const struct command_registration mips32_exec_command_handlers[] = {
1835 {
1836 .name = "cp0",
1837 .handler = mips32_handle_cp0_command,
1838 .mode = COMMAND_EXEC,
1839 .usage = "[[reg_name|regnum select] [value]]",
1840 .help = "display/modify cp0 register",
1841 },
1842 {
1843 .name = "cpuinfo",
1844 .handler = mips32_handle_cpuinfo_command,
1845 .mode = COMMAND_EXEC,
1846 .help = "display CPU information",
1847 .usage = "",
1848 },
1849 {
1850 .name = "scan_delay",
1851 .handler = mips32_handle_scan_delay_command,
1852 .mode = COMMAND_ANY,
1853 .help = "display/set scan delay in nano seconds",
1854 .usage = "[value]",
1855 },
1856 {
1857 .name = "ejtag_reg",
1858 .handler = mips32_handle_ejtag_reg_command,
1859 .mode = COMMAND_ANY,
1860 .help = "read ejtag registers",
1861 .usage = "",
1862 },
1863 COMMAND_REGISTRATION_DONE
1864 };
1865
1866 const struct command_registration mips32_command_handlers[] = {
1867 {
1868 .name = "mips32",
1869 .mode = COMMAND_ANY,
1870 .help = "mips32 command group",
1871 .usage = "",
1872 .chain = mips32_exec_command_handlers,
1873 },
1874 COMMAND_REGISTRATION_DONE
1875 };

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)