- further work on ETB decoding (not yet functional)
[fw/openocd] / 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 }