1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
7 * Copyright (C) 2008 by David T.L. Wong *
9 * Copyright (C) 2007,2008 Øyvind Harboe *
10 * oyvind.harboe@zylin.com *
12 * Copyright (C) 2011 by Drasko DRASKOVIC *
13 * drasko.draskovic@gmail.com *
14 ***************************************************************************/
22 #include "breakpoints.h"
23 #include "algorithm.h"
26 static const char *mips_isa_strings
[] = {
27 "MIPS32", "MIPS16", "", "MICRO MIPS32",
30 #define MIPS32_GDB_FP_REG 1
34 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
44 { 0, "r0", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
45 { 1, "r1", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
46 { 2, "r2", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
47 { 3, "r3", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
48 { 4, "r4", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
49 { 5, "r5", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
50 { 6, "r6", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
51 { 7, "r7", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
52 { 8, "r8", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
53 { 9, "r9", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
54 { 10, "r10", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 11, "r11", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 12, "r12", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 13, "r13", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 14, "r14", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 15, "r15", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 16, "r16", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 17, "r17", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 18, "r18", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 19, "r19", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 20, "r20", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { 21, "r21", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
66 { 22, "r22", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
67 { 23, "r23", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
68 { 24, "r24", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
69 { 25, "r25", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
70 { 26, "r26", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
71 { 27, "r27", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
72 { 28, "r28", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
73 { 29, "r29", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
74 { 30, "r30", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
75 { 31, "r31", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
76 { 32, "lo", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
77 { 33, "hi", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
79 { MIPS32_REGLIST_FP_INDEX
+ 0, "f0", REG_TYPE_IEEE_DOUBLE
, NULL
,
80 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
81 { MIPS32_REGLIST_FP_INDEX
+ 1, "f1", REG_TYPE_IEEE_DOUBLE
, NULL
,
82 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
83 { MIPS32_REGLIST_FP_INDEX
+ 2, "f2", REG_TYPE_IEEE_DOUBLE
, NULL
,
84 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
85 { MIPS32_REGLIST_FP_INDEX
+ 3, "f3", REG_TYPE_IEEE_DOUBLE
, NULL
,
86 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
87 { MIPS32_REGLIST_FP_INDEX
+ 4, "f4", REG_TYPE_IEEE_DOUBLE
, NULL
,
88 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
89 { MIPS32_REGLIST_FP_INDEX
+ 5, "f5", REG_TYPE_IEEE_DOUBLE
, NULL
,
90 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
91 { MIPS32_REGLIST_FP_INDEX
+ 6, "f6", REG_TYPE_IEEE_DOUBLE
, NULL
,
92 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
93 { MIPS32_REGLIST_FP_INDEX
+ 7, "f7", REG_TYPE_IEEE_DOUBLE
, NULL
,
94 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
95 { MIPS32_REGLIST_FP_INDEX
+ 8, "f8", REG_TYPE_IEEE_DOUBLE
, NULL
,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
97 { MIPS32_REGLIST_FP_INDEX
+ 9, "f9", REG_TYPE_IEEE_DOUBLE
, NULL
,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
99 { MIPS32_REGLIST_FP_INDEX
+ 10, "f10", REG_TYPE_IEEE_DOUBLE
, NULL
,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
101 { MIPS32_REGLIST_FP_INDEX
+ 11, "f11", REG_TYPE_IEEE_DOUBLE
, NULL
,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
103 { MIPS32_REGLIST_FP_INDEX
+ 12, "f12", REG_TYPE_IEEE_DOUBLE
, NULL
,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
105 { MIPS32_REGLIST_FP_INDEX
+ 13, "f13", REG_TYPE_IEEE_DOUBLE
, NULL
,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
107 { MIPS32_REGLIST_FP_INDEX
+ 14, "f14", REG_TYPE_IEEE_DOUBLE
, NULL
,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
109 { MIPS32_REGLIST_FP_INDEX
+ 15, "f15", REG_TYPE_IEEE_DOUBLE
, NULL
,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
111 { MIPS32_REGLIST_FP_INDEX
+ 16, "f16", REG_TYPE_IEEE_DOUBLE
, NULL
,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
113 { MIPS32_REGLIST_FP_INDEX
+ 17, "f17", REG_TYPE_IEEE_DOUBLE
, NULL
,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
115 { MIPS32_REGLIST_FP_INDEX
+ 18, "f18", REG_TYPE_IEEE_DOUBLE
, NULL
,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
117 { MIPS32_REGLIST_FP_INDEX
+ 19, "f19", REG_TYPE_IEEE_DOUBLE
, NULL
,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
119 { MIPS32_REGLIST_FP_INDEX
+ 20, "f20", REG_TYPE_IEEE_DOUBLE
, NULL
,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
121 { MIPS32_REGLIST_FP_INDEX
+ 21, "f21", REG_TYPE_IEEE_DOUBLE
, NULL
,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
123 { MIPS32_REGLIST_FP_INDEX
+ 22, "f22", REG_TYPE_IEEE_DOUBLE
, NULL
,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
125 { MIPS32_REGLIST_FP_INDEX
+ 23, "f23", REG_TYPE_IEEE_DOUBLE
, NULL
,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
127 { MIPS32_REGLIST_FP_INDEX
+ 24, "f24", REG_TYPE_IEEE_DOUBLE
, NULL
,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
129 { MIPS32_REGLIST_FP_INDEX
+ 25, "f25", REG_TYPE_IEEE_DOUBLE
, NULL
,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
131 { MIPS32_REGLIST_FP_INDEX
+ 26, "f26", REG_TYPE_IEEE_DOUBLE
, NULL
,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
133 { MIPS32_REGLIST_FP_INDEX
+ 27, "f27", REG_TYPE_IEEE_DOUBLE
, NULL
,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
135 { MIPS32_REGLIST_FP_INDEX
+ 28, "f28", REG_TYPE_IEEE_DOUBLE
, NULL
,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
137 { MIPS32_REGLIST_FP_INDEX
+ 29, "f29", REG_TYPE_IEEE_DOUBLE
, NULL
,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
139 { MIPS32_REGLIST_FP_INDEX
+ 30, "f30", REG_TYPE_IEEE_DOUBLE
, NULL
,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
141 { MIPS32_REGLIST_FP_INDEX
+ 31, "f31", REG_TYPE_IEEE_DOUBLE
, NULL
,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
144 { MIPS32_REGLIST_FPC_INDEX
+ 0, "fcsr", REG_TYPE_INT
, "float",
145 "org.gnu.gdb.mips.fpu", 0 },
146 { MIPS32_REGLIST_FPC_INDEX
+ 1, "fir", REG_TYPE_INT
, "float",
147 "org.gnu.gdb.mips.fpu", 0 },
149 { MIPS32_REGLIST_C0_STATUS_INDEX
, "status", REG_TYPE_INT
, NULL
,
150 "org.gnu.gdb.mips.cp0", 0 },
151 { MIPS32_REGLIST_C0_BADVADDR_INDEX
, "badvaddr", REG_TYPE_INT
, NULL
,
152 "org.gnu.gdb.mips.cp0", 0 },
153 { MIPS32_REGLIST_C0_CAUSE_INDEX
, "cause", REG_TYPE_INT
, NULL
,
154 "org.gnu.gdb.mips.cp0", 0 },
155 { MIPS32_REGLIST_C0_PC_INDEX
, "pc", REG_TYPE_INT
, NULL
,
156 "org.gnu.gdb.mips.cpu", 0 },
157 { MIPS32_REGLIST_C0_GUESTCTL1_INDEX
, "guestCtl1", REG_TYPE_INT
, NULL
,
158 "org.gnu.gdb.mips.cp0", 0 },
161 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
164 static int mips32_get_core_reg(struct reg
*reg
)
167 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
168 struct target
*target
= mips32_reg
->target
;
169 struct mips32_common
*mips32_target
= target_to_mips32(target
);
171 if (target
->state
!= TARGET_HALTED
)
172 return ERROR_TARGET_NOT_HALTED
;
174 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
179 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
181 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
182 struct target
*target
= mips32_reg
->target
;
186 value
= buf_get_u64(buf
, 0, 64);
188 value
= buf_get_u32(buf
, 0, 32);
190 if (target
->state
!= TARGET_HALTED
)
191 return ERROR_TARGET_NOT_HALTED
;
194 buf_set_u64(reg
->value
, 0, 64, value
);
196 buf_set_u32(reg
->value
, 0, 32, value
);
204 static int mips32_read_core_reg(struct target
*target
, unsigned int num
)
207 uint64_t reg_value
= 0;
209 /* get pointers to arch-specific information */
210 struct mips32_common
*mips32
= target_to_mips32(target
);
212 if (num
>= MIPS32_NUM_REGS
)
213 return ERROR_COMMAND_SYNTAX_ERROR
;
215 if (num
>= MIPS32_REGLIST_C0_INDEX
) {
217 cnum
= num
- MIPS32_REGLIST_C0_INDEX
;
218 reg_value
= mips32
->core_regs
.cp0
[cnum
];
219 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
220 } else if (num
>= MIPS32_REGLIST_FPC_INDEX
) {
222 cnum
= num
- MIPS32_REGLIST_FPC_INDEX
;
223 reg_value
= mips32
->core_regs
.fpcr
[cnum
];
224 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
225 } else if (num
>= MIPS32_REGLIST_FP_INDEX
) {
227 cnum
= num
- MIPS32_REGLIST_FP_INDEX
;
228 reg_value
= mips32
->core_regs
.fpr
[cnum
];
229 buf_set_u64(mips32
->core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
232 cnum
= num
- MIPS32_REGLIST_GP_INDEX
;
233 reg_value
= mips32
->core_regs
.gpr
[cnum
];
234 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
237 mips32
->core_cache
->reg_list
[num
].valid
= true;
238 mips32
->core_cache
->reg_list
[num
].dirty
= false;
240 LOG_DEBUG("read core reg %i value 0x%" PRIx64
"", num
, reg_value
);
245 static int mips32_write_core_reg(struct target
*target
, unsigned int num
)
250 /* get pointers to arch-specific information */
251 struct mips32_common
*mips32
= target_to_mips32(target
);
253 if (num
>= MIPS32_NUM_REGS
)
254 return ERROR_COMMAND_SYNTAX_ERROR
;
256 if (num
>= MIPS32_REGLIST_C0_INDEX
) {
258 cnum
= num
- MIPS32_REGLIST_C0_INDEX
;
259 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
260 mips32
->core_regs
.cp0
[cnum
] = (uint32_t)reg_value
;
261 } else if (num
>= MIPS32_REGLIST_FPC_INDEX
) {
263 cnum
= num
- MIPS32_REGLIST_FPC_INDEX
;
264 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
265 mips32
->core_regs
.fpcr
[cnum
] = (uint32_t)reg_value
;
266 } else if (num
>= MIPS32_REGLIST_FP_INDEX
) {
268 cnum
= num
- MIPS32_REGLIST_FP_INDEX
;
269 reg_value
= buf_get_u64(mips32
->core_cache
->reg_list
[num
].value
, 0, 64);
270 mips32
->core_regs
.fpr
[cnum
] = reg_value
;
273 cnum
= num
- MIPS32_REGLIST_GP_INDEX
;
274 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
275 mips32
->core_regs
.gpr
[cnum
] = (uint32_t)reg_value
;
278 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, reg_value
);
279 mips32
->core_cache
->reg_list
[num
].valid
= true;
280 mips32
->core_cache
->reg_list
[num
].dirty
= false;
285 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
286 int *reg_list_size
, enum target_register_class reg_class
)
288 /* get pointers to arch-specific information */
289 struct mips32_common
*mips32
= target_to_mips32(target
);
292 /* include floating point registers */
293 *reg_list_size
= MIPS32_NUM_REGS
;
294 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
296 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++)
297 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
302 int mips32_save_context(struct target
*target
)
306 /* get pointers to arch-specific information */
307 struct mips32_common
*mips32
= target_to_mips32(target
);
309 /* read core registers */
310 int retval
= mips32_pracc_read_regs(mips32
);
311 if (retval
!= ERROR_OK
) {
312 LOG_ERROR("Could not read core registers from target");
316 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
317 if (!mips32
->core_cache
->reg_list
[i
].valid
)
318 mips32
->read_core_reg(target
, i
);
324 int mips32_restore_context(struct target
*target
)
328 /* get pointers to arch-specific information */
329 struct mips32_common
*mips32
= target_to_mips32(target
);
331 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
332 if (mips32
->core_cache
->reg_list
[i
].dirty
)
333 mips32
->write_core_reg(target
, i
);
336 /* write core regs */
337 return mips32_pracc_write_regs(mips32
);
340 int mips32_arch_state(struct target
*target
)
342 struct mips32_common
*mips32
= target_to_mips32(target
);
344 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
345 mips_isa_strings
[mips32
->isa_mode
],
346 debug_reason_name(target
),
347 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32));
352 static const struct reg_arch_type mips32_reg_type
= {
353 .get
= mips32_get_core_reg
,
354 .set
= mips32_set_core_reg
,
357 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
359 /* get pointers to arch-specific information */
360 struct mips32_common
*mips32
= target_to_mips32(target
);
362 int num_regs
= MIPS32_NUM_REGS
;
363 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
364 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
365 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
366 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
367 struct reg_feature
*feature
;
370 /* Build the process context cache */
371 cache
->name
= "mips32 registers";
373 cache
->reg_list
= reg_list
;
374 cache
->num_regs
= num_regs
;
376 mips32
->core_cache
= cache
;
378 for (i
= 0; i
< num_regs
; i
++) {
379 arch_info
[i
].num
= mips32_regs
[i
].id
;
380 arch_info
[i
].target
= target
;
381 arch_info
[i
].mips32_common
= mips32
;
383 reg_list
[i
].name
= mips32_regs
[i
].name
;
384 reg_list
[i
].size
= mips32_regs
[i
].size
? 64 : 32;
386 reg_list
[i
].value
= mips32_regs
[i
].size
? calloc(1, 8) : calloc(1, 4);
387 reg_list
[i
].valid
= false;
388 reg_list
[i
].type
= &mips32_reg_type
;
389 reg_list
[i
].arch_info
= &arch_info
[i
];
391 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
392 if (reg_list
[i
].reg_data_type
)
393 reg_list
[i
].reg_data_type
->type
= mips32_regs
[i
].type
;
395 LOG_ERROR("unable to allocate reg type list");
398 reg_list
[i
].dirty
= false;
400 reg_list
[i
].group
= mips32_regs
[i
].group
;
401 reg_list
[i
].number
= i
;
402 reg_list
[i
].exist
= true;
403 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
405 feature
= calloc(1, sizeof(struct reg_feature
));
407 feature
->name
= mips32_regs
[i
].feature
;
408 reg_list
[i
].feature
= feature
;
410 LOG_ERROR("unable to allocate feature list");
416 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
418 target
->arch_info
= mips32
;
419 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
420 mips32
->fast_data_area
= NULL
;
421 mips32
->isa_imp
= MIPS32_ONLY
; /* default */
423 /* has breakpoint/watchpoint unit been scanned */
424 mips32
->bp_scanned
= 0;
425 mips32
->data_break_list
= NULL
;
427 mips32
->ejtag_info
.tap
= tap
;
428 mips32
->read_core_reg
= mips32_read_core_reg
;
429 mips32
->write_core_reg
= mips32_write_core_reg
;
430 /* if unknown endianness defaults to little endian, 1 */
431 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
432 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
433 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
434 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
435 mips32
->ejtag_info
.config_regs
= 0; /* no config register read */
439 /* run to exit point. return error if exit point was not reached. */
440 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
441 unsigned int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
445 /* This code relies on the target specific resume() and poll()->debug_entry()
446 * sequence to write register values to the processor and the read them back */
447 retval
= target_resume(target
, 0, entry_point
, 0, 1);
448 if (retval
!= ERROR_OK
)
451 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
452 /* If the target fails to halt due to the breakpoint, force a halt */
453 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
454 retval
= target_halt(target
);
455 if (retval
!= ERROR_OK
)
457 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
458 if (retval
!= ERROR_OK
)
460 return ERROR_TARGET_TIMEOUT
;
463 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32);
464 if (exit_point
&& (pc
!= exit_point
)) {
465 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
466 return ERROR_TARGET_TIMEOUT
;
472 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
473 struct mem_param
*mem_params
, int num_reg_params
,
474 struct reg_param
*reg_params
, target_addr_t entry_point
,
475 target_addr_t exit_point
, unsigned int timeout_ms
, void *arch_info
)
477 struct mips32_common
*mips32
= target_to_mips32(target
);
478 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
479 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
481 uint32_t context
[MIPS32_NUM_REGS
];
482 int retval
= ERROR_OK
;
484 LOG_DEBUG("Running algorithm");
486 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
487 * at the exit point */
489 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
490 LOG_ERROR("current target isn't a MIPS32 target");
491 return ERROR_TARGET_INVALID
;
494 if (target
->state
!= TARGET_HALTED
) {
495 LOG_TARGET_ERROR(target
, "not halted (run target algo)");
496 return ERROR_TARGET_NOT_HALTED
;
499 /* refresh core register cache */
500 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
501 if (!mips32
->core_cache
->reg_list
[i
].valid
)
502 mips32
->read_core_reg(target
, i
);
503 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
506 for (int i
= 0; i
< num_mem_params
; i
++) {
507 if (mem_params
[i
].direction
== PARAM_IN
)
509 retval
= target_write_buffer(target
, mem_params
[i
].address
,
510 mem_params
[i
].size
, mem_params
[i
].value
);
511 if (retval
!= ERROR_OK
)
515 for (int i
= 0; i
< num_reg_params
; i
++) {
516 if (reg_params
[i
].direction
== PARAM_IN
)
519 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
522 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
523 return ERROR_COMMAND_SYNTAX_ERROR
;
526 if (reg
->size
!= reg_params
[i
].size
) {
527 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
528 reg_params
[i
].reg_name
);
529 return ERROR_COMMAND_SYNTAX_ERROR
;
532 mips32_set_core_reg(reg
, reg_params
[i
].value
);
535 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
537 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
539 if (retval
!= ERROR_OK
)
542 for (int i
= 0; i
< num_mem_params
; i
++) {
543 if (mem_params
[i
].direction
!= PARAM_OUT
) {
544 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
545 mem_params
[i
].value
);
546 if (retval
!= ERROR_OK
)
551 for (int i
= 0; i
< num_reg_params
; i
++) {
552 if (reg_params
[i
].direction
!= PARAM_OUT
) {
553 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
555 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
556 return ERROR_COMMAND_SYNTAX_ERROR
;
559 if (reg
->size
!= reg_params
[i
].size
) {
560 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
561 reg_params
[i
].reg_name
);
562 return ERROR_COMMAND_SYNTAX_ERROR
;
565 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
569 /* restore everything we saved before */
570 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
572 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
573 if (regvalue
!= context
[i
]) {
574 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
575 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
576 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
578 mips32
->core_cache
->reg_list
[i
].valid
= true;
579 mips32
->core_cache
->reg_list
[i
].dirty
= true;
583 mips32
->isa_mode
= isa_mode
;
588 int mips32_examine(struct target
*target
)
590 struct mips32_common
*mips32
= target_to_mips32(target
);
592 if (!target_was_examined(target
)) {
593 target_set_examined(target
);
595 /* we will configure later */
596 mips32
->bp_scanned
= 0;
597 mips32
->num_inst_bpoints
= 0;
598 mips32
->num_data_bpoints
= 0;
599 mips32
->num_inst_bpoints_avail
= 0;
600 mips32
->num_data_bpoints_avail
= 0;
606 static int mips32_configure_ibs(struct target
*target
)
608 struct mips32_common
*mips32
= target_to_mips32(target
);
609 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
613 /* get number of inst breakpoints */
614 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
615 if (retval
!= ERROR_OK
)
618 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
619 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
620 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
621 sizeof(struct mips32_comparator
));
623 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
624 mips32
->inst_break_list
[i
].reg_address
=
625 ejtag_info
->ejtag_iba0_addr
+
626 (ejtag_info
->ejtag_iba_step_size
* i
);
629 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
633 static int mips32_configure_dbs(struct target
*target
)
635 struct mips32_common
*mips32
= target_to_mips32(target
);
636 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
640 /* get number of data breakpoints */
641 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
642 if (retval
!= ERROR_OK
)
645 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
646 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
647 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
648 sizeof(struct mips32_comparator
));
650 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
651 mips32
->data_break_list
[i
].reg_address
=
652 ejtag_info
->ejtag_dba0_addr
+
653 (ejtag_info
->ejtag_dba_step_size
* i
);
656 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
660 int mips32_configure_break_unit(struct target
*target
)
662 /* get pointers to arch-specific information */
663 struct mips32_common
*mips32
= target_to_mips32(target
);
664 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
668 if (mips32
->bp_scanned
)
671 /* get info about breakpoint support */
672 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
673 if (retval
!= ERROR_OK
)
676 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
677 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
678 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
679 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
680 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
681 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
682 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
684 /* keep debug caps for later use */
685 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
686 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
689 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
690 retval
= mips32_configure_ibs(target
);
691 if (retval
!= ERROR_OK
)
695 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
696 retval
= mips32_configure_dbs(target
);
697 if (retval
!= ERROR_OK
)
701 /* check if target endianness settings matches debug control register */
702 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
703 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
704 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
705 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
706 LOG_WARNING("DCR endianness settings does not match target settings");
708 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
709 mips32
->num_data_bpoints
);
711 mips32
->bp_scanned
= 1;
716 int mips32_enable_interrupts(struct target
*target
, int enable
)
722 /* read debug control register */
723 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
724 if (retval
!= ERROR_OK
)
728 if (!(dcr
& EJTAG_DCR_INTE
)) {
729 /* enable interrupts */
730 dcr
|= EJTAG_DCR_INTE
;
734 if (dcr
& EJTAG_DCR_INTE
) {
735 /* disable interrupts */
736 dcr
&= ~EJTAG_DCR_INTE
;
742 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
743 if (retval
!= ERROR_OK
)
750 /* read processor identification cp0 register */
751 static int mips32_read_c0_prid(struct target
*target
)
753 struct mips32_common
*mips32
= target_to_mips32(target
);
754 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
757 retval
= mips32_cp0_read(ejtag_info
, &mips32
->prid
, 15, 0);
758 if (retval
!= ERROR_OK
) {
759 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
767 * mips32_find_cpu_by_prid - Find CPU information by processor ID.
768 * @param[in] prid: Processor ID of the CPU.
770 * @brief This function looks up the CPU entry in the mips32_cpu_entry array based on the provided
771 * processor ID. It also handles special cases like AMD/Alchemy CPUs that use Company Options
772 * instead of Processor IDs.
774 * @return Pointer to the corresponding cpu_entry struct, or the 'unknown' entry if not found.
776 static const struct cpu_entry
*mips32_find_cpu_by_prid(uint32_t prid
)
778 /* AMD/Alchemy CPU uses Company Options instead of Processor ID.
779 * Therefore an extra transform step for prid to map it to an assigned ID,
781 if ((prid
& PRID_COMP_MASK
) == PRID_COMP_ALCHEMY
) {
782 /* Clears Processor ID field, then put Company Option field to its place */
783 prid
= (prid
& 0xFFFF00FF) | ((prid
& 0xFF000000) >> 16);
786 /* Mask out Company Option */
789 for (unsigned int i
= 0; i
< MIPS32_NUM_CPU_ENTRIES
; i
++) {
790 const struct cpu_entry
*entry
= &mips32_cpu_entry
[i
];
791 if ((entry
->prid
& MIPS32_CORE_MASK
) <= prid
&& prid
<= entry
->prid
)
795 /* If nothing matched, then return unknown entry */
796 return &mips32_cpu_entry
[MIPS32_NUM_CPU_ENTRIES
- 1];
800 * mips32_cpu_probe - Detects processor type and applies necessary quirks.
801 * @param[in] target: The target CPU to probe.
803 * @brief This function probes the CPU, reads its PRID (Processor ID), and determines the CPU type.
804 * It applies any quirks necessary for specific processor types.
806 * NOTE: The proper detection of certain CPUs can become quite complicated.
807 * Please consult the following Linux kernel code when adding new CPUs:
808 * arch/mips/include/asm/cpu.h
809 * arch/mips/kernel/cpu-probe.c
811 * @return ERROR_OK on success; error code on failure.
813 int mips32_cpu_probe(struct target
*target
)
815 struct mips32_common
*mips32
= target_to_mips32(target
);
819 return ERROR_OK
; /* Already probed once, return early. */
821 retval
= mips32_read_c0_prid(target
);
822 if (retval
!= ERROR_OK
)
825 const struct cpu_entry
*entry
= mips32_find_cpu_by_prid(mips32
->prid
);
827 switch (mips32
->prid
& PRID_COMP_MASK
) {
828 case PRID_COMP_INGENIC_E1
:
829 switch (mips32
->prid
& PRID_IMP_MASK
) {
830 case PRID_IMP_XBURST_REV1
:
831 mips32
->cpu_quirks
|= EJTAG_QUIRK_PAD_DRET
;
838 /* Determine which CP0 registers are available in the current processor core */
840 switch (entry
->prid
& PRID_IMP_MASK
) {
841 case PRID_IMP_MAPTIV_UC
:
842 mips32
->cp0_mask
= MIPS_CP0_MAPTIV_UC
;
844 case PRID_IMP_MAPTIV_UP
:
846 mips32
->cp0_mask
= MIPS_CP0_MAPTIV_UP
;
848 case PRID_IMP_IAPTIV
:
849 case PRID_IMP_IAPTIV_CM
:
850 mips32
->cp0_mask
= MIPS_CP0_IAPTIV
;
853 /* CP0 mask should be the same as MK4 by default */
854 mips32
->cp0_mask
= MIPS_CP0_MK4
;
862 mips32
->cpu_info
= entry
;
863 LOG_DEBUG("CPU: %s (PRId %08x)", entry
->cpu_name
, mips32
->prid
);
868 /* reads dsp implementation info from CP0 Config3 register {DSPP, DSPREV}*/
869 static void mips32_read_config_dsp(struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
)
871 uint32_t dsp_present
= ((ejtag_info
->config
[3] & MIPS32_CONFIG3_DSPP_MASK
) >> MIPS32_CONFIG3_DSPP_SHIFT
);
873 mips32
->dsp_imp
= ((ejtag_info
->config
[3] & MIPS32_CONFIG3_DSPREV_MASK
) >> MIPS32_CONFIG3_DSPREV_SHIFT
) + 1;
874 LOG_USER("DSP implemented: %s, rev %d", "yes", mips32
->dsp_imp
);
876 LOG_USER("DSP implemented: %s", "no");
880 /* read fpu implementation info from CP0 Config1 register {CU1, FP}*/
881 static int mips32_read_config_fpu(struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
)
884 uint32_t fp_imp
= (ejtag_info
->config
[1] & MIPS32_CONFIG1_FP_MASK
) >> MIPS32_CONFIG1_FP_SHIFT
;
887 LOG_USER("FPU implemented: %s", "no");
888 mips32
->fp_imp
= MIPS32_FP_IMP_NONE
;
891 uint32_t status_value
;
892 bool status_fr
, status_cu1
;
894 retval
= mips32_cp0_read(ejtag_info
, &status_value
, MIPS32_C0_STATUS
, 0);
895 if (retval
!= ERROR_OK
) {
896 LOG_ERROR("Failed to read cp0 status register");
900 status_fr
= (status_value
>> MIPS32_CP0_STATUS_FR_SHIFT
) & 0x1;
901 status_cu1
= (status_value
>> MIPS32_CP0_STATUS_CU1_SHIFT
) & 0x1;
903 /* TODO: read fpu(cp1) config register for current operating mode.
904 * Now its set to 32 bits by default. */
905 snprintf(buf
, sizeof(buf
), "yes");
906 fp_imp
= MIPS32_FP_IMP_32
;
908 snprintf(buf
, sizeof(buf
), "yes, disabled");
909 fp_imp
= MIPS32_FP_IMP_UNKNOWN
;
912 mips32
->fpu_in_64bit
= status_fr
;
913 mips32
->fpu_enabled
= status_cu1
;
915 LOG_USER("FPU implemented: %s", buf
);
916 mips32
->fp_imp
= fp_imp
;
922 * mips32_read_config_fdc - Read Fast Debug Channel configuration
923 * @param[in,out] mips32: MIPS32 common structure
924 * @param[in] ejtag_info: EJTAG information structure
925 * @param[in] dcr: Device Configuration Register value
927 * @brief Checks if the current target implements the Common Device Memory Map (CDMM) and Fast Debug Channel (FDC).
929 * This function examines the configuration registers and the Device Configuration Register (DCR) to determine
930 * if the current MIPS32 target supports the Common Device Memory Map (CDMM) and the Fast Debug Channel (FDC).
931 * If supported, it sets the corresponding flags in the MIPS32 common structure. \n
933 * NOTE:These are defined on MD00090, page 67 and MD00047F, page 82, respectively.
934 * MIPS Documents are pretty much all available online,
935 * it should pop up first when you search "MDxxxxx"
937 static void mips32_read_config_fdc(struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
, uint32_t dcr
)
939 if (((ejtag_info
->config
[3] & MIPS32_CONFIG3_CDMM_MASK
) != 0) && ((dcr
& EJTAG_DCR_FDC
) != 0)) {
941 mips32
->semihosting
= 1;
944 mips32
->semihosting
= 0;
948 /* read config to config3 cp0 registers and log isa implementation */
949 int mips32_read_config_regs(struct target
*target
)
951 struct mips32_common
*mips32
= target_to_mips32(target
);
952 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
956 if (ejtag_info
->config_regs
== 0)
957 for (int i
= 0; i
!= 4; i
++) {
958 retval
= mips32_cp0_read(ejtag_info
, &ejtag_info
->config
[i
], 16, i
);
959 if (retval
!= ERROR_OK
) {
960 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32
, i
);
961 ejtag_info
->config_regs
= 0;
964 ejtag_info
->config_regs
= i
+ 1;
965 if ((ejtag_info
->config
[i
] & (1 << 31)) == 0)
966 break; /* no more config registers implemented */
969 return ERROR_OK
; /* already successfully read */
971 LOG_DEBUG("read %"PRIu32
" config registers", ejtag_info
->config_regs
);
973 mips32
->isa_rel
= (ejtag_info
->config
[0] & MIPS32_CONFIG0_AR_MASK
) >> MIPS32_CONFIG0_AR_SHIFT
;
974 snprintf(buf
, sizeof(buf
), ", release %s(AR=%d)",
975 mips32
->isa_rel
== MIPS32_RELEASE_1
? "1"
976 : mips32
->isa_rel
== MIPS32_RELEASE_2
? "2"
977 : mips32
->isa_rel
== MIPS32_RELEASE_6
? "6"
978 : "unknown", mips32
->isa_rel
);
980 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
) {
981 mips32
->isa_imp
= MIPS32_MIPS16
;
982 LOG_USER("ISA implemented: %s%s", "MIPS32, MIPS16", buf
);
983 } else if (ejtag_info
->config_regs
>= 4) { /* config3 implemented */
984 unsigned isa_imp
= (ejtag_info
->config
[3] & MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
;
986 mips32
->isa_imp
= MMIPS32_ONLY
;
987 LOG_USER("ISA implemented: %s%s", "microMIPS32", buf
);
989 } else if (isa_imp
!= 0) {
990 mips32
->isa_imp
= MIPS32_MMIPS32
;
991 LOG_USER("ISA implemented: %s%s", "MIPS32, microMIPS32", buf
);
993 } else if (mips32
->isa_imp
== MIPS32_ONLY
) {
994 /* initial default value */
995 LOG_USER("ISA implemented: %s%s", "MIPS32", buf
);
998 /* Retrieve DSP info */
999 mips32_read_config_dsp(mips32
, ejtag_info
);
1001 /* Retrieve if Float Point CoProcessor Implemented */
1002 retval
= mips32_read_config_fpu(mips32
, ejtag_info
);
1003 if (retval
!= ERROR_OK
) {
1004 LOG_ERROR("fpu info is not available, error while reading cp0 status");
1005 mips32
->fp_imp
= MIPS32_FP_IMP_NONE
;
1011 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
1012 if (retval
!= ERROR_OK
) {
1013 LOG_ERROR("failed to read EJTAG_DCR register");
1017 /* Determine if FDC and CDMM are implemented for this core */
1018 mips32_read_config_fdc(mips32
, ejtag_info
, dcr
);
1023 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
1024 uint32_t count
, uint32_t *checksum
)
1026 struct working_area
*crc_algorithm
;
1027 struct reg_param reg_params
[2];
1028 struct mips32_algorithm mips32_info
;
1030 struct mips32_common
*mips32
= target_to_mips32(target
);
1031 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1033 /* see contrib/loaders/checksum/mips32.s for src */
1034 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
1036 uint32_t mips_crc_code
[] = {
1037 MIPS32_ADDIU(isa
, 12, 4, 0), /* addiu $t4, $a0, 0 */
1038 MIPS32_ADDIU(isa
, 10, 5, 0), /* addiu $t2, $a1, 0 */
1039 MIPS32_ADDIU(isa
, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
1040 MIPS32_BEQ(isa
, 0, 0, 0x10 << isa
), /* beq $zero, $zero, ncomp */
1041 MIPS32_ADDIU(isa
, 11, 0, 0), /* addiu $t3, $zero, 0 */
1043 MIPS32_LB(isa
, 5, 0, 12), /* lb $a1, ($t4) */
1044 MIPS32_ADDI(isa
, 12, 12, 1), /* addi $t4, $t4, 1 */
1045 MIPS32_SLL(isa
, 5, 5, 24), /* sll $a1, $a1, 24 */
1046 MIPS32_LUI(isa
, 2, 0x04c1), /* lui $v0, 0x04c1 */
1047 MIPS32_XOR(isa
, 4, 4, 5), /* xor $a0, $a0, $a1 */
1048 MIPS32_ORI(isa
, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
1049 MIPS32_ADDU(isa
, 6, 0, 0), /* addu $a2, $zero, $zero */
1051 MIPS32_SLL(isa
, 8, 4, 1), /* sll $t0, $a0, 1 */
1052 MIPS32_ADDIU(isa
, 6, 6, 1), /* addiu $a2, $a2, 1 */
1053 MIPS32_SLTI(isa
, 4, 4, 0), /* slti $a0, $a0, 0 */
1054 MIPS32_XOR(isa
, 9, 8, 7), /* xor $t1, $t0, $a3 */
1055 MIPS32_MOVN(isa
, 8, 9, 4), /* movn $t0, $t1, $a0 */
1056 MIPS32_SLTI(isa
, 3, 6, 8), /* slti $v1, $a2, 8 */
1057 MIPS32_BNE(isa
, 3, 0, NEG16(7 << isa
)), /* bne $v1, $zero, loop */
1058 MIPS32_ADDU(isa
, 4, 8, 0), /* addu $a0, $t0, $zero */
1060 MIPS32_BNE(isa
, 10, 11, NEG16(16 << isa
)), /* bne $t2, $t3, nbyte */
1061 MIPS32_ADDIU(isa
, 11, 11, 1), /* addiu $t3, $t3, 1 */
1065 /* make sure we have a working area */
1066 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
1067 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1069 pracc_swap16_array(ejtag_info
, mips_crc_code
, ARRAY_SIZE(mips_crc_code
));
1071 /* convert mips crc code into a buffer in target endianness */
1072 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
1073 target_buffer_set_u32_array(target
, mips_crc_code_8
,
1074 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
1076 int retval
= target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
1077 if (retval
!= ERROR_OK
)
1080 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
1081 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
; /* run isa as in debug mode */
1083 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
1084 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
1086 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
1087 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
1089 unsigned int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
1091 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
, crc_algorithm
->address
,
1092 crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
, &mips32_info
);
1094 if (retval
== ERROR_OK
)
1095 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
1097 destroy_reg_param(®_params
[0]);
1098 destroy_reg_param(®_params
[1]);
1100 target_free_working_area(target
, crc_algorithm
);
1105 /** Checks whether a memory region is erased. */
1106 int mips32_blank_check_memory(struct target
*target
,
1107 struct target_memory_check_block
*blocks
, int num_blocks
,
1108 uint8_t erased_value
)
1110 struct working_area
*erase_check_algorithm
;
1111 struct reg_param reg_params
[3];
1112 struct mips32_algorithm mips32_info
;
1114 struct mips32_common
*mips32
= target_to_mips32(target
);
1115 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1117 if (erased_value
!= 0xff) {
1118 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
1122 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
1123 uint32_t erase_check_code
[] = {
1125 MIPS32_LB(isa
, 8, 0, 4), /* lb $t0, ($a0) */
1126 MIPS32_AND(isa
, 6, 6, 8), /* and $a2, $a2, $t0 */
1127 MIPS32_ADDIU(isa
, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
1128 MIPS32_BNE(isa
, 5, 0, NEG16(4 << isa
)), /* bne $a1, $zero, nbyte */
1129 MIPS32_ADDIU(isa
, 4, 4, 1), /* addiu $a0, $a0, 1 */
1130 MIPS32_SDBBP(isa
) /* sdbbp */
1133 /* make sure we have a working area */
1134 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
1135 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1137 pracc_swap16_array(ejtag_info
, erase_check_code
, ARRAY_SIZE(erase_check_code
));
1139 /* convert erase check code into a buffer in target endianness */
1140 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
1141 target_buffer_set_u32_array(target
, erase_check_code_8
,
1142 ARRAY_SIZE(erase_check_code
), erase_check_code
);
1144 int retval
= target_write_buffer(target
, erase_check_algorithm
->address
,
1145 sizeof(erase_check_code
), erase_check_code_8
);
1146 if (retval
!= ERROR_OK
)
1149 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
1150 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
;
1152 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
1153 buf_set_u32(reg_params
[0].value
, 0, 32, blocks
[0].address
);
1155 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
1156 buf_set_u32(reg_params
[1].value
, 0, 32, blocks
[0].size
);
1158 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
1159 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
1161 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, erase_check_algorithm
->address
,
1162 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4), 10000, &mips32_info
);
1164 if (retval
== ERROR_OK
)
1165 blocks
[0].result
= buf_get_u32(reg_params
[2].value
, 0, 32);
1167 destroy_reg_param(®_params
[0]);
1168 destroy_reg_param(®_params
[1]);
1169 destroy_reg_param(®_params
[2]);
1172 target_free_working_area(target
, erase_check_algorithm
);
1174 if (retval
!= ERROR_OK
)
1177 return 1; /* only one block has been checked */
1180 static int mips32_verify_pointer(struct command_invocation
*cmd
,
1181 struct mips32_common
*mips32
)
1183 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
1184 command_print(cmd
, "target is not an MIPS32");
1185 return ERROR_TARGET_INVALID
;
1191 * mips32_read_config_mmu - Reads MMU configuration and logs relevant information.
1192 * @param[in] ejtag_info: EJTAG interface information.
1194 * @brief Reads the MMU configuration from the CP0 register and calculates the number of TLB entries,
1195 * ways, and sets. Handles different MMU types like VTLB only, root RPU/Fixed, and VTLB and FTLB.
1197 * @return ERROR_OK on success; error code on failure.
1199 static int mips32_read_config_mmu(struct mips_ejtag
*ejtag_info
)
1201 uint32_t config4
, tlb_entries
= 0, ways
= 0, sets
= 0;
1202 uint32_t config0
= ejtag_info
->config
[0];
1203 uint32_t config1
= ejtag_info
->config
[1];
1204 uint32_t config3
= ejtag_info
->config
[3];
1205 uint32_t mmu_type
= (config0
>> 7) & 7;
1206 uint32_t vz_present
= (config3
& BIT(23));
1208 int retval
= mips32_cp0_read(ejtag_info
, &config4
, 16, 4);
1209 if (retval
!= ERROR_OK
)
1212 /* mmu type = 1: VTLB only (Note: Does not account for Config4.ExtVTLB)
1213 * mmu type = 3: root RPU/Fixed (Note: Only valid with VZ ASE)
1214 * mmu type = 4: VTLB and FTLB
1216 if ((mmu_type
== 1 || mmu_type
== 4) || (mmu_type
== 3 && vz_present
)) {
1217 tlb_entries
= (uint32_t)(((config1
>> 25) & 0x3f) + 1);
1218 if (mmu_type
== 4) {
1219 /* Release 6 definition for Config4[0:15] (MD01251, page 243) */
1220 /* The FTLB ways field is defined as [2, 3, 4, 5, 6, 7, 8, ...0 (reserved)] */
1221 int index
= ((config4
>> 4) & 0xf);
1222 ways
= index
> 6 ? 0 : index
+ 2;
1224 /* The FTLB sets field is defined as [1, 2, 4, 8, ..., 16384, 32768] (powers of 2) */
1225 index
= (config4
& 0xf);
1227 tlb_entries
= tlb_entries
+ (ways
* sets
);
1230 LOG_USER("TLB Entries: %d (%d ways, %d sets per way)", tlb_entries
, ways
, sets
);
1236 * mips32_cp0_find_register_by_name - Find CP0 register by its name.
1237 * @param[in] cp0_mask: Mask to filter out irrelevant registers.
1238 * @param[in] reg_name: Name of the register to find.
1240 * @brief This function iterates through mips32_cp0_regs to find a register
1241 * matching reg_name, considering cp0_mask to filter out registers
1242 * not relevant for the current core.
1244 * @return Pointer to the found register, or NULL if not found.
1246 static const struct mips32_cp0
*mips32_cp0_find_register_by_name(uint32_t cp0_mask
, const char *reg_name
)
1249 for (unsigned int i
= 0; i
< MIPS32NUMCP0REGS
; i
++) {
1250 if ((mips32_cp0_regs
[i
].core
& cp0_mask
) == 0)
1253 if (strcmp(mips32_cp0_regs
[i
].name
, reg_name
) == 0)
1254 return &mips32_cp0_regs
[i
];
1260 * mips32_cp0_get_all_regs - Print all CP0 registers and their values.
1261 * @param[in] cmd: Command invocation context.
1262 * @param[in] ejtag_info: EJTAG interface information.
1263 * @param[in] cp0_mask: Mask to identify relevant registers.
1265 * @brief Iterates over all CP0 registers, reads their values, and prints them.
1266 * Only considers registers relevant to the current core, as defined by cp0_mask.
1268 * @return ERROR_OK on success; error code on failure.
1270 static int mips32_cp0_get_all_regs(struct command_invocation
*cmd
, struct mips_ejtag
*ejtag_info
, uint32_t cp0_mask
)
1274 for (unsigned int i
= 0; i
< MIPS32NUMCP0REGS
; i
++) {
1275 /* Register name not valid for this core */
1276 if ((mips32_cp0_regs
[i
].core
& cp0_mask
) == 0)
1279 int retval
= mips32_cp0_read(ejtag_info
, &value
, mips32_cp0_regs
[i
].reg
, mips32_cp0_regs
[i
].sel
);
1280 if (retval
!= ERROR_OK
) {
1281 command_print(CMD
, "Error: couldn't access reg %s", mips32_cp0_regs
[i
].name
);
1285 command_print(CMD
, "%*s: 0x%8.8" PRIx32
, 14, mips32_cp0_regs
[i
].name
, value
);
1291 * mips32_cp0_get_reg_by_name - Read and print a CP0 register's value by name.
1292 * @param[in] cmd: Command invocation context.
1293 * @param[in] ejtag_info: EJTAG interface information.
1294 * @param[in] cp0_mask: Mask to identify relevant registers.
1296 * @brief Finds a CP0 register by name, reads its value, and prints it.
1297 * Handles error scenarios like register not found or read failure.
1299 * @return ERROR_OK on success; error code on failure.
1301 static int mips32_cp0_get_reg_by_name(struct command_invocation
*cmd
, struct mips_ejtag
*ejtag_info
, uint32_t cp0_mask
)
1303 const struct mips32_cp0
*cp0_regs
= mips32_cp0_find_register_by_name(cp0_mask
, CMD_ARGV
[0]);
1305 command_print(CMD
, "Error: Register '%s' not found", CMD_ARGV
[0]);
1306 return ERROR_COMMAND_ARGUMENT_INVALID
;
1310 int retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_regs
->reg
, cp0_regs
->sel
);
1311 if (retval
!= ERROR_OK
) {
1312 command_print(CMD
, "Error: Encounter an Error while reading cp0 reg %d sel %d",
1313 cp0_regs
->reg
, cp0_regs
->sel
);
1317 command_print(CMD
, "0x%8.8" PRIx32
, value
);
1322 * mips32_cp0_get_reg_by_number - Read and print a CP0 register's value by number.
1323 * @param[in] cmd: Command invocation context.
1324 * @param[in] ejtag_info: EJTAG interface information.
1326 * @brief Reads a specific CP0 register (identified by number and selection) and prints its value.
1327 * The register number and selection are parsed from the command arguments.
1329 * @return ERROR_OK on success; error code on failure.
1331 static int mips32_cp0_get_reg_by_number(struct command_invocation
*cmd
, struct mips_ejtag
*ejtag_info
)
1333 uint32_t cp0_reg
, cp0_sel
, value
;
1334 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
1335 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
1337 int retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
1338 if (retval
!= ERROR_OK
) {
1340 "Error: couldn't access reg %" PRIu32
,
1345 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1346 cp0_reg
, cp0_sel
, value
);
1351 * mips32_cp0_set_reg_by_name - Write to a CP0 register identified by name.
1352 * @param[in] cmd: Command invocation context.
1353 * @param[in] mips32: Common MIPS32 data structure.
1354 * @param[in] ejtag_info: EJTAG interface information.
1356 * @brief Writes a value to a CP0 register specified by name. Updates internal
1357 * cache if specific registers (STATUS, CAUSE, DEPC, GUESTCTL1) are modified.
1359 * @return ERROR_OK on success; error code on failure.
1361 static int mips32_cp0_set_reg_by_name(struct command_invocation
*cmd
,
1362 struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
)
1364 const struct mips32_cp0
*cp0_regs
= mips32_cp0_find_register_by_name(mips32
->cp0_mask
, CMD_ARGV
[0]);
1366 command_print(CMD
, "Error: Register '%s' not found", CMD_ARGV
[0]);
1367 return ERROR_COMMAND_ARGUMENT_INVALID
;
1372 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
1374 if (cp0_regs
->reg
== MIPS32_C0_STATUS
&& cp0_regs
->sel
== 0) {
1375 /* Update cached Status register if user is writing to Status */
1376 mips32
->core_regs
.cp0
[MIPS32_REG_C0_STATUS_INDEX
] = value
;
1377 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_STATUS_INDEX
].dirty
= 1;
1378 } else if (cp0_regs
->reg
== MIPS32_C0_CAUSE
&& cp0_regs
->sel
== 0) {
1379 /* Update register cache with new value if its Cause */
1380 mips32
->core_regs
.cp0
[MIPS32_REG_C0_CAUSE_INDEX
] = value
;
1381 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_CAUSE_INDEX
].dirty
= 1;
1382 } else if (cp0_regs
->reg
== MIPS32_C0_DEPC
&& cp0_regs
->sel
== 0) {
1383 /* Update cached PC if its DEPC */
1384 mips32
->core_regs
.cp0
[MIPS32_REG_C0_PC_INDEX
] = value
;
1385 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].dirty
= 1;
1386 } else if (cp0_regs
->reg
== MIPS32_C0_GUESTCTL1
&& cp0_regs
->sel
== 4) {
1387 /* Update cached guestCtl1 */
1388 mips32
->core_regs
.cp0
[MIPS32_REG_C0_GUESTCTL1_INDEX
] = value
;
1389 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_GUESTCTL1_INDEX
].dirty
= 1;
1392 int retval
= mips32_cp0_write(ejtag_info
, value
,
1395 if (retval
!= ERROR_OK
) {
1396 command_print(CMD
, "Error: Encounter an Error while writing to cp0 reg %d, sel %d",
1397 cp0_regs
->reg
, cp0_regs
->sel
);
1401 command_print(CMD
, "cp0 reg %s (%u, select %u: %8.8" PRIx32
")",
1402 CMD_ARGV
[0], cp0_regs
->reg
, cp0_regs
->sel
, value
);
1407 * mips32_cp0_set_reg_by_number - Write to a CP0 register identified by number.
1408 * @param[in] cmd: Command invocation context.
1409 * @param[in] mips32: Common MIPS32 data structure.
1410 * @param[in] ejtag_info: EJTAG interface information.
1412 * @brief Writes a value to a CP0 register specified by number and selection.
1413 * Handles special cases like updating the internal cache for certain registers.
1415 * @return ERROR_OK on success; error code on failure.
1417 static int mips32_cp0_set_reg_by_number(struct command_invocation
*cmd
,
1418 struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
)
1420 uint32_t cp0_reg
, cp0_sel
, value
;
1421 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
1422 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
1423 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
1425 if (cp0_reg
== MIPS32_C0_STATUS
&& cp0_sel
== 0) {
1426 /* Update cached status register if user is writing to Status register */
1427 mips32
->core_regs
.cp0
[MIPS32_REG_C0_STATUS_INDEX
] = value
;
1428 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_STATUS_INDEX
].dirty
= 1;
1429 } else if (cp0_reg
== MIPS32_C0_CAUSE
&& cp0_sel
== 0) {
1430 /* Update register cache with new value if its Cause register */
1431 mips32
->core_regs
.cp0
[MIPS32_REG_C0_CAUSE_INDEX
] = value
;
1432 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_CAUSE_INDEX
].dirty
= 1;
1433 } else if (cp0_reg
== MIPS32_C0_DEPC
&& cp0_sel
== 0) {
1434 /* Update cached PC if its DEPC */
1435 mips32
->core_regs
.cp0
[MIPS32_REG_C0_PC_INDEX
] = value
;
1436 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].dirty
= 1;
1437 } else if (cp0_reg
== MIPS32_C0_GUESTCTL1
&& cp0_sel
== 4) {
1438 /* Update cached guestCtl1, too */
1439 mips32
->core_regs
.cp0
[MIPS32_REG_C0_GUESTCTL1_INDEX
] = value
;
1440 mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_GUESTCTL1_INDEX
].dirty
= 1;
1443 int retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
1444 if (retval
!= ERROR_OK
) {
1446 "Error: couldn't access cp0 reg %" PRIu32
", select %" PRIu32
,
1451 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1452 cp0_reg
, cp0_sel
, value
);
1457 * mips32_handle_cp0_command - Handle commands related to CP0 registers.
1458 * @cmd: Command invocation context.
1460 * Orchestrates different operations on CP0 registers based on the command arguments.
1461 * Supports operations like reading all registers, reading/writing a specific register
1462 * by name or number.
1464 * Return: ERROR_OK on success; error code on failure.
1466 COMMAND_HANDLER(mips32_handle_cp0_command
)
1469 struct target
*target
= get_current_target(CMD_CTX
);
1470 struct mips32_common
*mips32
= target_to_mips32(target
);
1471 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1474 retval
= mips32_verify_pointer(CMD
, mips32
);
1475 if (retval
!= ERROR_OK
)
1478 if (target
->state
!= TARGET_HALTED
) {
1479 command_print(CMD
, "Error: target must be stopped for \"%s\" command", CMD_NAME
);
1480 return ERROR_TARGET_NOT_HALTED
;
1484 case 0: /* No arg => print out all cp0 regs */
1485 retval
= mips32_cp0_get_all_regs(CMD
, ejtag_info
, mips32
->cp0_mask
);
1487 case 1: /* 1 arg => get cp0 #reg/#sel value by name */
1488 retval
= mips32_cp0_get_reg_by_name(CMD
, ejtag_info
, mips32
->cp0_mask
);
1490 case 2: /* 2 args => get cp0 reg/sel value or set value by name */
1492 if (isdigit(tmp
)) /* starts from number then args are #reg and #sel */
1493 retval
= mips32_cp0_get_reg_by_number(CMD
, ejtag_info
);
1494 else /* or set value by register name */
1495 retval
= mips32_cp0_set_reg_by_name(CMD
, mips32
, ejtag_info
);
1498 case 3: /* 3 args => set cp0 reg/sel value*/
1499 retval
= mips32_cp0_set_reg_by_number(CMD
, mips32
, ejtag_info
);
1501 default: /* Other argc => err */
1502 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1510 * mips32_handle_cpuinfo_command - Handles the 'cpuinfo' command.
1511 * @param[in] cmd: Command invocation context.
1513 * @brief Executes the 'cpuinfo' command which displays detailed information about the current CPU core.
1514 * This includes core type, vendor, instruction set, cache size, and other relevant details.
1516 * @return ERROR_OK on success; error code on failure.
1518 COMMAND_HANDLER(mips32_handle_cpuinfo_command
)
1521 struct target
*target
= get_current_target(CMD_CTX
);
1522 struct mips32_common
*mips32
= target_to_mips32(target
);
1523 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1525 uint32_t prid
= mips32
->prid
; /* cp0 PRID - 15, 0 */
1526 uint32_t config0
= ejtag_info
->config
[0]; /* cp0 config - 16, 0 */
1527 uint32_t config1
= ejtag_info
->config
[1]; /* cp0 config - 16, 1 */
1528 uint32_t config3
= ejtag_info
->config
[3]; /* cp0 config - 16, 3 */
1530 /* Following configs are not read during probe */
1531 uint32_t config5
; /* cp0 config - 16, 5 */
1533 /* No args for now */
1535 return ERROR_COMMAND_SYNTAX_ERROR
;
1537 if (target
->state
!= TARGET_HALTED
) {
1538 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
1539 return ERROR_TARGET_NOT_HALTED
;
1542 retval
= mips32_cp0_read(ejtag_info
, &config5
, 16, 5);
1543 if (retval
!= ERROR_OK
)
1546 /* Determine Core info */
1547 const struct cpu_entry
*entry
= mips32
->cpu_info
;
1548 /* Display Core Type info */
1549 command_print(CMD
, "CPU Core: %s", entry
->cpu_name
);
1551 /* Display Core Vendor ID if it's unknown */
1552 if (entry
== &mips32_cpu_entry
[MIPS32_NUM_CPU_ENTRIES
- 1])
1553 command_print(CMD
, "Vendor: Unknown CPU vendor code %x.", ((prid
& 0x00ffff00) >> 16));
1555 command_print(CMD
, "Vendor: %s", entry
->vendor
);
1557 /* If MIPS release 2 or above, then get exception base info */
1558 enum mips32_isa_rel ar
= mips32
->isa_rel
;
1559 if (ar
> MIPS32_RELEASE_1
) { /* release 2 and above */
1561 retval
= mips32_cp0_read(ejtag_info
, &ebase
, 15, 1);
1562 if (retval
!= ERROR_OK
)
1565 command_print(CMD
, "Current CPU ID: %d", (ebase
& 0x1ff));
1567 command_print(CMD
, "Current CPU ID: 0");
1571 switch ((config3
& MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
) {
1576 instr
= "microMIPS";
1579 instr
= "MIPS32 (at reset) and microMIPS";
1582 instr
= "microMIPS (at reset) and MIPS32";
1586 /* Display Instruction Set Info */
1587 command_print(CMD
, "Instr set: %s", instr
);
1588 command_print(CMD
, "Instr rel: %s",
1589 ar
== MIPS32_RELEASE_1
? "1"
1590 : ar
== MIPS32_RELEASE_2
? "2"
1591 : ar
== MIPS32_RELEASE_6
? "6"
1593 command_print(CMD
, "PRId: %x", prid
);
1594 /* Some of MIPS CPU Revisions(for M74K) can be seen on MD00541, page 26 */
1595 uint32_t rev
= prid
& 0x000000ff;
1596 command_print(CMD
, "RTL Rev: %d.%d.%d", (rev
& 0xE0), (rev
& 0x1C), (rev
& 0x3));
1598 command_print(CMD
, "Max Number of Instr Breakpoints: %d", mips32
->num_inst_bpoints
);
1599 command_print(CMD
, "Max Number of Data Breakpoints: %d", mips32
->num_data_bpoints
);
1602 uint32_t mmu_type
= (config0
>> 7) & 7; /* MMU Type Info */
1605 case MIPS32_MMU_TLB
:
1608 case MIPS32_MMU_BAT
:
1611 case MIPS32_MMU_FIXED
:
1614 case MIPS32_MMU_DUAL_VTLB_FTLB
:
1615 mmu
= "DUAL VAR/FIXED";
1620 command_print(CMD
, "MMU Type: %s", mmu
);
1622 retval
= mips32_read_config_mmu(ejtag_info
);
1623 if (retval
!= ERROR_OK
)
1626 /* Definitions of I/D Cache Sizes are available on MD01251, page 224~226 */
1628 uint32_t ways
, sets
, bpl
;
1630 /* Determine Instr Cache Size */
1631 /* Ways mapping = [1, 2, 3, 4, 5, 6, 7, 8] */
1632 ways
= ((config1
>> MIPS32_CFG1_IASHIFT
) & 7);
1634 /* Sets per way = [64, 128, 256, 512, 1024, 2048, 4096, 32] */
1635 index
= ((config1
>> MIPS32_CFG1_ISSHIFT
) & 7);
1636 sets
= index
== 7 ? 32 : 32 << (index
+ 1);
1638 /* Bytes per line = [0, 4, 8, 16, 32, 64, 128, Reserved] */
1639 index
= ((config1
>> MIPS32_CFG1_ILSHIFT
) & 7);
1640 bpl
= index
== 0 ? 0 : 4 << (index
- 1);
1641 command_print(CMD
, "Instr Cache: %d (%d ways, %d lines, %d byte per line)", ways
* sets
* bpl
, ways
, sets
, bpl
);
1643 /* Determine data cache size, same as above */
1644 ways
= ((config1
>> MIPS32_CFG1_DASHIFT
) & 7);
1646 index
= ((config1
>> MIPS32_CFG1_DSSHIFT
) & 7);
1647 sets
= index
== 7 ? 32 : 32 << (index
+ 1);
1649 index
= ((config1
>> MIPS32_CFG1_DLSHIFT
) & 7);
1650 bpl
= index
== 0 ? 0 : 4 << (index
- 1);
1651 command_print(CMD
, " Data Cache: %d (%d ways, %d lines, %d byte per line)", ways
* sets
* bpl
, ways
, sets
, bpl
);
1653 /* does the core hava FPU*/
1654 mips32_read_config_fpu(mips32
, ejtag_info
);
1656 /* does the core support a DSP */
1657 mips32_read_config_dsp(mips32
, ejtag_info
);
1660 uint32_t vzase
= (config3
& BIT(23));
1662 command_print(CMD
, "VZ implemented: yes");
1664 command_print(CMD
, "VZ implemented: no");
1666 /* multithreading */
1667 uint32_t mtase
= (config3
& BIT(2));
1669 command_print(CMD
, "MT implemented: yes");
1671 /* Get VPE and Thread info */
1675 /* Read tcbind register */
1676 retval
= mips32_cp0_read(ejtag_info
, &tcbind
, 2, 2);
1677 if (retval
!= ERROR_OK
)
1680 command_print(CMD
, " | Current VPE: %d", (tcbind
& 0xf));
1681 command_print(CMD
, " | Current TC: %d", ((tcbind
>> 21) & 0xff));
1683 /* Read mvpconf0 register */
1684 retval
= mips32_cp0_read(ejtag_info
, &mvpconf0
, 0, 2);
1685 if (retval
!= ERROR_OK
)
1688 command_print(CMD
, " | Total TC: %d", (mvpconf0
& 0xf) + 1);
1689 command_print(CMD
, " | Total VPE: %d", ((mvpconf0
>> 10) & 0xf) + 1);
1691 command_print(CMD
, "MT implemented: no");
1694 /* MIPS SIMD Architecture (MSA) */
1695 uint32_t msa
= (config3
& BIT(28));
1696 command_print(CMD
, "MSA implemented: %s", msa
? "yes" : "no");
1698 /* Move To/From High COP0 (MTHC0/MFHC0) instructions are implemented.
1699 * Implicates current ISA release >= 5.*/
1700 uint32_t mvh
= (config5
& BIT(5));
1701 command_print(CMD
, "MVH implemented: %s", mvh
? "yes" : "no");
1703 /* Common Device Memory Map implemented? */
1704 uint32_t cdmm
= (config3
& BIT(3));
1705 command_print(CMD
, "CDMM implemented: %s", cdmm
? "yes" : "no");
1710 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
1712 struct target
*target
= get_current_target(CMD_CTX
);
1713 struct mips32_common
*mips32
= target_to_mips32(target
);
1714 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1717 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
1718 else if (CMD_ARGC
> 1)
1719 return ERROR_COMMAND_SYNTAX_ERROR
;
1721 command_print(CMD
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
1722 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
1723 ejtag_info
->mode
= 0;
1724 command_print(CMD
, "running in legacy mode");
1726 ejtag_info
->mode
= 1;
1727 command_print(CMD
, "running in fast queued mode");
1733 static const struct command_registration mips32_exec_command_handlers
[] = {
1736 .handler
= mips32_handle_cp0_command
,
1737 .mode
= COMMAND_EXEC
,
1738 .usage
= "[[reg_name|regnum select] [value]]",
1739 .help
= "display/modify cp0 register",
1743 .handler
= mips32_handle_cpuinfo_command
,
1744 .mode
= COMMAND_EXEC
,
1745 .help
= "display CPU information",
1749 .name
= "scan_delay",
1750 .handler
= mips32_handle_scan_delay_command
,
1751 .mode
= COMMAND_ANY
,
1752 .help
= "display/set scan delay in nano seconds",
1755 COMMAND_REGISTRATION_DONE
1758 const struct command_registration mips32_command_handlers
[] = {
1761 .mode
= COMMAND_ANY
,
1762 .help
= "mips32 command group",
1764 .chain
= mips32_exec_command_handlers
,
1766 COMMAND_REGISTRATION_DONE
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)