jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / mips32_dmaacc.c
1 /***************************************************************************
2 * Copyright (C) 2008 by John McCarthy *
3 * jgmcc@magma.ca *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2008 by David T.L. Wong *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "mips32_dmaacc.h"
29 #include <helper/time_support.h>
30
31 static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info,
32 uint32_t addr, int count, uint8_t *buf);
33 static int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info,
34 uint32_t addr, int count, uint16_t *buf);
35 static int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info,
36 uint32_t addr, int count, uint32_t *buf);
37
38 static int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info,
39 uint32_t addr, int count, const uint8_t *buf);
40 static int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info,
41 uint32_t addr, int count, const uint16_t *buf);
42 static int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info,
43 uint32_t addr, int count, const uint32_t *buf);
44
45 /*
46 * The following logic shamelessly cloned from HairyDairyMaid's wrt54g_debrick
47 * to support the Broadcom BCM5352 SoC in the Linksys WRT54GL wireless router
48 * (and any others that support EJTAG DMA transfers).
49 * Note: This only supports memory read/write. Since the BCM5352 doesn't
50 * appear to support PRACC accesses, all debug functions except halt
51 * do not work. Still, this does allow erasing/writing flash as well as
52 * displaying/modifying memory and memory mapped registers.
53 */
54
55 static int ejtag_dma_dstrt_poll(struct mips_ejtag *ejtag_info)
56 {
57 uint32_t ejtag_ctrl;
58 int64_t start = timeval_ms();
59
60 do {
61 if (timeval_ms() - start > 1000) {
62 LOG_ERROR("DMA time out");
63 return -ETIMEDOUT;
64 }
65 ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
66 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
67 } while (ejtag_ctrl & EJTAG_CTRL_DSTRT);
68 return 0;
69 }
70
71 static int ejtag_dma_read(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *data)
72 {
73 uint32_t v;
74 uint32_t ejtag_ctrl;
75 int retries = RETRY_ATTEMPTS;
76
77 begin_ejtag_dma_read:
78
79 /* Setup Address */
80 v = addr;
81 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
82 mips_ejtag_drscan_32(ejtag_info, &v);
83
84 /* Initiate DMA Read & set DSTRT */
85 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
86 ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
87 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
88
89 /* Wait for DSTRT to Clear */
90 ejtag_dma_dstrt_poll(ejtag_info);
91
92 /* Read Data */
93 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
94 mips_ejtag_drscan_32(ejtag_info, data);
95
96 /* Clear DMA & Check DERR */
97 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
98 ejtag_ctrl = ejtag_info->ejtag_ctrl;
99 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
100 if (ejtag_ctrl & EJTAG_CTRL_DERR) {
101 if (retries--) {
102 LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr);
103 goto begin_ejtag_dma_read;
104 } else
105 LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr);
106 return ERROR_JTAG_DEVICE_ERROR;
107 }
108
109 return ERROR_OK;
110 }
111
112 static int ejtag_dma_read_h(struct mips_ejtag *ejtag_info, uint32_t addr, uint16_t *data)
113 {
114 uint32_t v;
115 uint32_t ejtag_ctrl;
116 int retries = RETRY_ATTEMPTS;
117
118 begin_ejtag_dma_read_h:
119
120 /* Setup Address */
121 v = addr;
122 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
123 mips_ejtag_drscan_32(ejtag_info, &v);
124
125 /* Initiate DMA Read & set DSTRT */
126 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
127 ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD |
128 EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
129 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
130
131 /* Wait for DSTRT to Clear */
132 ejtag_dma_dstrt_poll(ejtag_info);
133
134 /* Read Data */
135 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
136 mips_ejtag_drscan_32(ejtag_info, &v);
137
138 /* Clear DMA & Check DERR */
139 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
140 ejtag_ctrl = ejtag_info->ejtag_ctrl;
141 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
142 if (ejtag_ctrl & EJTAG_CTRL_DERR) {
143 if (retries--) {
144 LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr);
145 goto begin_ejtag_dma_read_h;
146 } else
147 LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr);
148 return ERROR_JTAG_DEVICE_ERROR;
149 }
150
151 /* Handle the bigendian/littleendian */
152 if (addr & 0x2)
153 *data = (v >> 16) & 0xffff;
154 else
155 *data = (v & 0x0000ffff);
156
157 return ERROR_OK;
158 }
159
160 static int ejtag_dma_read_b(struct mips_ejtag *ejtag_info, uint32_t addr, uint8_t *data)
161 {
162 uint32_t v;
163 uint32_t ejtag_ctrl;
164 int retries = RETRY_ATTEMPTS;
165
166 begin_ejtag_dma_read_b:
167
168 /* Setup Address */
169 v = addr;
170 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
171 mips_ejtag_drscan_32(ejtag_info, &v);
172
173 /* Initiate DMA Read & set DSTRT */
174 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
175 ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
176 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
177
178 /* Wait for DSTRT to Clear */
179 ejtag_dma_dstrt_poll(ejtag_info);
180
181 /* Read Data */
182 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
183 mips_ejtag_drscan_32(ejtag_info, &v);
184
185 /* Clear DMA & Check DERR */
186 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
187 ejtag_ctrl = ejtag_info->ejtag_ctrl;
188 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
189 if (ejtag_ctrl & EJTAG_CTRL_DERR) {
190 if (retries--) {
191 LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr);
192 goto begin_ejtag_dma_read_b;
193 } else
194 LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr);
195 return ERROR_JTAG_DEVICE_ERROR;
196 }
197
198 /* Handle the bigendian/littleendian */
199 switch (addr & 0x3) {
200 case 0:
201 *data = v & 0xff;
202 break;
203 case 1:
204 *data = (v >> 8) & 0xff;
205 break;
206 case 2:
207 *data = (v >> 16) & 0xff;
208 break;
209 case 3:
210 *data = (v >> 24) & 0xff;
211 break;
212 }
213
214 return ERROR_OK;
215 }
216
217 static int ejtag_dma_write(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data)
218 {
219 uint32_t v;
220 uint32_t ejtag_ctrl;
221 int retries = RETRY_ATTEMPTS;
222
223 begin_ejtag_dma_write:
224
225 /* Setup Address */
226 v = addr;
227 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
228 mips_ejtag_drscan_32(ejtag_info, &v);
229
230 /* Setup Data */
231 v = data;
232 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
233 mips_ejtag_drscan_32(ejtag_info, &v);
234
235 /* Initiate DMA Write & set DSTRT */
236 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
237 ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
238 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
239
240 /* Wait for DSTRT to Clear */
241 ejtag_dma_dstrt_poll(ejtag_info);
242
243 /* Clear DMA & Check DERR */
244 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
245 ejtag_ctrl = ejtag_info->ejtag_ctrl;
246 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
247 if (ejtag_ctrl & EJTAG_CTRL_DERR) {
248 if (retries--) {
249 LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr);
250 goto begin_ejtag_dma_write;
251 } else
252 LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr);
253 return ERROR_JTAG_DEVICE_ERROR;
254 }
255
256 return ERROR_OK;
257 }
258
259 static int ejtag_dma_write_h(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data)
260 {
261 uint32_t v;
262 uint32_t ejtag_ctrl;
263 int retries = RETRY_ATTEMPTS;
264
265 /* Handle the bigendian/littleendian */
266 data &= 0xffff;
267 data |= data << 16;
268
269 begin_ejtag_dma_write_h:
270
271 /* Setup Address */
272 v = addr;
273 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
274 mips_ejtag_drscan_32(ejtag_info, &v);
275
276 /* Setup Data */
277 v = data;
278 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
279 mips_ejtag_drscan_32(ejtag_info, &v);
280
281 /* Initiate DMA Write & set DSTRT */
282 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
283 ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
284 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
285
286 /* Wait for DSTRT to Clear */
287 ejtag_dma_dstrt_poll(ejtag_info);
288
289 /* Clear DMA & Check DERR */
290 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
291 ejtag_ctrl = ejtag_info->ejtag_ctrl;
292 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
293 if (ejtag_ctrl & EJTAG_CTRL_DERR) {
294 if (retries--) {
295 LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr);
296 goto begin_ejtag_dma_write_h;
297 } else
298 LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr);
299 return ERROR_JTAG_DEVICE_ERROR;
300 }
301
302 return ERROR_OK;
303 }
304
305 static int ejtag_dma_write_b(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data)
306 {
307 uint32_t v;
308 uint32_t ejtag_ctrl;
309 int retries = RETRY_ATTEMPTS;
310
311 /* Handle the bigendian/littleendian */
312 data &= 0xff;
313 data |= data << 8;
314 data |= data << 16;
315
316 begin_ejtag_dma_write_b:
317
318 /* Setup Address*/
319 v = addr;
320 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
321 mips_ejtag_drscan_32(ejtag_info, &v);
322
323 /* Setup Data */
324 v = data;
325 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
326 mips_ejtag_drscan_32(ejtag_info, &v);
327
328 /* Initiate DMA Write & set DSTRT */
329 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
330 ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
331 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
332
333 /* Wait for DSTRT to Clear */
334 ejtag_dma_dstrt_poll(ejtag_info);
335
336 /* Clear DMA & Check DERR */
337 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
338 ejtag_ctrl = ejtag_info->ejtag_ctrl;
339 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
340 if (ejtag_ctrl & EJTAG_CTRL_DERR) {
341 if (retries--) {
342 LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr);
343 goto begin_ejtag_dma_write_b;
344 } else
345 LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr);
346 return ERROR_JTAG_DEVICE_ERROR;
347 }
348
349 return ERROR_OK;
350 }
351
352 int mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
353 {
354 switch (size) {
355 case 1:
356 return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (uint8_t *)buf);
357 case 2:
358 return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (uint16_t *)buf);
359 case 4:
360 return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (uint32_t *)buf);
361 }
362
363 return ERROR_OK;
364 }
365
366 static int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
367 {
368 int i;
369 int retval;
370
371 for (i = 0; i < count; i++) {
372 retval = ejtag_dma_read(ejtag_info, addr + i * sizeof(*buf), &buf[i]);
373 if (retval != ERROR_OK)
374 return retval;
375 }
376
377 return ERROR_OK;
378 }
379
380 static int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
381 {
382 int i;
383 int retval;
384
385 for (i = 0; i < count; i++) {
386 retval = ejtag_dma_read_h(ejtag_info, addr + i * sizeof(*buf), &buf[i]);
387 if (retval != ERROR_OK)
388 return retval;
389 }
390
391 return ERROR_OK;
392 }
393
394 static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
395 {
396 int i;
397 int retval;
398
399 for (i = 0; i < count; i++) {
400 retval = ejtag_dma_read_b(ejtag_info, addr + i * sizeof(*buf), &buf[i]);
401 if (retval != ERROR_OK)
402 return retval;
403 }
404
405 return ERROR_OK;
406 }
407
408 int mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, const void *buf)
409 {
410 switch (size) {
411 case 1:
412 return mips32_dmaacc_write_mem8(ejtag_info, addr, count, buf);
413 case 2:
414 return mips32_dmaacc_write_mem16(ejtag_info, addr, count, buf);
415 case 4:
416 return mips32_dmaacc_write_mem32(ejtag_info, addr, count, buf);
417 }
418
419 return ERROR_OK;
420 }
421
422 static int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint32_t *buf)
423 {
424 int i;
425 int retval;
426
427 for (i = 0; i < count; i++) {
428 retval = ejtag_dma_write(ejtag_info, addr + i * sizeof(*buf), buf[i]);
429 if (retval != ERROR_OK)
430 return retval;
431 }
432
433 return ERROR_OK;
434 }
435
436 static int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint16_t *buf)
437 {
438 int i;
439 int retval;
440
441 for (i = 0; i < count; i++) {
442 retval = ejtag_dma_write_h(ejtag_info, addr + i * sizeof(*buf), buf[i]);
443 if (retval != ERROR_OK)
444 return retval;
445 }
446
447 return ERROR_OK;
448 }
449
450 static int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint8_t *buf)
451 {
452 int i;
453 int retval;
454
455 for (i = 0; i < count; i++) {
456 retval = ejtag_dma_write_b(ejtag_info, addr + i * sizeof(*buf), buf[i]);
457 if (retval != ERROR_OK)
458 return retval;
459 }
460
461 return ERROR_OK;
462 }

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)