1 /***************************************************************************
2 * Copyright (C) 2005 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
;
345 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
347 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
353 command_print(cmd_ctx
, "no ETB configured for current target");
357 if (!(arm7_9
->etb
->RAM_depth
&& arm7_9
->etb
->RAM_width
))
359 /* identify ETB RAM depth and width */
360 etb_read_reg(&arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_DEPTH
]);
361 etb_read_reg(&arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_WIDTH
]);
362 jtag_execute_queue();
364 arm7_9
->etb
->RAM_depth
= buf_get_u32(arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_DEPTH
].value
, 0, 32);
365 arm7_9
->etb
->RAM_width
= buf_get_u32(arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_WIDTH
].value
, 0, 32);
368 /* always start reading from the beginning of the buffer */
369 etb_write_reg(&arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_READ_POINTER
], 0x0);
370 for (i
= 0; i
< arm7_9
->etb
->RAM_depth
; i
++)
373 etb_read_reg(&arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_DATA
]);
374 jtag_execute_queue();
375 trace_data
= buf_get_u32(arm7_9
->etb
->reg_cache
->reg_list
[ETB_RAM_DATA
].value
, 0, 32);
376 command_print(cmd_ctx
, "%8.8i: %i %2.2x %2.2x %2.2x (0x%8.8x)",
377 i
, (trace_data
>> 19) & 1, (trace_data
>> 11) & 0xff, (trace_data
>> 3) & 0xff, trace_data
& 0x7, trace_data
);
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)