- improved ETB trace output
[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 int etb_set_instr(etb_t *etb, u32 new_instr)
62 {
63         jtag_device_t *device = jtag_get_device(etb->chain_pos);
64         
65         if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
66         {
67                 scan_field_t field;
68         
69                 field.device = etb->chain_pos;
70                 field.num_bits = device->ir_length;
71                 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
72                 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
73                 field.out_mask = NULL;
74                 field.in_value = NULL;
75                 field.in_check_value = NULL;
76                 field.in_check_mask = NULL;
77                 field.in_handler = NULL;
78                 field.in_handler_priv = NULL;
79                                 
80                 jtag_add_ir_scan(1, &field, -1, NULL);
81                 
82                 free(field.out_value);
83         }
84         
85         return ERROR_OK;
86 }
87
88 int etb_scann(etb_t *etb, u32 new_scan_chain)
89 {
90         if(etb->cur_scan_chain != new_scan_chain)
91         {
92                 scan_field_t field;
93                 
94                 field.device = etb->chain_pos;
95                 field.num_bits = 5;
96                 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
97                 buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
98                 field.out_mask = NULL;
99                 field.in_value = NULL;
100                 field.in_check_value = NULL;
101                 field.in_check_mask = NULL;
102                 field.in_handler = NULL;
103                 field.in_handler_priv = NULL;
104                 
105                 /* select INTEST instruction */
106                 etb_set_instr(etb, 0x2);
107                 jtag_add_dr_scan(1, &field, -1, NULL);
108                 
109                 etb->cur_scan_chain = new_scan_chain;
110                 
111                 free(field.out_value);
112         }
113
114         return ERROR_OK;
115 }
116
117 reg_cache_t* etb_build_reg_cache(etb_t *etb)
118 {
119         reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
120         reg_t *reg_list = NULL;
121         etb_reg_t *arch_info = NULL;
122         int num_regs = 9;
123         int i;
124         
125         /* register a register arch-type for etm registers only once */
126         if (etb_reg_arch_type == -1)
127                 etb_reg_arch_type = register_reg_arch_type(etb_get_reg, etb_set_reg_w_exec);
128         
129         /* the actual registers are kept in two arrays */
130         reg_list = calloc(num_regs, sizeof(reg_t));
131         arch_info = calloc(num_regs, sizeof(etb_reg_t));
132         
133         /* fill in values for the reg cache */
134         reg_cache->name = "etb registers";
135         reg_cache->next = NULL;
136         reg_cache->reg_list = reg_list;
137         reg_cache->num_regs = num_regs;
138         
139         /* set up registers */
140         for (i = 0; i < num_regs; i++)
141         {
142                 reg_list[i].name = etb_reg_list[i];
143                 reg_list[i].size = 32;
144                 reg_list[i].dirty = 0;
145                 reg_list[i].valid = 0;
146                 reg_list[i].bitfield_desc = NULL;
147                 reg_list[i].num_bitfields = 0;
148                 reg_list[i].value = calloc(1, 4);
149                 reg_list[i].arch_info = &arch_info[i];
150                 reg_list[i].arch_type = etb_reg_arch_type;
151                 reg_list[i].size = 32;
152                 arch_info[i].addr = i;
153                 arch_info[i].etb = etb;
154         }
155         
156         return reg_cache;
157 }
158
159 int etb_get_reg(reg_t *reg)
160 {
161         if (etb_read_reg(reg) != ERROR_OK)
162         {
163                 ERROR("BUG: error scheduling etm register read");
164                 exit(-1);
165         }
166         
167         if (jtag_execute_queue() != ERROR_OK)
168         {
169                 ERROR("register read failed");
170         }
171         
172         return ERROR_OK;
173 }
174
175 int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
176 {
177         etb_reg_t *etb_reg = reg->arch_info;
178         u8 reg_addr = etb_reg->addr & 0x7f;
179         scan_field_t fields[3];
180         
181         DEBUG("%i", etb_reg->addr);
182
183         jtag_add_end_state(TAP_RTI);
184         etb_scann(etb_reg->etb, 0x0);
185         etb_set_instr(etb_reg->etb, 0xc);
186         
187         fields[0].device = etb_reg->etb->chain_pos;
188         fields[0].num_bits = 32;
189         fields[0].out_value = reg->value;
190         fields[0].out_mask = NULL;
191         fields[0].in_value = NULL;
192         fields[0].in_check_value = NULL;
193         fields[0].in_check_mask = NULL;
194         fields[0].in_handler = NULL;
195         fields[0].in_handler_priv = NULL;
196         
197         fields[1].device = etb_reg->etb->chain_pos;
198         fields[1].num_bits = 7;
199         fields[1].out_value = malloc(1);
200         buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
201         fields[1].out_mask = NULL;
202         fields[1].in_value = NULL;
203         fields[1].in_check_value = NULL;
204         fields[1].in_check_mask = NULL;
205         fields[1].in_handler = NULL;
206         fields[1].in_handler_priv = NULL;
207
208         fields[2].device = etb_reg->etb->chain_pos;
209         fields[2].num_bits = 1;
210         fields[2].out_value = malloc(1);
211         buf_set_u32(fields[2].out_value, 0, 1, 0);
212         fields[2].out_mask = NULL;
213         fields[2].in_value = NULL;
214         fields[2].in_check_value = NULL;
215         fields[2].in_check_mask = NULL;
216         fields[2].in_handler = NULL;
217         fields[2].in_handler_priv = NULL;
218         
219         jtag_add_dr_scan(3, fields, -1, NULL);
220         
221         /* read the identification register in the second run, to make sure we
222          * don't read the ETB data register twice, skipping every second entry
223          */
224         buf_set_u32(fields[1].out_value, 0, 7, 0x0);
225         fields[0].in_value = reg->value;
226         fields[0].in_check_value = check_value;
227         fields[0].in_check_mask = check_mask;
228                 
229         jtag_add_dr_scan(3, fields, -1, NULL);
230
231         free(fields[1].out_value);
232         free(fields[2].out_value);
233         
234         return ERROR_OK;
235 }
236
237 int etb_read_reg(reg_t *reg)
238 {
239         return etb_read_reg_w_check(reg, NULL, NULL);   
240 }
241
242 int etb_set_reg(reg_t *reg, u32 value)
243 {
244         if (etb_write_reg(reg, value) != ERROR_OK)
245         {
246                 ERROR("BUG: error scheduling etm register write");
247                 exit(-1);
248         }
249         
250         buf_set_u32(reg->value, 0, reg->size, value);
251         reg->valid = 1;
252         reg->dirty = 0;
253         
254         return ERROR_OK;
255 }
256
257 int etb_set_reg_w_exec(reg_t *reg, u8 *buf)
258 {
259         etb_set_reg(reg, buf_get_u32(buf, 0, reg->size));
260         
261         if (jtag_execute_queue() != ERROR_OK)
262         {
263                 ERROR("register write failed");
264                 exit(-1);
265         }
266         return ERROR_OK;
267 }
268
269 int etb_write_reg(reg_t *reg, u32 value)
270 {
271         etb_reg_t *etb_reg = reg->arch_info;
272         u8 reg_addr = etb_reg->addr & 0x7f;
273         scan_field_t fields[3];
274         
275         DEBUG("%i: 0x%8.8x", etb_reg->addr, value);
276         
277         jtag_add_end_state(TAP_RTI);
278         etb_scann(etb_reg->etb, 0x0);
279         etb_set_instr(etb_reg->etb, 0xc);
280         
281         fields[0].device = etb_reg->etb->chain_pos;
282         fields[0].num_bits = 32;
283         fields[0].out_value = malloc(4);
284         buf_set_u32(fields[0].out_value, 0, 32, value);
285         fields[0].out_mask = NULL;
286         fields[0].in_value = NULL;
287         fields[0].in_check_value = NULL;
288         fields[0].in_check_mask = NULL;
289         fields[0].in_handler = NULL;
290         fields[0].in_handler_priv = NULL;
291         
292         fields[1].device = etb_reg->etb->chain_pos;
293         fields[1].num_bits = 7;
294         fields[1].out_value = malloc(1);
295         buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
296         fields[1].out_mask = NULL;
297         fields[1].in_value = NULL;
298         fields[1].in_check_value = NULL;
299         fields[1].in_check_mask = NULL;
300         fields[1].in_handler = NULL;
301         fields[1].in_handler_priv = NULL;
302
303         fields[2].device = etb_reg->etb->chain_pos;
304         fields[2].num_bits = 1;
305         fields[2].out_value = malloc(1);
306         buf_set_u32(fields[2].out_value, 0, 1, 1);
307         fields[2].out_mask = NULL;
308         fields[2].in_value = NULL;
309         fields[2].in_check_value = NULL;
310         fields[2].in_check_mask = NULL;
311         fields[2].in_handler = NULL;
312         fields[2].in_handler_priv = NULL;
313         
314         jtag_add_dr_scan(3, fields, -1, NULL);
315         
316         free(fields[0].out_value);
317         free(fields[1].out_value);
318         free(fields[2].out_value);
319         
320         return ERROR_OK;
321 }
322
323 int etb_store_reg(reg_t *reg)
324 {
325         return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
326 }
327
328 int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd)
329 {
330         register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
331
332         register_command(cmd_ctx, arm7_9_cmd, "etb_dump", handle_arm7_9_etb_dump_command, COMMAND_EXEC, "dump current ETB content");
333
334         return ERROR_OK;
335 }
336
337 int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
338 {
339         int retval;
340         target_t *target = get_current_target(cmd_ctx);
341         armv4_5_common_t *armv4_5;
342         arm7_9_common_t *arm7_9;
343         int i;
344         int first_frame = 0;
345         int last_frame;
346
347         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
348         {
349                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
350                 return ERROR_OK;
351         }
352         
353         if (!arm7_9->etb)
354         {
355                 command_print(cmd_ctx, "no ETB configured for current target");
356                 return ERROR_OK;
357         }
358         
359         if (!(arm7_9->etb->RAM_depth && arm7_9->etb->RAM_width))
360         {
361                 /* identify ETB RAM depth and width */
362                 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH]);
363                 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH]);
364                 jtag_execute_queue();
365         
366                 arm7_9->etb->RAM_depth = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32);
367                 arm7_9->etb->RAM_width = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32);
368         }
369         
370         etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_STATUS]);
371         etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER]);
372         
373         /* check if we overflowed, and adjust first and last frame of the trace accordingly */
374         if (buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_STATUS].value, 1, 1))
375         {
376                 first_frame = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32);
377                 last_frame = first_frame - 1;
378         }
379         else
380         {
381                 last_frame = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32) - 1;
382         }
383         
384         etb_write_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], first_frame);
385         for (i = first_frame; (i % arm7_9->etb->RAM_depth) != last_frame; i++)
386         {
387                 u32 trace_data;
388                 etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA]);
389                 jtag_execute_queue();
390                 trace_data = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA].value, 0, 32);
391                 command_print(cmd_ctx, "%8.8i: %i %2.2x %2.2x %2.2x (0x%8.8x)",
392                         i % 2048, (trace_data >> 19) & 1, (trace_data >> 11) & 0xff, (trace_data >> 3) & 0xff, trace_data & 0x7, trace_data);
393         }
394         
395         return ERROR_OK;
396 }