21f250aa7f3e3b34c419e236eaeacfd8b0e0e023
[openocd.git] / src / target / etb.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm7_9_common.h"
25 #include "etb.h"
26
27 #include "log.h"
28 #include "types.h"
29 #include "binarybuffer.h"
30 #include "target.h"
31 #include "register.h"
32 #include "jtag.h"
33
34 #include <stdlib.h>
35
36 char* etb_reg_list[] =
37 {
38 "ETB_identification",
39 "ETB_ram_depth",
40 "ETB_ram_width",
41 "ETB_status",
42 "ETB_ram_data",
43 "ETB_ram_read_pointer",
44 "ETB_ram_write_pointer",
45 "ETB_trigger_counter",
46 "ETB_control",
47 };
48
49 int etb_reg_arch_type = -1;
50
51 int etb_get_reg(reg_t *reg);
52 int etb_set_reg(reg_t *reg, u32 value);
53 int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
54
55 int etb_write_reg(reg_t *reg, u32 value);
56 int etb_read_reg(reg_t *reg);
57
58 int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
59 int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
60
61 char *etmv1_branch_reason_string[] =
62 {
63 "normal pc change", "tracing enabled", "restart after FIFO overflow",
64 "exit from debug state", "peridoic synchronization point",
65 "reserved", "reserved", "reserved"
66 };
67
68
69 int etb_set_instr(etb_t *etb, u32 new_instr)
70 {
71 jtag_device_t *device = jtag_get_device(etb->chain_pos);
72
73 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
74 {
75 scan_field_t field;
76
77 field.device = etb->chain_pos;
78 field.num_bits = device->ir_length;
79 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
80 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
81 field.out_mask = NULL;
82 field.in_value = NULL;
83 field.in_check_value = NULL;
84 field.in_check_mask = NULL;
85 field.in_handler = NULL;
86 field.in_handler_priv = NULL;
87
88 jtag_add_ir_scan(1, &field, -1, NULL);
89
90 free(field.out_value);
91 }
92
93 return ERROR_OK;
94 }
95
96 int etb_scann(etb_t *etb, u32 new_scan_chain)
97 {
98 if(etb->cur_scan_chain != new_scan_chain)
99 {
100 scan_field_t field;
101
102 field.device = etb->chain_pos;
103 field.num_bits = 5;
104 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
105 buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
106 field.out_mask = NULL;
107 field.in_value = NULL;
108 field.in_check_value = NULL;
109 field.in_check_mask = NULL;
110 field.in_handler = NULL;
111 field.in_handler_priv = NULL;
112
113 /* select INTEST instruction */
114 etb_set_instr(etb, 0x2);
115 jtag_add_dr_scan(1, &field, -1, NULL);
116
117 etb->cur_scan_chain = new_scan_chain;
118
119 free(field.out_value);
120 }
121
122 return ERROR_OK;
123 }
124
125 reg_cache_t* etb_build_reg_cache(etb_t *etb)
126 {
127 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
128 reg_t *reg_list = NULL;
129 etb_reg_t *arch_info = NULL;
130 int num_regs = 9;
131 int i;
132
133 /* register a register arch-type for etm registers only once */
134 if (etb_reg_arch_type == -1)
135 etb_reg_arch_type = register_reg_arch_type(etb_get_reg, etb_set_reg_w_exec);
136
137 /* the actual registers are kept in two arrays */
138 reg_list = calloc(num_regs, sizeof(reg_t));
139 arch_info = calloc(num_regs, sizeof(etb_reg_t));
140
141 /* fill in values for the reg cache */
142 reg_cache->name = "etb registers";
143 reg_cache->next = NULL;
144 reg_cache->reg_list = reg_list;
145 reg_cache->num_regs = num_regs;
146
147 /* set up registers */
148 for (i = 0; i < num_regs; i++)
149 {
150 reg_list[i].name = etb_reg_list[i];
151 reg_list[i].size = 32;
152 reg_list[i].dirty = 0;
153 reg_list[i].valid = 0;
154 reg_list[i].bitfield_desc = NULL;
155 reg_list[i].num_bitfields = 0;
156 reg_list[i].value = calloc(1, 4);
157 reg_list[i].arch_info = &arch_info[i];
158 reg_list[i].arch_type = etb_reg_arch_type;
159 reg_list[i].size = 32;
160 arch_info[i].addr = i;
161 arch_info[i].etb = etb;
162 }
163
164 return reg_cache;
165 }
166
167 int etb_get_reg(reg_t *reg)
168 {
169 if (etb_read_reg(reg) != ERROR_OK)
170 {
171 ERROR("BUG: error scheduling etm register read");
172 exit(-1);
173 }
174
175 if (jtag_execute_queue() != ERROR_OK)
176 {
177 ERROR("register read failed");
178 }
179
180 return ERROR_OK;
181 }
182
183 int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
184 {
185 etb_reg_t *etb_reg = reg->arch_info;
186 u8 reg_addr = etb_reg->addr & 0x7f;
187 scan_field_t fields[3];
188
189 DEBUG("%i", etb_reg->addr);
190
191 jtag_add_end_state(TAP_RTI);
192 etb_scann(etb_reg->etb, 0x0);
193 etb_set_instr(etb_reg->etb, 0xc);
194
195 fields[0].device = etb_reg->etb->chain_pos;
196 fields[0].num_bits = 32;
197 fields[0].out_value = reg->value;
198 fields[0].out_mask = NULL;
199 fields[0].in_value = NULL;
200 fields[0].in_check_value = NULL;
201 fields[0].in_check_mask = NULL;
202 fields[0].in_handler = NULL;
203 fields[0].in_handler_priv = NULL;
204
205 fields[1].device = etb_reg->etb->chain_pos;
206 fields[1].num_bits = 7;
207 fields[1].out_value = malloc(1);
208 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
209 fields[1].out_mask = NULL;
210 fields[1].in_value = NULL;
211 fields[1].in_check_value = NULL;
212 fields[1].in_check_mask = NULL;
213 fields[1].in_handler = NULL;
214 fields[1].in_handler_priv = NULL;
215
216 fields[2].device = etb_reg->etb->chain_pos;
217 fields[2].num_bits = 1;
218 fields[2].out_value = malloc(1);
219 buf_set_u32(fields[2].out_value, 0, 1, 0);
220 fields[2].out_mask = NULL;
221 fields[2].in_value = NULL;
222 fields[2].in_check_value = NULL;
223 fields[2].in_check_mask = NULL;
224 fields[2].in_handler = NULL;
225 fields[2].in_handler_priv = NULL;
226
227 jtag_add_dr_scan(3, fields, -1, NULL);
228
229 /* read the identification register in the second run, to make sure we
230 * don't read the ETB data register twice, skipping every second entry
231 */
232 buf_set_u32(fields[1].out_value, 0, 7, 0x0);
233 fields[0].in_value = reg->value;
234 fields[0].in_check_value = check_value;
235 fields[0].in_check_mask = check_mask;
236
237 jtag_add_dr_scan(3, fields, -1, NULL);
238
239 free(fields[1].out_value);
240 free(fields[2].out_value);
241
242 return ERROR_OK;
243 }
244
245 int etb_read_reg(reg_t *reg)
246 {
247 return etb_read_reg_w_check(reg, NULL, NULL);
248 }
249
250 int etb_set_reg(reg_t *reg, u32 value)
251 {
252 if (etb_write_reg(reg, value) != ERROR_OK)
253 {
254 ERROR("BUG: error scheduling etm register write");
255 exit(-1);
256 }
257
258 buf_set_u32(reg->value, 0, reg->size, value);
259 reg->valid = 1;
260 reg->dirty = 0;
261
262 return ERROR_OK;
263 }
264
265 int etb_set_reg_w_exec(reg_t *reg, u8 *buf)
266 {
267 etb_set_reg(reg, buf_get_u32(buf, 0, reg->size));
268
269 if (jtag_execute_queue() != ERROR_OK)
270 {
271 ERROR("register write failed");
272 exit(-1);
273 }
274 return ERROR_OK;
275 }
276
277 int etb_write_reg(reg_t *reg, u32 value)
278 {
279 etb_reg_t *etb_reg = reg->arch_info;
280 u8 reg_addr = etb_reg->addr & 0x7f;
281 scan_field_t fields[3];
282
283 DEBUG("%i: 0x%8.8x", etb_reg->addr, value);
284
285 jtag_add_end_state(TAP_RTI);
286 etb_scann(etb_reg->etb, 0x0);
287 etb_set_instr(etb_reg->etb, 0xc);
288
289 fields[0].device = etb_reg->etb->chain_pos;
290 fields[0].num_bits = 32;
291 fields[0].out_value = malloc(4);
292 buf_set_u32(fields[0].out_value, 0, 32, value);
293 fields[0].out_mask = NULL;
294 fields[0].in_value = NULL;
295 fields[0].in_check_value = NULL;
296 fields[0].in_check_mask = NULL;
297 fields[0].in_handler = NULL;
298 fields[0].in_handler_priv = NULL;
299
300 fields[1].device = etb_reg->etb->chain_pos;
301 fields[1].num_bits = 7;
302 fields[1].out_value = malloc(1);
303 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
304 fields[1].out_mask = NULL;
305 fields[1].in_value = NULL;
306 fields[1].in_check_value = NULL;
307 fields[1].in_check_mask = NULL;
308 fields[1].in_handler = NULL;
309 fields[1].in_handler_priv = NULL;
310
311 fields[2].device = etb_reg->etb->chain_pos;
312 fields[2].num_bits = 1;
313 fields[2].out_value = malloc(1);
314 buf_set_u32(fields[2].out_value, 0, 1, 1);
315 fields[2].out_mask = NULL;
316 fields[2].in_value = NULL;
317 fields[2].in_check_value = NULL;
318 fields[2].in_check_mask = NULL;
319 fields[2].in_handler = NULL;
320 fields[2].in_handler_priv = NULL;
321
322 jtag_add_dr_scan(3, fields, -1, NULL);
323
324 free(fields[0].out_value);
325 free(fields[1].out_value);
326 free(fields[2].out_value);
327
328 return ERROR_OK;
329 }
330
331 int etb_store_reg(reg_t *reg)
332 {
333 return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
334 }
335
336 int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd)
337 {
338 register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
339
340 register_command(cmd_ctx, arm7_9_cmd, "etb_dump", handle_arm7_9_etb_dump_command, COMMAND_EXEC, "dump current ETB content");
341
342 return ERROR_OK;
343 }
344
345 #define PIPESTAT(x) ((x) & 0x7)
346 #define TRACEPKT(x) (((x) & 0x7fff8) >> 3)
347 #define TRACESYNC(x) (((x) & 0x80000) >> 19)
348
349 int etmv1_next_packet(int trace_depth, u32 *trace_data, int frame, int *port_half, int apo, u8 *packet)
350 {
351 while (frame < trace_depth)
352 {
353 if (apo > 0)
354 {
355 if (TRACESYNC(trace_data[frame]))
356 apo--;
357 }
358 else
359 {
360 /* we're looking for a branch address, skip if TRACESYNC isn't set */
361 if ((apo == 0) && (!TRACESYNC(trace_data[frame])))
362 {
363 frame++;
364 continue;
365 }
366
367 /* TRACEPKT is valid if this isn't a TD nor a TRIGGER cycle */
368 if (((PIPESTAT(trace_data[frame]) != 0x7) && (PIPESTAT(trace_data[frame]) != 0x6))
369 && !((apo == 0) && (!TRACESYNC(trace_data[frame]))))
370 {
371 if (*port_half == 0)
372 {
373 *packet = TRACEPKT(trace_data[frame]) & 0xff;
374 *port_half = 1;
375 }
376 else
377 {
378 *packet = (TRACEPKT(trace_data[frame]) & 0xff00) >> 8;
379 *port_half = 0;
380 frame++;
381 }
382 return frame;
383 }
384 }
385 frame++;
386 }
387
388 /* we reached the end of the trace without finding the packet we're looking for
389 * tracing is finished
390 */
391 return -1;
392 }
393
394 int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
395 {
396 int retval;
397 target_t *target = get_current_target(cmd_ctx);
398 armv4_5_common_t *armv4_5;
399 arm7_9_common_t *arm7_9;
400 int i, j, k;
401 int first_frame = 0;
402 int last_frame;
403 int addressbits_valid = 0;
404 u32 address = 0x0;
405 u32 *trace_data;
406 int port_half = 0;
407 int last_instruction = -1;
408 u8 branch_reason;
409 u8 packet;
410 char trace_output[256];
411 int trace_output_len;
412 u8 apo;
413
414 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
415 {
416 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
417 return ERROR_OK;
418 }
419
420 if (!arm7_9->etb)
421 {
422 command_print(cmd_ctx, "no ETB configured for current target");
423 return ERROR_OK;
424 }
425
426 if (!(arm7_9->etb->RAM_depth && arm7_9->etb->RAM_width))
427 {
428 /* identify ETB RAM depth and width */
429 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH]);
430 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH]);
431 jtag_execute_queue();
432
433 arm7_9->etb->RAM_depth = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32);
434 arm7_9->etb->RAM_width = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32);
435 }
436
437 trace_data = malloc(sizeof(u32) * arm7_9->etb->RAM_depth);
438
439 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_STATUS]);
440 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER]);
441 jtag_execute_queue();
442
443 /* check if we overflowed, and adjust first and last frame of the trace accordingly */
444 if (buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_STATUS].value, 1, 1))
445 {
446 first_frame = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32);
447 }
448
449 last_frame = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32) - 1;
450
451 etb_write_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], first_frame);
452
453 /* read trace data from ETB */
454 i = first_frame;
455 j = 0;
456 do {
457 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA]);
458 jtag_execute_queue();
459 trace_data[j++] = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA].value, 0, 32);
460 i++;
461 } while ((i % arm7_9->etb->RAM_depth) != (first_frame % arm7_9->etb->RAM_depth));
462
463 for (i = 0, j = 0; i < arm7_9->etb->RAM_depth; i++)
464 {
465 int trigger = 0;
466
467 trace_output_len = 0;
468
469 /* catch trigger, actual PIPESTAT is encoded in TRACEPKT[2:0] */
470 if (PIPESTAT(trace_data[i]) == 0x6)
471 {
472 trigger = 1;
473 trace_data[i] &= ~0x7;
474 trace_data[i] |= TRACEPKT(trace_data[i]) & 0x7;
475 }
476
477 if (addressbits_valid == 32)
478 {
479 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
480 "%i: 0x%8.8x %s", i, address, (trigger) ? "(TRIGGER) " : "");
481 }
482 else if (addressbits_valid != 0)
483 {
484 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
485 "%i: 0x...%x %s", i, address, (trigger) ? "(TRIGGER) " : "");
486 }
487 else
488 {
489 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
490 "%i: 0xUNK %s", i, (trigger) ? "(TRIGGER) " : "");
491 }
492
493 switch (PIPESTAT(trace_data[i]))
494 {
495 case 0x0:
496 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
497 "IE");
498 break;
499 case 0x1:
500 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
501 "ID");
502 break;
503 case 0x2:
504 /* Instruction exectued - TRACEPKT might be valid, but belongs to another cycle */
505 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
506 "IN");
507 break;
508 case 0x3:
509 /* WAIT cycle - TRACEPKT is valid, but belongs to another cycle */
510 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
511 "WT");
512 break;
513 case 0x4:
514 /* following a branch two APO cycles are output on PIPESTAT[1:0]
515 * but another BE/BD could overwrite the current branch,
516 * or a trigger could cause the APO to be output on TRACEPKT[1:0]
517 */
518 if ((PIPESTAT(trace_data[i + 1]) == 0x4)
519 || (PIPESTAT(trace_data[i + 1]) == 0x5))
520 {
521 /* another branch occured, we ignore this one */
522 j = (j < i + 1) ? i + 1 : j;
523 break;
524 }
525 else if (PIPESTAT(trace_data[i + 1]) == 0x6)
526 {
527 apo = TRACEPKT(trace_data[i + 1]) & 0x3;
528 }
529 else
530 {
531 apo = PIPESTAT(trace_data[i + 1]) & 0x3;
532 }
533
534 if ((PIPESTAT(trace_data[i + 2]) == 0x4)
535 || (PIPESTAT(trace_data[i + 2]) == 0x5))
536 {
537 j = (j < i + 2) ? i + 1 : j;
538 i = i + 1;
539 break;
540 }
541 else if (PIPESTAT(trace_data[i + 2]) == 0x6)
542 {
543 apo |= (TRACEPKT(trace_data[i + 2]) & 0x3) << 2;
544 }
545 else
546 {
547 apo = (PIPESTAT(trace_data[i + 1]) & 0x3) << 2;
548 }
549
550 branch_reason = -1;
551 k = 0;
552 do
553 {
554 if ((j = etmv1_next_packet(arm7_9->etb->RAM_depth, trace_data, j, &port_half, apo, &packet)) != -1)
555 {
556 address &= ~(0x7f << (k * 7));
557 address |= (packet & 0x7f) << (k * 7);
558 }
559 else
560 {
561 break;
562 }
563 k++;
564 } while ((k < 5) && (packet & 0x80));
565
566 if (addressbits_valid < ((k * 7 > 32) ? 32 : k * 7))
567 addressbits_valid = (k * 7 > 32) ? 32 : k * 7;
568
569 if (k == 5)
570 {
571 branch_reason = (packet & 0x7) >> 4;
572 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
573 "BE 0x%x (/%i) (%s)", address, addressbits_valid, etmv1_branch_reason_string[branch_reason]);
574 }
575 else
576 {
577 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
578 "BE 0x%x (/%i)", address, addressbits_valid);
579 }
580
581 break;
582 case 0x5:
583 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
584 "BD");
585 break;
586 case 0x6:
587 /* We catch the trigger event before we get here */
588 ERROR("TR pipestat should have been caught earlier");
589 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
590 "--");
591 break;
592 case 0x7:
593 /* TRACE disabled - TRACEPKT = invalid */
594 trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
595 "TD");
596 break;
597 }
598
599 /* PIPESTAT other than WT (b011) and TD (b111) mean we executed an instruction */
600 if ((PIPESTAT(trace_data[i]) & 0x3) != 0x3)
601 {
602 last_instruction = i;
603 address += 4;
604 }
605
606 /* The group of packets for a particular instruction cannot start on or before any
607 * previous functional PIPESTAT (IE, IN, ID, BE, or BD)
608 */
609 if (j < last_instruction)
610 {
611 j = last_instruction + 1;
612 }
613
614 /* restore trigger PIPESTAT to ensure TRACEPKT is ignored */
615 if (trigger == 1)
616 {
617 trace_data[i] &= ~0x7;
618 trace_data[i] |= 0x6;
619 }
620
621 command_print(cmd_ctx, "%s (raw: 0x%8.8x)", trace_output, trace_data[i]);
622 }
623
624 return ERROR_OK;
625 }