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 ***************************************************************************/
24 #include "replacements.h"
34 int trace_point(target_t
*target
, u32 number
)
36 trace_t
*trace
= target
->trace_info
;
38 LOG_DEBUG("tracepoint: %i", number
);
40 if (number
< trace
->num_trace_points
)
41 trace
->trace_points
[number
].hit_counter
++;
43 if (trace
->trace_history_size
)
45 trace
->trace_history
[trace
->trace_history_pos
++] = number
;
46 if (trace
->trace_history_pos
== trace
->trace_history_size
)
48 trace
->trace_history_pos
= 0;
49 trace
->trace_history_overflowed
= 1;
56 int handle_trace_point_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
58 target_t
*target
= get_current_target(cmd_ctx
);
59 trace_t
*trace
= target
->trace_info
;
65 for (i
= 0; i
< trace
->num_trace_points
; i
++)
67 command_print(cmd_ctx
, "trace point 0x%8.8x (%"PRIi64
" times hit)",
68 trace
->trace_points
[i
].address
,
69 trace
->trace_points
[i
].hit_counter
);
75 if (!strcmp(args
[0], "clear"))
77 if (trace
->trace_points
)
79 free(trace
->trace_points
);
80 trace
->trace_points
= NULL
;
82 trace
->num_trace_points
= 0;
83 trace
->trace_points_size
= 0;
88 /* resize array if necessary */
89 if (!trace
->trace_points
|| (trace
->trace_points_size
== trace
->num_trace_points
))
91 trace
->trace_points
= realloc(trace
->trace_points
, sizeof(trace_point_t
) * (trace
->trace_points_size
+ 32));
92 trace
->trace_points_size
+= 32;
95 trace
->trace_points
[trace
->num_trace_points
].address
= strtoul(args
[0], NULL
, 0);
96 trace
->trace_points
[trace
->num_trace_points
].hit_counter
= 0;
97 trace
->num_trace_points
++;
102 int handle_trace_history_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
104 target_t
*target
= get_current_target(cmd_ctx
);
105 trace_t
*trace
= target
->trace_info
;
109 trace
->trace_history_pos
= 0;
110 trace
->trace_history_overflowed
= 0;
112 if (!strcmp(args
[0], "clear"))
114 /* clearing is implicit, we've just reset position anyway */
118 if (trace
->trace_history
)
119 free(trace
->trace_history
);
121 trace
->trace_history_size
= strtoul(args
[0], NULL
, 0);
122 trace
->trace_history
= malloc(sizeof(u32
) * trace
->trace_history_size
);
124 command_print(cmd_ctx
, "new trace history size: %i", trace
->trace_history_size
);
130 u32 last
= trace
->trace_history_pos
;
132 if ( !trace
->trace_history_size
) {
133 command_print(cmd_ctx
, "trace history buffer is not allocated");
136 if (trace
->trace_history_overflowed
)
138 first
= trace
->trace_history_pos
;
139 last
= trace
->trace_history_pos
- 1;
142 for (i
= first
; (i
% trace
->trace_history_size
) != last
; i
++)
144 if (trace
->trace_history
[i
% trace
->trace_history_size
] < trace
->num_trace_points
)
147 address
= trace
->trace_points
[trace
->trace_history
[i
% trace
->trace_history_size
]].address
;
148 command_print(cmd_ctx
, "trace point %i: 0x%8.8x",
149 trace
->trace_history
[i
% trace
->trace_history_size
],
155 command_print(cmd_ctx
, "trace point %i: -not defined-", trace
->trace_history
[i
% trace
->trace_history_size
]);
163 int trace_register_commands(struct command_context_s
*cmd_ctx
)
165 command_t
*trace_cmd
=
166 register_command(cmd_ctx
, NULL
, "trace", NULL
, COMMAND_ANY
, "trace commands");
168 register_command(cmd_ctx
, trace_cmd
, "history", handle_trace_history_command
,
169 COMMAND_EXEC
, "display trace history, ['clear'] history or set [size]");
171 register_command(cmd_ctx
, trace_cmd
, "point", handle_trace_point_command
,
172 COMMAND_EXEC
, "display trace points, ['clear'] list of trace points, or add new tracepoint at [address]");