- fixed arm926 cp15 command bug (thanks to Vincent Palatin for this patch)
[openocd.git] / src / target / etb.c
1 /***************************************************************************
2 * Copyright (C) 2005 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 "etb.h"
25
26 #include "log.h"
27 #include "types.h"
28 #include "binarybuffer.h"
29 #include "target.h"
30 #include "register.h"
31 #include "jtag.h"
32
33 #include <stdlib.h>
34
35 char* etb_reg_list[] =
36 {
37 "ETB_identification",
38 "ETB_ram_depth",
39 "ETB_ram_width",
40 "ETB_status",
41 "ETB_ram_data",
42 "ETB_ram_read_pointer",
43 "ETB_ram_write_pointer",
44 "ETB_trigger_counter",
45 "ETB_control",
46 };
47
48 int etb_reg_arch_type = -1;
49
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);
53
54 int etb_write_reg(reg_t *reg, u32 value);
55 int etb_read_reg(reg_t *reg);
56
57 int etb_set_instr(etb_t *etb, u32 new_instr)
58 {
59 jtag_device_t *device = jtag_get_device(etb->chain_pos);
60
61 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
62 {
63 scan_field_t field;
64
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;
75
76 jtag_add_ir_scan(1, &field, -1);
77
78 free(field.out_value);
79 }
80
81 return ERROR_OK;
82 }
83
84 int etb_scann(etb_t *etb, u32 new_scan_chain)
85 {
86 if(etb->cur_scan_chain != new_scan_chain)
87 {
88 scan_field_t field;
89
90 field.device = etb->chain_pos;
91 field.num_bits = 5;
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;
100
101 /* select INTEST instruction */
102 etb_set_instr(etb, 0x2);
103 jtag_add_dr_scan(1, &field, -1);
104
105 etb->cur_scan_chain = new_scan_chain;
106
107 free(field.out_value);
108 }
109
110 return ERROR_OK;
111 }
112
113 reg_cache_t* etb_build_reg_cache(etb_t *etb)
114 {
115 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
116 reg_t *reg_list = NULL;
117 etb_reg_t *arch_info = NULL;
118 int num_regs = 9;
119 int i;
120
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);
124
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));
128
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;
134
135 /* set up registers */
136 for (i = 0; i < num_regs; i++)
137 {
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;
150 }
151
152 return reg_cache;
153 }
154
155 int etb_get_reg(reg_t *reg)
156 {
157 if (etb_read_reg(reg) != ERROR_OK)
158 {
159 ERROR("BUG: error scheduling etm register read");
160 exit(-1);
161 }
162
163 if (jtag_execute_queue() != ERROR_OK)
164 {
165 ERROR("register read failed");
166 }
167
168 return ERROR_OK;
169 }
170
171 int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
172 {
173 etb_reg_t *etb_reg = reg->arch_info;
174 u8 reg_addr = etb_reg->addr & 0x7f;
175 scan_field_t fields[3];
176
177 DEBUG("%i", etb_reg->addr);
178
179 jtag_add_end_state(TAP_RTI);
180 etb_scann(etb_reg->etb, 0x0);
181 etb_set_instr(etb_reg->etb, 0xc);
182
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;
192
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;
203
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;
214
215 jtag_add_dr_scan(3, fields, -1);
216
217 fields[0].in_value = reg->value;
218 fields[0].in_check_value = check_value;
219 fields[0].in_check_mask = check_mask;
220
221 jtag_add_dr_scan(3, fields, -1);
222
223 free(fields[1].out_value);
224 free(fields[2].out_value);
225
226 return ERROR_OK;
227 }
228
229 int etb_read_reg(reg_t *reg)
230 {
231 return etb_read_reg_w_check(reg, NULL, NULL);
232 }
233
234 int etb_set_reg(reg_t *reg, u32 value)
235 {
236 if (etb_write_reg(reg, value) != ERROR_OK)
237 {
238 ERROR("BUG: error scheduling etm register write");
239 exit(-1);
240 }
241
242 buf_set_u32(reg->value, 0, reg->size, value);
243 reg->valid = 1;
244 reg->dirty = 0;
245
246 return ERROR_OK;
247 }
248
249 int etb_set_reg_w_exec(reg_t *reg, u8 *buf)
250 {
251 etb_set_reg(reg, buf_get_u32(buf, 0, reg->size));
252
253 if (jtag_execute_queue() != ERROR_OK)
254 {
255 ERROR("register write failed");
256 exit(-1);
257 }
258 return ERROR_OK;
259 }
260
261 int etb_write_reg(reg_t *reg, u32 value)
262 {
263 etb_reg_t *etb_reg = reg->arch_info;
264 u8 reg_addr = etb_reg->addr & 0x7f;
265 scan_field_t fields[3];
266
267 DEBUG("%i: 0x%8.8x", etb_reg->addr, value);
268
269 jtag_add_end_state(TAP_RTI);
270 etb_scann(etb_reg->etb, 0x0);
271 etb_set_instr(etb_reg->etb, 0xc);
272
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;
283
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;
294
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;
305
306 jtag_add_dr_scan(3, fields, -1);
307
308 free(fields[0].out_value);
309 free(fields[1].out_value);
310 free(fields[2].out_value);
311
312 return ERROR_OK;
313 }
314
315 int etb_store_reg(reg_t *reg)
316 {
317 return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
318 }
319