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 ***************************************************************************/
28 #include "binarybuffer.h"
35 char* etb_reg_list[] =
42 "ETB_ram_read_pointer",
43 "ETB_ram_write_pointer",
44 "ETB_trigger_counter",
48 int etb_reg_arch_type = -1;
50 int etb_get_reg(reg_t *reg);
51 int etb_set_reg(reg_t *reg, u32 value);
52 int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
54 int etb_write_reg(reg_t *reg, u32 value);
55 int etb_read_reg(reg_t *reg);
57 int etb_set_instr(etb_t *etb, u32 new_instr)
59 jtag_device_t *device = jtag_get_device(etb->chain_pos);
61 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
65 field.device = etb->chain_pos;
66 field.num_bits = device->ir_length;
67 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
68 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
69 field.out_mask = NULL;
70 field.in_value = NULL;
71 field.in_check_value = NULL;
72 field.in_check_mask = NULL;
73 field.in_handler = NULL;
74 field.in_handler_priv = NULL;
76 jtag_add_ir_scan(1, &field, -1);
78 free(field.out_value);
84 int etb_scann(etb_t *etb, u32 new_scan_chain)
86 if(etb->cur_scan_chain != new_scan_chain)
90 field.device = etb->chain_pos;
92 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
93 buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
94 field.out_mask = NULL;
95 field.in_value = NULL;
96 field.in_check_value = NULL;
97 field.in_check_mask = NULL;
98 field.in_handler = NULL;
99 field.in_handler_priv = NULL;
101 /* select INTEST instruction */
102 etb_set_instr(etb, 0x2);
103 jtag_add_dr_scan(1, &field, -1);
105 etb->cur_scan_chain = new_scan_chain;
107 free(field.out_value);
113 reg_cache_t* etb_build_reg_cache(etb_t *etb)
115 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
116 reg_t *reg_list = NULL;
117 etb_reg_t *arch_info = NULL;
121 /* register a register arch-type for etm registers only once */
122 if (etb_reg_arch_type == -1)
123 etb_reg_arch_type = register_reg_arch_type(etb_get_reg, etb_set_reg_w_exec);
125 /* the actual registers are kept in two arrays */
126 reg_list = calloc(num_regs, sizeof(reg_t));
127 arch_info = calloc(num_regs, sizeof(etb_reg_t));
129 /* fill in values for the reg cache */
130 reg_cache->name = "etb registers";
131 reg_cache->next = NULL;
132 reg_cache->reg_list = reg_list;
133 reg_cache->num_regs = num_regs;
135 /* set up registers */
136 for (i = 0; i < num_regs; i++)
138 reg_list[i].name = etb_reg_list[i];
139 reg_list[i].size = 32;
140 reg_list[i].dirty = 0;
141 reg_list[i].valid = 0;
142 reg_list[i].bitfield_desc = NULL;
143 reg_list[i].num_bitfields = 0;
144 reg_list[i].value = calloc(1, 4);
145 reg_list[i].arch_info = &arch_info[i];
146 reg_list[i].arch_type = etb_reg_arch_type;
147 reg_list[i].size = 32;
148 arch_info[i].addr = i;
149 arch_info[i].etb = etb;
155 int etb_get_reg(reg_t *reg)
157 if (etb_read_reg(reg) != ERROR_OK)
159 ERROR("BUG: error scheduling etm register read");
163 if (jtag_execute_queue() != ERROR_OK)
165 ERROR("register read failed");
171 int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
173 etb_reg_t *etb_reg = reg->arch_info;
174 u8 reg_addr = etb_reg->addr & 0x7f;
175 scan_field_t fields[3];
177 DEBUG("%i", etb_reg->addr);
179 jtag_add_end_state(TAP_RTI);
180 etb_scann(etb_reg->etb, 0x0);
181 etb_set_instr(etb_reg->etb, 0xc);
183 fields[0].device = etb_reg->etb->chain_pos;
184 fields[0].num_bits = 32;
185 fields[0].out_value = reg->value;
186 fields[0].out_mask = NULL;
187 fields[0].in_value = NULL;
188 fields[0].in_check_value = NULL;
189 fields[0].in_check_mask = NULL;
190 fields[0].in_handler = NULL;
191 fields[0].in_handler_priv = NULL;
193 fields[1].device = etb_reg->etb->chain_pos;
194 fields[1].num_bits = 7;
195 fields[1].out_value = malloc(1);
196 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
197 fields[1].out_mask = NULL;
198 fields[1].in_value = NULL;
199 fields[1].in_check_value = NULL;
200 fields[1].in_check_mask = NULL;
201 fields[1].in_handler = NULL;
202 fields[1].in_handler_priv = NULL;
204 fields[2].device = etb_reg->etb->chain_pos;
205 fields[2].num_bits = 1;
206 fields[2].out_value = malloc(1);
207 buf_set_u32(fields[2].out_value, 0, 1, 0);
208 fields[2].out_mask = NULL;
209 fields[2].in_value = NULL;
210 fields[2].in_check_value = NULL;
211 fields[2].in_check_mask = NULL;
212 fields[2].in_handler = NULL;
213 fields[2].in_handler_priv = NULL;
215 jtag_add_dr_scan(3, fields, -1);
217 fields[0].in_value = reg->value;
218 fields[0].in_check_value = check_value;
219 fields[0].in_check_mask = check_mask;
221 jtag_add_dr_scan(3, fields, -1);
223 free(fields[1].out_value);
224 free(fields[2].out_value);
229 int etb_read_reg(reg_t *reg)
231 return etb_read_reg_w_check(reg, NULL, NULL);
234 int etb_set_reg(reg_t *reg, u32 value)
236 if (etb_write_reg(reg, value) != ERROR_OK)
238 ERROR("BUG: error scheduling etm register write");
242 buf_set_u32(reg->value, 0, reg->size, value);
249 int etb_set_reg_w_exec(reg_t *reg, u8 *buf)
251 etb_set_reg(reg, buf_get_u32(buf, 0, reg->size));
253 if (jtag_execute_queue() != ERROR_OK)
255 ERROR("register write failed");
261 int etb_write_reg(reg_t *reg, u32 value)
263 etb_reg_t *etb_reg = reg->arch_info;
264 u8 reg_addr = etb_reg->addr & 0x7f;
265 scan_field_t fields[3];
267 DEBUG("%i: 0x%8.8x", etb_reg->addr, value);
269 jtag_add_end_state(TAP_RTI);
270 etb_scann(etb_reg->etb, 0x0);
271 etb_set_instr(etb_reg->etb, 0xc);
273 fields[0].device = etb_reg->etb->chain_pos;
274 fields[0].num_bits = 32;
275 fields[0].out_value = malloc(4);
276 buf_set_u32(fields[0].out_value, 0, 32, value);
277 fields[0].out_mask = NULL;
278 fields[0].in_value = NULL;
279 fields[0].in_check_value = NULL;
280 fields[0].in_check_mask = NULL;
281 fields[0].in_handler = NULL;
282 fields[0].in_handler_priv = NULL;
284 fields[1].device = etb_reg->etb->chain_pos;
285 fields[1].num_bits = 7;
286 fields[1].out_value = malloc(1);
287 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
288 fields[1].out_mask = NULL;
289 fields[1].in_value = NULL;
290 fields[1].in_check_value = NULL;
291 fields[1].in_check_mask = NULL;
292 fields[1].in_handler = NULL;
293 fields[1].in_handler_priv = NULL;
295 fields[2].device = etb_reg->etb->chain_pos;
296 fields[2].num_bits = 1;
297 fields[2].out_value = malloc(1);
298 buf_set_u32(fields[2].out_value, 0, 1, 1);
299 fields[2].out_mask = NULL;
300 fields[2].in_value = NULL;
301 fields[2].in_check_value = NULL;
302 fields[2].in_check_mask = NULL;
303 fields[2].in_handler = NULL;
304 fields[2].in_handler_priv = NULL;
306 jtag_add_dr_scan(3, fields, -1);
308 free(fields[0].out_value);
309 free(fields[1].out_value);
310 free(fields[2].out_value);
315 int etb_store_reg(reg_t *reg)
317 return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));