- fixed arm926 cp15 command bug (thanks to Vincent Palatin for this patch)
[fw/openocd] / 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