jtag: linuxgpiod: drop extra parenthesis
[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
165 #define zero 0
166
167 #define AT 1
168
169 #define v0 2
170 #define v1 3
171
172 #define a0 4
173 #define a1 5
174 #define a2 6
175 #define a3 7
176 #define t0 8
177 #define t1 9
178 #define t2 10
179 #define t3 11
180 #define t4 12
181 #define t5 13
182 #define t6 14
183 #define t7 15
184 #define ta0 12 /* alias for $t4 */
185 #define ta1 13 /* alias for $t5 */
186 #define ta2 14 /* alias for $t6 */
187 #define ta3 15 /* alias for $t7 */
188
189 #define s0 16
190 #define s1 17
191 #define s2 18
192 #define s3 19
193 #define s4 20
194 #define s5 21
195 #define s6 22
196 #define s7 23
197 #define s8 30 /* == fp */
198
199 #define t8 24
200 #define t9 25
201 #define k0 26
202 #define k1 27
203
204 #define gp 28
205
206 #define sp 29
207 #define fp 30
208 #define ra 31
209
210
211 static const struct {
212 const char *name;
213 } mips32_dsp_regs[MIPS32NUMDSPREGS] = {
214 { "hi0"},
215 { "hi1"},
216 { "hi2"},
217 { "hi3"},
218 { "lo0"},
219 { "lo1"},
220 { "lo2"},
221 { "lo3"},
222 { "control"},
223 };
224
225 static int mips32_get_core_reg(struct reg *reg)
226 {
227 int retval;
228 struct mips32_core_reg *mips32_reg = reg->arch_info;
229 struct target *target = mips32_reg->target;
230 struct mips32_common *mips32_target = target_to_mips32(target);
231
232 if (target->state != TARGET_HALTED)
233 return ERROR_TARGET_NOT_HALTED;
234
235 retval = mips32_target->read_core_reg(target, mips32_reg->num);
236
237 return retval;
238 }
239
240 static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
241 {
242 struct mips32_core_reg *mips32_reg = reg->arch_info;
243 struct target *target = mips32_reg->target;
244 uint64_t value;
245
246 if (reg->size == 64)
247 value = buf_get_u64(buf, 0, 64);
248 else
249 value = buf_get_u32(buf, 0, 32);
250
251 if (target->state != TARGET_HALTED)
252 return ERROR_TARGET_NOT_HALTED;
253
254 if (reg->size == 64)
255 buf_set_u64(reg->value, 0, 64, value);
256 else
257 buf_set_u32(reg->value, 0, 32, value);
258
259 reg->dirty = true;
260 reg->valid = true;
261
262 return ERROR_OK;
263 }
264
265 /**
266 * mips32_set_all_fpr_width - Set the width of all floating-point registers
267 * @param[in] mips32: MIPS32 common structure
268 * @param[in] fp64: Flag indicating whether to set the width to 64 bits (double precision)
269 *
270 * @brief Sets the width of all floating-point registers based on the specified flag.
271 */
272 static void mips32_set_all_fpr_width(struct mips32_common *mips32, bool fp64)
273 {
274 struct reg_cache *cache = mips32->core_cache;
275 struct reg *reg_list = cache->reg_list;
276 int i;
277
278 for (i = MIPS32_REGLIST_FP_INDEX; i < (MIPS32_REGLIST_FP_INDEX + MIPS32_REG_FP_COUNT); i++) {
279 reg_list[i].size = fp64 ? 64 : 32;
280 reg_list[i].reg_data_type->type = fp64 ? REG_TYPE_IEEE_DOUBLE : REG_TYPE_IEEE_SINGLE;
281 }
282 }
283
284 /**
285 * mips32_detect_fpr_mode_change - Detect changes in floating-point register mode
286 * @param[in] mips32: MIPS32 common structure
287 * @param[in] cp0_status: Value of the CP0 status register
288 *
289 * @brief Detects changes in the floating-point register mode based on the CP0 status register.
290 * If changes are detected, it updates the internal state
291 * and logs a warning message indicating the mode change.
292 */
293 static void mips32_detect_fpr_mode_change(struct mips32_common *mips32, uint32_t cp0_status)
294 {
295 if (!mips32->fp_imp)
296 return;
297
298 /* CP0.Status.FR indicates the working mode of floating-point register.
299 * When FP = 0, fpr can contain any 32bit data type,
300 * 64bit data types are stored in even-odd register pairs.
301 * When FP = 1, fpr can contain any data types.*/
302 bool fpu_in_64bit = ((cp0_status & BIT(MIPS32_CP0_STATUS_FR_SHIFT)) != 0);
303
304 /* CP0.Status.CU1 indicated whether CoProcessor1(which is FPU) is present. */
305 bool fp_enabled = ((cp0_status & BIT(MIPS32_CP0_STATUS_CU1_SHIFT)) != 0);
306
307 if (mips32->fpu_in_64bit != fpu_in_64bit) {
308 mips32->fpu_in_64bit = fpu_in_64bit;
309 mips32_set_all_fpr_width(mips32, fpu_in_64bit);
310 LOG_WARNING("** FP mode changed to %sbit, you must reconnect GDB **", fpu_in_64bit ? "64" : "32");
311 }
312
313 if (mips32->fpu_enabled != fp_enabled) {
314 mips32->fpu_enabled = fp_enabled;
315 const char *s = fp_enabled ? "enabled" : "disabled";
316 LOG_WARNING("** FP is %s, register update %s **", s, s);
317 }
318 }
319
320 static int mips32_read_core_reg(struct target *target, unsigned int num)
321 {
322 unsigned int cnum;
323 uint64_t reg_value = 0;
324
325 /* get pointers to arch-specific information */
326 struct mips32_common *mips32 = target_to_mips32(target);
327
328 if (num >= MIPS32_NUM_REGS)
329 return ERROR_COMMAND_SYNTAX_ERROR;
330
331 if (num >= MIPS32_REGLIST_C0_INDEX) {
332 /* CP0 */
333 cnum = num - MIPS32_REGLIST_C0_INDEX;
334 reg_value = mips32->core_regs.cp0[cnum];
335 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
336 if (cnum == MIPS32_REG_C0_STATUS_INDEX)
337 mips32_detect_fpr_mode_change(mips32, reg_value);
338 } else if (num >= MIPS32_REGLIST_FPC_INDEX) {
339 /* FPCR */
340 cnum = num - MIPS32_REGLIST_FPC_INDEX;
341 reg_value = mips32->core_regs.fpcr[cnum];
342 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
343 } else if (num >= MIPS32_REGLIST_FP_INDEX) {
344 /* FPR */
345 cnum = num - MIPS32_REGLIST_FP_INDEX;
346 reg_value = mips32->core_regs.fpr[cnum];
347 buf_set_u64(mips32->core_cache->reg_list[num].value, 0, 64, reg_value);
348 } else {
349 /* GPR */
350 cnum = num - MIPS32_REGLIST_GP_INDEX;
351 reg_value = mips32->core_regs.gpr[cnum];
352 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
353 }
354
355 mips32->core_cache->reg_list[num].valid = true;
356 mips32->core_cache->reg_list[num].dirty = false;
357
358 LOG_DEBUG("read core reg %i value 0x%" PRIx64 "", num, reg_value);
359
360 return ERROR_OK;
361 }
362
363 static int mips32_write_core_reg(struct target *target, unsigned int num)
364 {
365 unsigned int cnum;
366 uint64_t reg_value;
367
368 /* get pointers to arch-specific information */
369 struct mips32_common *mips32 = target_to_mips32(target);
370
371 if (num >= MIPS32_NUM_REGS)
372 return ERROR_COMMAND_SYNTAX_ERROR;
373
374 if (num >= MIPS32_REGLIST_C0_INDEX) {
375 /* CP0 */
376 cnum = num - MIPS32_REGLIST_C0_INDEX;
377 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
378 mips32->core_regs.cp0[cnum] = (uint32_t)reg_value;
379 if (cnum == MIPS32_REG_C0_STATUS_INDEX)
380 mips32_detect_fpr_mode_change(mips32, reg_value);
381 } else if (num >= MIPS32_REGLIST_FPC_INDEX) {
382 /* FPCR */
383 cnum = num - MIPS32_REGLIST_FPC_INDEX;
384 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
385 mips32->core_regs.fpcr[cnum] = (uint32_t)reg_value;
386 } else if (num >= MIPS32_REGLIST_FP_INDEX) {
387 /* FPR */
388 cnum = num - MIPS32_REGLIST_FP_INDEX;
389 reg_value = buf_get_u64(mips32->core_cache->reg_list[num].value, 0, 64);
390 mips32->core_regs.fpr[cnum] = reg_value;
391 } else {
392 /* GPR */
393 cnum = num - MIPS32_REGLIST_GP_INDEX;
394 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
395 mips32->core_regs.gpr[cnum] = (uint32_t)reg_value;
396 }
397
398 LOG_DEBUG("write core reg %i value 0x%" PRIx64 "", num, reg_value);
399 mips32->core_cache->reg_list[num].valid = true;
400 mips32->core_cache->reg_list[num].dirty = false;
401
402 return ERROR_OK;
403 }
404
405 int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
406 int *reg_list_size, enum target_register_class reg_class)
407 {
408 /* get pointers to arch-specific information */
409 struct mips32_common *mips32 = target_to_mips32(target);
410 unsigned int i;
411
412 /* include floating point registers */
413 *reg_list_size = MIPS32_NUM_REGS;
414 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
415
416 for (i = 0; i < MIPS32_NUM_REGS; i++)
417 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
418
419 return ERROR_OK;
420 }
421
422 int mips32_save_context(struct target *target)
423 {
424 unsigned int i;
425
426 /* get pointers to arch-specific information */
427 struct mips32_common *mips32 = target_to_mips32(target);
428
429 /* read core registers */
430 int retval = mips32_pracc_read_regs(mips32);
431 if (retval != ERROR_OK) {
432 LOG_ERROR("Could not read core registers from target");
433 return retval;
434 }
435
436 for (i = 0; i < MIPS32_NUM_REGS; i++) {
437 if (!mips32->core_cache->reg_list[i].valid)
438 mips32->read_core_reg(target, i);
439 }
440
441 return ERROR_OK;
442 }
443
444 int mips32_restore_context(struct target *target)
445 {
446 unsigned int i;
447
448 /* get pointers to arch-specific information */
449 struct mips32_common *mips32 = target_to_mips32(target);
450
451 for (i = 0; i < MIPS32_NUM_REGS; i++) {
452 if (mips32->core_cache->reg_list[i].dirty)
453 mips32->write_core_reg(target, i);
454 }
455
456 /* write core regs */
457 return mips32_pracc_write_regs(mips32);
458 }
459
460 int mips32_arch_state(struct target *target)
461 {
462 struct mips32_common *mips32 = target_to_mips32(target);
463
464 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
465 mips_isa_strings[mips32->isa_mode],
466 debug_reason_name(target),
467 buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32));
468
469 return ERROR_OK;
470 }
471
472 static const struct reg_arch_type mips32_reg_type = {
473 .get = mips32_get_core_reg,
474 .set = mips32_set_core_reg,
475 };
476
477 struct reg_cache *mips32_build_reg_cache(struct target *target)
478 {
479 /* get pointers to arch-specific information */
480 struct mips32_common *mips32 = target_to_mips32(target);
481
482 int num_regs = MIPS32_NUM_REGS;
483 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
484 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
485 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
486 struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
487 struct reg_feature *feature;
488 int i;
489
490 /* Build the process context cache */
491 cache->name = "mips32 registers";
492 cache->next = NULL;
493 cache->reg_list = reg_list;
494 cache->num_regs = num_regs;
495 (*cache_p) = cache;
496 mips32->core_cache = cache;
497
498 for (i = 0; i < num_regs; i++) {
499 arch_info[i].num = mips32_regs[i].id;
500 arch_info[i].target = target;
501 arch_info[i].mips32_common = mips32;
502
503 reg_list[i].name = mips32_regs[i].name;
504 reg_list[i].size = mips32_regs[i].size ? 64 : 32;
505
506 reg_list[i].value = mips32_regs[i].size ? calloc(1, 8) : calloc(1, 4);
507 reg_list[i].valid = false;
508 reg_list[i].type = &mips32_reg_type;
509 reg_list[i].arch_info = &arch_info[i];
510
511 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
512 if (reg_list[i].reg_data_type)
513 reg_list[i].reg_data_type->type = mips32_regs[i].type;
514 else
515 LOG_ERROR("unable to allocate reg type list");
516
517
518 reg_list[i].dirty = false;
519
520 reg_list[i].group = mips32_regs[i].group;
521 reg_list[i].number = i;
522 reg_list[i].exist = true;
523 reg_list[i].caller_save = true; /* gdb defaults to true */
524
525 feature = calloc(1, sizeof(struct reg_feature));
526 if (feature) {
527 feature->name = mips32_regs[i].feature;
528 reg_list[i].feature = feature;
529 } else
530 LOG_ERROR("unable to allocate feature list");
531 }
532
533 return cache;
534 }
535
536 int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)
537 {
538 target->arch_info = mips32;
539 mips32->common_magic = MIPS32_COMMON_MAGIC;
540 mips32->fast_data_area = NULL;
541 mips32->isa_imp = MIPS32_ONLY; /* default */
542
543 /* has breakpoint/watchpoint unit been scanned */
544 mips32->bp_scanned = 0;
545 mips32->data_break_list = NULL;
546
547 mips32->ejtag_info.tap = tap;
548 mips32->read_core_reg = mips32_read_core_reg;
549 mips32->write_core_reg = mips32_write_core_reg;
550 /* if unknown endianness defaults to little endian, 1 */
551 mips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1;
552 mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE;
553 mips32->ejtag_info.mode = 0; /* Initial default value */
554 mips32->ejtag_info.isa = 0; /* isa on debug mips32, updated by poll function */
555 mips32->ejtag_info.config_regs = 0; /* no config register read */
556 return ERROR_OK;
557 }
558
559 /* run to exit point. return error if exit point was not reached. */
560 static int mips32_run_and_wait(struct target *target, target_addr_t entry_point,
561 unsigned int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32)
562 {
563 uint32_t pc;
564 int retval;
565 /* This code relies on the target specific resume() and poll()->debug_entry()
566 * sequence to write register values to the processor and the read them back */
567 retval = target_resume(target, 0, entry_point, 0, 1);
568 if (retval != ERROR_OK)
569 return retval;
570
571 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
572 /* If the target fails to halt due to the breakpoint, force a halt */
573 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
574 retval = target_halt(target);
575 if (retval != ERROR_OK)
576 return retval;
577 retval = target_wait_state(target, TARGET_HALTED, 500);
578 if (retval != ERROR_OK)
579 return retval;
580 return ERROR_TARGET_TIMEOUT;
581 }
582
583 pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32);
584 if (exit_point && (pc != exit_point)) {
585 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
586 return ERROR_TARGET_TIMEOUT;
587 }
588
589 return ERROR_OK;
590 }
591
592 int mips32_run_algorithm(struct target *target, int num_mem_params,
593 struct mem_param *mem_params, int num_reg_params,
594 struct reg_param *reg_params, target_addr_t entry_point,
595 target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
596 {
597 struct mips32_common *mips32 = target_to_mips32(target);
598 struct mips32_algorithm *mips32_algorithm_info = arch_info;
599 enum mips32_isa_mode isa_mode = mips32->isa_mode;
600
601 uint32_t context[MIPS32_NUM_REGS];
602 int retval = ERROR_OK;
603
604 LOG_DEBUG("Running algorithm");
605
606 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
607 * at the exit point */
608
609 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
610 LOG_ERROR("current target isn't a MIPS32 target");
611 return ERROR_TARGET_INVALID;
612 }
613
614 if (target->state != TARGET_HALTED) {
615 LOG_TARGET_ERROR(target, "not halted (run target algo)");
616 return ERROR_TARGET_NOT_HALTED;
617 }
618
619 /* refresh core register cache */
620 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
621 if (!mips32->core_cache->reg_list[i].valid)
622 mips32->read_core_reg(target, i);
623 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
624 }
625
626 for (int i = 0; i < num_mem_params; i++) {
627 if (mem_params[i].direction == PARAM_IN)
628 continue;
629 retval = target_write_buffer(target, mem_params[i].address,
630 mem_params[i].size, mem_params[i].value);
631 if (retval != ERROR_OK)
632 return retval;
633 }
634
635 for (int i = 0; i < num_reg_params; i++) {
636 if (reg_params[i].direction == PARAM_IN)
637 continue;
638
639 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);
640
641 if (!reg) {
642 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
643 return ERROR_COMMAND_SYNTAX_ERROR;
644 }
645
646 if (reg->size != reg_params[i].size) {
647 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
648 reg_params[i].reg_name);
649 return ERROR_COMMAND_SYNTAX_ERROR;
650 }
651
652 mips32_set_core_reg(reg, reg_params[i].value);
653 }
654
655 mips32->isa_mode = mips32_algorithm_info->isa_mode;
656
657 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
658
659 if (retval != ERROR_OK)
660 return retval;
661
662 for (int i = 0; i < num_mem_params; i++) {
663 if (mem_params[i].direction != PARAM_OUT) {
664 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
665 mem_params[i].value);
666 if (retval != ERROR_OK)
667 return retval;
668 }
669 }
670
671 for (int i = 0; i < num_reg_params; i++) {
672 if (reg_params[i].direction != PARAM_OUT) {
673 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);
674 if (!reg) {
675 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
676 return ERROR_COMMAND_SYNTAX_ERROR;
677 }
678
679 if (reg->size != reg_params[i].size) {
680 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
681 reg_params[i].reg_name);
682 return ERROR_COMMAND_SYNTAX_ERROR;
683 }
684
685 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
686 }
687 }
688
689 /* restore everything we saved before */
690 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
691 uint32_t regvalue;
692 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
693 if (regvalue != context[i]) {
694 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
695 mips32->core_cache->reg_list[i].name, context[i]);
696 buf_set_u32(mips32->core_cache->reg_list[i].value,
697 0, 32, context[i]);
698 mips32->core_cache->reg_list[i].valid = true;
699 mips32->core_cache->reg_list[i].dirty = true;
700 }
701 }
702
703 mips32->isa_mode = isa_mode;
704
705 return ERROR_OK;
706 }
707
708 int mips32_examine(struct target *target)
709 {
710 struct mips32_common *mips32 = target_to_mips32(target);
711
712 if (!target_was_examined(target)) {
713 target_set_examined(target);
714
715 /* we will configure later */
716 mips32->bp_scanned = 0;
717 mips32->num_inst_bpoints = 0;
718 mips32->num_data_bpoints = 0;
719 mips32->num_inst_bpoints_avail = 0;
720 mips32->num_data_bpoints_avail = 0;
721 }
722
723 return ERROR_OK;
724 }
725
726 static int mips32_configure_ibs(struct target *target)
727 {
728 struct mips32_common *mips32 = target_to_mips32(target);
729 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
730 int retval, i;
731 uint32_t bpinfo;
732
733 /* get number of inst breakpoints */
734 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
735 if (retval != ERROR_OK)
736 return retval;
737
738 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
739 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
740 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
741 sizeof(struct mips32_comparator));
742
743 for (i = 0; i < mips32->num_inst_bpoints; i++)
744 mips32->inst_break_list[i].reg_address =
745 ejtag_info->ejtag_iba0_addr +
746 (ejtag_info->ejtag_iba_step_size * i);
747
748 /* clear IBIS reg */
749 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
750 return retval;
751 }
752
753 static int mips32_configure_dbs(struct target *target)
754 {
755 struct mips32_common *mips32 = target_to_mips32(target);
756 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
757 int retval, i;
758 uint32_t bpinfo;
759
760 /* get number of data breakpoints */
761 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
762 if (retval != ERROR_OK)
763 return retval;
764
765 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
766 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
767 mips32->data_break_list = calloc(mips32->num_data_bpoints,
768 sizeof(struct mips32_comparator));
769
770 for (i = 0; i < mips32->num_data_bpoints; i++)
771 mips32->data_break_list[i].reg_address =
772 ejtag_info->ejtag_dba0_addr +
773 (ejtag_info->ejtag_dba_step_size * i);
774
775 /* clear DBIS reg */
776 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
777 return retval;
778 }
779
780 int mips32_configure_break_unit(struct target *target)
781 {
782 /* get pointers to arch-specific information */
783 struct mips32_common *mips32 = target_to_mips32(target);
784 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
785 int retval;
786 uint32_t dcr;
787
788 if (mips32->bp_scanned)
789 return ERROR_OK;
790
791 /* get info about breakpoint support */
792 retval = target_read_u32(target, EJTAG_DCR, &dcr);
793 if (retval != ERROR_OK)
794 return retval;
795
796 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
797 if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
798 ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;
799 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))
800 ejtag_info->debug_caps |= EJTAG_DCR_IB;
801 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))
802 ejtag_info->debug_caps |= EJTAG_DCR_DB;
803 } else
804 /* keep debug caps for later use */
805 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
806 | EJTAG_DCR_IB | EJTAG_DCR_DB);
807
808
809 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
810 retval = mips32_configure_ibs(target);
811 if (retval != ERROR_OK)
812 return retval;
813 }
814
815 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
816 retval = mips32_configure_dbs(target);
817 if (retval != ERROR_OK)
818 return retval;
819 }
820
821 /* check if target endianness settings matches debug control register */
822 if (((ejtag_info->debug_caps & EJTAG_DCR_ENM)
823 && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
824 (!(ejtag_info->debug_caps & EJTAG_DCR_ENM)
825 && (target->endianness == TARGET_BIG_ENDIAN)))
826 LOG_WARNING("DCR endianness settings does not match target settings");
827
828 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
829 mips32->num_data_bpoints);
830
831 mips32->bp_scanned = 1;
832
833 return ERROR_OK;
834 }
835
836 int mips32_enable_interrupts(struct target *target, int enable)
837 {
838 int retval;
839 int update = 0;
840 uint32_t dcr;
841
842 /* read debug control register */
843 retval = target_read_u32(target, EJTAG_DCR, &dcr);
844 if (retval != ERROR_OK)
845 return retval;
846
847 if (enable) {
848 if (!(dcr & EJTAG_DCR_INTE)) {
849 /* enable interrupts */
850 dcr |= EJTAG_DCR_INTE;
851 update = 1;
852 }
853 } else {
854 if (dcr & EJTAG_DCR_INTE) {
855 /* disable interrupts */
856 dcr &= ~EJTAG_DCR_INTE;
857 update = 1;
858 }
859 }
860
861 if (update) {
862 retval = target_write_u32(target, EJTAG_DCR, dcr);
863 if (retval != ERROR_OK)
864 return retval;
865 }
866
867 return ERROR_OK;
868 }
869
870 /* read processor identification cp0 register */
871 static int mips32_read_c0_prid(struct target *target)
872 {
873 struct mips32_common *mips32 = target_to_mips32(target);
874 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
875 int retval;
876
877 retval = mips32_cp0_read(ejtag_info, &mips32->prid, 15, 0);
878 if (retval != ERROR_OK) {
879 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
880 mips32->prid = 0;
881 }
882
883 return retval;
884 }
885
886 /**
887 * mips32_find_cpu_by_prid - Find CPU information by processor ID.
888 * @param[in] prid: Processor ID of the CPU.
889 *
890 * @brief This function looks up the CPU entry in the mips32_cpu_entry array based on the provided
891 * processor ID. It also handles special cases like AMD/Alchemy CPUs that use Company Options
892 * instead of Processor IDs.
893 *
894 * @return Pointer to the corresponding cpu_entry struct, or the 'unknown' entry if not found.
895 */
896 static const struct cpu_entry *mips32_find_cpu_by_prid(uint32_t prid)
897 {
898 /* AMD/Alchemy CPU uses Company Options instead of Processor ID.
899 * Therefore an extra transform step for prid to map it to an assigned ID,
900 */
901 if ((prid & PRID_COMP_MASK) == PRID_COMP_ALCHEMY) {
902 /* Clears Processor ID field, then put Company Option field to its place */
903 prid = (prid & 0xFFFF00FF) | ((prid & 0xFF000000) >> 16);
904 }
905
906 /* Mask out Company Option */
907 prid &= 0x00FFFFFF;
908
909 for (unsigned int i = 0; i < MIPS32_NUM_CPU_ENTRIES; i++) {
910 const struct cpu_entry *entry = &mips32_cpu_entry[i];
911 if ((entry->prid & MIPS32_CORE_MASK) <= prid && prid <= entry->prid)
912 return entry;
913 }
914
915 /* If nothing matched, then return unknown entry */
916 return &mips32_cpu_entry[MIPS32_NUM_CPU_ENTRIES - 1];
917 }
918
919 static bool mips32_cpu_is_lexra(struct mips_ejtag *ejtag_info)
920 {
921 return (ejtag_info->prid & PRID_COMP_MASK) == PRID_COMP_LEXRA;
922 }
923
924 static int mips32_cpu_get_release(struct mips_ejtag *ejtag_info)
925 {
926 return (ejtag_info->config[0] & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;
927 }
928
929 /**
930 * mips32_cpu_support_sync - Checks CPU supports ordering
931 * @param[in] ejtag_info: MIPS EJTAG information structure.
932 *
933 * @brief MIPS ISA implemented on Lexra CPUs is MIPS-I, similar to R3000,
934 * which does not have the SYNC instruction alone with unaligned
935 * load/store instructions.
936 *
937 * @returns true if current CPU supports sync instruction(CPU is not Lexra)
938 */
939 bool mips32_cpu_support_sync(struct mips_ejtag *ejtag_info)
940 {
941 return !mips32_cpu_is_lexra(ejtag_info);
942 }
943
944 /**
945 * mips32_cpu_support_hazard_barrier - Checks CPU supports hazard barrier
946 * @param[in] ejtag_info: MIPS EJTAG information structure.
947 *
948 * @brief hazard barrier instructions EHB and *.HB was introduced to MIPS from release 2.
949 *
950 * @returns true if current CPU supports hazard barrier(release > 1)
951 */
952 bool mips32_cpu_support_hazard_barrier(struct mips_ejtag *ejtag_info)
953 {
954 return mips32_cpu_get_release(ejtag_info) > MIPS32_RELEASE_1;
955 }
956
957 /**
958 * mips32_cpu_probe - Detects processor type and applies necessary quirks.
959 * @param[in] target: The target CPU to probe.
960 *
961 * @brief This function probes the CPU, reads its PRID (Processor ID), and determines the CPU type.
962 * It applies any quirks necessary for specific processor types.
963 *
964 * NOTE: The proper detection of certain CPUs can become quite complicated.
965 * Please consult the following Linux kernel code when adding new CPUs:
966 * arch/mips/include/asm/cpu.h
967 * arch/mips/kernel/cpu-probe.c
968 *
969 * @return ERROR_OK on success; error code on failure.
970 */
971 int mips32_cpu_probe(struct target *target)
972 {
973 struct mips32_common *mips32 = target_to_mips32(target);
974 int retval;
975
976 if (mips32->prid)
977 return ERROR_OK; /* Already probed once, return early. */
978
979 retval = mips32_read_c0_prid(target);
980 if (retval != ERROR_OK)
981 return retval;
982
983 const struct cpu_entry *entry = mips32_find_cpu_by_prid(mips32->prid);
984
985 switch (mips32->prid & PRID_COMP_MASK) {
986 case PRID_COMP_INGENIC_E1:
987 switch (mips32->prid & PRID_IMP_MASK) {
988 case PRID_IMP_XBURST_REV1:
989 mips32->cpu_quirks |= EJTAG_QUIRK_PAD_DRET;
990 break;
991 default:
992 break;
993 }
994 break;
995
996 /* Determine which CP0 registers are available in the current processor core */
997 case PRID_COMP_MTI:
998 switch (entry->prid & PRID_IMP_MASK) {
999 case PRID_IMP_MAPTIV_UC:
1000 mips32->cp0_mask = MIPS_CP0_MAPTIV_UC;
1001 break;
1002 case PRID_IMP_MAPTIV_UP:
1003 case PRID_IMP_M5150:
1004 mips32->cp0_mask = MIPS_CP0_MAPTIV_UP;
1005 break;
1006 case PRID_IMP_IAPTIV:
1007 case PRID_IMP_IAPTIV_CM:
1008 mips32->cp0_mask = MIPS_CP0_IAPTIV;
1009 break;
1010 default:
1011 /* CP0 mask should be the same as MK4 by default */
1012 mips32->cp0_mask = MIPS_CP0_MK4;
1013 break;
1014 }
1015
1016 default:
1017 break;
1018 }
1019
1020 mips32->cpu_info = entry;
1021 LOG_DEBUG("CPU: %s (PRId %08x)", entry->cpu_name, mips32->prid);
1022
1023 return ERROR_OK;
1024 }
1025
1026 /* reads dsp implementation info from CP0 Config3 register {DSPP, DSPREV}*/
1027 static void mips32_read_config_dsp(struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
1028 {
1029 uint32_t dsp_present = ((ejtag_info->config[3] & MIPS32_CONFIG3_DSPP_MASK) >> MIPS32_CONFIG3_DSPP_SHIFT);
1030 if (dsp_present) {
1031 mips32->dsp_imp = ((ejtag_info->config[3] & MIPS32_CONFIG3_DSPREV_MASK) >> MIPS32_CONFIG3_DSPREV_SHIFT) + 1;
1032 LOG_USER("DSP implemented: %s, rev %d", "yes", mips32->dsp_imp);
1033 } else {
1034 LOG_USER("DSP implemented: %s", "no");
1035 }
1036 }
1037
1038 /* read fpu implementation info from CP0 Config1 register {CU1, FP}*/
1039 static int mips32_read_config_fpu(struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
1040 {
1041 int retval;
1042 uint32_t fp_imp = (ejtag_info->config[1] & MIPS32_CONFIG1_FP_MASK) >> MIPS32_CONFIG1_FP_SHIFT;
1043 char buf[60] = {0};
1044 if (!fp_imp) {
1045 LOG_USER("FPU implemented: %s", "no");
1046 mips32->fp_imp = MIPS32_FP_IMP_NONE;
1047 return ERROR_OK;
1048 }
1049 uint32_t fir_value, status_value;
1050 bool fpu_in_64bit, fp_enabled;
1051
1052 retval = mips32_cp0_read(ejtag_info, &status_value, MIPS32_C0_STATUS, 0);
1053 if (retval != ERROR_OK) {
1054 LOG_ERROR("Failed to read cp0 status register");
1055 return retval;
1056 }
1057
1058 fpu_in_64bit = (status_value & BIT(MIPS32_CP0_STATUS_FR_SHIFT)) != 0;
1059 fp_enabled = (status_value & BIT(MIPS32_CP0_STATUS_CU1_SHIFT)) != 0;
1060 if (fp_enabled) {
1061 retval = mips32_cp1_control_read(ejtag_info, &fir_value, 0);
1062 if (retval != ERROR_OK) {
1063 LOG_ERROR("Failed to read cp1 FIR register");
1064 return retval;
1065 }
1066
1067 if ((fir_value >> MIPS32_CP1_FIR_F64_SHIFT) & 0x1)
1068 fp_imp++;
1069 } else {
1070 /* This is the only condition that writes to buf */
1071 snprintf(buf, sizeof(buf), "yes, disabled");
1072 fp_imp = MIPS32_FP_IMP_UNKNOWN;
1073 }
1074
1075 mips32->fpu_in_64bit = fpu_in_64bit;
1076 mips32->fpu_enabled = fp_enabled;
1077
1078 mips32_set_all_fpr_width(mips32, fpu_in_64bit);
1079
1080 /* If fpu is not disabled, print out more information */
1081 if (!buf[0])
1082 snprintf(buf, sizeof(buf), "yes, %sbit (%s, working in %sbit)",
1083 fp_imp == MIPS32_FP_IMP_64 ? "64" : "32",
1084 fp_enabled ? "enabled" : "disabled",
1085 fpu_in_64bit ? "64" : "32");
1086
1087 LOG_USER("FPU implemented: %s", buf);
1088 mips32->fp_imp = fp_imp;
1089
1090 return ERROR_OK;
1091 }
1092
1093 /**
1094 * mips32_read_config_fdc - Read Fast Debug Channel configuration
1095 * @param[in,out] mips32: MIPS32 common structure
1096 * @param[in] ejtag_info: EJTAG information structure
1097 * @param[in] dcr: Device Configuration Register value
1098 *
1099 * @brief Checks if the current target implements the Common Device Memory Map (CDMM) and Fast Debug Channel (FDC).
1100 *
1101 * This function examines the configuration registers and the Device Configuration Register (DCR) to determine
1102 * if the current MIPS32 target supports the Common Device Memory Map (CDMM) and the Fast Debug Channel (FDC).
1103 * If supported, it sets the corresponding flags in the MIPS32 common structure. \n
1104 *
1105 * NOTE:These are defined on MD00090, page 67 and MD00047F, page 82, respectively.
1106 * MIPS Documents are pretty much all available online,
1107 * it should pop up first when you search "MDxxxxx"
1108 */
1109 static void mips32_read_config_fdc(struct mips32_common *mips32, struct mips_ejtag *ejtag_info, uint32_t dcr)
1110 {
1111 if (((ejtag_info->config[3] & MIPS32_CONFIG3_CDMM_MASK) != 0) && ((dcr & EJTAG_DCR_FDC) != 0)) {
1112 mips32->fdc = 1;
1113 mips32->semihosting = 1;
1114 } else {
1115 mips32->fdc = 0;
1116 mips32->semihosting = 0;
1117 }
1118 }
1119
1120 /* read config to config3 cp0 registers and log isa implementation */
1121 int mips32_read_config_regs(struct target *target)
1122 {
1123 struct mips32_common *mips32 = target_to_mips32(target);
1124 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1125 char buf[60] = {0};
1126 int retval;
1127
1128 if (ejtag_info->config_regs == 0)
1129 for (int i = 0; i != 4; i++) {
1130 retval = mips32_cp0_read(ejtag_info, &ejtag_info->config[i], 16, i);
1131 if (retval != ERROR_OK) {
1132 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32, i);
1133 ejtag_info->config_regs = 0;
1134 return retval;
1135 }
1136 ejtag_info->config_regs = i + 1;
1137 if ((ejtag_info->config[i] & (1 << 31)) == 0)
1138 break; /* no more config registers implemented */
1139 }
1140 else
1141 return ERROR_OK; /* already successfully read */
1142
1143 LOG_DEBUG("read %"PRIu32" config registers", ejtag_info->config_regs);
1144
1145 mips32->isa_rel = (ejtag_info->config[0] & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;
1146 snprintf(buf, sizeof(buf), ", release %s(AR=%d)",
1147 mips32->isa_rel == MIPS32_RELEASE_1 ? "1"
1148 : mips32->isa_rel == MIPS32_RELEASE_2 ? "2"
1149 : mips32->isa_rel == MIPS32_RELEASE_6 ? "6"
1150 : "unknown", mips32->isa_rel);
1151
1152 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
1153 mips32->isa_imp = MIPS32_MIPS16;
1154 LOG_USER("ISA implemented: %s%s", "MIPS32, MIPS16", buf);
1155 } else if (ejtag_info->config_regs >= 4) { /* config3 implemented */
1156 unsigned isa_imp = (ejtag_info->config[3] & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT;
1157 if (isa_imp == 1) {
1158 mips32->isa_imp = MMIPS32_ONLY;
1159 LOG_USER("ISA implemented: %s%s", "microMIPS32", buf);
1160
1161 } else if (isa_imp != 0) {
1162 mips32->isa_imp = MIPS32_MMIPS32;
1163 LOG_USER("ISA implemented: %s%s", "MIPS32, microMIPS32", buf);
1164 }
1165 } else if (mips32->isa_imp == MIPS32_ONLY) {
1166 /* initial default value */
1167 LOG_USER("ISA implemented: %s%s", "MIPS32", buf);
1168 }
1169
1170 /* Retrieve DSP info */
1171 mips32_read_config_dsp(mips32, ejtag_info);
1172
1173 /* Retrieve if Float Point CoProcessor Implemented */
1174 retval = mips32_read_config_fpu(mips32, ejtag_info);
1175 if (retval != ERROR_OK) {
1176 LOG_ERROR("fpu info is not available, error while reading cp0 status");
1177 mips32->fp_imp = MIPS32_FP_IMP_NONE;
1178 return retval;
1179 }
1180
1181 uint32_t dcr;
1182
1183 retval = target_read_u32(target, EJTAG_DCR, &dcr);
1184 if (retval != ERROR_OK) {
1185 LOG_ERROR("failed to read EJTAG_DCR register");
1186 return retval;
1187 }
1188
1189 /* Determine if FDC and CDMM are implemented for this core */
1190 mips32_read_config_fdc(mips32, ejtag_info, dcr);
1191
1192 return ERROR_OK;
1193 }
1194
1195 int mips32_checksum_memory(struct target *target, target_addr_t address,
1196 uint32_t count, uint32_t *checksum)
1197 {
1198 struct working_area *crc_algorithm;
1199 struct reg_param reg_params[2];
1200 struct mips32_algorithm mips32_info;
1201
1202 struct mips32_common *mips32 = target_to_mips32(target);
1203 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1204
1205 /* see contrib/loaders/checksum/mips32.s for src */
1206 uint32_t isa = ejtag_info->isa ? 1 : 0;
1207
1208 uint32_t mips_crc_code[] = {
1209 MIPS32_ADDIU(isa, 12, 4, 0), /* addiu $t4, $a0, 0 */
1210 MIPS32_ADDIU(isa, 10, 5, 0), /* addiu $t2, $a1, 0 */
1211 MIPS32_ADDIU(isa, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
1212 MIPS32_BEQ(isa, 0, 0, 0x10 << isa), /* beq $zero, $zero, ncomp */
1213 MIPS32_ADDIU(isa, 11, 0, 0), /* addiu $t3, $zero, 0 */
1214 /* nbyte: */
1215 MIPS32_LB(isa, 5, 0, 12), /* lb $a1, ($t4) */
1216 MIPS32_ADDI(isa, 12, 12, 1), /* addi $t4, $t4, 1 */
1217 MIPS32_SLL(isa, 5, 5, 24), /* sll $a1, $a1, 24 */
1218 MIPS32_LUI(isa, 2, 0x04c1), /* lui $v0, 0x04c1 */
1219 MIPS32_XOR(isa, 4, 4, 5), /* xor $a0, $a0, $a1 */
1220 MIPS32_ORI(isa, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
1221 MIPS32_ADDU(isa, 6, 0, 0), /* addu $a2, $zero, $zero */
1222 /* loop */
1223 MIPS32_SLL(isa, 8, 4, 1), /* sll $t0, $a0, 1 */
1224 MIPS32_ADDIU(isa, 6, 6, 1), /* addiu $a2, $a2, 1 */
1225 MIPS32_SLTI(isa, 4, 4, 0), /* slti $a0, $a0, 0 */
1226 MIPS32_XOR(isa, 9, 8, 7), /* xor $t1, $t0, $a3 */
1227 MIPS32_MOVN(isa, 8, 9, 4), /* movn $t0, $t1, $a0 */
1228 MIPS32_SLTI(isa, 3, 6, 8), /* slti $v1, $a2, 8 */
1229 MIPS32_BNE(isa, 3, 0, NEG16(7 << isa)), /* bne $v1, $zero, loop */
1230 MIPS32_ADDU(isa, 4, 8, 0), /* addu $a0, $t0, $zero */
1231 /* ncomp */
1232 MIPS32_BNE(isa, 10, 11, NEG16(16 << isa)), /* bne $t2, $t3, nbyte */
1233 MIPS32_ADDIU(isa, 11, 11, 1), /* addiu $t3, $t3, 1 */
1234 MIPS32_SDBBP(isa),
1235 };
1236
1237 /* make sure we have a working area */
1238 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
1239 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1240
1241 pracc_swap16_array(ejtag_info, mips_crc_code, ARRAY_SIZE(mips_crc_code));
1242
1243 /* convert mips crc code into a buffer in target endianness */
1244 uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
1245 target_buffer_set_u32_array(target, mips_crc_code_8,
1246 ARRAY_SIZE(mips_crc_code), mips_crc_code);
1247
1248 int retval = target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
1249 if (retval != ERROR_OK)
1250 return retval;
1251
1252 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
1253 mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32; /* run isa as in debug mode */
1254
1255 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
1256 buf_set_u32(reg_params[0].value, 0, 32, address);
1257
1258 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
1259 buf_set_u32(reg_params[1].value, 0, 32, count);
1260
1261 unsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));
1262
1263 retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
1264 crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout, &mips32_info);
1265
1266 if (retval == ERROR_OK)
1267 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
1268
1269 destroy_reg_param(&reg_params[0]);
1270 destroy_reg_param(&reg_params[1]);
1271
1272 target_free_working_area(target, crc_algorithm);
1273
1274 return retval;
1275 }
1276
1277 /** Checks whether a memory region is erased. */
1278 int mips32_blank_check_memory(struct target *target,
1279 struct target_memory_check_block *blocks, int num_blocks,
1280 uint8_t erased_value)
1281 {
1282 struct working_area *erase_check_algorithm;
1283 struct reg_param reg_params[3];
1284 struct mips32_algorithm mips32_info;
1285
1286 struct mips32_common *mips32 = target_to_mips32(target);
1287 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1288
1289 if (erased_value != 0xff) {
1290 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for MIPS32",
1291 erased_value);
1292 return ERROR_FAIL;
1293 }
1294 uint32_t isa = ejtag_info->isa ? 1 : 0;
1295 uint32_t erase_check_code[] = {
1296 /* nbyte: */
1297 MIPS32_LB(isa, 8, 0, 4), /* lb $t0, ($a0) */
1298 MIPS32_AND(isa, 6, 6, 8), /* and $a2, $a2, $t0 */
1299 MIPS32_ADDIU(isa, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
1300 MIPS32_BNE(isa, 5, 0, NEG16(4 << isa)), /* bne $a1, $zero, nbyte */
1301 MIPS32_ADDIU(isa, 4, 4, 1), /* addiu $a0, $a0, 1 */
1302 MIPS32_SDBBP(isa) /* sdbbp */
1303 };
1304
1305 /* make sure we have a working area */
1306 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
1307 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1308
1309 pracc_swap16_array(ejtag_info, erase_check_code, ARRAY_SIZE(erase_check_code));
1310
1311 /* convert erase check code into a buffer in target endianness */
1312 uint8_t erase_check_code_8[sizeof(erase_check_code)];
1313 target_buffer_set_u32_array(target, erase_check_code_8,
1314 ARRAY_SIZE(erase_check_code), erase_check_code);
1315
1316 int retval = target_write_buffer(target, erase_check_algorithm->address,
1317 sizeof(erase_check_code), erase_check_code_8);
1318 if (retval != ERROR_OK)
1319 goto cleanup;
1320
1321 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
1322 mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;
1323
1324 init_reg_param(&reg_params[0], "r4", 32, PARAM_OUT);
1325 buf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);
1326
1327 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
1328 buf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);
1329
1330 init_reg_param(&reg_params[2], "r6", 32, PARAM_IN_OUT);
1331 buf_set_u32(reg_params[2].value, 0, 32, erased_value);
1332
1333 retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
1334 erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);
1335
1336 if (retval == ERROR_OK)
1337 blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
1338
1339 destroy_reg_param(&reg_params[0]);
1340 destroy_reg_param(&reg_params[1]);
1341 destroy_reg_param(&reg_params[2]);
1342
1343 cleanup:
1344 target_free_working_area(target, erase_check_algorithm);
1345
1346 if (retval != ERROR_OK)
1347 return retval;
1348
1349 return 1; /* only one block has been checked */
1350 }
1351
1352 static int mips32_verify_pointer(struct command_invocation *cmd,
1353 struct mips32_common *mips32)
1354 {
1355 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
1356 command_print(cmd, "target is not an MIPS32");
1357 return ERROR_TARGET_INVALID;
1358 }
1359 return ERROR_OK;
1360 }
1361
1362 /**
1363 * mips32_read_config_mmu - Reads MMU configuration and logs relevant information.
1364 * @param[in] ejtag_info: EJTAG interface information.
1365 *
1366 * @brief Reads the MMU configuration from the CP0 register and calculates the number of TLB entries,
1367 * ways, and sets. Handles different MMU types like VTLB only, root RPU/Fixed, and VTLB and FTLB.
1368 *
1369 * @return ERROR_OK on success; error code on failure.
1370 */
1371 static int mips32_read_config_mmu(struct mips_ejtag *ejtag_info)
1372 {
1373 uint32_t config4, tlb_entries = 0, ways = 0, sets = 0;
1374 uint32_t config0 = ejtag_info->config[0];
1375 uint32_t config1 = ejtag_info->config[1];
1376 uint32_t config3 = ejtag_info->config[3];
1377 uint32_t mmu_type = (config0 >> 7) & 7;
1378 uint32_t vz_present = (config3 & BIT(23));
1379
1380 int retval = mips32_cp0_read(ejtag_info, &config4, 16, 4);
1381 if (retval != ERROR_OK)
1382 return retval;
1383
1384 /* mmu type = 1: VTLB only (Note: Does not account for Config4.ExtVTLB)
1385 * mmu type = 3: root RPU/Fixed (Note: Only valid with VZ ASE)
1386 * mmu type = 4: VTLB and FTLB
1387 */
1388 if ((mmu_type == 1 || mmu_type == 4) || (mmu_type == 3 && vz_present)) {
1389 tlb_entries = (uint32_t)(((config1 >> 25) & 0x3f) + 1);
1390 if (mmu_type == 4) {
1391 /* Release 6 definition for Config4[0:15] (MD01251, page 243) */
1392 /* The FTLB ways field is defined as [2, 3, 4, 5, 6, 7, 8, ...0 (reserved)] */
1393 int index = ((config4 >> 4) & 0xf);
1394 ways = index > 6 ? 0 : index + 2;
1395
1396 /* The FTLB sets field is defined as [1, 2, 4, 8, ..., 16384, 32768] (powers of 2) */
1397 index = (config4 & 0xf);
1398 sets = 1 << index;
1399 tlb_entries = tlb_entries + (ways * sets);
1400 }
1401 }
1402 LOG_USER("TLB Entries: %d (%d ways, %d sets per way)", tlb_entries, ways, sets);
1403
1404 return ERROR_OK;
1405 }
1406
1407 /**
1408 * mips32_cp0_find_register_by_name - Find CP0 register by its name.
1409 * @param[in] cp0_mask: Mask to filter out irrelevant registers.
1410 * @param[in] reg_name: Name of the register to find.
1411 *
1412 * @brief This function iterates through mips32_cp0_regs to find a register
1413 * matching reg_name, considering cp0_mask to filter out registers
1414 * not relevant for the current core.
1415 *
1416 * @return Pointer to the found register, or NULL if not found.
1417 */
1418 static const struct mips32_cp0 *mips32_cp0_find_register_by_name(uint32_t cp0_mask, const char *reg_name)
1419 {
1420 if (reg_name)
1421 for (unsigned int i = 0; i < MIPS32NUMCP0REGS; i++) {
1422 if ((mips32_cp0_regs[i].core & cp0_mask) == 0)
1423 continue;
1424
1425 if (strcmp(mips32_cp0_regs[i].name, reg_name) == 0)
1426 return &mips32_cp0_regs[i];
1427 }
1428 return NULL;
1429 }
1430
1431 /**
1432 * mips32_cp0_get_all_regs - Print all CP0 registers and their values.
1433 * @param[in] cmd: Command invocation context.
1434 * @param[in] ejtag_info: EJTAG interface information.
1435 * @param[in] cp0_mask: Mask to identify relevant registers.
1436 *
1437 * @brief Iterates over all CP0 registers, reads their values, and prints them.
1438 * Only considers registers relevant to the current core, as defined by cp0_mask.
1439 *
1440 * @return ERROR_OK on success; error code on failure.
1441 */
1442 static int mips32_cp0_get_all_regs(struct command_invocation *cmd, struct mips_ejtag *ejtag_info, uint32_t cp0_mask)
1443 {
1444 uint32_t value;
1445
1446 for (unsigned int i = 0; i < MIPS32NUMCP0REGS; i++) {
1447 /* Register name not valid for this core */
1448 if ((mips32_cp0_regs[i].core & cp0_mask) == 0)
1449 continue;
1450
1451 int retval = mips32_cp0_read(ejtag_info, &value, mips32_cp0_regs[i].reg, mips32_cp0_regs[i].sel);
1452 if (retval != ERROR_OK) {
1453 command_print(CMD, "Error: couldn't access reg %s", mips32_cp0_regs[i].name);
1454 return retval;
1455 }
1456
1457 command_print(CMD, "%*s: 0x%8.8" PRIx32, 14, mips32_cp0_regs[i].name, value);
1458 }
1459 return ERROR_OK;
1460 }
1461
1462 /**
1463 * mips32_cp0_get_reg_by_name - Read and print a CP0 register's value by name.
1464 * @param[in] cmd: Command invocation context.
1465 * @param[in] ejtag_info: EJTAG interface information.
1466 * @param[in] cp0_mask: Mask to identify relevant registers.
1467 *
1468 * @brief Finds a CP0 register by name, reads its value, and prints it.
1469 * Handles error scenarios like register not found or read failure.
1470 *
1471 * @return ERROR_OK on success; error code on failure.
1472 */
1473 static int mips32_cp0_get_reg_by_name(struct command_invocation *cmd, struct mips_ejtag *ejtag_info, uint32_t cp0_mask)
1474 {
1475 const struct mips32_cp0 *cp0_regs = mips32_cp0_find_register_by_name(cp0_mask, CMD_ARGV[0]);
1476 if (!cp0_regs) {
1477 command_print(CMD, "Error: Register '%s' not found", CMD_ARGV[0]);
1478 return ERROR_COMMAND_ARGUMENT_INVALID;
1479 }
1480
1481 uint32_t value;
1482 int retval = mips32_cp0_read(ejtag_info, &value, cp0_regs->reg, cp0_regs->sel);
1483 if (retval != ERROR_OK) {
1484 command_print(CMD, "Error: Encounter an Error while reading cp0 reg %d sel %d",
1485 cp0_regs->reg, cp0_regs->sel);
1486 return retval;
1487 }
1488
1489 command_print(CMD, "0x%8.8" PRIx32, value);
1490 return ERROR_OK;
1491 }
1492
1493 /**
1494 * mips32_cp0_get_reg_by_number - Read and print a CP0 register's value by number.
1495 * @param[in] cmd: Command invocation context.
1496 * @param[in] ejtag_info: EJTAG interface information.
1497 *
1498 * @brief Reads a specific CP0 register (identified by number and selection) and prints its value.
1499 * The register number and selection are parsed from the command arguments.
1500 *
1501 * @return ERROR_OK on success; error code on failure.
1502 */
1503 static int mips32_cp0_get_reg_by_number(struct command_invocation *cmd, struct mips_ejtag *ejtag_info)
1504 {
1505 uint32_t cp0_reg, cp0_sel, value;
1506 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
1507 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
1508
1509 int retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
1510 if (retval != ERROR_OK) {
1511 command_print(CMD,
1512 "Error: couldn't access reg %" PRIu32,
1513 cp0_reg);
1514 return retval;
1515 }
1516
1517 command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
1518 cp0_reg, cp0_sel, value);
1519 return ERROR_OK;
1520 }
1521
1522 /**
1523 * mips32_cp0_set_reg_by_name - Write to a CP0 register identified by name.
1524 * @param[in] cmd: Command invocation context.
1525 * @param[in] mips32: Common MIPS32 data structure.
1526 * @param[in] ejtag_info: EJTAG interface information.
1527 *
1528 * @brief Writes a value to a CP0 register specified by name. Updates internal
1529 * cache if specific registers (STATUS, CAUSE, DEPC, GUESTCTL1) are modified.
1530 *
1531 * @return ERROR_OK on success; error code on failure.
1532 */
1533 static int mips32_cp0_set_reg_by_name(struct command_invocation *cmd,
1534 struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
1535 {
1536 const struct mips32_cp0 *cp0_regs = mips32_cp0_find_register_by_name(mips32->cp0_mask, CMD_ARGV[0]);
1537 if (!cp0_regs) {
1538 command_print(CMD, "Error: Register '%s' not found", CMD_ARGV[0]);
1539 return ERROR_COMMAND_ARGUMENT_INVALID;
1540 }
1541
1542
1543 uint32_t value;
1544 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1545
1546 if (cp0_regs->reg == MIPS32_C0_STATUS && cp0_regs->sel == 0) {
1547 /* Update cached Status register if user is writing to Status */
1548 mips32->core_regs.cp0[MIPS32_REG_C0_STATUS_INDEX] = value;
1549 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_STATUS_INDEX].dirty = 1;
1550 } else if (cp0_regs->reg == MIPS32_C0_CAUSE && cp0_regs->sel == 0) {
1551 /* Update register cache with new value if its Cause */
1552 mips32->core_regs.cp0[MIPS32_REG_C0_CAUSE_INDEX] = value;
1553 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_CAUSE_INDEX].dirty = 1;
1554 } else if (cp0_regs->reg == MIPS32_C0_DEPC && cp0_regs->sel == 0) {
1555 /* Update cached PC if its DEPC */
1556 mips32->core_regs.cp0[MIPS32_REG_C0_PC_INDEX] = value;
1557 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = 1;
1558 } else if (cp0_regs->reg == MIPS32_C0_GUESTCTL1 && cp0_regs->sel == 4) {
1559 /* Update cached guestCtl1 */
1560 mips32->core_regs.cp0[MIPS32_REG_C0_GUESTCTL1_INDEX] = value;
1561 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_GUESTCTL1_INDEX].dirty = 1;
1562 }
1563
1564 int retval = mips32_cp0_write(ejtag_info, value,
1565 cp0_regs->reg,
1566 cp0_regs->sel);
1567 if (retval != ERROR_OK) {
1568 command_print(CMD, "Error: Encounter an Error while writing to cp0 reg %d, sel %d",
1569 cp0_regs->reg, cp0_regs->sel);
1570 return retval;
1571 }
1572
1573 command_print(CMD, "cp0 reg %s (%u, select %u: %8.8" PRIx32 ")",
1574 CMD_ARGV[0], cp0_regs->reg, cp0_regs->sel, value);
1575 return ERROR_OK;
1576 }
1577
1578 /**
1579 * mips32_cp0_set_reg_by_number - Write to a CP0 register identified by number.
1580 * @param[in] cmd: Command invocation context.
1581 * @param[in] mips32: Common MIPS32 data structure.
1582 * @param[in] ejtag_info: EJTAG interface information.
1583 *
1584 * @brief Writes a value to a CP0 register specified by number and selection.
1585 * Handles special cases like updating the internal cache for certain registers.
1586 *
1587 * @return ERROR_OK on success; error code on failure.
1588 */
1589 static int mips32_cp0_set_reg_by_number(struct command_invocation *cmd,
1590 struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
1591 {
1592 uint32_t cp0_reg, cp0_sel, value;
1593 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
1594 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
1595 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1596
1597 if (cp0_reg == MIPS32_C0_STATUS && cp0_sel == 0) {
1598 /* Update cached status register if user is writing to Status register */
1599 mips32->core_regs.cp0[MIPS32_REG_C0_STATUS_INDEX] = value;
1600 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_STATUS_INDEX].dirty = 1;
1601 } else if (cp0_reg == MIPS32_C0_CAUSE && cp0_sel == 0) {
1602 /* Update register cache with new value if its Cause register */
1603 mips32->core_regs.cp0[MIPS32_REG_C0_CAUSE_INDEX] = value;
1604 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_CAUSE_INDEX].dirty = 1;
1605 } else if (cp0_reg == MIPS32_C0_DEPC && cp0_sel == 0) {
1606 /* Update cached PC if its DEPC */
1607 mips32->core_regs.cp0[MIPS32_REG_C0_PC_INDEX] = value;
1608 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = 1;
1609 } else if (cp0_reg == MIPS32_C0_GUESTCTL1 && cp0_sel == 4) {
1610 /* Update cached guestCtl1, too */
1611 mips32->core_regs.cp0[MIPS32_REG_C0_GUESTCTL1_INDEX] = value;
1612 mips32->core_cache->reg_list[MIPS32_REGLIST_C0_GUESTCTL1_INDEX].dirty = 1;
1613 }
1614
1615 int retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
1616 if (retval != ERROR_OK) {
1617 command_print(CMD,
1618 "Error: couldn't access cp0 reg %" PRIu32 ", select %" PRIu32,
1619 cp0_reg, cp0_sel);
1620 return retval;
1621 }
1622
1623 command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
1624 cp0_reg, cp0_sel, value);
1625 return ERROR_OK;
1626 }
1627
1628 /**
1629 * mips32_handle_cp0_command - Handle commands related to CP0 registers.
1630 * @cmd: Command invocation context.
1631 *
1632 * Orchestrates different operations on CP0 registers based on the command arguments.
1633 * Supports operations like reading all registers, reading/writing a specific register
1634 * by name or number.
1635 *
1636 * Return: ERROR_OK on success; error code on failure.
1637 */
1638 COMMAND_HANDLER(mips32_handle_cp0_command)
1639 {
1640 int retval, tmp;
1641 struct target *target = get_current_target(CMD_CTX);
1642 struct mips32_common *mips32 = target_to_mips32(target);
1643 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1644
1645
1646 retval = mips32_verify_pointer(CMD, mips32);
1647 if (retval != ERROR_OK)
1648 return retval;
1649
1650 if (target->state != TARGET_HALTED) {
1651 command_print(CMD, "Error: target must be stopped for \"%s\" command", CMD_NAME);
1652 return ERROR_TARGET_NOT_HALTED;
1653 }
1654
1655 switch (CMD_ARGC) {
1656 case 0: /* No arg => print out all cp0 regs */
1657 retval = mips32_cp0_get_all_regs(CMD, ejtag_info, mips32->cp0_mask);
1658 break;
1659 case 1: /* 1 arg => get cp0 #reg/#sel value by name */
1660 retval = mips32_cp0_get_reg_by_name(CMD, ejtag_info, mips32->cp0_mask);
1661 break;
1662 case 2: /* 2 args => get cp0 reg/sel value or set value by name */
1663 tmp = *CMD_ARGV[0];
1664 if (isdigit(tmp)) /* starts from number then args are #reg and #sel */
1665 retval = mips32_cp0_get_reg_by_number(CMD, ejtag_info);
1666 else /* or set value by register name */
1667 retval = mips32_cp0_set_reg_by_name(CMD, mips32, ejtag_info);
1668
1669 break;
1670 case 3: /* 3 args => set cp0 reg/sel value*/
1671 retval = mips32_cp0_set_reg_by_number(CMD, mips32, ejtag_info);
1672 break;
1673 default: /* Other argc => err */
1674 retval = ERROR_COMMAND_SYNTAX_ERROR;
1675 break;
1676 }
1677
1678 return retval;
1679 }
1680
1681 /**
1682 * mips32_dsp_enable - Enable access to DSP registers
1683 * @param[in] ctx: Context information for the pracc queue
1684 * @param[in] isa: Instruction Set Architecture identifier
1685 *
1686 * @brief Enables access to DSP registers by modifying the status register.
1687 *
1688 * This function adds instructions to the context queue for enabling
1689 * access to DSP registers by modifying the status register.
1690 */
1691 static void mips32_dsp_enable(struct pracc_queue_info *ctx, int isa)
1692 {
1693 /* Save Status Register */
1694 /* move status to $9 (t1) 2*/
1695 pracc_add(ctx, 0, MIPS32_MFC0(isa, 9, 12, 0));
1696
1697 /* Read it again in order to modify it */
1698 /* move status to $0 (t0) 3*/
1699 pracc_add(ctx, 0, MIPS32_MFC0(isa, 8, 12, 0));
1700
1701 /* Enable access to DSP registers by setting MX bit in status register */
1702 /* $15 = MIPS32_PRACC_STACK 4/5/6*/
1703 pracc_add(ctx, 0, MIPS32_LUI(isa, 15, UPPER16(MIPS32_DSP_ENABLE)));
1704 pracc_add(ctx, 0, MIPS32_ORI(isa, 15, 15, LOWER16(MIPS32_DSP_ENABLE)));
1705 pracc_add(ctx, 0, MIPS32_ISA_OR(8, 8, 15));
1706 /* Enable DSP - update status registers 7*/
1707 pracc_add(ctx, 0, MIPS32_MTC0(isa, 8, 12, 0));
1708 }
1709
1710 /**
1711 * mips32_dsp_restore - Restore DSP status registers to the previous setting
1712 * @param[in] ctx: Context information pracc queue
1713 * @param[in] isa: isa identifier
1714 *
1715 * @brief Restores the DSP status registers to their previous setting.
1716 *
1717 * This function adds instructions to the context queue for restoring the DSP
1718 * status registers to their values before the operation.
1719 */
1720 static void mips32_dsp_restore(struct pracc_queue_info *ctx, int isa)
1721 {
1722 pracc_add(ctx, 0, MIPS32_MTC0(isa, 9, 12, 0)); /* Restore status registers to previous setting */
1723 pracc_add(ctx, 0, MIPS32_NOP); /* nop */
1724 }
1725
1726 /**
1727 * mips32_pracc_read_dsp_reg - Read a value from a MIPS32 DSP register
1728 * @param[in] ejtag_info: EJTAG information structure
1729 * @param[out] val: Pointer to store the read value
1730 * @param[in] reg: Index of the DSP register to read
1731 *
1732 * @brief Reads the value from the specified MIPS32 DSP register using EJTAG access.
1733 *
1734 * This function initiates a sequence of instructions to read the value from the
1735 * specified DSP register. It will enable dsp module if its not enabled
1736 * and restoring the status registers after the read operation.
1737 *
1738 * @return ERROR_OK on success; error code on failure.
1739 */
1740 static int mips32_pracc_read_dsp_reg(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t reg)
1741 {
1742 int isa = 0;
1743
1744 struct pracc_queue_info ctx = {
1745 .max_code = 48,
1746 .ejtag_info = ejtag_info
1747 };
1748
1749 uint32_t dsp_read_code[] = {
1750 MIPS32_MFHI(isa, t0), /* mfhi t0 ($ac0) - OPCODE - 0x00004010 */
1751 MIPS32_DSP_MFHI(t0, 1), /* mfhi t0,$ac1 - OPCODE - 0x00204010 */
1752 MIPS32_DSP_MFHI(t0, 2), /* mfhi t0,$ac2 - OPCODE - 0x00404010 */
1753 MIPS32_DSP_MFHI(t0, 3), /* mfhi t0,$ac3 - OPCODE - 0x00604010*/
1754 MIPS32_MFLO(isa, t0), /* mflo t0 ($ac0) - OPCODE - 0x00004012 */
1755 MIPS32_DSP_MFLO(t0, 1), /* mflo t0,$ac1 - OPCODE - 0x00204012 */
1756 MIPS32_DSP_MFLO(t0, 2), /* mflo t0,$ac2 - OPCODE - 0x00404012 */
1757 MIPS32_DSP_MFLO(t0, 3), /* mflo t0,$ac3 - OPCODE - 0x00604012 */
1758 MIPS32_DSP_RDDSP(t0, 0x3F), /* rddsp t0, 0x3f (DSPCtl) - OPCODE - 0x7c3f44b8 */
1759 };
1760
1761 /* Check status register to determine if dsp register access is enabled */
1762 /* Get status register so it can be restored later */
1763
1764 ctx.pracc_list = NULL;
1765
1766 /* Init context queue */
1767 pracc_queue_init(&ctx);
1768
1769 if (ctx.retval != ERROR_OK)
1770 goto exit;
1771
1772 /* Enables DSP whether its already enabled or not */
1773 mips32_dsp_enable(&ctx, isa);
1774
1775 /* move AC or Control to $8 (t0) 8*/
1776 pracc_add(&ctx, 0, dsp_read_code[reg]);
1777 /* Restore status registers to previous setting */
1778 mips32_dsp_restore(&ctx, isa);
1779
1780 /* $15 = MIPS32_PRACC_BASE_ADDR 1*/
1781 pracc_add(&ctx, 0, MIPS32_LUI(isa, 15, PRACC_UPPER_BASE_ADDR));
1782 /* store $8 to pracc_out 10*/
1783 pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT, MIPS32_SW(isa, 8, PRACC_OUT_OFFSET, 15));
1784 /* move COP0 DeSave to $15 11*/
1785 pracc_add(&ctx, 0, MIPS32_MFC0(isa, 15, 31, 0));
1786 /* restore upper 16 of $8 12*/
1787 pracc_add(&ctx, 0, MIPS32_LUI(isa, 8, UPPER16(ejtag_info->reg8)));
1788 /* restore lower 16 of $8 13*/
1789 pracc_add(&ctx, 0, MIPS32_ORI(isa, 8, 8, LOWER16(ejtag_info->reg8)));
1790 /* restore upper 16 of $9 14*/
1791 pracc_add(&ctx, 0, MIPS32_LUI(isa, 9, UPPER16(ejtag_info->reg9)));
1792 pracc_add(&ctx, 0, MIPS32_SYNC(isa));
1793 /* jump to start 18*/
1794 pracc_add(&ctx, 0, MIPS32_B(isa, NEG16(ctx.code_count + 1)));
1795 /* restore lower 16 of $9 15*/
1796 pracc_add(&ctx, 0, MIPS32_ORI(isa, 9, 9, LOWER16(ejtag_info->reg9)));
1797
1798 ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val, 1);
1799 exit:
1800 pracc_queue_free(&ctx);
1801 return ctx.retval;
1802 }
1803
1804 /**
1805 * mips32_pracc_write_dsp_reg - Write a value to a MIPS32 DSP register
1806 * @param[in] ejtag_info: EJTAG information structure
1807 * @param[in] val: Value to be written to the register
1808 * @param[in] reg: Index of the DSP register to write
1809 *
1810 * @brief Writes the specified value to the specified MIPS32 DSP register.
1811 *
1812 * This function initiates a sequence of instructions to write the given value to the
1813 * specified DSP register.
1814 *
1815 * @return ERROR_OK on success; error code on failure.
1816 */
1817 static int mips32_pracc_write_dsp_reg(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t reg)
1818 {
1819 int isa = 0;
1820
1821 struct pracc_queue_info ctx = {
1822 .max_code = 48,
1823 .ejtag_info = ejtag_info
1824 };
1825
1826 uint32_t dsp_write_code[] = {
1827 MIPS32_MTHI(isa, t0), /* mthi t0 ($ac0) - OPCODE - 0x01000011 */
1828 MIPS32_DSP_MTHI(t0, 1), /* mthi t0, $ac1 - OPCODE - 0x01000811 */
1829 MIPS32_DSP_MTHI(t0, 2), /* mthi t0, $ac2 - OPCODE - 0x01001011 */
1830 MIPS32_DSP_MTHI(t0, 3), /* mthi t0, $ac3 - OPCODE - 0x01001811 */
1831 MIPS32_MTLO(isa, t0), /* mtlo t0 ($ac0) - OPCODE - 0x01000013 */
1832 MIPS32_DSP_MTLO(t0, 1), /* mtlo t0, $ac1 - OPCODE - 0x01000813 */
1833 MIPS32_DSP_MTLO(t0, 2), /* mtlo t0, $ac2 - OPCODE - 0x01001013 */
1834 MIPS32_DSP_MTLO(t0, 3), /* mtlo t0, $ac3 - OPCODE - 0x01001813 */
1835 MIPS32_DSP_WRDSP(t0, 0x1F), /* wrdsp t0, 0x1f (DSPCtl) - OPCODE - 0x7d00fcf8*/
1836 };
1837
1838 /* Init context queue */
1839 pracc_queue_init(&ctx);
1840 if (ctx.retval != ERROR_OK)
1841 goto exit;
1842
1843 /* Enables DSP whether its already enabled or not */
1844 mips32_dsp_enable(&ctx, isa);
1845
1846 /* Load val to $8 (t0) */
1847 pracc_add(&ctx, 0, MIPS32_LUI(isa, 8, UPPER16(val)));
1848 pracc_add(&ctx, 0, MIPS32_ORI(isa, 8, 8, LOWER16(val)));
1849
1850 /* move AC or Control to $8 (t0) */
1851 pracc_add(&ctx, 0, dsp_write_code[reg]);
1852
1853 /* nop, delay in order to ensure write */
1854 pracc_add(&ctx, 0, MIPS32_NOP);
1855 /* Restore status registers to previous setting */
1856 mips32_dsp_restore(&ctx, isa);
1857
1858 /* move COP0 DeSave to $15 */
1859 pracc_add(&ctx, 0, MIPS32_MFC0(isa, 15, 31, 0));
1860
1861 /* restore $8 */
1862 pracc_add(&ctx, 0, MIPS32_LUI(isa, 8, UPPER16(ejtag_info->reg8)));
1863 pracc_add(&ctx, 0, MIPS32_ORI(isa, 8, 8, LOWER16(ejtag_info->reg8)));
1864
1865 /* restore upper 16 of $9 */
1866 pracc_add(&ctx, 0, MIPS32_LUI(isa, 9, UPPER16(ejtag_info->reg9)));
1867
1868 /* jump to start */
1869 pracc_add(&ctx, 0, MIPS32_B(isa, NEG16(ctx.code_count + 1)));
1870 /* restore lower 16 of $9 */
1871 pracc_add(&ctx, 0, MIPS32_ORI(isa, 9, 9, LOWER16(ejtag_info->reg9)));
1872
1873 ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
1874 exit:
1875 pracc_queue_free(&ctx);
1876 return ctx.retval;
1877 }
1878
1879 /**
1880 * mips32_handle_cpuinfo_command - Handles the 'cpuinfo' command.
1881 * @param[in] cmd: Command invocation context.
1882 *
1883 * @brief Executes the 'cpuinfo' command which displays detailed information about the current CPU core.
1884 * This includes core type, vendor, instruction set, cache size, and other relevant details.
1885 *
1886 * @return ERROR_OK on success; error code on failure.
1887 */
1888 COMMAND_HANDLER(mips32_handle_cpuinfo_command)
1889 {
1890 int retval;
1891 struct target *target = get_current_target(CMD_CTX);
1892 struct mips32_common *mips32 = target_to_mips32(target);
1893 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1894
1895 uint32_t prid = mips32->prid; /* cp0 PRID - 15, 0 */
1896 uint32_t config0 = ejtag_info->config[0]; /* cp0 config - 16, 0 */
1897 uint32_t config1 = ejtag_info->config[1]; /* cp0 config - 16, 1 */
1898 uint32_t config3 = ejtag_info->config[3]; /* cp0 config - 16, 3 */
1899
1900 /* Following configs are not read during probe */
1901 uint32_t config5; /* cp0 config - 16, 5 */
1902
1903 /* No args for now */
1904 if (CMD_ARGC != 0)
1905 return ERROR_COMMAND_SYNTAX_ERROR;
1906
1907 if (target->state != TARGET_HALTED) {
1908 command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
1909 return ERROR_TARGET_NOT_HALTED;
1910 }
1911
1912 retval = mips32_cp0_read(ejtag_info, &config5, 16, 5);
1913 if (retval != ERROR_OK)
1914 return retval;
1915
1916 /* Determine Core info */
1917 const struct cpu_entry *entry = mips32->cpu_info;
1918 /* Display Core Type info */
1919 command_print(CMD, "CPU Core: %s", entry->cpu_name);
1920
1921 /* Display Core Vendor ID if it's unknown */
1922 if (entry == &mips32_cpu_entry[MIPS32_NUM_CPU_ENTRIES - 1])
1923 command_print(CMD, "Vendor: Unknown CPU vendor code %x.", ((prid & 0x00ffff00) >> 16));
1924 else
1925 command_print(CMD, "Vendor: %s", entry->vendor);
1926
1927 /* If MIPS release 2 or above, then get exception base info */
1928 enum mips32_isa_rel ar = mips32->isa_rel;
1929 if (ar > MIPS32_RELEASE_1) { /* release 2 and above */
1930 uint32_t ebase;
1931 retval = mips32_cp0_read(ejtag_info, &ebase, 15, 1);
1932 if (retval != ERROR_OK)
1933 return retval;
1934
1935 command_print(CMD, "Current CPU ID: %d", (ebase & 0x1ff));
1936 } else {
1937 command_print(CMD, "Current CPU ID: 0");
1938 }
1939
1940 char *instr;
1941 switch ((config3 & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT) {
1942 case 0:
1943 instr = "MIPS32";
1944 break;
1945 case 1:
1946 instr = "microMIPS";
1947 break;
1948 case 2:
1949 instr = "MIPS32 (at reset) and microMIPS";
1950 break;
1951 case 3:
1952 default:
1953 instr = "microMIPS (at reset) and MIPS32";
1954 break;
1955 }
1956
1957 /* Display Instruction Set Info */
1958 command_print(CMD, "Instr set: %s", instr);
1959 command_print(CMD, "Instr rel: %s",
1960 ar == MIPS32_RELEASE_1 ? "1"
1961 : ar == MIPS32_RELEASE_2 ? "2"
1962 : ar == MIPS32_RELEASE_6 ? "6"
1963 : "unknown");
1964 command_print(CMD, "PRId: %x", prid);
1965 /* Some of MIPS CPU Revisions(for M74K) can be seen on MD00541, page 26 */
1966 uint32_t rev = prid & 0x000000ff;
1967 command_print(CMD, "RTL Rev: %d.%d.%d", (rev & 0xE0), (rev & 0x1C), (rev & 0x3));
1968
1969 command_print(CMD, "Max Number of Instr Breakpoints: %d", mips32->num_inst_bpoints);
1970 command_print(CMD, "Max Number of Data Breakpoints: %d", mips32->num_data_bpoints);
1971
1972 /* MMU Support */
1973 uint32_t mmu_type = (config0 >> 7) & 7; /* MMU Type Info */
1974 char *mmu;
1975 switch (mmu_type) {
1976 case MIPS32_MMU_TLB:
1977 mmu = "TLB";
1978 break;
1979 case MIPS32_MMU_BAT:
1980 mmu = "BAT";
1981 break;
1982 case MIPS32_MMU_FIXED:
1983 mmu = "FIXED";
1984 break;
1985 case MIPS32_MMU_DUAL_VTLB_FTLB:
1986 mmu = "DUAL VAR/FIXED";
1987 break;
1988 default:
1989 mmu = "Unknown";
1990 }
1991 command_print(CMD, "MMU Type: %s", mmu);
1992
1993 retval = mips32_read_config_mmu(ejtag_info);
1994 if (retval != ERROR_OK)
1995 return retval;
1996
1997 /* Definitions of I/D Cache Sizes are available on MD01251, page 224~226 */
1998 int index;
1999 uint32_t ways, sets, bpl;
2000
2001 /* Determine Instr Cache Size */
2002 /* Ways mapping = [1, 2, 3, 4, 5, 6, 7, 8] */
2003 ways = ((config1 >> MIPS32_CFG1_IASHIFT) & 7);
2004
2005 /* Sets per way = [64, 128, 256, 512, 1024, 2048, 4096, 32] */
2006 index = ((config1 >> MIPS32_CFG1_ISSHIFT) & 7);
2007 sets = index == 7 ? 32 : 32 << (index + 1);
2008
2009 /* Bytes per line = [0, 4, 8, 16, 32, 64, 128, Reserved] */
2010 index = ((config1 >> MIPS32_CFG1_ILSHIFT) & 7);
2011 bpl = index == 0 ? 0 : 4 << (index - 1);
2012 command_print(CMD, "Instr Cache: %d (%d ways, %d lines, %d byte per line)", ways * sets * bpl, ways, sets, bpl);
2013
2014 /* Determine data cache size, same as above */
2015 ways = ((config1 >> MIPS32_CFG1_DASHIFT) & 7);
2016
2017 index = ((config1 >> MIPS32_CFG1_DSSHIFT) & 7);
2018 sets = index == 7 ? 32 : 32 << (index + 1);
2019
2020 index = ((config1 >> MIPS32_CFG1_DLSHIFT) & 7);
2021 bpl = index == 0 ? 0 : 4 << (index - 1);
2022 command_print(CMD, " Data Cache: %d (%d ways, %d lines, %d byte per line)", ways * sets * bpl, ways, sets, bpl);
2023
2024 /* does the core hava FPU*/
2025 mips32_read_config_fpu(mips32, ejtag_info);
2026
2027 /* does the core support a DSP */
2028 mips32_read_config_dsp(mips32, ejtag_info);
2029
2030 /* VZ module */
2031 uint32_t vzase = (config3 & BIT(23));
2032 if (vzase)
2033 command_print(CMD, "VZ implemented: yes");
2034 else
2035 command_print(CMD, "VZ implemented: no");
2036
2037 /* multithreading */
2038 uint32_t mtase = (config3 & BIT(2));
2039 if (mtase) {
2040 command_print(CMD, "MT implemented: yes");
2041
2042 /* Get VPE and Thread info */
2043 uint32_t tcbind;
2044 uint32_t mvpconf0;
2045
2046 /* Read tcbind register */
2047 retval = mips32_cp0_read(ejtag_info, &tcbind, 2, 2);
2048 if (retval != ERROR_OK)
2049 return retval;
2050
2051 command_print(CMD, " | Current VPE: %d", (tcbind & 0xf));
2052 command_print(CMD, " | Current TC: %d", ((tcbind >> 21) & 0xff));
2053
2054 /* Read mvpconf0 register */
2055 retval = mips32_cp0_read(ejtag_info, &mvpconf0, 0, 2);
2056 if (retval != ERROR_OK)
2057 return retval;
2058
2059 command_print(CMD, " | Total TC: %d", (mvpconf0 & 0xf) + 1);
2060 command_print(CMD, " | Total VPE: %d", ((mvpconf0 >> 10) & 0xf) + 1);
2061 } else {
2062 command_print(CMD, "MT implemented: no");
2063 }
2064
2065 /* MIPS SIMD Architecture (MSA) */
2066 uint32_t msa = (config3 & BIT(28));
2067 command_print(CMD, "MSA implemented: %s", msa ? "yes" : "no");
2068
2069 /* Move To/From High COP0 (MTHC0/MFHC0) instructions are implemented.
2070 * Implicates current ISA release >= 5.*/
2071 uint32_t mvh = (config5 & BIT(5));
2072 command_print(CMD, "MVH implemented: %s", mvh ? "yes" : "no");
2073
2074 /* Common Device Memory Map implemented? */
2075 uint32_t cdmm = (config3 & BIT(3));
2076 command_print(CMD, "CDMM implemented: %s", cdmm ? "yes" : "no");
2077
2078 return ERROR_OK;
2079 }
2080
2081 /**
2082 * mips32_dsp_find_register_by_name - Find DSP register index by name
2083 * @param[in] reg_name: Name of the DSP register to find
2084 *
2085 * @brief Searches for a DSP register by name and returns its index.
2086 * If no match is found, it returns MIPS32NUMDSPREGS.
2087 *
2088 * @return Index of the found register or MIPS32NUMDSPREGS if not found.
2089 */
2090 static int mips32_dsp_find_register_by_name(const char *reg_name)
2091 {
2092 if (reg_name)
2093 for (int i = 0; i < MIPS32NUMDSPREGS; i++) {
2094 if (strcmp(mips32_dsp_regs[i].name, reg_name) == 0)
2095 return i;
2096 }
2097 return MIPS32NUMDSPREGS;
2098 }
2099
2100 /**
2101 * mips32_dsp_get_all_regs - Get values of all MIPS32 DSP registers
2102 * @param[in] cmd: Command invocation context
2103 * @param[in] ejtag_info: EJTAG information structure
2104 *
2105 * @brief This function iterates through all DSP registers, reads their values,
2106 * and prints each register name along with its corresponding value.
2107 *
2108 * @return ERROR_OK on success; error code on failure.
2109 */
2110 static int mips32_dsp_get_all_regs(struct command_invocation *cmd, struct mips_ejtag *ejtag_info)
2111 {
2112 uint32_t value = 0;
2113 for (int i = 0; i < MIPS32NUMDSPREGS; i++) {
2114 int retval = mips32_pracc_read_dsp_reg(ejtag_info, &value, i);
2115 if (retval != ERROR_OK) {
2116 command_print(CMD, "couldn't access reg %s", mips32_dsp_regs[i].name);
2117 return retval;
2118 }
2119 command_print(CMD, "%*s: 0x%8.8x", 7, mips32_dsp_regs[i].name, value);
2120 }
2121 return ERROR_OK;
2122 }
2123
2124 /**
2125 * mips32_dsp_get_register - Get the value of a MIPS32 DSP register
2126 * @param[in] cmd: Command invocation context
2127 * @param[in] ejtag_info: EJTAG information structure
2128 *
2129 * @brief Retrieves the value of a specified MIPS32 DSP register.
2130 * If the register is found, it reads the register value and prints the result.
2131 * If the register is not found, it prints an error message.
2132 *
2133 * @return ERROR_OK on success; error code on failure.
2134 */
2135 static int mips32_dsp_get_register(struct command_invocation *cmd, struct mips_ejtag *ejtag_info)
2136 {
2137 uint32_t value = 0;
2138 int index = mips32_dsp_find_register_by_name(CMD_ARGV[0]);
2139 if (index == MIPS32NUMDSPREGS) {
2140 command_print(CMD, "ERROR: register '%s' not found", CMD_ARGV[0]);
2141 return ERROR_COMMAND_SYNTAX_ERROR;
2142 }
2143
2144 int retval = mips32_pracc_read_dsp_reg(ejtag_info, &value, index);
2145 if (retval != ERROR_OK)
2146 command_print(CMD, "ERROR: Could not access dsp register %s", CMD_ARGV[0]);
2147 else
2148 command_print(CMD, "0x%8.8x", value);
2149
2150 return retval;
2151 }
2152
2153 /**
2154 * mips32_dsp_set_register - Set the value of a MIPS32 DSP register
2155 * @param[in] cmd: Command invocation context
2156 * @param[in] ejtag_info: EJTAG information structure
2157 *
2158 * @brief Sets the value of a specified MIPS32 DSP register.
2159 * If the register is found, it writes provided value to the register.
2160 * If the register is not found or there is an error in writing the value,
2161 * it prints an error message.
2162 *
2163 * @return ERROR_OK on success; error code on failure.
2164 */
2165 static int mips32_dsp_set_register(struct command_invocation *cmd, struct mips_ejtag *ejtag_info)
2166 {
2167 uint32_t value;
2168 int index = mips32_dsp_find_register_by_name(CMD_ARGV[0]);
2169 if (index == MIPS32NUMDSPREGS) {
2170 command_print(CMD, "ERROR: register '%s' not found", CMD_ARGV[0]);
2171 return ERROR_COMMAND_SYNTAX_ERROR;
2172 }
2173
2174 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
2175
2176 int retval = mips32_pracc_write_dsp_reg(ejtag_info, value, index);
2177 if (retval != ERROR_OK)
2178 command_print(CMD, "Error: could not write to dsp register %s", CMD_ARGV[0]);
2179
2180 return retval;
2181 }
2182
2183 /**
2184 * mips32_handle_dsp_command - Handles mips dsp related command
2185 * @param[in] cmd: Command invocation context
2186 *
2187 * @brief Reads or sets the content of each dsp register.
2188 *
2189 * @return ERROR_OK on success; error code on failure.
2190 */
2191 COMMAND_HANDLER(mips32_handle_dsp_command)
2192 {
2193 int retval, tmp;
2194 struct target *target = get_current_target(CMD_CTX);
2195 struct mips32_common *mips32 = target_to_mips32(target);
2196 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
2197
2198 retval = mips32_verify_pointer(CMD, mips32);
2199 if (retval != ERROR_OK)
2200 return retval;
2201
2202 if (target->state != TARGET_HALTED) {
2203 command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
2204 return ERROR_OK;
2205 }
2206
2207 /* Check for too many command args */
2208 if (CMD_ARGC >= 3)
2209 return ERROR_COMMAND_SYNTAX_ERROR;
2210
2211 /* Check if DSP access supported or not */
2212 if (!mips32->dsp_imp) {
2213 /* Issue Error Message */
2214 command_print(CMD, "DSP not implemented by this processor");
2215 return ERROR_OK;
2216 }
2217
2218 switch (CMD_ARGC) {
2219 case 0:
2220 retval = mips32_dsp_get_all_regs(CMD, ejtag_info);
2221 break;
2222 case 1:
2223 retval = mips32_dsp_get_register(CMD, ejtag_info);
2224 break;
2225 case 2:
2226 tmp = *CMD_ARGV[0];
2227 if (isdigit(tmp)) {
2228 command_print(CMD, "Error: invalid dsp command format");
2229 retval = ERROR_COMMAND_ARGUMENT_INVALID;
2230 } else {
2231 retval = mips32_dsp_set_register(CMD, ejtag_info);
2232 }
2233 break;
2234 default:
2235 command_print(CMD, "Error: invalid argument format, required 0-2, given %d", CMD_ARGC);
2236 retval = ERROR_COMMAND_ARGUMENT_INVALID;
2237 break;
2238 }
2239 return retval;
2240 }
2241
2242 /**
2243 * mips32_handle_ejtag_reg_command - Handler commands related to EJTAG
2244 * @param[in] cmd: Command invocation context
2245 *
2246 * @brief Prints all EJTAG Registers including DCR features.
2247 *
2248 * @return ERROR_OK on success; error code on failure.
2249 */
2250 COMMAND_HANDLER(mips32_handle_ejtag_reg_command)
2251 {
2252 struct target *target = get_current_target(CMD_CTX);
2253 struct mips32_common *mips32 = target_to_mips32(target);
2254 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
2255
2256 uint32_t ejtag_ctrl;
2257 uint32_t dcr;
2258 int retval;
2259
2260 retval = mips_ejtag_get_idcode(ejtag_info);
2261 if (retval != ERROR_OK)
2262 command_print(CMD, "Error: Encounter an Error while getting idcode");
2263 else
2264 command_print(CMD, " idcode: 0x%8.8" PRIx32, ejtag_info->idcode);
2265
2266 retval = mips_ejtag_get_impcode(ejtag_info);
2267 if (retval != ERROR_OK)
2268 command_print(CMD, "Error: Encounter an Error while getting impcode");
2269 else
2270 command_print(CMD, " impcode: 0x%8.8" PRIx32, ejtag_info->impcode);
2271
2272 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
2273 ejtag_ctrl = ejtag_info->ejtag_ctrl;
2274 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
2275 if (retval != ERROR_OK)
2276 command_print(CMD, "Error: Encounter an Error while executing drscan reading EJTAG Control register");
2277 else
2278 command_print(CMD, "ejtag control: 0x%8.8" PRIx32, ejtag_ctrl);
2279
2280 ejtag_main_print_imp(ejtag_info);
2281
2282 /* Display current DCR */
2283 retval = target_read_u32(target, EJTAG_DCR, &dcr);
2284 if (retval != ERROR_OK)
2285 command_print(CMD, "Error: Encounter an Error while reading Debug Control Register");
2286 else
2287 command_print(CMD, " DCR: 0x%8.8" PRIx32, dcr);
2288
2289 for (unsigned int i = 0; i < EJTAG_DCR_ENTRIES; i++) {
2290 if (dcr & BIT(dcr_features[i].bit))
2291 command_print(CMD, "%s supported", dcr_features[i].name);
2292 }
2293
2294 return ERROR_OK;
2295 }
2296
2297 /**
2298 * mips32_handle_scan_delay_command - Handler command for changing scan delay
2299 * @param[in] cmd: Command invocation context
2300 *
2301 * @brief Changes current scan mode between legacy and fast queued mode.
2302 *
2303 * @return ERROR_OK on success; error code on failure.
2304 */
2305 COMMAND_HANDLER(mips32_handle_scan_delay_command)
2306 {
2307 struct target *target = get_current_target(CMD_CTX);
2308 struct mips32_common *mips32 = target_to_mips32(target);
2309 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
2310
2311 if (CMD_ARGC == 1)
2312 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
2313 else if (CMD_ARGC > 1)
2314 return ERROR_COMMAND_SYNTAX_ERROR;
2315
2316 command_print(CMD, "scan delay: %d nsec", ejtag_info->scan_delay);
2317 if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
2318 ejtag_info->mode = 0;
2319 command_print(CMD, "running in legacy mode");
2320 } else {
2321 ejtag_info->mode = 1;
2322 command_print(CMD, "running in fast queued mode");
2323 }
2324
2325 return ERROR_OK;
2326 }
2327
2328 static const struct command_registration mips32_exec_command_handlers[] = {
2329 {
2330 .name = "cp0",
2331 .handler = mips32_handle_cp0_command,
2332 .mode = COMMAND_EXEC,
2333 .usage = "[[reg_name|regnum select] [value]]",
2334 .help = "display/modify cp0 register",
2335 },
2336 {
2337 .name = "cpuinfo",
2338 .handler = mips32_handle_cpuinfo_command,
2339 .mode = COMMAND_EXEC,
2340 .help = "display CPU information",
2341 .usage = "",
2342 },
2343 {
2344 .name = "dsp",
2345 .handler = mips32_handle_dsp_command,
2346 .mode = COMMAND_EXEC,
2347 .help = "display or set DSP register; "
2348 "with no arguments, displays all registers and their values",
2349 .usage = "[[register_name] [value]]",
2350 },
2351 {
2352 .name = "scan_delay",
2353 .handler = mips32_handle_scan_delay_command,
2354 .mode = COMMAND_ANY,
2355 .help = "display/set scan delay in nano seconds",
2356 .usage = "[value]",
2357 },
2358 {
2359 .name = "ejtag_reg",
2360 .handler = mips32_handle_ejtag_reg_command,
2361 .mode = COMMAND_ANY,
2362 .help = "read ejtag registers",
2363 .usage = "",
2364 },
2365 COMMAND_REGISTRATION_DONE
2366 };
2367
2368 const struct command_registration mips32_command_handlers[] = {
2369 {
2370 .name = "mips32",
2371 .mode = COMMAND_ANY,
2372 .help = "mips32 command group",
2373 .usage = "",
2374 .chain = mips32_exec_command_handlers,
2375 },
2376 COMMAND_REGISTRATION_DONE
2377 };

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)