1 /***************************************************************************
2 * Copyright (C) 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 "arm7_9_common.h"
29 #include "binarybuffer.h"
36 char* etb_reg_list[] =
43 "ETB_ram_read_pointer",
44 "ETB_ram_write_pointer",
45 "ETB_trigger_counter",
49 int etb_reg_arch_type = -1;
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);
55 int etb_write_reg(reg_t *reg, u32 value);
56 int etb_read_reg(reg_t *reg);
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);
61 int etb_set_instr(etb_t *etb, u32 new_instr)
63 jtag_device_t *device = jtag_get_device(etb->chain_pos);
65 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
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;
80 jtag_add_ir_scan(1, &field, -1, NULL);
82 free(field.out_value);
88 int etb_scann(etb_t *etb, u32 new_scan_chain)
90 if(etb->cur_scan_chain != new_scan_chain)
94 field.device = etb->chain_pos;
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;
105 /* select INTEST instruction */
106 etb_set_instr(etb, 0x2);
107 jtag_add_dr_scan(1, &field, -1, NULL);
109 etb->cur_scan_chain = new_scan_chain;
111 free(field.out_value);
117 reg_cache_t* etb_build_reg_cache(etb_t *etb)
119 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
120 reg_t *reg_list = NULL;
121 etb_reg_t *arch_info = NULL;
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);
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));
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;
139 /* set up registers */
140 for (i = 0; i < num_regs; i++)
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;
159 int etb_get_reg(reg_t *reg)
161 if (etb_read_reg(reg) != ERROR_OK)
163 ERROR("BUG: error scheduling etm register read");
167 if (jtag_execute_queue() != ERROR_OK)
169 ERROR("register read failed");
175 int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
177 etb_reg_t *etb_reg = reg->arch_info;
178 u8 reg_addr = etb_reg->addr & 0x7f;
179 scan_field_t fields[3];
181 DEBUG("%i", etb_reg->addr);
183 jtag_add_end_state(TAP_RTI);
184 etb_scann(etb_reg->etb, 0x0);
185 etb_set_instr(etb_reg->etb, 0xc);
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;
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;
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;
219 jtag_add_dr_scan(3, fields, -1, NULL);
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
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;
229 jtag_add_dr_scan(3, fields, -1, NULL);
231 free(fields[1].out_value);
232 free(fields[2].out_value);
237 int etb_read_reg(reg_t *reg)
239 return etb_read_reg_w_check(reg, NULL, NULL);
242 int etb_set_reg(reg_t *reg, u32 value)
244 if (etb_write_reg(reg, value) != ERROR_OK)
246 ERROR("BUG: error scheduling etm register write");
250 buf_set_u32(reg->value, 0, reg->size, value);
257 int etb_set_reg_w_exec(reg_t *reg, u8 *buf)
259 etb_set_reg(reg, buf_get_u32(buf, 0, reg->size));
261 if (jtag_execute_queue() != ERROR_OK)
263 ERROR("register write failed");
269 int etb_write_reg(reg_t *reg, u32 value)
271 etb_reg_t *etb_reg = reg->arch_info;
272 u8 reg_addr = etb_reg->addr & 0x7f;
273 scan_field_t fields[3];
275 DEBUG("%i: 0x%8.8x", etb_reg->addr, value);
277 jtag_add_end_state(TAP_RTI);
278 etb_scann(etb_reg->etb, 0x0);
279 etb_set_instr(etb_reg->etb, 0xc);
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;
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;
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;
314 jtag_add_dr_scan(3, fields, -1, NULL);
316 free(fields[0].out_value);
317 free(fields[1].out_value);
318 free(fields[2].out_value);
323 int etb_store_reg(reg_t *reg)
325 return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
328 int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd)
330 register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
332 register_command(cmd_ctx, arm7_9_cmd, "etb_dump", handle_arm7_9_etb_dump_command, COMMAND_EXEC, "dump current ETB content");
337 int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
340 target_t *target = get_current_target(cmd_ctx);
341 armv4_5_common_t *armv4_5;
342 arm7_9_common_t *arm7_9;
347 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
349 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
355 command_print(cmd_ctx, "no ETB configured for current target");
359 if (!(arm7_9->etb->RAM_depth && arm7_9->etb->RAM_width))
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();
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);
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]);
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))
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;
381 last_frame = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32) - 1;
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++)
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);