1 /***************************************************************************
2 * Copyright (C) 2005, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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. *
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. *
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 ***************************************************************************/
28 int trace_point(target_t
*target
, u32 number
)
30 trace_t
*trace
= target
->trace_info
;
32 LOG_DEBUG("tracepoint: %i", number
);
34 if (number
< trace
->num_trace_points
)
35 trace
->trace_points
[number
].hit_counter
++;
37 if (trace
->trace_history_size
)
39 trace
->trace_history
[trace
->trace_history_pos
++] = number
;
40 if (trace
->trace_history_pos
== trace
->trace_history_size
)
42 trace
->trace_history_pos
= 0;
43 trace
->trace_history_overflowed
= 1;
50 static int handle_trace_point_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
52 target_t
*target
= get_current_target(cmd_ctx
);
53 trace_t
*trace
= target
->trace_info
;
59 for (i
= 0; i
< trace
->num_trace_points
; i
++)
61 command_print(cmd_ctx
, "trace point 0x%8.8x (%lld times hit)",
62 trace
->trace_points
[i
].address
,
63 trace
->trace_points
[i
].hit_counter
);
69 if (!strcmp(args
[0], "clear"))
71 if (trace
->trace_points
)
73 free(trace
->trace_points
);
74 trace
->trace_points
= NULL
;
76 trace
->num_trace_points
= 0;
77 trace
->trace_points_size
= 0;
82 /* resize array if necessary */
83 if (!trace
->trace_points
|| (trace
->trace_points_size
== trace
->num_trace_points
))
85 trace
->trace_points
= realloc(trace
->trace_points
, sizeof(trace_point_t
) * (trace
->trace_points_size
+ 32));
86 trace
->trace_points_size
+= 32;
89 trace
->trace_points
[trace
->num_trace_points
].address
= strtoul(args
[0], NULL
, 0);
90 trace
->trace_points
[trace
->num_trace_points
].hit_counter
= 0;
91 trace
->num_trace_points
++;
96 static int handle_trace_history_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
98 target_t
*target
= get_current_target(cmd_ctx
);
99 trace_t
*trace
= target
->trace_info
;
103 trace
->trace_history_pos
= 0;
104 trace
->trace_history_overflowed
= 0;
106 if (!strcmp(args
[0], "clear"))
108 /* clearing is implicit, we've just reset position anyway */
112 if (trace
->trace_history
)
113 free(trace
->trace_history
);
115 trace
->trace_history_size
= strtoul(args
[0], NULL
, 0);
116 trace
->trace_history
= malloc(sizeof(u32
) * trace
->trace_history_size
);
118 command_print(cmd_ctx
, "new trace history size: %i", trace
->trace_history_size
);
124 u32 last
= trace
->trace_history_pos
;
126 if ( !trace
->trace_history_size
) {
127 command_print(cmd_ctx
, "trace history buffer is not allocated");
130 if (trace
->trace_history_overflowed
)
132 first
= trace
->trace_history_pos
;
133 last
= trace
->trace_history_pos
- 1;
136 for (i
= first
; (i
% trace
->trace_history_size
) != last
; i
++)
138 if (trace
->trace_history
[i
% trace
->trace_history_size
] < trace
->num_trace_points
)
141 address
= trace
->trace_points
[trace
->trace_history
[i
% trace
->trace_history_size
]].address
;
142 command_print(cmd_ctx
, "trace point %i: 0x%8.8x",
143 trace
->trace_history
[i
% trace
->trace_history_size
],
149 command_print(cmd_ctx
, "trace point %i: -not defined-", trace
->trace_history
[i
% trace
->trace_history_size
]);
157 int trace_register_commands(struct command_context_s
*cmd_ctx
)
159 command_t
*trace_cmd
=
160 register_command(cmd_ctx
, NULL
, "trace", NULL
, COMMAND_ANY
, "trace commands");
162 register_command(cmd_ctx
, trace_cmd
, "history", handle_trace_history_command
,
163 COMMAND_EXEC
, "display trace history, ['clear'] history or set [size]");
165 register_command(cmd_ctx
, trace_cmd
, "point", handle_trace_point_command
,
166 COMMAND_EXEC
, "display trace points, ['clear'] list of trace points, or add new tracepoint at [address]");