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