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

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)