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

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)