2 * Support for processors implementing MIPS64 instruction set
4 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
5 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
6 * Copyright (C) 2014 by Antony Pavlov <antonynpavlov@gmail.com>
7 * Copyright (C) 2014 by Peter Mamonov <pmamonov@gmail.com>
9 * Based on the work of:
10 * Copyright (C) 2008 by Spencer Oliver
11 * Copyright (C) 2008 by David T.L. Wong
12 * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
14 * SPDX-License-Identifier: GPL-2.0-or-later
31 { 0, "r0", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
32 { 1, "r1", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
33 { 2, "r2", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
34 { 3, "r3", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
35 { 4, "r4", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
36 { 5, "r5", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
37 { 6, "r6", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
38 { 7, "r7", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
39 { 8, "r8", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
40 { 9, "r9", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
41 { 10, "r10", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
42 { 11, "r11", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
43 { 12, "r12", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
44 { 13, "r13", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
45 { 14, "r14", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
46 { 15, "r15", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
47 { 16, "r16", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
48 { 17, "r17", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
49 { 18, "r18", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
50 { 19, "r19", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
51 { 20, "r20", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
52 { 21, "r21", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
53 { 22, "r22", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
54 { 23, "r23", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 24, "r24", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 25, "r25", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 26, "r26", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 27, "r27", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 28, "r28", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 29, "r29", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 30, "r30", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 31, "r31", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 32, "lo", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 33, "hi", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { MIPS64_NUM_CORE_REGS
+ 0, "pc", REG_TYPE_UINT64
, NULL
,
66 "org.gnu.gdb.mips.cpu", 0 },
67 { MIPS64_NUM_CORE_REGS
+ 1, "Random", REG_TYPE_UINT32
, NULL
,
68 "org.gnu.gdb.mips.cp0", 0 },
69 { MIPS64_NUM_CORE_REGS
+ 2, "Entrylo_0", REG_TYPE_UINT64
, NULL
,
70 "org.gnu.gdb.mips.cp0", 0 },
71 { MIPS64_NUM_CORE_REGS
+ 3, "Entrylo_1", REG_TYPE_UINT64
, NULL
,
72 "org.gnu.gdb.mips.cp0", 0 },
73 { MIPS64_NUM_CORE_REGS
+ 4, "Context", REG_TYPE_UINT64
, NULL
,
74 "org.gnu.gdb.mips.cp0", 0 },
75 { MIPS64_NUM_CORE_REGS
+ 5, "Pagemask", REG_TYPE_UINT32
, NULL
,
76 "org.gnu.gdb.mips.cp0", 0 },
77 { MIPS64_NUM_CORE_REGS
+ 6, "Wired", REG_TYPE_UINT32
, NULL
,
78 "org.gnu.gdb.mips.cp0", 0 },
79 { MIPS64_NUM_CORE_REGS
+ 7, "badvaddr", REG_TYPE_UINT64
, NULL
,
80 "org.gnu.gdb.mips.cp0", 0 },
81 { MIPS64_NUM_CORE_REGS
+ 8, "Count", REG_TYPE_UINT32
, NULL
,
82 "org.gnu.gdb.mips.cp0", 0 },
83 { MIPS64_NUM_CORE_REGS
+ 9, "EntryHi", REG_TYPE_UINT64
, NULL
,
84 "org.gnu.gdb.mips.cp0", 0 },
85 { MIPS64_NUM_CORE_REGS
+ 10, "Compare", REG_TYPE_UINT32
, NULL
,
86 "org.gnu.gdb.mips.cp0", 0 },
87 { MIPS64_NUM_CORE_REGS
+ 11, "status", REG_TYPE_UINT32
, NULL
,
88 "org.gnu.gdb.mips.cp0", 0 },
89 { MIPS64_NUM_CORE_REGS
+ 12, "cause", REG_TYPE_UINT32
, NULL
,
90 "org.gnu.gdb.mips.cp0", 0 },
91 { MIPS64_NUM_CORE_REGS
+ 13, "EPC", REG_TYPE_UINT64
, NULL
,
92 "org.gnu.gdb.mips.cp0", 0 },
93 { MIPS64_NUM_CORE_REGS
+ 14, "PrID", REG_TYPE_UINT32
, NULL
,
94 "org.gnu.gdb.mips.cp0", 0 },
95 { MIPS64_NUM_CORE_REGS
+ 15, "Config", REG_TYPE_UINT32
, NULL
,
96 "org.gnu.gdb.mips.cp0", 0 },
97 { MIPS64_NUM_CORE_REGS
+ 16, "LLA", REG_TYPE_UINT32
, NULL
,
98 "org.gnu.gdb.mips.cp0", 0 },
99 { MIPS64_NUM_CORE_REGS
+ 17, "WatchLo0", REG_TYPE_UINT64
, NULL
,
100 "org.gnu.gdb.mips.cp0", 0 },
101 { MIPS64_NUM_CORE_REGS
+ 18, "WatchLo1", REG_TYPE_UINT64
, NULL
,
102 "org.gnu.gdb.mips.cp0", 0 },
103 { MIPS64_NUM_CORE_REGS
+ 19, "WatchHi0", REG_TYPE_UINT32
, NULL
,
104 "org.gnu.gdb.mips.cp0", 0 },
105 { MIPS64_NUM_CORE_REGS
+ 20, "WatchHi1", REG_TYPE_UINT32
, NULL
,
106 "org.gnu.gdb.mips.cp0", 0 },
107 { MIPS64_NUM_CORE_REGS
+ 21, "Xcontext", REG_TYPE_UINT64
, NULL
,
108 "org.gnu.gdb.mips.cp0", 0 },
109 { MIPS64_NUM_CORE_REGS
+ 22, "ChipMemCtrl", REG_TYPE_UINT32
, NULL
,
110 "org.gnu.gdb.mips.cp0", 0 },
111 { MIPS64_NUM_CORE_REGS
+ 23, "Debug", REG_TYPE_UINT32
, NULL
,
112 "org.gnu.gdb.mips.cp0", 0 },
113 { MIPS64_NUM_CORE_REGS
+ 24, "Perfcount, sel=0", REG_TYPE_UINT32
, NULL
,
114 "org.gnu.gdb.mips.cp0", 0 },
115 { MIPS64_NUM_CORE_REGS
+ 25, "Perfcount, sel=1", REG_TYPE_UINT64
, NULL
,
116 "org.gnu.gdb.mips.cp0", 0 },
117 { MIPS64_NUM_CORE_REGS
+ 26, "Perfcount, sel=2", REG_TYPE_UINT32
, NULL
,
118 "org.gnu.gdb.mips.cp0", 0 },
119 { MIPS64_NUM_CORE_REGS
+ 27, "Perfcount, sel=3", REG_TYPE_UINT64
, NULL
,
120 "org.gnu.gdb.mips.cp0", 0 },
121 { MIPS64_NUM_CORE_REGS
+ 28, "ECC", REG_TYPE_UINT32
, NULL
,
122 "org.gnu.gdb.mips.cp0", 0 },
123 { MIPS64_NUM_CORE_REGS
+ 29, "CacheErr", REG_TYPE_UINT32
, NULL
,
124 "org.gnu.gdb.mips.cp0", 0 },
125 { MIPS64_NUM_CORE_REGS
+ 30, "TagLo", REG_TYPE_UINT32
, NULL
,
126 "org.gnu.gdb.mips.cp0", 0 },
127 { MIPS64_NUM_CORE_REGS
+ 31, "TagHi", REG_TYPE_UINT32
, NULL
,
128 "org.gnu.gdb.mips.cp0", 0 },
129 { MIPS64_NUM_CORE_REGS
+ 32, "DataHi", REG_TYPE_UINT64
, NULL
,
130 "org.gnu.gdb.mips.cp0", 0 },
131 { MIPS64_NUM_CORE_REGS
+ 33, "EEPC", REG_TYPE_UINT64
, NULL
,
132 "org.gnu.gdb.mips.cp0", 0 },
133 { MIPS64_NUM_CORE_C0_REGS
+ 0, "f0", REG_TYPE_IEEE_DOUBLE
, NULL
,
134 "org.gnu.gdb.mips.fpu", 0 },
135 { MIPS64_NUM_CORE_C0_REGS
+ 1, "f1", REG_TYPE_IEEE_DOUBLE
, NULL
,
136 "org.gnu.gdb.mips.fpu", 0 },
137 { MIPS64_NUM_CORE_C0_REGS
+ 2, "f2", REG_TYPE_IEEE_DOUBLE
, NULL
,
138 "org.gnu.gdb.mips.fpu", 0 },
139 { MIPS64_NUM_CORE_C0_REGS
+ 3, "f3", REG_TYPE_IEEE_DOUBLE
, NULL
,
140 "org.gnu.gdb.mips.fpu", 0 },
141 { MIPS64_NUM_CORE_C0_REGS
+ 4, "f4", REG_TYPE_IEEE_DOUBLE
, NULL
,
142 "org.gnu.gdb.mips.fpu", 0 },
143 { MIPS64_NUM_CORE_C0_REGS
+ 5, "f5", REG_TYPE_IEEE_DOUBLE
, NULL
,
144 "org.gnu.gdb.mips.fpu", 0 },
145 { MIPS64_NUM_CORE_C0_REGS
+ 6, "f6", REG_TYPE_IEEE_DOUBLE
, NULL
,
146 "org.gnu.gdb.mips.fpu", 0 },
147 { MIPS64_NUM_CORE_C0_REGS
+ 7, "f7", REG_TYPE_IEEE_DOUBLE
, NULL
,
148 "org.gnu.gdb.mips.fpu", 0 },
149 { MIPS64_NUM_CORE_C0_REGS
+ 8, "f8", REG_TYPE_IEEE_DOUBLE
, NULL
,
150 "org.gnu.gdb.mips.fpu", 0 },
151 { MIPS64_NUM_CORE_C0_REGS
+ 9, "f9", REG_TYPE_IEEE_DOUBLE
, NULL
,
152 "org.gnu.gdb.mips.fpu", 0 },
153 { MIPS64_NUM_CORE_C0_REGS
+ 10, "f10", REG_TYPE_IEEE_DOUBLE
, NULL
,
154 "org.gnu.gdb.mips.fpu", 0 },
155 { MIPS64_NUM_CORE_C0_REGS
+ 11, "f11", REG_TYPE_IEEE_DOUBLE
, NULL
,
156 "org.gnu.gdb.mips.fpu", 0 },
157 { MIPS64_NUM_CORE_C0_REGS
+ 12, "f12", REG_TYPE_IEEE_DOUBLE
, NULL
,
158 "org.gnu.gdb.mips.fpu", 0 },
159 { MIPS64_NUM_CORE_C0_REGS
+ 13, "f13", REG_TYPE_IEEE_DOUBLE
, NULL
,
160 "org.gnu.gdb.mips.fpu", 0 },
161 { MIPS64_NUM_CORE_C0_REGS
+ 14, "f14", REG_TYPE_IEEE_DOUBLE
, NULL
,
162 "org.gnu.gdb.mips.fpu", 0 },
163 { MIPS64_NUM_CORE_C0_REGS
+ 15, "f15", REG_TYPE_IEEE_DOUBLE
, NULL
,
164 "org.gnu.gdb.mips.fpu", 0 },
165 { MIPS64_NUM_CORE_C0_REGS
+ 16, "f16", REG_TYPE_IEEE_DOUBLE
, NULL
,
166 "org.gnu.gdb.mips.fpu", 0 },
167 { MIPS64_NUM_CORE_C0_REGS
+ 17, "f17", REG_TYPE_IEEE_DOUBLE
, NULL
,
168 "org.gnu.gdb.mips.fpu", 0 },
169 { MIPS64_NUM_CORE_C0_REGS
+ 18, "f18", REG_TYPE_IEEE_DOUBLE
, NULL
,
170 "org.gnu.gdb.mips.fpu", 0 },
171 { MIPS64_NUM_CORE_C0_REGS
+ 19, "f19", REG_TYPE_IEEE_DOUBLE
, NULL
,
172 "org.gnu.gdb.mips.fpu", 0 },
173 { MIPS64_NUM_CORE_C0_REGS
+ 20, "f20", REG_TYPE_IEEE_DOUBLE
, NULL
,
174 "org.gnu.gdb.mips.fpu", 0 },
175 { MIPS64_NUM_CORE_C0_REGS
+ 21, "f21", REG_TYPE_IEEE_DOUBLE
, NULL
,
176 "org.gnu.gdb.mips.fpu", 0 },
177 { MIPS64_NUM_CORE_C0_REGS
+ 22, "f22", REG_TYPE_IEEE_DOUBLE
, NULL
,
178 "org.gnu.gdb.mips.fpu", 0 },
179 { MIPS64_NUM_CORE_C0_REGS
+ 23, "f23", REG_TYPE_IEEE_DOUBLE
, NULL
,
180 "org.gnu.gdb.mips.fpu", 0 },
181 { MIPS64_NUM_CORE_C0_REGS
+ 24, "f24", REG_TYPE_IEEE_DOUBLE
, NULL
,
182 "org.gnu.gdb.mips.fpu", 0 },
183 { MIPS64_NUM_CORE_C0_REGS
+ 25, "f25", REG_TYPE_IEEE_DOUBLE
, NULL
,
184 "org.gnu.gdb.mips.fpu", 0 },
185 { MIPS64_NUM_CORE_C0_REGS
+ 26, "f26", REG_TYPE_IEEE_DOUBLE
, NULL
,
186 "org.gnu.gdb.mips.fpu", 0 },
187 { MIPS64_NUM_CORE_C0_REGS
+ 27, "f27", REG_TYPE_IEEE_DOUBLE
, NULL
,
188 "org.gnu.gdb.mips.fpu", 0 },
189 { MIPS64_NUM_CORE_C0_REGS
+ 28, "f28", REG_TYPE_IEEE_DOUBLE
, NULL
,
190 "org.gnu.gdb.mips.fpu", 0 },
191 { MIPS64_NUM_CORE_C0_REGS
+ 29, "f29", REG_TYPE_IEEE_DOUBLE
, NULL
,
192 "org.gnu.gdb.mips.fpu", 0 },
193 { MIPS64_NUM_CORE_C0_REGS
+ 30, "f30", REG_TYPE_IEEE_DOUBLE
, NULL
,
194 "org.gnu.gdb.mips.fpu", 0 },
195 { MIPS64_NUM_CORE_C0_REGS
+ 31, "f31", REG_TYPE_IEEE_DOUBLE
, NULL
,
196 "org.gnu.gdb.mips.fpu", 0 },
197 { MIPS64_NUM_CORE_C0_REGS
+ 32, "fcsr", REG_TYPE_INT
, "float",
198 "org.gnu.gdb.mips.fpu", 0 },
199 { MIPS64_NUM_CORE_C0_REGS
+ 33, "fir", REG_TYPE_INT
, "float",
200 "org.gnu.gdb.mips.fpu", 0 },
201 { MIPS64_NUM_CORE_C0_REGS
+ 34, "fconfig", REG_TYPE_INT
, "float",
202 "org.gnu.gdb.mips.fpu", 0 },
203 { MIPS64_NUM_CORE_C0_REGS
+ 35, "fccr", REG_TYPE_INT
, "float",
204 "org.gnu.gdb.mips.fpu", 0 },
205 { MIPS64_NUM_CORE_C0_REGS
+ 36, "fexr", REG_TYPE_INT
, "float",
206 "org.gnu.gdb.mips.fpu", 0 },
207 { MIPS64_NUM_CORE_C0_REGS
+ 37, "fenr", REG_TYPE_INT
, "float",
208 "org.gnu.gdb.mips.fpu", 0 },
211 static int reg_type2size(enum reg_type type
)
214 case REG_TYPE_UINT32
:
217 case REG_TYPE_UINT64
:
218 case REG_TYPE_IEEE_DOUBLE
:
225 static int mips64_get_core_reg(struct reg
*reg
)
228 struct mips64_core_reg
*mips64_reg
= reg
->arch_info
;
229 struct target
*target
= mips64_reg
->target
;
230 struct mips64_common
*mips64_target
= target
->arch_info
;
232 if (target
->state
!= TARGET_HALTED
)
233 return ERROR_TARGET_NOT_HALTED
;
235 retval
= mips64_target
->read_core_reg(target
, mips64_reg
->num
);
240 static int mips64_set_core_reg(struct reg
*reg
, uint8_t *buf
)
242 struct mips64_core_reg
*mips64_reg
= reg
->arch_info
;
243 struct target
*target
= mips64_reg
->target
;
244 uint64_t value
= buf_get_u64(buf
, 0, 64);
246 if (target
->state
!= TARGET_HALTED
)
247 return ERROR_TARGET_NOT_HALTED
;
249 buf_set_u64(reg
->value
, 0, 64, value
);
256 static int mips64_read_core_reg(struct target
*target
, int num
)
260 /* get pointers to arch-specific information */
261 struct mips64_common
*mips64
= target
->arch_info
;
263 if ((num
< 0) || (num
>= MIPS64_NUM_REGS
))
264 return ERROR_COMMAND_ARGUMENT_INVALID
;
266 reg_value
= mips64
->core_regs
[num
];
267 buf_set_u64(mips64
->core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
268 mips64
->core_cache
->reg_list
[num
].valid
= 1;
269 mips64
->core_cache
->reg_list
[num
].dirty
= 0;
274 static int mips64_write_core_reg(struct target
*target
, int num
)
278 /* get pointers to arch-specific information */
279 struct mips64_common
*mips64
= target
->arch_info
;
281 if ((num
< 0) || (num
>= MIPS64_NUM_REGS
))
282 return ERROR_COMMAND_ARGUMENT_INVALID
;
284 reg_value
= buf_get_u64(mips64
->core_cache
->reg_list
[num
].value
, 0, 64);
285 mips64
->core_regs
[num
] = reg_value
;
286 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, reg_value
);
287 mips64
->core_cache
->reg_list
[num
].valid
= 1;
288 mips64
->core_cache
->reg_list
[num
].dirty
= 0;
293 int mips64_invalidate_core_regs(struct target
*target
)
295 /* get pointers to arch-specific information */
296 struct mips64_common
*mips64
= target
->arch_info
;
299 for (i
= 0; i
< mips64
->core_cache
->num_regs
; i
++) {
300 mips64
->core_cache
->reg_list
[i
].valid
= 0;
301 mips64
->core_cache
->reg_list
[i
].dirty
= 0;
308 int mips64_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
309 int *reg_list_size
, enum target_register_class reg_class
)
311 /* get pointers to arch-specific information */
312 struct mips64_common
*mips64
= target
->arch_info
;
315 /* include floating point registers */
316 *reg_list_size
= MIPS64_NUM_REGS
;
317 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
319 for (i
= 0; i
< MIPS64_NUM_REGS
; i
++)
320 (*reg_list
)[i
] = &mips64
->core_cache
->reg_list
[i
];
325 int mips64_save_context(struct target
*target
)
328 struct mips64_common
*mips64
= target
->arch_info
;
329 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
331 retval
= mips64_pracc_read_regs(ejtag_info
, mips64
->core_regs
);
332 if (retval
!= ERROR_OK
)
335 for (unsigned i
= 0; i
< MIPS64_NUM_REGS
; i
++)
336 retval
= mips64
->read_core_reg(target
, i
);
341 int mips64_restore_context(struct target
*target
)
343 struct mips64_common
*mips64
= target
->arch_info
;
344 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
346 for (unsigned i
= 0; i
< MIPS64_NUM_REGS
; i
++) {
347 if (mips64
->core_cache
->reg_list
[i
].dirty
)
348 mips64
->write_core_reg(target
, i
);
351 return mips64_pracc_write_regs(ejtag_info
, mips64
->core_regs
);
354 int mips64_arch_state(struct target
*target
)
356 struct mips64_common
*mips64
= target
->arch_info
;
357 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
359 if (mips64
->common_magic
!= MIPS64_COMMON_MAGIC
) {
360 LOG_ERROR("BUG: called for a non-MIPS64 target");
364 LOG_USER("target halted due to %s, pc: 0x%" PRIx64
"",
365 debug_reason_name(target
), buf_get_u64(pc
->value
, 0, 64));
370 static const struct reg_arch_type mips64_reg_type
= {
371 .get
= mips64_get_core_reg
,
372 .set
= mips64_set_core_reg
,
375 int mips64_build_reg_cache(struct target
*target
)
377 /* get pointers to arch-specific information */
378 struct mips64_common
*mips64
= target
->arch_info
;
379 struct reg_cache
**cache_p
, *cache
;
380 struct mips64_core_reg
*arch_info
= NULL
;
381 struct reg
*reg_list
= NULL
;
384 cache
= calloc(1, sizeof(*cache
));
386 LOG_ERROR("unable to allocate cache");
390 reg_list
= calloc(MIPS64_NUM_REGS
, sizeof(*reg_list
));
392 LOG_ERROR("unable to allocate reg_list");
396 arch_info
= calloc(MIPS64_NUM_REGS
, sizeof(*arch_info
));
398 LOG_ERROR("unable to allocate arch_info");
402 for (i
= 0; i
< MIPS64_NUM_REGS
; i
++) {
403 struct mips64_core_reg
*a
= &arch_info
[i
];
404 struct reg
*r
= ®_list
[i
];
406 r
->arch_info
= &arch_info
[i
];
407 r
->caller_save
= true; /* gdb defaults to true */
409 r
->feature
= &a
->feature
;
410 r
->feature
->name
= mips64_regs
[i
].feature
;
411 r
->group
= mips64_regs
[i
].group
;
412 r
->name
= mips64_regs
[i
].name
;
414 r
->reg_data_type
= &a
->reg_data_type
;
415 r
->reg_data_type
->type
= mips64_regs
[i
].type
;
416 r
->size
= reg_type2size(mips64_regs
[i
].type
);
417 r
->type
= &mips64_reg_type
;
418 r
->value
= &a
->value
[0];
420 a
->mips64_common
= mips64
;
421 a
->num
= mips64_regs
[i
].id
;
425 cache
->name
= "mips64 registers";
426 cache
->reg_list
= reg_list
;
427 cache
->num_regs
= MIPS64_NUM_REGS
;
429 cache_p
= register_get_last_cache_p(&target
->reg_cache
);
432 mips64
->core_cache
= cache
;
444 int mips64_init_arch_info(struct target
*target
, struct mips64_common
*mips64
,
445 struct jtag_tap
*tap
)
447 mips64
->bp_scanned
= false;
448 mips64
->common_magic
= MIPS64_COMMON_MAGIC
;
449 mips64
->data_break_list
= NULL
;
450 mips64
->ejtag_info
.tap
= tap
;
451 mips64
->fast_data_area
= NULL
;
452 mips64
->mips64mode32
= false;
453 mips64
->read_core_reg
= mips64_read_core_reg
;
454 mips64
->write_core_reg
= mips64_write_core_reg
;
459 int mips64_run_algorithm(struct target
*target
, int num_mem_params
,
460 struct mem_param
*mem_params
, int num_reg_params
,
461 struct reg_param
*reg_params
, target_addr_t entry_point
,
462 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
468 int mips64_examine(struct target
*target
)
470 struct mips64_common
*mips64
= target
->arch_info
;
472 if (target_was_examined(target
))
475 /* TODO: why we do not do mips64_configure_break_unit() here? */
476 mips64
->bp_scanned
= false;
477 mips64
->num_data_bpoints
= 0;
478 mips64
->num_data_bpoints_avail
= 0;
479 mips64
->num_inst_bpoints
= 0;
480 mips64
->num_inst_bpoints_avail
= 0;
482 target_set_examined(target
);
487 static int mips64_configure_i_break_unit(struct target
*target
)
489 /* get pointers to arch-specific information */
490 struct mips64_common
*mips64
= target
->arch_info
;
491 struct mips64_comparator
*ibl
;
496 /* get number of inst breakpoints */
497 retval
= target_read_u64(target
, EJTAG64_V25_IBS
, &bpinfo
);
498 if (retval
!= ERROR_OK
)
501 mips64
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
502 mips64
->num_inst_bpoints_avail
= mips64
->num_inst_bpoints
;
503 ibl
= calloc(mips64
->num_inst_bpoints
, sizeof(*ibl
));
505 LOG_ERROR("unable to allocate inst_break_list");
509 for (i
= 0; i
< mips64
->num_inst_bpoints
; i
++)
510 ibl
[i
].reg_address
= EJTAG64_V25_IBA0
+ (0x100 * i
);
512 mips64
->inst_break_list
= ibl
;
514 retval
= target_write_u64(target
, EJTAG64_V25_IBS
, 0);
515 if (retval
!= ERROR_OK
)
521 static int mips64_configure_d_break_unit(struct target
*target
)
523 struct mips64_common
*mips64
= target
->arch_info
;
524 struct mips64_comparator
*dbl
;
529 /* get number of data breakpoints */
530 retval
= target_read_u64(target
, EJTAG64_V25_DBS
, &bpinfo
);
531 if (retval
!= ERROR_OK
)
534 mips64
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
535 mips64
->num_data_bpoints_avail
= mips64
->num_data_bpoints
;
537 dbl
= calloc(mips64
->num_data_bpoints
, sizeof(*dbl
));
540 LOG_ERROR("unable to allocate data_break_list");
544 for (i
= 0; i
< mips64
->num_data_bpoints
; i
++)
545 dbl
[i
].reg_address
= EJTAG64_V25_DBA0
+ (0x100 * i
);
547 mips64
->data_break_list
= dbl
;
550 retval
= target_write_u64(target
, EJTAG64_V25_DBS
, 0);
551 if (retval
!= ERROR_OK
)
557 int mips64_configure_break_unit(struct target
*target
)
559 struct mips64_common
*mips64
= target
->arch_info
;
563 if (mips64
->bp_scanned
)
566 /* get info about breakpoint support */
567 retval
= target_read_u64(target
, EJTAG64_DCR
, &dcr
);
568 if (retval
!= ERROR_OK
)
571 if (dcr
& EJTAG64_DCR_IB
) {
572 retval
= mips64_configure_i_break_unit(target
);
573 if (retval
!= ERROR_OK
)
577 if (dcr
& EJTAG64_DCR_DB
) {
578 retval
= mips64_configure_d_break_unit(target
);
579 if (retval
!= ERROR_OK
)
583 LOG_DEBUG("DCR 0x%" PRIx64
" numinst %i numdata %i", dcr
,
584 mips64
->num_inst_bpoints
, mips64
->num_data_bpoints
);
586 mips64
->bp_scanned
= true;
591 int mips64_enable_interrupts(struct target
*target
, bool enable
)
597 /* read debug control register */
598 retval
= target_read_u64(target
, EJTAG64_DCR
, &dcr
);
599 if (retval
!= ERROR_OK
)
603 if (!(dcr
& EJTAG64_DCR_INTE
)) {
604 /* enable interrupts */
605 dcr
|= EJTAG64_DCR_INTE
;
609 if (dcr
& EJTAG64_DCR_INTE
) {
610 /* disable interrupts */
611 dcr
&= ~(uint64_t)EJTAG64_DCR_INTE
;
617 retval
= target_write_u64(target
, EJTAG64_DCR
, dcr
);
618 if (retval
!= ERROR_OK
)
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)