1 /***************************************************************************
2 * Copyright (C) 2011 by Julius Baxter *
3 * julius@opencores.org *
5 * Copyright (C) 2013 by Marek Czerski *
6 * ma.czerski@gmail.com *
8 * Copyright (C) 2013 by Franck Jullien *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
17 * This program is distributed in the hope that it will be useful, *
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20 * GNU General Public License for more details. *
22 * You should have received a copy of the GNU General Public License *
23 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
24 ***************************************************************************/
30 #include <jtag/jtag.h>
31 #include <target/register.h>
32 #include <target/target.h>
33 #include <target/breakpoints.h>
34 #include <target/target_type.h>
35 #include <helper/time_support.h>
36 #include <helper/fileio.h>
44 static int or1k_remove_breakpoint(struct target
*target
,
45 struct breakpoint
*breakpoint
);
47 static int or1k_read_core_reg(struct target
*target
, int num
);
48 static int or1k_write_core_reg(struct target
*target
, int num
);
50 static struct or1k_core_reg
*or1k_core_reg_list_arch_info
;
52 static const struct or1k_core_reg_init or1k_init_reg_list
[] = {
53 {"r0" , GROUP0
+ 1024, "org.gnu.gdb.or1k.group0", NULL
},
54 {"r1" , GROUP0
+ 1025, "org.gnu.gdb.or1k.group0", NULL
},
55 {"r2" , GROUP0
+ 1026, "org.gnu.gdb.or1k.group0", NULL
},
56 {"r3" , GROUP0
+ 1027, "org.gnu.gdb.or1k.group0", NULL
},
57 {"r4" , GROUP0
+ 1028, "org.gnu.gdb.or1k.group0", NULL
},
58 {"r5" , GROUP0
+ 1029, "org.gnu.gdb.or1k.group0", NULL
},
59 {"r6" , GROUP0
+ 1030, "org.gnu.gdb.or1k.group0", NULL
},
60 {"r7" , GROUP0
+ 1031, "org.gnu.gdb.or1k.group0", NULL
},
61 {"r8" , GROUP0
+ 1032, "org.gnu.gdb.or1k.group0", NULL
},
62 {"r9" , GROUP0
+ 1033, "org.gnu.gdb.or1k.group0", NULL
},
63 {"r10" , GROUP0
+ 1034, "org.gnu.gdb.or1k.group0", NULL
},
64 {"r11" , GROUP0
+ 1035, "org.gnu.gdb.or1k.group0", NULL
},
65 {"r12" , GROUP0
+ 1036, "org.gnu.gdb.or1k.group0", NULL
},
66 {"r13" , GROUP0
+ 1037, "org.gnu.gdb.or1k.group0", NULL
},
67 {"r14" , GROUP0
+ 1038, "org.gnu.gdb.or1k.group0", NULL
},
68 {"r15" , GROUP0
+ 1039, "org.gnu.gdb.or1k.group0", NULL
},
69 {"r16" , GROUP0
+ 1040, "org.gnu.gdb.or1k.group0", NULL
},
70 {"r17" , GROUP0
+ 1041, "org.gnu.gdb.or1k.group0", NULL
},
71 {"r18" , GROUP0
+ 1042, "org.gnu.gdb.or1k.group0", NULL
},
72 {"r19" , GROUP0
+ 1043, "org.gnu.gdb.or1k.group0", NULL
},
73 {"r20" , GROUP0
+ 1044, "org.gnu.gdb.or1k.group0", NULL
},
74 {"r21" , GROUP0
+ 1045, "org.gnu.gdb.or1k.group0", NULL
},
75 {"r22" , GROUP0
+ 1046, "org.gnu.gdb.or1k.group0", NULL
},
76 {"r23" , GROUP0
+ 1047, "org.gnu.gdb.or1k.group0", NULL
},
77 {"r24" , GROUP0
+ 1048, "org.gnu.gdb.or1k.group0", NULL
},
78 {"r25" , GROUP0
+ 1049, "org.gnu.gdb.or1k.group0", NULL
},
79 {"r26" , GROUP0
+ 1050, "org.gnu.gdb.or1k.group0", NULL
},
80 {"r27" , GROUP0
+ 1051, "org.gnu.gdb.or1k.group0", NULL
},
81 {"r28" , GROUP0
+ 1052, "org.gnu.gdb.or1k.group0", NULL
},
82 {"r29" , GROUP0
+ 1053, "org.gnu.gdb.or1k.group0", NULL
},
83 {"r30" , GROUP0
+ 1054, "org.gnu.gdb.or1k.group0", NULL
},
84 {"r31" , GROUP0
+ 1055, "org.gnu.gdb.or1k.group0", NULL
},
85 {"ppc" , GROUP0
+ 18, "org.gnu.gdb.or1k.group0", NULL
},
86 {"npc" , GROUP0
+ 16, "org.gnu.gdb.or1k.group0", NULL
},
87 {"sr" , GROUP0
+ 17, "org.gnu.gdb.or1k.group0", NULL
},
88 {"vr" , GROUP0
+ 0, "org.gnu.gdb.or1k.group0", "system"},
89 {"upr" , GROUP0
+ 1, "org.gnu.gdb.or1k.group0", "system"},
90 {"cpucfgr" , GROUP0
+ 2, "org.gnu.gdb.or1k.group0", "system"},
91 {"dmmucfgr" , GROUP0
+ 3, "org.gnu.gdb.or1k.group0", "system"},
92 {"immucfgr" , GROUP0
+ 4, "org.gnu.gdb.or1k.group0", "system"},
93 {"dccfgr" , GROUP0
+ 5, "org.gnu.gdb.or1k.group0", "system"},
94 {"iccfgr" , GROUP0
+ 6, "org.gnu.gdb.or1k.group0", "system"},
95 {"dcfgr" , GROUP0
+ 7, "org.gnu.gdb.or1k.group0", "system"},
96 {"pccfgr" , GROUP0
+ 8, "org.gnu.gdb.or1k.group0", "system"},
97 {"fpcsr" , GROUP0
+ 20, "org.gnu.gdb.or1k.group0", "system"},
98 {"epcr0" , GROUP0
+ 32, "org.gnu.gdb.or1k.group0", "system"},
99 {"epcr1" , GROUP0
+ 33, "org.gnu.gdb.or1k.group0", "system"},
100 {"epcr2" , GROUP0
+ 34, "org.gnu.gdb.or1k.group0", "system"},
101 {"epcr3" , GROUP0
+ 35, "org.gnu.gdb.or1k.group0", "system"},
102 {"epcr4" , GROUP0
+ 36, "org.gnu.gdb.or1k.group0", "system"},
103 {"epcr5" , GROUP0
+ 37, "org.gnu.gdb.or1k.group0", "system"},
104 {"epcr6" , GROUP0
+ 38, "org.gnu.gdb.or1k.group0", "system"},
105 {"epcr7" , GROUP0
+ 39, "org.gnu.gdb.or1k.group0", "system"},
106 {"epcr8" , GROUP0
+ 40, "org.gnu.gdb.or1k.group0", "system"},
107 {"epcr9" , GROUP0
+ 41, "org.gnu.gdb.or1k.group0", "system"},
108 {"epcr10" , GROUP0
+ 42, "org.gnu.gdb.or1k.group0", "system"},
109 {"epcr11" , GROUP0
+ 43, "org.gnu.gdb.or1k.group0", "system"},
110 {"epcr12" , GROUP0
+ 44, "org.gnu.gdb.or1k.group0", "system"},
111 {"epcr13" , GROUP0
+ 45, "org.gnu.gdb.or1k.group0", "system"},
112 {"epcr14" , GROUP0
+ 46, "org.gnu.gdb.or1k.group0", "system"},
113 {"epcr15" , GROUP0
+ 47, "org.gnu.gdb.or1k.group0", "system"},
114 {"eear0" , GROUP0
+ 48, "org.gnu.gdb.or1k.group0", "system"},
115 {"eear1" , GROUP0
+ 49, "org.gnu.gdb.or1k.group0", "system"},
116 {"eear2" , GROUP0
+ 50, "org.gnu.gdb.or1k.group0", "system"},
117 {"eear3" , GROUP0
+ 51, "org.gnu.gdb.or1k.group0", "system"},
118 {"eear4" , GROUP0
+ 52, "org.gnu.gdb.or1k.group0", "system"},
119 {"eear5" , GROUP0
+ 53, "org.gnu.gdb.or1k.group0", "system"},
120 {"eear6" , GROUP0
+ 54, "org.gnu.gdb.or1k.group0", "system"},
121 {"eear7" , GROUP0
+ 55, "org.gnu.gdb.or1k.group0", "system"},
122 {"eear8" , GROUP0
+ 56, "org.gnu.gdb.or1k.group0", "system"},
123 {"eear9" , GROUP0
+ 57, "org.gnu.gdb.or1k.group0", "system"},
124 {"eear10" , GROUP0
+ 58, "org.gnu.gdb.or1k.group0", "system"},
125 {"eear11" , GROUP0
+ 59, "org.gnu.gdb.or1k.group0", "system"},
126 {"eear12" , GROUP0
+ 60, "org.gnu.gdb.or1k.group0", "system"},
127 {"eear13" , GROUP0
+ 61, "org.gnu.gdb.or1k.group0", "system"},
128 {"eear14" , GROUP0
+ 62, "org.gnu.gdb.or1k.group0", "system"},
129 {"eear15" , GROUP0
+ 63, "org.gnu.gdb.or1k.group0", "system"},
130 {"esr0" , GROUP0
+ 64, "org.gnu.gdb.or1k.group0", "system"},
131 {"esr1" , GROUP0
+ 65, "org.gnu.gdb.or1k.group0", "system"},
132 {"esr2" , GROUP0
+ 66, "org.gnu.gdb.or1k.group0", "system"},
133 {"esr3" , GROUP0
+ 67, "org.gnu.gdb.or1k.group0", "system"},
134 {"esr4" , GROUP0
+ 68, "org.gnu.gdb.or1k.group0", "system"},
135 {"esr5" , GROUP0
+ 69, "org.gnu.gdb.or1k.group0", "system"},
136 {"esr6" , GROUP0
+ 70, "org.gnu.gdb.or1k.group0", "system"},
137 {"esr7" , GROUP0
+ 71, "org.gnu.gdb.or1k.group0", "system"},
138 {"esr8" , GROUP0
+ 72, "org.gnu.gdb.or1k.group0", "system"},
139 {"esr9" , GROUP0
+ 73, "org.gnu.gdb.or1k.group0", "system"},
140 {"esr10" , GROUP0
+ 74, "org.gnu.gdb.or1k.group0", "system"},
141 {"esr11" , GROUP0
+ 75, "org.gnu.gdb.or1k.group0", "system"},
142 {"esr12" , GROUP0
+ 76, "org.gnu.gdb.or1k.group0", "system"},
143 {"esr13" , GROUP0
+ 77, "org.gnu.gdb.or1k.group0", "system"},
144 {"esr14" , GROUP0
+ 78, "org.gnu.gdb.or1k.group0", "system"},
145 {"esr15" , GROUP0
+ 79, "org.gnu.gdb.or1k.group0", "system"},
147 {"dmmuucr" , GROUP1
+ 0, "org.gnu.gdb.or1k.group1", "dmmu"},
148 {"dmmuupr" , GROUP1
+ 1, "org.gnu.gdb.or1k.group1", "dmmu"},
149 {"dtlbeir" , GROUP1
+ 2, "org.gnu.gdb.or1k.group1", "dmmu"},
150 {"datbmr0" , GROUP1
+ 4, "org.gnu.gdb.or1k.group1", "dmmu"},
151 {"datbmr1" , GROUP1
+ 5, "org.gnu.gdb.or1k.group1", "dmmu"},
152 {"datbmr2" , GROUP1
+ 6, "org.gnu.gdb.or1k.group1", "dmmu"},
153 {"datbmr3" , GROUP1
+ 7, "org.gnu.gdb.or1k.group1", "dmmu"},
154 {"datbtr0" , GROUP1
+ 8, "org.gnu.gdb.or1k.group1", "dmmu"},
155 {"datbtr1" , GROUP1
+ 9, "org.gnu.gdb.or1k.group1", "dmmu"},
156 {"datbtr2" , GROUP1
+ 10, "org.gnu.gdb.or1k.group1", "dmmu"},
157 {"datbtr3" , GROUP1
+ 11, "org.gnu.gdb.or1k.group1", "dmmu"},
159 {"immucr" , GROUP2
+ 0, "org.gnu.gdb.or1k.group2", "immu"},
160 {"immupr" , GROUP2
+ 1, "org.gnu.gdb.or1k.group2", "immu"},
161 {"itlbeir" , GROUP2
+ 2, "org.gnu.gdb.or1k.group2", "immu"},
162 {"iatbmr0" , GROUP2
+ 4, "org.gnu.gdb.or1k.group2", "immu"},
163 {"iatbmr1" , GROUP2
+ 5, "org.gnu.gdb.or1k.group2", "immu"},
164 {"iatbmr2" , GROUP2
+ 6, "org.gnu.gdb.or1k.group2", "immu"},
165 {"iatbmr3" , GROUP2
+ 7, "org.gnu.gdb.or1k.group2", "immu"},
166 {"iatbtr0" , GROUP2
+ 8, "org.gnu.gdb.or1k.group2", "immu"},
167 {"iatbtr1" , GROUP2
+ 9, "org.gnu.gdb.or1k.group2", "immu"},
168 {"iatbtr2" , GROUP2
+ 10, "org.gnu.gdb.or1k.group2", "immu"},
169 {"iatbtr3" , GROUP2
+ 11, "org.gnu.gdb.or1k.group2", "immu"},
171 {"dccr" , GROUP3
+ 0, "org.gnu.gdb.or1k.group3", "dcache"},
172 {"dcbpr" , GROUP3
+ 1, "org.gnu.gdb.or1k.group3", "dcache"},
173 {"dcbfr" , GROUP3
+ 2, "org.gnu.gdb.or1k.group3", "dcache"},
174 {"dcbir" , GROUP3
+ 3, "org.gnu.gdb.or1k.group3", "dcache"},
175 {"dcbwr" , GROUP3
+ 4, "org.gnu.gdb.or1k.group3", "dcache"},
176 {"dcblr" , GROUP3
+ 5, "org.gnu.gdb.or1k.group3", "dcache"},
178 {"iccr" , GROUP4
+ 0, "org.gnu.gdb.or1k.group4", "icache"},
179 {"icbpr" , GROUP4
+ 1, "org.gnu.gdb.or1k.group4", "icache"},
180 {"icbir" , GROUP4
+ 2, "org.gnu.gdb.or1k.group4", "icache"},
181 {"icblr" , GROUP4
+ 3, "org.gnu.gdb.or1k.group4", "icache"},
183 {"maclo" , GROUP5
+ 0, "org.gnu.gdb.or1k.group5", "mac"},
184 {"machi" , GROUP5
+ 1, "org.gnu.gdb.or1k.group5", "mac"},
186 {"dvr0" , GROUP6
+ 0, "org.gnu.gdb.or1k.group6", "debug"},
187 {"dvr1" , GROUP6
+ 1, "org.gnu.gdb.or1k.group6", "debug"},
188 {"dvr2" , GROUP6
+ 2, "org.gnu.gdb.or1k.group6", "debug"},
189 {"dvr3" , GROUP6
+ 3, "org.gnu.gdb.or1k.group6", "debug"},
190 {"dvr4" , GROUP6
+ 4, "org.gnu.gdb.or1k.group6", "debug"},
191 {"dvr5" , GROUP6
+ 5, "org.gnu.gdb.or1k.group6", "debug"},
192 {"dvr6" , GROUP6
+ 6, "org.gnu.gdb.or1k.group6", "debug"},
193 {"dvr7" , GROUP6
+ 7, "org.gnu.gdb.or1k.group6", "debug"},
194 {"dcr0" , GROUP6
+ 8, "org.gnu.gdb.or1k.group6", "debug"},
195 {"dcr1" , GROUP6
+ 9, "org.gnu.gdb.or1k.group6", "debug"},
196 {"dcr2" , GROUP6
+ 10, "org.gnu.gdb.or1k.group6", "debug"},
197 {"dcr3" , GROUP6
+ 11, "org.gnu.gdb.or1k.group6", "debug"},
198 {"dcr4" , GROUP6
+ 12, "org.gnu.gdb.or1k.group6", "debug"},
199 {"dcr5" , GROUP6
+ 13, "org.gnu.gdb.or1k.group6", "debug"},
200 {"dcr6" , GROUP6
+ 14, "org.gnu.gdb.or1k.group6", "debug"},
201 {"dcr7" , GROUP6
+ 15, "org.gnu.gdb.or1k.group6", "debug"},
202 {"dmr1" , GROUP6
+ 16, "org.gnu.gdb.or1k.group6", "debug"},
203 {"dmr2" , GROUP6
+ 17, "org.gnu.gdb.or1k.group6", "debug"},
204 {"dcwr0" , GROUP6
+ 18, "org.gnu.gdb.or1k.group6", "debug"},
205 {"dcwr1" , GROUP6
+ 19, "org.gnu.gdb.or1k.group6", "debug"},
206 {"dsr" , GROUP6
+ 20, "org.gnu.gdb.or1k.group6", "debug"},
207 {"drr" , GROUP6
+ 21, "org.gnu.gdb.or1k.group6", "debug"},
209 {"pccr0" , GROUP7
+ 0, "org.gnu.gdb.or1k.group7", "perf"},
210 {"pccr1" , GROUP7
+ 1, "org.gnu.gdb.or1k.group7", "perf"},
211 {"pccr2" , GROUP7
+ 2, "org.gnu.gdb.or1k.group7", "perf"},
212 {"pccr3" , GROUP7
+ 3, "org.gnu.gdb.or1k.group7", "perf"},
213 {"pccr4" , GROUP7
+ 4, "org.gnu.gdb.or1k.group7", "perf"},
214 {"pccr5" , GROUP7
+ 5, "org.gnu.gdb.or1k.group7", "perf"},
215 {"pccr6" , GROUP7
+ 6, "org.gnu.gdb.or1k.group7", "perf"},
216 {"pccr7" , GROUP7
+ 7, "org.gnu.gdb.or1k.group7", "perf"},
217 {"pcmr0" , GROUP7
+ 8, "org.gnu.gdb.or1k.group7", "perf"},
218 {"pcmr1" , GROUP7
+ 9, "org.gnu.gdb.or1k.group7", "perf"},
219 {"pcmr2" , GROUP7
+ 10, "org.gnu.gdb.or1k.group7", "perf"},
220 {"pcmr3" , GROUP7
+ 11, "org.gnu.gdb.or1k.group7", "perf"},
221 {"pcmr4" , GROUP7
+ 12, "org.gnu.gdb.or1k.group7", "perf"},
222 {"pcmr5" , GROUP7
+ 13, "org.gnu.gdb.or1k.group7", "perf"},
223 {"pcmr6" , GROUP7
+ 14, "org.gnu.gdb.or1k.group7", "perf"},
224 {"pcmr7" , GROUP7
+ 15, "org.gnu.gdb.or1k.group7", "perf"},
226 {"pmr" , GROUP8
+ 0, "org.gnu.gdb.or1k.group8", "power"},
228 {"picmr" , GROUP9
+ 0, "org.gnu.gdb.or1k.group9", "pic"},
229 {"picsr" , GROUP9
+ 2, "org.gnu.gdb.or1k.group9", "pic"},
231 {"ttmr" , GROUP10
+ 0, "org.gnu.gdb.or1k.group10", "timer"},
232 {"ttcr" , GROUP10
+ 1, "org.gnu.gdb.or1k.group10", "timer"},
235 static int or1k_add_reg(struct target
*target
, struct or1k_core_reg
*new_reg
)
237 struct or1k_common
*or1k
= target_to_or1k(target
);
238 int reg_list_size
= or1k
->nb_regs
* sizeof(struct or1k_core_reg
);
240 or1k_core_reg_list_arch_info
= realloc(or1k_core_reg_list_arch_info
,
241 reg_list_size
+ sizeof(struct or1k_core_reg
));
243 memcpy(&or1k_core_reg_list_arch_info
[or1k
->nb_regs
], new_reg
,
244 sizeof(struct or1k_core_reg
));
246 or1k_core_reg_list_arch_info
[or1k
->nb_regs
].list_num
= or1k
->nb_regs
;
253 static int or1k_create_reg_list(struct target
*target
)
255 struct or1k_common
*or1k
= target_to_or1k(target
);
259 or1k_core_reg_list_arch_info
= malloc(ARRAY_SIZE(or1k_init_reg_list
) *
260 sizeof(struct or1k_core_reg
));
262 for (int i
= 0; i
< (int)ARRAY_SIZE(or1k_init_reg_list
); i
++) {
263 or1k_core_reg_list_arch_info
[i
].name
= or1k_init_reg_list
[i
].name
;
264 or1k_core_reg_list_arch_info
[i
].spr_num
= or1k_init_reg_list
[i
].spr_num
;
265 or1k_core_reg_list_arch_info
[i
].group
= or1k_init_reg_list
[i
].group
;
266 or1k_core_reg_list_arch_info
[i
].feature
= or1k_init_reg_list
[i
].feature
;
267 or1k_core_reg_list_arch_info
[i
].list_num
= i
;
268 or1k_core_reg_list_arch_info
[i
].target
= NULL
;
269 or1k_core_reg_list_arch_info
[i
].or1k_common
= NULL
;
272 or1k
->nb_regs
= ARRAY_SIZE(or1k_init_reg_list
);
274 struct or1k_core_reg new_reg
;
275 new_reg
.target
= NULL
;
276 new_reg
.or1k_common
= NULL
;
279 for (int way
= 0; way
< 4; way
++) {
280 for (int i
= 0; i
< 128; i
++) {
282 sprintf(name
, "dtlbw%dmr%d", way
, i
);
283 new_reg
.name
= strdup(name
);
284 new_reg
.spr_num
= GROUP1
+ 512 + i
+ (way
* 256);
285 new_reg
.feature
= "org.gnu.gdb.or1k.group1";
286 new_reg
.group
= "dmmu";
287 or1k_add_reg(target
, &new_reg
);
289 sprintf(name
, "dtlbw%dtr%d", way
, i
);
290 new_reg
.name
= strdup(name
);
291 new_reg
.spr_num
= GROUP1
+ 640 + i
+ (way
* 256);
292 new_reg
.feature
= "org.gnu.gdb.or1k.group1";
293 new_reg
.group
= "dmmu";
294 or1k_add_reg(target
, &new_reg
);
297 sprintf(name
, "itlbw%dmr%d", way
, i
);
298 new_reg
.name
= strdup(name
);
299 new_reg
.spr_num
= GROUP2
+ 512 + i
+ (way
* 256);
300 new_reg
.feature
= "org.gnu.gdb.or1k.group2";
301 new_reg
.group
= "immu";
302 or1k_add_reg(target
, &new_reg
);
305 sprintf(name
, "itlbw%dtr%d", way
, i
);
306 new_reg
.name
= strdup(name
);
307 new_reg
.spr_num
= GROUP2
+ 640 + i
+ (way
* 256);
308 new_reg
.feature
= "org.gnu.gdb.or1k.group2";
309 new_reg
.group
= "immu";
310 or1k_add_reg(target
, &new_reg
);
318 static int or1k_jtag_read_regs(struct or1k_common
*or1k
, uint32_t *regs
)
320 struct or1k_du
*du_core
= or1k_jtag_to_du(&or1k
->jtag
);
324 return du_core
->or1k_jtag_read_cpu(&or1k
->jtag
,
325 or1k
->arch_info
[OR1K_REG_R0
].spr_num
, OR1K_REG_R31
+ 1,
329 static int or1k_jtag_write_regs(struct or1k_common
*or1k
, uint32_t *regs
)
331 struct or1k_du
*du_core
= or1k_jtag_to_du(&or1k
->jtag
);
335 return du_core
->or1k_jtag_write_cpu(&or1k
->jtag
,
336 or1k
->arch_info
[OR1K_REG_R0
].spr_num
, OR1K_REG_R31
+ 1,
340 static int or1k_save_context(struct target
*target
)
342 struct or1k_common
*or1k
= target_to_or1k(target
);
343 struct or1k_du
*du_core
= or1k_to_du(or1k
);
349 for (int i
= 0; i
< OR1KNUMCOREREGS
; i
++) {
350 if (!or1k
->core_cache
->reg_list
[i
].valid
) {
351 if (i
== OR1K_REG_PPC
|| i
== OR1K_REG_NPC
|| i
== OR1K_REG_SR
) {
352 retval
= du_core
->or1k_jtag_read_cpu(&or1k
->jtag
,
353 or1k
->arch_info
[i
].spr_num
, 1,
354 &or1k
->core_regs
[i
]);
355 if (retval
!= ERROR_OK
)
357 } else if (!regs_read
) {
358 /* read gpr registers at once (but only one time in this loop) */
359 retval
= or1k_jtag_read_regs(or1k
, or1k
->core_regs
);
360 if (retval
!= ERROR_OK
)
362 /* prevent next reads in this loop */
365 /* We've just updated the core_reg[i], now update
367 or1k_read_core_reg(target
, i
);
374 static int or1k_restore_context(struct target
*target
)
376 struct or1k_common
*or1k
= target_to_or1k(target
);
377 struct or1k_du
*du_core
= or1k_to_du(or1k
);
383 for (int i
= 0; i
< OR1KNUMCOREREGS
; i
++) {
384 if (or1k
->core_cache
->reg_list
[i
].dirty
) {
385 or1k_write_core_reg(target
, i
);
387 if (i
== OR1K_REG_PPC
|| i
== OR1K_REG_NPC
|| i
== OR1K_REG_SR
) {
388 retval
= du_core
->or1k_jtag_write_cpu(&or1k
->jtag
,
389 or1k
->arch_info
[i
].spr_num
, 1,
390 &or1k
->core_regs
[i
]);
391 if (retval
!= ERROR_OK
) {
392 LOG_ERROR("Error while restoring context");
401 /* read gpr registers at once (but only one time in this loop) */
402 retval
= or1k_jtag_write_regs(or1k
, or1k
->core_regs
);
403 if (retval
!= ERROR_OK
) {
404 LOG_ERROR("Error while restoring context");
412 static int or1k_read_core_reg(struct target
*target
, int num
)
414 struct or1k_common
*or1k
= target_to_or1k(target
);
415 struct or1k_du
*du_core
= or1k_to_du(or1k
);
420 if ((num
< 0) || (num
>= or1k
->nb_regs
))
421 return ERROR_COMMAND_SYNTAX_ERROR
;
423 if ((num
>= 0) && (num
< OR1KNUMCOREREGS
)) {
424 reg_value
= or1k
->core_regs
[num
];
425 buf_set_u32(or1k
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
426 LOG_DEBUG("Read core reg %i value 0x%08" PRIx32
, num
, reg_value
);
427 or1k
->core_cache
->reg_list
[num
].valid
= 1;
428 or1k
->core_cache
->reg_list
[num
].dirty
= 0;
430 /* This is an spr, always read value from HW */
431 int retval
= du_core
->or1k_jtag_read_cpu(&or1k
->jtag
,
432 or1k
->arch_info
[num
].spr_num
, 1, ®_value
);
433 if (retval
!= ERROR_OK
) {
434 LOG_ERROR("Error while reading spr 0x%08" PRIx32
, or1k
->arch_info
[num
].spr_num
);
437 buf_set_u32(or1k
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
438 LOG_DEBUG("Read spr reg %i value 0x%08" PRIx32
, num
, reg_value
);
444 static int or1k_write_core_reg(struct target
*target
, int num
)
446 struct or1k_common
*or1k
= target_to_or1k(target
);
450 if ((num
< 0) || (num
>= OR1KNUMCOREREGS
))
451 return ERROR_COMMAND_SYNTAX_ERROR
;
453 uint32_t reg_value
= buf_get_u32(or1k
->core_cache
->reg_list
[num
].value
, 0, 32);
454 or1k
->core_regs
[num
] = reg_value
;
455 LOG_DEBUG("Write core reg %i value 0x%08" PRIx32
, num
, reg_value
);
456 or1k
->core_cache
->reg_list
[num
].valid
= 1;
457 or1k
->core_cache
->reg_list
[num
].dirty
= 0;
462 static int or1k_get_core_reg(struct reg
*reg
)
464 struct or1k_core_reg
*or1k_reg
= reg
->arch_info
;
465 struct target
*target
= or1k_reg
->target
;
469 if (target
->state
!= TARGET_HALTED
)
470 return ERROR_TARGET_NOT_HALTED
;
472 return or1k_read_core_reg(target
, or1k_reg
->list_num
);
475 static int or1k_set_core_reg(struct reg
*reg
, uint8_t *buf
)
477 struct or1k_core_reg
*or1k_reg
= reg
->arch_info
;
478 struct target
*target
= or1k_reg
->target
;
479 struct or1k_common
*or1k
= target_to_or1k(target
);
480 struct or1k_du
*du_core
= or1k_to_du(or1k
);
481 uint32_t value
= buf_get_u32(buf
, 0, 32);
485 if (target
->state
!= TARGET_HALTED
)
486 return ERROR_TARGET_NOT_HALTED
;
488 if (or1k_reg
->list_num
< OR1KNUMCOREREGS
) {
489 buf_set_u32(reg
->value
, 0, 32, value
);
493 /* This is an spr, write it to the HW */
494 int retval
= du_core
->or1k_jtag_write_cpu(&or1k
->jtag
,
495 or1k_reg
->spr_num
, 1, &value
);
496 if (retval
!= ERROR_OK
) {
497 LOG_ERROR("Error while writing spr 0x%08" PRIx32
, or1k_reg
->spr_num
);
505 static const struct reg_arch_type or1k_reg_type
= {
506 .get
= or1k_get_core_reg
,
507 .set
= or1k_set_core_reg
,
510 static struct reg_cache
*or1k_build_reg_cache(struct target
*target
)
512 struct or1k_common
*or1k
= target_to_or1k(target
);
513 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
514 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
515 struct reg
*reg_list
= calloc(or1k
->nb_regs
, sizeof(struct reg
));
516 struct or1k_core_reg
*arch_info
=
517 malloc((or1k
->nb_regs
) * sizeof(struct or1k_core_reg
));
518 struct reg_feature
*feature
;
522 /* Build the process context cache */
523 cache
->name
= "OpenRISC 1000 registers";
525 cache
->reg_list
= reg_list
;
526 cache
->num_regs
= or1k
->nb_regs
;
528 or1k
->core_cache
= cache
;
529 or1k
->arch_info
= arch_info
;
531 for (int i
= 0; i
< or1k
->nb_regs
; i
++) {
532 arch_info
[i
] = or1k_core_reg_list_arch_info
[i
];
533 arch_info
[i
].target
= target
;
534 arch_info
[i
].or1k_common
= or1k
;
535 reg_list
[i
].name
= or1k_core_reg_list_arch_info
[i
].name
;
537 feature
= malloc(sizeof(struct reg_feature
));
538 feature
->name
= or1k_core_reg_list_arch_info
[i
].feature
;
539 reg_list
[i
].feature
= feature
;
541 reg_list
[i
].group
= or1k_core_reg_list_arch_info
[i
].group
;
542 reg_list
[i
].size
= 32;
543 reg_list
[i
].value
= calloc(1, 4);
544 reg_list
[i
].dirty
= 0;
545 reg_list
[i
].valid
= 0;
546 reg_list
[i
].type
= &or1k_reg_type
;
547 reg_list
[i
].arch_info
= &arch_info
[i
];
548 reg_list
[i
].number
= i
;
549 reg_list
[i
].exist
= true;
555 static int or1k_debug_entry(struct target
*target
)
559 int retval
= or1k_save_context(target
);
560 if (retval
!= ERROR_OK
) {
561 LOG_ERROR("Error while calling or1k_save_context");
565 struct or1k_common
*or1k
= target_to_or1k(target
);
566 uint32_t addr
= or1k
->core_regs
[OR1K_REG_NPC
];
568 if (breakpoint_find(target
, addr
))
569 /* Halted on a breakpoint, step back to permit executing the instruction there */
570 retval
= or1k_set_core_reg(&or1k
->core_cache
->reg_list
[OR1K_REG_NPC
],
576 static int or1k_halt(struct target
*target
)
578 struct or1k_common
*or1k
= target_to_or1k(target
);
579 struct or1k_du
*du_core
= or1k_to_du(or1k
);
581 LOG_DEBUG("target->state: %s",
582 target_state_name(target
));
584 if (target
->state
== TARGET_HALTED
) {
585 LOG_DEBUG("Target was already halted");
589 if (target
->state
== TARGET_UNKNOWN
)
590 LOG_WARNING("Target was in unknown state when halt was requested");
592 if (target
->state
== TARGET_RESET
) {
593 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) &&
595 LOG_ERROR("Can't request a halt while in reset if nSRST pulls nTRST");
596 return ERROR_TARGET_FAILURE
;
598 target
->debug_reason
= DBG_REASON_DBGRQ
;
603 int retval
= du_core
->or1k_cpu_stall(&or1k
->jtag
, CPU_STALL
);
604 if (retval
!= ERROR_OK
) {
605 LOG_ERROR("Impossible to stall the CPU");
609 target
->debug_reason
= DBG_REASON_DBGRQ
;
614 static int or1k_is_cpu_running(struct target
*target
, int *running
)
616 struct or1k_common
*or1k
= target_to_or1k(target
);
617 struct or1k_du
*du_core
= or1k_to_du(or1k
);
620 const int RETRIES_MAX
= 5;
622 /* Have a retry loop to determine of the CPU is running.
623 If target has been hard reset for any reason, it might take a couple
624 of goes before it's ready again.
626 while (tries
< RETRIES_MAX
) {
630 retval
= du_core
->or1k_is_cpu_running(&or1k
->jtag
, running
);
631 if (retval
!= ERROR_OK
) {
632 LOG_WARNING("Debug IF CPU control reg read failure.");
633 /* Try once to restart the JTAG infrastructure -
634 quite possibly the board has just been reset. */
635 LOG_WARNING("Resetting JTAG TAP state and reconnectiong to debug IF.");
636 du_core
->or1k_jtag_init(&or1k
->jtag
);
638 LOG_WARNING("...attempt %d of %d", tries
, RETRIES_MAX
);
647 LOG_ERROR("Could not re-establish communication with target");
651 static int or1k_poll(struct target
*target
)
656 retval
= or1k_is_cpu_running(target
, &running
);
657 if (retval
!= ERROR_OK
) {
658 LOG_ERROR("Error while calling or1k_is_cpu_running");
662 /* check for processor halted */
664 /* It's actually stalled, so update our software's state */
665 if ((target
->state
== TARGET_RUNNING
) ||
666 (target
->state
== TARGET_RESET
)) {
668 target
->state
= TARGET_HALTED
;
670 retval
= or1k_debug_entry(target
);
671 if (retval
!= ERROR_OK
) {
672 LOG_ERROR("Error while calling or1k_debug_entry");
676 target_call_event_callbacks(target
,
677 TARGET_EVENT_HALTED
);
678 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
679 target
->state
= TARGET_HALTED
;
681 retval
= or1k_debug_entry(target
);
682 if (retval
!= ERROR_OK
) {
683 LOG_ERROR("Error while calling or1k_debug_entry");
687 target_call_event_callbacks(target
,
688 TARGET_EVENT_DEBUG_HALTED
);
690 } else { /* ... target is running */
692 /* If target was supposed to be stalled, stall it again */
693 if (target
->state
== TARGET_HALTED
) {
695 target
->state
= TARGET_RUNNING
;
697 retval
= or1k_halt(target
);
698 if (retval
!= ERROR_OK
) {
699 LOG_ERROR("Error while calling or1k_halt");
703 retval
= or1k_debug_entry(target
);
704 if (retval
!= ERROR_OK
) {
705 LOG_ERROR("Error while calling or1k_debug_entry");
709 target_call_event_callbacks(target
,
710 TARGET_EVENT_DEBUG_HALTED
);
713 target
->state
= TARGET_RUNNING
;
720 static int or1k_assert_reset(struct target
*target
)
722 struct or1k_common
*or1k
= target_to_or1k(target
);
723 struct or1k_du
*du_core
= or1k_to_du(or1k
);
727 int retval
= du_core
->or1k_cpu_reset(&or1k
->jtag
, CPU_RESET
);
728 if (retval
!= ERROR_OK
) {
729 LOG_ERROR("Error while asserting RESET");
736 static int or1k_deassert_reset(struct target
*target
)
738 struct or1k_common
*or1k
= target_to_or1k(target
);
739 struct or1k_du
*du_core
= or1k_to_du(or1k
);
743 int retval
= du_core
->or1k_cpu_reset(&or1k
->jtag
, CPU_NOT_RESET
);
744 if (retval
!= ERROR_OK
) {
745 LOG_ERROR("Error while desasserting RESET");
752 static int or1k_soft_reset_halt(struct target
*target
)
754 struct or1k_common
*or1k
= target_to_or1k(target
);
755 struct or1k_du
*du_core
= or1k_to_du(or1k
);
759 int retval
= du_core
->or1k_cpu_stall(&or1k
->jtag
, CPU_STALL
);
760 if (retval
!= ERROR_OK
) {
761 LOG_ERROR("Error while stalling the CPU");
765 retval
= or1k_assert_reset(target
);
766 if (retval
!= ERROR_OK
)
769 retval
= or1k_deassert_reset(target
);
770 if (retval
!= ERROR_OK
)
776 static bool is_any_soft_breakpoint(struct target
*target
)
778 struct breakpoint
*breakpoint
= target
->breakpoints
;
783 if (breakpoint
->type
== BKPT_SOFT
)
789 static int or1k_resume_or_step(struct target
*target
, int current
,
790 uint32_t address
, int handle_breakpoints
,
791 int debug_execution
, int step
)
793 struct or1k_common
*or1k
= target_to_or1k(target
);
794 struct or1k_du
*du_core
= or1k_to_du(or1k
);
795 struct breakpoint
*breakpoint
= NULL
;
797 uint32_t debug_reg_list
[OR1K_DEBUG_REG_NUM
];
799 LOG_DEBUG("Addr: 0x%" PRIx32
", stepping: %s, handle breakpoints %s\n",
800 address
, step
? "yes" : "no", handle_breakpoints
? "yes" : "no");
802 if (target
->state
!= TARGET_HALTED
) {
803 LOG_ERROR("Target not halted");
804 return ERROR_TARGET_NOT_HALTED
;
807 if (!debug_execution
)
808 target_free_all_working_areas(target
);
810 /* current ? continue on current pc : continue at <address> */
812 buf_set_u32(or1k
->core_cache
->reg_list
[OR1K_REG_NPC
].value
, 0,
815 int retval
= or1k_restore_context(target
);
816 if (retval
!= ERROR_OK
) {
817 LOG_ERROR("Error while calling or1k_restore_context");
821 /* read debug registers (starting from DMR1 register) */
822 retval
= du_core
->or1k_jtag_read_cpu(&or1k
->jtag
, OR1K_DMR1_CPU_REG_ADD
,
823 OR1K_DEBUG_REG_NUM
, debug_reg_list
);
824 if (retval
!= ERROR_OK
) {
825 LOG_ERROR("Error while reading debug registers");
829 /* Clear Debug Reason Register (DRR) */
830 debug_reg_list
[OR1K_DEBUG_REG_DRR
] = 0;
832 /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) */
833 debug_reg_list
[OR1K_DEBUG_REG_DMR2
] &= ~OR1K_DMR2_WGB
;
835 /* Set the single step trigger in Debug Mode Register 1 (DMR1) */
836 debug_reg_list
[OR1K_DEBUG_REG_DMR1
] |= OR1K_DMR1_ST
| OR1K_DMR1_BT
;
838 /* Clear the single step trigger in Debug Mode Register 1 (DMR1) */
839 debug_reg_list
[OR1K_DEBUG_REG_DMR1
] &= ~(OR1K_DMR1_ST
| OR1K_DMR1_BT
);
841 /* Set traps to be handled by the debug unit in the Debug Stop
842 Register (DSR). Check if we have any software breakpoints in
843 place before setting this value - the kernel, for instance,
844 relies on l.trap instructions not stalling the processor ! */
845 if (is_any_soft_breakpoint(target
) == true)
846 debug_reg_list
[OR1K_DEBUG_REG_DSR
] |= OR1K_DSR_TE
;
848 /* Write debug registers (starting from DMR1 register) */
849 retval
= du_core
->or1k_jtag_write_cpu(&or1k
->jtag
, OR1K_DMR1_CPU_REG_ADD
,
850 OR1K_DEBUG_REG_NUM
, debug_reg_list
);
851 if (retval
!= ERROR_OK
) {
852 LOG_ERROR("Error while writing back debug registers");
856 resume_pc
= buf_get_u32(or1k
->core_cache
->reg_list
[OR1K_REG_NPC
].value
,
859 /* The front-end may request us not to handle breakpoints */
860 if (handle_breakpoints
) {
861 /* Single step past breakpoint at current address */
862 breakpoint
= breakpoint_find(target
, resume_pc
);
864 LOG_DEBUG("Unset breakpoint at 0x%08" PRIx32
, breakpoint
->address
);
865 retval
= or1k_remove_breakpoint(target
, breakpoint
);
866 if (retval
!= ERROR_OK
)
872 retval
= du_core
->or1k_cpu_stall(&or1k
->jtag
, CPU_UNSTALL
);
873 if (retval
!= ERROR_OK
) {
874 LOG_ERROR("Error while unstalling the CPU");
879 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
881 target
->debug_reason
= DBG_REASON_NOTHALTED
;
883 /* Registers are now invalid */
884 register_cache_invalidate(or1k
->core_cache
);
886 if (!debug_execution
) {
887 target
->state
= TARGET_RUNNING
;
888 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
889 LOG_DEBUG("Target resumed at 0x%08" PRIx32
, resume_pc
);
891 target
->state
= TARGET_DEBUG_RUNNING
;
892 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
893 LOG_DEBUG("Target debug resumed at 0x%08" PRIx32
, resume_pc
);
899 static int or1k_resume(struct target
*target
, int current
,
900 uint32_t address
, int handle_breakpoints
, int debug_execution
)
902 return or1k_resume_or_step(target
, current
, address
,
908 static int or1k_step(struct target
*target
, int current
,
909 uint32_t address
, int handle_breakpoints
)
911 return or1k_resume_or_step(target
, current
, address
,
918 static int or1k_add_breakpoint(struct target
*target
,
919 struct breakpoint
*breakpoint
)
921 struct or1k_common
*or1k
= target_to_or1k(target
);
922 struct or1k_du
*du_core
= or1k_to_du(or1k
);
925 LOG_DEBUG("Adding breakpoint: addr 0x%08" PRIx32
", len %d, type %d, set: %d, id: %" PRId32
,
926 breakpoint
->address
, breakpoint
->length
, breakpoint
->type
,
927 breakpoint
->set
, breakpoint
->unique_id
);
929 /* Only support SW breakpoints for now. */
930 if (breakpoint
->type
== BKPT_HARD
)
931 LOG_ERROR("HW breakpoints not supported for now. Doing SW breakpoint.");
933 /* Read and save the instruction */
934 int retval
= du_core
->or1k_jtag_read_memory(&or1k
->jtag
,
939 if (retval
!= ERROR_OK
) {
940 LOG_ERROR("Error while reading the instruction at 0x%08" PRIx32
,
941 breakpoint
->address
);
945 if (breakpoint
->orig_instr
!= NULL
)
946 free(breakpoint
->orig_instr
);
948 breakpoint
->orig_instr
= malloc(breakpoint
->length
);
949 memcpy(breakpoint
->orig_instr
, &data
, breakpoint
->length
);
951 /* Sub in the OR1K trap instruction */
952 uint8_t or1k_trap_insn
[4];
953 target_buffer_set_u32(target
, or1k_trap_insn
, OR1K_TRAP_INSTR
);
954 retval
= du_core
->or1k_jtag_write_memory(&or1k
->jtag
,
960 if (retval
!= ERROR_OK
) {
961 LOG_ERROR("Error while writing OR1K_TRAP_INSTR at 0x%08" PRIx32
,
962 breakpoint
->address
);
966 /* invalidate instruction cache */
967 retval
= du_core
->or1k_jtag_write_cpu(&or1k
->jtag
,
968 OR1K_ICBIR_CPU_REG_ADD
, 1, &breakpoint
->address
);
969 if (retval
!= ERROR_OK
) {
970 LOG_ERROR("Error while invalidating the ICACHE");
977 static int or1k_remove_breakpoint(struct target
*target
,
978 struct breakpoint
*breakpoint
)
980 struct or1k_common
*or1k
= target_to_or1k(target
);
981 struct or1k_du
*du_core
= or1k_to_du(or1k
);
983 LOG_DEBUG("Removing breakpoint: addr 0x%08" PRIx32
", len %d, type %d, set: %d, id: %" PRId32
,
984 breakpoint
->address
, breakpoint
->length
, breakpoint
->type
,
985 breakpoint
->set
, breakpoint
->unique_id
);
987 /* Only support SW breakpoints for now. */
988 if (breakpoint
->type
== BKPT_HARD
)
989 LOG_ERROR("HW breakpoints not supported for now. Doing SW breakpoint.");
991 /* Replace the removed instruction */
992 int retval
= du_core
->or1k_jtag_write_memory(&or1k
->jtag
,
996 breakpoint
->orig_instr
);
998 if (retval
!= ERROR_OK
) {
999 LOG_ERROR("Error while writing back the instruction at 0x%08" PRIx32
,
1000 breakpoint
->address
);
1004 /* invalidate instruction cache */
1005 retval
= du_core
->or1k_jtag_write_cpu(&or1k
->jtag
,
1006 OR1K_ICBIR_CPU_REG_ADD
, 1, &breakpoint
->address
);
1007 if (retval
!= ERROR_OK
) {
1008 LOG_ERROR("Error while invalidating the ICACHE");
1015 static int or1k_add_watchpoint(struct target
*target
,
1016 struct watchpoint
*watchpoint
)
1018 LOG_ERROR("%s: implement me", __func__
);
1022 static int or1k_remove_watchpoint(struct target
*target
,
1023 struct watchpoint
*watchpoint
)
1025 LOG_ERROR("%s: implement me", __func__
);
1029 static int or1k_read_memory(struct target
*target
, uint32_t address
,
1030 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1032 struct or1k_common
*or1k
= target_to_or1k(target
);
1033 struct or1k_du
*du_core
= or1k_to_du(or1k
);
1035 LOG_DEBUG("Read memory at 0x%08" PRIx32
", size: %" PRIu32
", count: 0x%08" PRIx32
, address
, size
, count
);
1037 if (target
->state
!= TARGET_HALTED
) {
1038 LOG_ERROR("Target not halted");
1039 return ERROR_TARGET_NOT_HALTED
;
1042 /* Sanitize arguments */
1043 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !buffer
) {
1044 LOG_ERROR("Bad arguments");
1045 return ERROR_COMMAND_SYNTAX_ERROR
;
1048 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
))) {
1049 LOG_ERROR("Can't handle unaligned memory access");
1050 return ERROR_TARGET_UNALIGNED_ACCESS
;
1053 return du_core
->or1k_jtag_read_memory(&or1k
->jtag
, address
, size
, count
, buffer
);
1056 static int or1k_write_memory(struct target
*target
, uint32_t address
,
1057 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1059 struct or1k_common
*or1k
= target_to_or1k(target
);
1060 struct or1k_du
*du_core
= or1k_to_du(or1k
);
1062 LOG_DEBUG("Write memory at 0x%08" PRIx32
", size: %" PRIu32
", count: 0x%08" PRIx32
, address
, size
, count
);
1064 if (target
->state
!= TARGET_HALTED
) {
1065 LOG_WARNING("Target not halted");
1066 return ERROR_TARGET_NOT_HALTED
;
1069 /* Sanitize arguments */
1070 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !buffer
) {
1071 LOG_ERROR("Bad arguments");
1072 return ERROR_COMMAND_SYNTAX_ERROR
;
1075 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
))) {
1076 LOG_ERROR("Can't handle unaligned memory access");
1077 return ERROR_TARGET_UNALIGNED_ACCESS
;
1080 return du_core
->or1k_jtag_write_memory(&or1k
->jtag
, address
, size
, count
, buffer
);
1083 static int or1k_init_target(struct command_context
*cmd_ctx
,
1084 struct target
*target
)
1086 struct or1k_common
*or1k
= target_to_or1k(target
);
1087 struct or1k_du
*du_core
= or1k_to_du(or1k
);
1088 struct or1k_jtag
*jtag
= &or1k
->jtag
;
1090 if (du_core
== NULL
) {
1091 LOG_ERROR("No debug unit selected");
1095 if (jtag
->tap_ip
== NULL
) {
1096 LOG_ERROR("No tap selected");
1100 or1k
->jtag
.tap
= target
->tap
;
1101 or1k
->jtag
.or1k_jtag_inited
= 0;
1102 or1k
->jtag
.or1k_jtag_module_selected
= -1;
1103 or1k
->jtag
.target
= target
;
1105 or1k_build_reg_cache(target
);
1110 static int or1k_target_create(struct target
*target
, Jim_Interp
*interp
)
1112 if (target
->tap
== NULL
)
1115 struct or1k_common
*or1k
= calloc(1, sizeof(struct or1k_common
));
1117 target
->arch_info
= or1k
;
1119 or1k_create_reg_list(target
);
1121 or1k_tap_vjtag_register();
1122 or1k_tap_xilinx_bscan_register();
1123 or1k_tap_mohor_register();
1125 or1k_du_adv_register();
1130 static int or1k_examine(struct target
*target
)
1132 struct or1k_common
*or1k
= target_to_or1k(target
);
1133 struct or1k_du
*du_core
= or1k_to_du(or1k
);
1135 if (!target_was_examined(target
)) {
1137 target_set_examined(target
);
1141 int retval
= du_core
->or1k_is_cpu_running(&or1k
->jtag
, &running
);
1142 if (retval
!= ERROR_OK
) {
1143 LOG_ERROR("Couldn't read the CPU state");
1147 target
->state
= TARGET_RUNNING
;
1149 LOG_DEBUG("Target is halted");
1151 /* This is the first time we examine the target,
1152 * it is stalled and we don't know why. Let's
1153 * assume this is because of a debug reason.
1155 if (target
->state
== TARGET_UNKNOWN
)
1156 target
->debug_reason
= DBG_REASON_DBGRQ
;
1158 target
->state
= TARGET_HALTED
;
1166 static int or1k_arch_state(struct target
*target
)
1171 static int or1k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1172 int *reg_list_size
, enum target_register_class reg_class
)
1174 struct or1k_common
*or1k
= target_to_or1k(target
);
1176 if (reg_class
== REG_CLASS_GENERAL
) {
1177 /* We will have this called whenever GDB connects. */
1178 int retval
= or1k_save_context(target
);
1179 if (retval
!= ERROR_OK
) {
1180 LOG_ERROR("Error while calling or1k_save_context");
1183 *reg_list_size
= OR1KNUMCOREREGS
;
1184 /* this is free()'d back in gdb_server.c's gdb_get_register_packet() */
1185 *reg_list
= malloc((*reg_list_size
) * sizeof(struct reg
*));
1187 for (int i
= 0; i
< OR1KNUMCOREREGS
; i
++)
1188 (*reg_list
)[i
] = &or1k
->core_cache
->reg_list
[i
];
1190 *reg_list_size
= or1k
->nb_regs
;
1191 *reg_list
= malloc((*reg_list_size
) * sizeof(struct reg
*));
1193 for (int i
= 0; i
< or1k
->nb_regs
; i
++)
1194 (*reg_list
)[i
] = &or1k
->core_cache
->reg_list
[i
];
1201 int or1k_get_gdb_fileio_info(struct target
*target
, struct gdb_fileio_info
*fileio_info
)
1206 static int or1k_checksum_memory(struct target
*target
, uint32_t address
,
1207 uint32_t count
, uint32_t *checksum
) {
1212 static int or1k_profiling(struct target
*target
, uint32_t *samples
,
1213 uint32_t max_num_samples
, uint32_t *num_samples
, uint32_t seconds
)
1215 struct timeval timeout
, now
;
1216 struct or1k_common
*or1k
= target_to_or1k(target
);
1217 struct or1k_du
*du_core
= or1k_to_du(or1k
);
1218 int retval
= ERROR_OK
;
1220 gettimeofday(&timeout
, NULL
);
1221 timeval_add_time(&timeout
, seconds
, 0);
1223 LOG_INFO("Starting or1k profiling. Sampling npc as fast as we can...");
1225 /* Make sure the target is running */
1226 target_poll(target
);
1227 if (target
->state
== TARGET_HALTED
)
1228 retval
= target_resume(target
, 1, 0, 0, 0);
1230 if (retval
!= ERROR_OK
) {
1231 LOG_ERROR("Error while resuming target");
1235 uint32_t sample_count
= 0;
1239 retval
= du_core
->or1k_jtag_read_cpu(&or1k
->jtag
, GROUP0
+ 16 /* NPC */, 1, ®_value
);
1240 if (retval
!= ERROR_OK
) {
1241 LOG_ERROR("Error while reading NPC");
1245 samples
[sample_count
++] = reg_value
;
1247 gettimeofday(&now
, NULL
);
1248 if ((sample_count
>= max_num_samples
) ||
1249 ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
))) {
1250 LOG_INFO("Profiling completed. %" PRIu32
" samples.", sample_count
);
1255 *num_samples
= sample_count
;
1259 COMMAND_HANDLER(or1k_tap_select_command_handler
)
1261 struct target
*target
= get_current_target(CMD_CTX
);
1262 struct or1k_common
*or1k
= target_to_or1k(target
);
1263 struct or1k_jtag
*jtag
= &or1k
->jtag
;
1264 struct or1k_tap_ip
*or1k_tap
;
1267 return ERROR_COMMAND_SYNTAX_ERROR
;
1269 list_for_each_entry(or1k_tap
, &tap_list
, list
) {
1270 if (or1k_tap
->name
) {
1271 if (!strcmp(CMD_ARGV
[0], or1k_tap
->name
)) {
1272 jtag
->tap_ip
= or1k_tap
;
1273 LOG_INFO("%s tap selected", or1k_tap
->name
);
1279 LOG_ERROR("%s unknown, no tap selected", CMD_ARGV
[0]);
1280 return ERROR_COMMAND_SYNTAX_ERROR
;
1283 COMMAND_HANDLER(or1k_tap_list_command_handler
)
1285 struct or1k_tap_ip
*or1k_tap
;
1288 return ERROR_COMMAND_SYNTAX_ERROR
;
1290 list_for_each_entry(or1k_tap
, &tap_list
, list
) {
1292 command_print(CMD_CTX
, "%s", or1k_tap
->name
);
1298 COMMAND_HANDLER(or1k_du_select_command_handler
)
1300 struct target
*target
= get_current_target(CMD_CTX
);
1301 struct or1k_common
*or1k
= target_to_or1k(target
);
1302 struct or1k_jtag
*jtag
= &or1k
->jtag
;
1303 struct or1k_du
*or1k_du
;
1306 return ERROR_COMMAND_SYNTAX_ERROR
;
1308 list_for_each_entry(or1k_du
, &du_list
, list
) {
1309 if (or1k_du
->name
) {
1310 if (!strcmp(CMD_ARGV
[0], or1k_du
->name
)) {
1311 jtag
->du_core
= or1k_du
;
1312 LOG_INFO("%s debug unit selected", or1k_du
->name
);
1314 if (CMD_ARGC
== 2) {
1316 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], options
);
1317 or1k_du
->options
= options
;
1318 LOG_INFO("Option %x is passed to %s debug unit"
1319 , options
, or1k_du
->name
);
1327 LOG_ERROR("%s unknown, no debug unit selected", CMD_ARGV
[0]);
1328 return ERROR_COMMAND_SYNTAX_ERROR
;
1331 COMMAND_HANDLER(or1k_du_list_command_handler
)
1333 struct or1k_du
*or1k_du
;
1336 return ERROR_COMMAND_SYNTAX_ERROR
;
1338 list_for_each_entry(or1k_du
, &du_list
, list
) {
1340 command_print(CMD_CTX
, "%s", or1k_du
->name
);
1346 COMMAND_HANDLER(or1k_addreg_command_handler
)
1348 struct target
*target
= get_current_target(CMD_CTX
);
1349 struct or1k_core_reg new_reg
;
1352 return ERROR_COMMAND_SYNTAX_ERROR
;
1354 new_reg
.target
= NULL
;
1355 new_reg
.or1k_common
= NULL
;
1358 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], addr
);
1360 new_reg
.name
= strdup(CMD_ARGV
[0]);
1361 new_reg
.spr_num
= addr
;
1362 new_reg
.feature
= strdup(CMD_ARGV
[2]);
1363 new_reg
.group
= strdup(CMD_ARGV
[3]);
1365 or1k_add_reg(target
, &new_reg
);
1367 LOG_DEBUG("Add reg \"%s\" @ 0x%08" PRIx32
", group \"%s\", feature \"%s\"",
1368 new_reg
.name
, addr
, new_reg
.group
, new_reg
.feature
);
1373 static const struct command_registration or1k_hw_ip_command_handlers
[] = {
1376 .handler
= or1k_tap_select_command_handler
,
1377 .mode
= COMMAND_ANY
,
1378 .usage
= "tap_select name",
1379 .help
= "Select the TAP core to use",
1383 .handler
= or1k_tap_list_command_handler
,
1384 .mode
= COMMAND_ANY
,
1385 .usage
= "tap_list",
1386 .help
= "Display available TAP core",
1390 .handler
= or1k_du_select_command_handler
,
1391 .mode
= COMMAND_ANY
,
1392 .usage
= "du_select name",
1393 .help
= "Select the Debug Unit core to use",
1397 .handler
= or1k_du_list_command_handler
,
1398 .mode
= COMMAND_ANY
,
1399 .usage
= "select_tap name",
1400 .help
= "Display available Debug Unit core",
1402 COMMAND_REGISTRATION_DONE
1405 static const struct command_registration or1k_reg_command_handlers
[] = {
1408 .handler
= or1k_addreg_command_handler
,
1409 .mode
= COMMAND_ANY
,
1410 .usage
= "addreg name addr feature group",
1411 .help
= "Add a register to the register list",
1413 COMMAND_REGISTRATION_DONE
1416 static const struct command_registration or1k_command_handlers
[] = {
1418 .chain
= or1k_reg_command_handlers
,
1421 .chain
= or1k_hw_ip_command_handlers
,
1423 COMMAND_REGISTRATION_DONE
1427 struct target_type or1k_target
= {
1431 .arch_state
= or1k_arch_state
,
1433 .target_request_data
= NULL
,
1436 .resume
= or1k_resume
,
1439 .assert_reset
= or1k_assert_reset
,
1440 .deassert_reset
= or1k_deassert_reset
,
1441 .soft_reset_halt
= or1k_soft_reset_halt
,
1443 .get_gdb_reg_list
= or1k_get_gdb_reg_list
,
1445 .read_memory
= or1k_read_memory
,
1446 .write_memory
= or1k_write_memory
,
1447 .checksum_memory
= or1k_checksum_memory
,
1449 .commands
= or1k_command_handlers
,
1450 .add_breakpoint
= or1k_add_breakpoint
,
1451 .remove_breakpoint
= or1k_remove_breakpoint
,
1452 .add_watchpoint
= or1k_add_watchpoint
,
1453 .remove_watchpoint
= or1k_remove_watchpoint
,
1455 .target_create
= or1k_target_create
,
1456 .init_target
= or1k_init_target
,
1457 .examine
= or1k_examine
,
1459 .get_gdb_fileio_info
= or1k_get_gdb_fileio_info
,
1461 .profiling
= or1k_profiling
,
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)