armv7a_mmu: s/LOG_ERROR/LOG_WARNING/ on address translation failure
[openocd.git] / src / target / esirisc_jtag.c
1 /***************************************************************************
2 * Copyright (C) 2018 by Square, Inc. *
3 * Steven Stallion <stallion@squareup.com> *
4 * James Zhao <hjz@squareup.com> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <helper/binarybuffer.h>
25 #include <helper/log.h>
26 #include <helper/types.h>
27 #include <jtag/jtag.h>
28 #include <jtag/commands.h>
29 #include <jtag/interface.h>
30
31 #include "esirisc_jtag.h"
32
33 static void esirisc_jtag_set_instr(struct esirisc_jtag *jtag_info, uint32_t new_instr)
34 {
35 struct jtag_tap *tap = jtag_info->tap;
36
37 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
38 struct scan_field field;
39 uint8_t t[4];
40
41 field.num_bits = tap->ir_length;
42 field.out_value = t;
43 buf_set_u32(t, 0, field.num_bits, new_instr);
44 field.in_value = NULL;
45
46 jtag_add_ir_scan(tap, &field, TAP_IDLE);
47 }
48 }
49
50 /*
51 * The data register is latched every 8 bits while in the Shift-DR state
52 * (Update-DR is not supported). This necessitates prepending padding
53 * bits to ensure data is aligned when multiple TAPs are present.
54 */
55 static int esirisc_jtag_get_padding(void)
56 {
57 int padding = 0;
58 int bypass_devices = 0;
59
60 for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL;
61 tap = jtag_tap_next_enabled(tap))
62 if (tap->bypass)
63 bypass_devices++;
64
65 int num_bits = bypass_devices % 8;
66 if (num_bits > 0)
67 padding = 8 - num_bits;
68
69 return padding;
70 }
71
72 static int esirisc_jtag_count_bits(int num_fields, struct scan_field *fields)
73 {
74 int bit_count = 0;
75
76 for (int i = 0; i < num_fields; ++i)
77 bit_count += fields[i].num_bits;
78
79 return bit_count;
80 }
81
82 /*
83 * Data received from the target will be byte-stuffed if it contains
84 * either the pad byte (0xAA) or stuffing marker (0x55). Buffers should
85 * be sized twice the expected length to account for stuffing overhead.
86 */
87 static void esirisc_jtag_unstuff(uint8_t *data, size_t len)
88 {
89 uint8_t *r, *w;
90 uint8_t *end;
91
92 r = w = data;
93 end = data + len;
94 while (r < end) {
95 if (*r == STUFF_MARKER) {
96 r++; /* skip stuffing marker */
97 assert(r < end);
98 *w++ = *r++ ^ STUFF_MARKER;
99 } else
100 *w++ = *r++;
101 }
102 }
103
104 /*
105 * The eSi-Debug protocol defines a byte-oriented command/response
106 * channel that operates over serial or JTAG. While not strictly
107 * required, separate DR scans are used for sending and receiving data.
108 * This allows the TAP to recover gracefully if the byte stream is
109 * corrupted at the expense of sending additional padding bits.
110 */
111
112 static int esirisc_jtag_send(struct esirisc_jtag *jtag_info, uint8_t command,
113 int num_out_fields, struct scan_field *out_fields)
114 {
115 int num_fields = 2 + num_out_fields;
116 struct scan_field *fields = cmd_queue_alloc(num_fields * sizeof(struct scan_field));
117
118 esirisc_jtag_set_instr(jtag_info, INSTR_DEBUG);
119
120 fields[0].num_bits = esirisc_jtag_get_padding();
121 fields[0].out_value = NULL;
122 fields[0].in_value = NULL;
123
124 fields[1].num_bits = 8;
125 fields[1].out_value = &command;
126 fields[1].in_value = NULL;
127
128 /* append command data */
129 for (int i = 0; i < num_out_fields; ++i)
130 jtag_scan_field_clone(&fields[2+i], &out_fields[i]);
131
132 jtag_add_dr_scan(jtag_info->tap, num_fields, fields, TAP_IDLE);
133
134 return jtag_execute_queue();
135 }
136
137 static int esirisc_jtag_recv(struct esirisc_jtag *jtag_info,
138 int num_in_fields, struct scan_field *in_fields)
139 {
140 int num_in_bits = esirisc_jtag_count_bits(num_in_fields, in_fields);
141 int num_in_bytes = DIV_ROUND_UP(num_in_bits, 8);
142
143 struct scan_field fields[3];
144 uint8_t r[num_in_bytes * 2];
145
146 esirisc_jtag_set_instr(jtag_info, INSTR_DEBUG);
147
148 fields[0].num_bits = esirisc_jtag_get_padding() + 1;
149 fields[0].out_value = NULL;
150 fields[0].in_value = NULL;
151
152 fields[1].num_bits = 8;
153 fields[1].out_value = NULL;
154 fields[1].in_value = &jtag_info->status;
155
156 fields[2].num_bits = num_in_bits * 2;
157 fields[2].out_value = NULL;
158 fields[2].in_value = r;
159
160 jtag_add_dr_scan(jtag_info->tap, ARRAY_SIZE(fields), fields, TAP_IDLE);
161
162 int retval = jtag_execute_queue();
163 if (retval != ERROR_OK)
164 return retval;
165
166 /* unstuff response data and write back to caller */
167 if (num_in_fields > 0) {
168 esirisc_jtag_unstuff(r, ARRAY_SIZE(r));
169
170 int bit_count = 0;
171 for (int i = 0; i < num_in_fields; ++i) {
172 buf_set_buf(r, bit_count, in_fields[i].in_value, 0, in_fields[i].num_bits);
173 bit_count += in_fields[i].num_bits;
174 }
175 }
176
177 return ERROR_OK;
178 }
179
180 static int esirisc_jtag_check_status(struct esirisc_jtag *jtag_info)
181 {
182 uint8_t eid = esirisc_jtag_get_eid(jtag_info);
183 if (eid != EID_NONE) {
184 LOG_ERROR("esirisc_jtag: bad status: 0x%02" PRIx32 " (DA: %" PRId32 ", "
185 "S: %" PRId32 ", EID: 0x%02" PRIx32 ")",
186 jtag_info->status, esirisc_jtag_is_debug_active(jtag_info),
187 esirisc_jtag_is_stopped(jtag_info), eid);
188 return ERROR_FAIL;
189 }
190
191 return ERROR_OK;
192 }
193
194 static int esirisc_jtag_send_and_recv(struct esirisc_jtag *jtag_info, uint8_t command,
195 int num_out_fields, struct scan_field *out_fields,
196 int num_in_fields, struct scan_field *in_fields)
197 {
198 int retval;
199
200 jtag_info->status = 0; /* clear status */
201
202 retval = esirisc_jtag_send(jtag_info, command, num_out_fields, out_fields);
203 if (retval != ERROR_OK) {
204 LOG_ERROR("esirisc_jtag: send failed (command: 0x%02" PRIx32 ")", command);
205 return ERROR_FAIL;
206 }
207
208 retval = esirisc_jtag_recv(jtag_info, num_in_fields, in_fields);
209 if (retval != ERROR_OK) {
210 LOG_ERROR("esirisc_jtag: recv failed (command: 0x%02" PRIx32 ")", command);
211 return ERROR_FAIL;
212 }
213
214 return esirisc_jtag_check_status(jtag_info);
215 }
216
217 /*
218 * Status is automatically updated after each command completes;
219 * these functions make each field available to the caller.
220 */
221
222 bool esirisc_jtag_is_debug_active(struct esirisc_jtag *jtag_info)
223 {
224 return !!(jtag_info->status & 1<<7); /* DA */
225 }
226
227 bool esirisc_jtag_is_stopped(struct esirisc_jtag *jtag_info)
228 {
229 return !!(jtag_info->status & 1<<6); /* S */
230 }
231
232 uint8_t esirisc_jtag_get_eid(struct esirisc_jtag *jtag_info)
233 {
234 return jtag_info->status & 0x3f; /* EID */
235 }
236
237 /*
238 * Most commands manipulate target data (eg. memory and registers); each
239 * command returns a status byte that indicates success. Commands must
240 * transmit multibyte values in big-endian order, however response
241 * values are in little-endian order. Target endianness does not have an
242 * effect on this ordering.
243 */
244
245 int esirisc_jtag_read_byte(struct esirisc_jtag *jtag_info, uint32_t address, uint8_t *data)
246 {
247 struct scan_field out_fields[1];
248 uint8_t a[4];
249
250 out_fields[0].num_bits = 32;
251 out_fields[0].out_value = a;
252 h_u32_to_be(a, address);
253 out_fields[0].in_value = NULL;
254
255 struct scan_field in_fields[1];
256 uint8_t d[1];
257
258 in_fields[0].num_bits = 8;
259 in_fields[0].out_value = NULL;
260 in_fields[0].in_value = d;
261
262 int retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_BYTE,
263 ARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);
264 if (retval != ERROR_OK)
265 return retval;
266
267 *data = *d;
268
269 return ERROR_OK;
270 }
271
272 int esirisc_jtag_read_hword(struct esirisc_jtag *jtag_info, uint32_t address, uint16_t *data)
273 {
274 struct scan_field out_fields[1];
275 uint8_t a[4];
276
277 out_fields[0].num_bits = 32;
278 out_fields[0].out_value = a;
279 h_u32_to_be(a, address);
280 out_fields[0].in_value = NULL;
281
282 struct scan_field in_fields[1];
283 uint8_t d[2];
284
285 in_fields[0].num_bits = 16;
286 in_fields[0].out_value = NULL;
287 in_fields[0].in_value = d;
288
289 int retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_HWORD,
290 ARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);
291 if (retval != ERROR_OK)
292 return retval;
293
294 *data = le_to_h_u16(d);
295
296 return ERROR_OK;
297 }
298
299 int esirisc_jtag_read_word(struct esirisc_jtag *jtag_info, uint32_t address, uint32_t *data)
300 {
301 struct scan_field out_fields[1];
302 uint8_t a[4];
303
304 out_fields[0].num_bits = 32;
305 out_fields[0].out_value = a;
306 h_u32_to_be(a, address);
307 out_fields[0].in_value = NULL;
308
309 struct scan_field in_fields[1];
310 uint8_t d[4];
311
312 in_fields[0].num_bits = 32;
313 in_fields[0].out_value = NULL;
314 in_fields[0].in_value = d;
315
316 int retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_WORD,
317 ARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);
318 if (retval != ERROR_OK)
319 return retval;
320
321 *data = le_to_h_u32(d);
322
323 return ERROR_OK;
324 }
325
326 int esirisc_jtag_write_byte(struct esirisc_jtag *jtag_info, uint32_t address, uint8_t data)
327 {
328 struct scan_field out_fields[2];
329 uint8_t a[4];
330
331 out_fields[0].num_bits = 32;
332 out_fields[0].out_value = a;
333 h_u32_to_be(a, address);
334 out_fields[0].in_value = NULL;
335
336 out_fields[1].num_bits = 8;
337 out_fields[1].out_value = &data;
338 out_fields[1].in_value = NULL;
339
340 return esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_BYTE,
341 ARRAY_SIZE(out_fields), out_fields, 0, NULL);
342 }
343
344 int esirisc_jtag_write_hword(struct esirisc_jtag *jtag_info, uint32_t address, uint16_t data)
345 {
346 struct scan_field out_fields[2];
347 uint8_t a[4], d[2];
348
349 out_fields[0].num_bits = 32;
350 out_fields[0].out_value = a;
351 h_u32_to_be(a, address);
352 out_fields[0].in_value = NULL;
353
354 out_fields[1].num_bits = 16;
355 out_fields[1].out_value = d;
356 h_u16_to_be(d, data);
357 out_fields[1].in_value = NULL;
358
359 return esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_HWORD,
360 ARRAY_SIZE(out_fields), out_fields, 0, NULL);
361 }
362
363 int esirisc_jtag_write_word(struct esirisc_jtag *jtag_info, uint32_t address, uint32_t data)
364 {
365 struct scan_field out_fields[2];
366 uint8_t a[4], d[4];
367
368 out_fields[0].num_bits = 32;
369 out_fields[0].out_value = a;
370 h_u32_to_be(a, address);
371 out_fields[0].in_value = NULL;
372
373 out_fields[1].num_bits = 32;
374 out_fields[1].out_value = d;
375 h_u32_to_be(d, data);
376 out_fields[1].in_value = NULL;
377
378 return esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_WORD,
379 ARRAY_SIZE(out_fields), out_fields, 0, NULL);
380 }
381
382 int esirisc_jtag_read_reg(struct esirisc_jtag *jtag_info, uint8_t reg, uint32_t *data)
383 {
384 struct scan_field out_fields[1];
385
386 out_fields[0].num_bits = 8;
387 out_fields[0].out_value = &reg;
388 out_fields[0].in_value = NULL;
389
390 struct scan_field in_fields[1];
391 uint8_t d[4];
392
393 in_fields[0].num_bits = 32;
394 in_fields[0].out_value = NULL;
395 in_fields[0].in_value = d;
396
397 int retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_REG,
398 ARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);
399 if (retval != ERROR_OK)
400 return retval;
401
402 *data = le_to_h_u32(d);
403
404 return ERROR_OK;
405 }
406
407 int esirisc_jtag_write_reg(struct esirisc_jtag *jtag_info, uint8_t reg, uint32_t data)
408 {
409 struct scan_field out_fields[2];
410 uint8_t d[4];
411
412 out_fields[0].num_bits = 8;
413 out_fields[0].out_value = &reg;
414 out_fields[0].in_value = NULL;
415
416 out_fields[1].num_bits = 32;
417 out_fields[1].out_value = d;
418 h_u32_to_be(d, data);
419 out_fields[1].in_value = NULL;
420
421 return esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_REG,
422 ARRAY_SIZE(out_fields), out_fields, 0, NULL);
423 }
424
425 int esirisc_jtag_read_csr(struct esirisc_jtag *jtag_info, uint8_t bank, uint8_t csr, uint32_t *data)
426 {
427 struct scan_field out_fields[1];
428 uint8_t c[2];
429
430 out_fields[0].num_bits = 16;
431 out_fields[0].out_value = c;
432 h_u16_to_be(c, (csr << 5) | bank);
433 out_fields[0].in_value = NULL;
434
435 struct scan_field in_fields[1];
436 uint8_t d[4];
437
438 in_fields[0].num_bits = 32;
439 in_fields[0].out_value = NULL;
440 in_fields[0].in_value = d;
441
442 int retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_CSR,
443 ARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);
444 if (retval != ERROR_OK)
445 return retval;
446
447 *data = le_to_h_u32(d);
448
449 return ERROR_OK;
450 }
451
452 int esirisc_jtag_write_csr(struct esirisc_jtag *jtag_info, uint8_t bank, uint8_t csr, uint32_t data)
453 {
454 struct scan_field out_fields[2];
455 uint8_t c[2], d[4];
456
457 out_fields[0].num_bits = 16;
458 out_fields[0].out_value = c;
459 h_u16_to_be(c, (csr << 5) | bank);
460 out_fields[0].in_value = NULL;
461
462 out_fields[1].num_bits = 32;
463 out_fields[1].out_value = d;
464 h_u32_to_be(d, data);
465 out_fields[1].in_value = NULL;
466
467 return esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_CSR,
468 ARRAY_SIZE(out_fields), out_fields, 0, NULL);
469 }
470
471 /*
472 * Control commands affect CPU operation; these commands send no data
473 * and return a status byte.
474 */
475
476 static inline int esirisc_jtag_send_ctrl(struct esirisc_jtag *jtag_info, uint8_t command)
477 {
478 return esirisc_jtag_send_and_recv(jtag_info, command, 0, NULL, 0, NULL);
479 }
480
481 int esirisc_jtag_enable_debug(struct esirisc_jtag *jtag_info)
482 {
483 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_ENABLE_DEBUG);
484 }
485
486 int esirisc_jtag_disable_debug(struct esirisc_jtag *jtag_info)
487 {
488 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_DISABLE_DEBUG);
489 }
490
491 int esirisc_jtag_assert_reset(struct esirisc_jtag *jtag_info)
492 {
493 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_ASSERT_RESET);
494 }
495
496 int esirisc_jtag_deassert_reset(struct esirisc_jtag *jtag_info)
497 {
498 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_DEASSERT_RESET);
499 }
500
501 int esirisc_jtag_break(struct esirisc_jtag *jtag_info)
502 {
503 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_BREAK);
504 }
505
506 int esirisc_jtag_continue(struct esirisc_jtag *jtag_info)
507 {
508 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_CONTINUE);
509 }
510
511 int esirisc_jtag_flush_caches(struct esirisc_jtag *jtag_info)
512 {
513 return esirisc_jtag_send_ctrl(jtag_info, DEBUG_FLUSH_CACHES);
514 }

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)