- prepare OpenOCD for branching, created ./trunk/
[openocd.git] / src / target / embeddedice.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 #include "config.h"
21
22 #include "embeddedice.h"
23
24 #include "armv4_5.h"
25 #include "arm7_9_common.h"
26
27 #include "log.h"
28 #include "arm_jtag.h"
29 #include "types.h"
30 #include "binarybuffer.h"
31 #include "target.h"
32 #include "register.h"
33 #include "jtag.h"
34
35 #include <stdlib.h>
36
37 bitfield_desc_t embeddedice_comms_ctrl_bitfield_desc[] =
38 {
39 {"R", 1},
40 {"W", 1},
41 {"reserved", 26},
42 {"version", 4}
43 };
44
45 int embeddedice_reg_arch_info[] =
46 {
47 0x0, 0x1, 0x4, 0x5,
48 0x8, 0x9, 0xa, 0xb, 0xc, 0xd,
49 0x10, 0x11, 0x12, 0x13, 0x14, 0x15
50 };
51
52 char* embeddedice_reg_list[] =
53 {
54 "debug_ctrl",
55 "debug_status",
56
57 "comms_ctrl",
58 "comms_data",
59
60 "watch 0 addr value",
61 "watch 0 addr mask",
62 "watch 0 data value",
63 "watch 0 data mask",
64 "watch 0 control value",
65 "watch 0 control mask",
66
67 "watch 1 addr value",
68 "watch 1 addr mask",
69 "watch 1 data value",
70 "watch 1 data mask",
71 "watch 1 control value",
72 "watch 1 control mask"
73 };
74
75 int embeddedice_reg_arch_type = -1;
76
77 int embeddedice_get_reg(reg_t *reg);
78 int embeddedice_set_reg(reg_t *reg, u32 value);
79
80 int embeddedice_write_reg(reg_t *reg, u32 value);
81 int embeddedice_read_reg(reg_t *reg);
82
83 reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, int extra_reg)
84 {
85 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
86 reg_t *reg_list = NULL;
87 embeddedice_reg_t *arch_info = NULL;
88 int num_regs = 16 + extra_reg;
89 int i;
90
91 /* register a register arch-type for EmbeddedICE registers only once */
92 if (embeddedice_reg_arch_type == -1)
93 embeddedice_reg_arch_type = register_reg_arch_type(embeddedice_get_reg, embeddedice_set_reg_w_exec);
94
95 /* the actual registers are kept in two arrays */
96 reg_list = calloc(num_regs, sizeof(reg_t));
97 arch_info = calloc(num_regs, sizeof(embeddedice_reg_t));
98
99 /* fill in values for the reg cache */
100 reg_cache->name = "EmbeddedICE registers";
101 reg_cache->next = NULL;
102 reg_cache->reg_list = reg_list;
103 reg_cache->num_regs = num_regs;
104
105 /* set up registers */
106 for (i = 0; i < num_regs - extra_reg; i++)
107 {
108 reg_list[i].name = embeddedice_reg_list[i];
109 reg_list[i].size = 32;
110 reg_list[i].dirty = 0;
111 reg_list[i].valid = 0;
112 reg_list[i].bitfield_desc = NULL;
113 reg_list[i].num_bitfields = 0;
114 reg_list[i].value = calloc(1, 4);
115 reg_list[i].arch_info = &arch_info[i];
116 reg_list[i].arch_type = embeddedice_reg_arch_type;
117 arch_info[i].addr = embeddedice_reg_arch_info[i];
118 arch_info[i].jtag_info = jtag_info;
119 }
120
121 /* there may be one extra reg (Abort status (ARM7 rev4) or Vector catch (ARM9)) */
122 if (extra_reg)
123 {
124 reg_list[num_regs - 1].arch_info = &arch_info[num_regs - 1];
125 arch_info[num_regs - 1].jtag_info = jtag_info;
126 }
127
128 return reg_cache;
129 }
130
131 int embeddedice_get_reg(reg_t *reg)
132 {
133 if (embeddedice_read_reg(reg) != ERROR_OK)
134 {
135 ERROR("BUG: error scheduling EmbeddedICE register read");
136 exit(-1);
137 }
138
139 if (jtag_execute_queue() != ERROR_OK)
140 {
141 ERROR("register read failed");
142 }
143
144 return ERROR_OK;
145 }
146
147 int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
148 {
149 embeddedice_reg_t *ice_reg = reg->arch_info;
150 u8 reg_addr = ice_reg->addr & 0x1f;
151 scan_field_t fields[3];
152
153 DEBUG("%i", ice_reg->addr);
154
155 jtag_add_end_state(TAP_RTI);
156 arm_jtag_scann(ice_reg->jtag_info, 0x2);
157 arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr);
158
159 fields[0].device = ice_reg->jtag_info->chain_pos;
160 fields[0].num_bits = 32;
161 fields[0].out_value = reg->value;
162 fields[0].out_mask = NULL;
163 fields[0].in_value = NULL;
164 fields[0].in_check_value = NULL;
165 fields[0].in_check_mask = NULL;
166 fields[0].in_handler = NULL;
167 fields[0].in_handler_priv = NULL;
168
169 fields[1].device = ice_reg->jtag_info->chain_pos;
170 fields[1].num_bits = 5;
171 fields[1].out_value = malloc(1);
172 buf_set_u32(fields[1].out_value, 0, 5, reg_addr);
173 fields[1].out_mask = NULL;
174 fields[1].in_value = NULL;
175 fields[1].in_check_value = NULL;
176 fields[1].in_check_mask = NULL;
177 fields[1].in_handler = NULL;
178 fields[1].in_handler_priv = NULL;
179
180 fields[2].device = ice_reg->jtag_info->chain_pos;
181 fields[2].num_bits = 1;
182 fields[2].out_value = malloc(1);
183 buf_set_u32(fields[2].out_value, 0, 1, 0);
184 fields[2].out_mask = NULL;
185 fields[2].in_value = NULL;
186 fields[2].in_check_value = NULL;
187 fields[2].in_check_mask = NULL;
188 fields[2].in_handler = NULL;
189 fields[2].in_handler_priv = NULL;
190
191 jtag_add_dr_scan(3, fields, -1);
192
193 fields[0].in_value = reg->value;
194 fields[0].in_check_value = check_value;
195 fields[0].in_check_mask = check_mask;
196
197 /* when reading the DCC data register, leaving the address field set to
198 * EICE_COMMS_DATA would read the register twice
199 * reading the control register is safe
200 */
201 buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]);
202
203 jtag_add_dr_scan(3, fields, -1);
204
205 free(fields[1].out_value);
206 free(fields[2].out_value);
207
208 return ERROR_OK;
209 }
210
211 int embeddedice_read_reg(reg_t *reg)
212 {
213 return embeddedice_read_reg_w_check(reg, NULL, NULL);
214 }
215
216 int embeddedice_set_reg(reg_t *reg, u32 value)
217 {
218 if (embeddedice_write_reg(reg, value) != ERROR_OK)
219 {
220 ERROR("BUG: error scheduling EmbeddedICE register write");
221 exit(-1);
222 }
223
224 buf_set_u32(reg->value, 0, reg->size, value);
225 reg->valid = 1;
226 reg->dirty = 0;
227
228 return ERROR_OK;
229 }
230
231 int embeddedice_set_reg_w_exec(reg_t *reg, u32 value)
232 {
233 embeddedice_set_reg(reg, value);
234
235 if (jtag_execute_queue() != ERROR_OK)
236 {
237 ERROR("register write failed");
238 exit(-1);
239 }
240 return ERROR_OK;
241 }
242
243 int embeddedice_write_reg(reg_t *reg, u32 value)
244 {
245 embeddedice_reg_t *ice_reg = reg->arch_info;
246 u8 reg_addr = ice_reg->addr & 0x1f;
247 scan_field_t fields[3];
248
249 DEBUG("%i: 0x%8.8x", ice_reg->addr, value);
250
251 jtag_add_end_state(TAP_RTI);
252 arm_jtag_scann(ice_reg->jtag_info, 0x2);
253 arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr);
254
255 fields[0].device = ice_reg->jtag_info->chain_pos;
256 fields[0].num_bits = 32;
257 fields[0].out_value = malloc(4);
258 buf_set_u32(fields[0].out_value, 0, 32, value);
259 fields[0].out_mask = NULL;
260 fields[0].in_value = NULL;
261 fields[0].in_check_value = NULL;
262 fields[0].in_check_mask = NULL;
263 fields[0].in_handler = NULL;
264 fields[0].in_handler_priv = NULL;
265
266 fields[1].device = ice_reg->jtag_info->chain_pos;
267 fields[1].num_bits = 5;
268 fields[1].out_value = malloc(1);
269 buf_set_u32(fields[1].out_value, 0, 5, reg_addr);
270 fields[1].out_mask = NULL;
271 fields[1].in_value = NULL;
272 fields[1].in_check_value = NULL;
273 fields[1].in_check_mask = NULL;
274 fields[1].in_handler = NULL;
275 fields[1].in_handler_priv = NULL;
276
277 fields[2].device = ice_reg->jtag_info->chain_pos;
278 fields[2].num_bits = 1;
279 fields[2].out_value = malloc(1);
280 buf_set_u32(fields[2].out_value, 0, 1, 1);
281 fields[2].out_mask = NULL;
282 fields[2].in_value = NULL;
283 fields[2].in_check_value = NULL;
284 fields[2].in_check_mask = NULL;
285 fields[2].in_handler = NULL;
286 fields[2].in_handler_priv = NULL;
287
288 jtag_add_dr_scan(3, fields, -1);
289
290 free(fields[0].out_value);
291 free(fields[1].out_value);
292 free(fields[2].out_value);
293
294 return ERROR_OK;
295 }
296
297 int embeddedice_store_reg(reg_t *reg)
298 {
299 return embeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
300 }
301

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)