1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2008 by John McCarthy *
7 * Copyright (C) 2008 by Spencer Oliver *
8 * spen@spen-soft.co.uk *
10 * Copyright (C) 2008 by David T.L. Wong *
11 ***************************************************************************/
17 #include "mips32_dmaacc.h"
18 #include <helper/time_support.h>
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
);
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
);
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.
44 static int ejtag_dma_dstrt_poll(struct mips_ejtag
*ejtag_info
)
47 int64_t start
= timeval_ms();
50 if (timeval_ms() - start
> 1000) {
51 LOG_ERROR("DMA time out");
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
);
60 static int ejtag_dma_read(struct mips_ejtag
*ejtag_info
, uint32_t addr
, uint32_t *data
)
64 int retries
= RETRY_ATTEMPTS
;
70 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
71 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
);
78 /* Wait for DSTRT to Clear */
79 ejtag_dma_dstrt_poll(ejtag_info
);
82 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_DATA
);
83 mips_ejtag_drscan_32(ejtag_info
, data
);
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
) {
91 LOG_ERROR("DMA Read Addr = %08" PRIx32
" Data = ERROR ON READ (retrying)", addr
);
92 goto begin_ejtag_dma_read
;
94 LOG_ERROR("DMA Read Addr = %08" PRIx32
" Data = ERROR ON READ", addr
);
95 return ERROR_JTAG_DEVICE_ERROR
;
101 static int ejtag_dma_read_h(struct mips_ejtag
*ejtag_info
, uint32_t addr
, uint16_t *data
)
105 int retries
= RETRY_ATTEMPTS
;
107 begin_ejtag_dma_read_h
:
111 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
112 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
);
120 /* Wait for DSTRT to Clear */
121 ejtag_dma_dstrt_poll(ejtag_info
);
124 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_DATA
);
125 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
) {
133 LOG_ERROR("DMA Read Addr = %08" PRIx32
" Data = ERROR ON READ (retrying)", addr
);
134 goto begin_ejtag_dma_read_h
;
136 LOG_ERROR("DMA Read Addr = %08" PRIx32
" Data = ERROR ON READ", addr
);
137 return ERROR_JTAG_DEVICE_ERROR
;
140 /* Handle the bigendian/littleendian */
142 *data
= (v
>> 16) & 0xffff;
144 *data
= (v
& 0x0000ffff);
149 static int ejtag_dma_read_b(struct mips_ejtag
*ejtag_info
, uint32_t addr
, uint8_t *data
)
153 int retries
= RETRY_ATTEMPTS
;
155 begin_ejtag_dma_read_b
:
159 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
160 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
);
167 /* Wait for DSTRT to Clear */
168 ejtag_dma_dstrt_poll(ejtag_info
);
171 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_DATA
);
172 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
) {
180 LOG_ERROR("DMA Read Addr = %08" PRIx32
" Data = ERROR ON READ (retrying)", addr
);
181 goto begin_ejtag_dma_read_b
;
183 LOG_ERROR("DMA Read Addr = %08" PRIx32
" Data = ERROR ON READ", addr
);
184 return ERROR_JTAG_DEVICE_ERROR
;
187 /* Handle the bigendian/littleendian */
188 switch (addr
& 0x3) {
193 *data
= (v
>> 8) & 0xff;
196 *data
= (v
>> 16) & 0xff;
199 *data
= (v
>> 24) & 0xff;
206 static int ejtag_dma_write(struct mips_ejtag
*ejtag_info
, uint32_t addr
, uint32_t data
)
210 int retries
= RETRY_ATTEMPTS
;
212 begin_ejtag_dma_write
:
216 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
217 mips_ejtag_drscan_32(ejtag_info
, &v
);
221 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_DATA
);
222 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
);
229 /* Wait for DSTRT to Clear */
230 ejtag_dma_dstrt_poll(ejtag_info
);
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
) {
238 LOG_ERROR("DMA Write Addr = %08" PRIx32
" Data = ERROR ON WRITE (retrying)", addr
);
239 goto begin_ejtag_dma_write
;
241 LOG_ERROR("DMA Write Addr = %08" PRIx32
" Data = ERROR ON WRITE", addr
);
242 return ERROR_JTAG_DEVICE_ERROR
;
248 static int ejtag_dma_write_h(struct mips_ejtag
*ejtag_info
, uint32_t addr
, uint32_t data
)
252 int retries
= RETRY_ATTEMPTS
;
254 /* Handle the bigendian/littleendian */
258 begin_ejtag_dma_write_h
:
262 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
263 mips_ejtag_drscan_32(ejtag_info
, &v
);
267 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_DATA
);
268 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
);
275 /* Wait for DSTRT to Clear */
276 ejtag_dma_dstrt_poll(ejtag_info
);
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
) {
284 LOG_ERROR("DMA Write Addr = %08" PRIx32
" Data = ERROR ON WRITE (retrying)", addr
);
285 goto begin_ejtag_dma_write_h
;
287 LOG_ERROR("DMA Write Addr = %08" PRIx32
" Data = ERROR ON WRITE", addr
);
288 return ERROR_JTAG_DEVICE_ERROR
;
294 static int ejtag_dma_write_b(struct mips_ejtag
*ejtag_info
, uint32_t addr
, uint32_t data
)
298 int retries
= RETRY_ATTEMPTS
;
300 /* Handle the bigendian/littleendian */
305 begin_ejtag_dma_write_b
:
309 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_ADDRESS
);
310 mips_ejtag_drscan_32(ejtag_info
, &v
);
314 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_DATA
);
315 mips_ejtag_drscan_32(ejtag_info
, &v
);
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
);
322 /* Wait for DSTRT to Clear */
323 ejtag_dma_dstrt_poll(ejtag_info
);
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
) {
331 LOG_ERROR("DMA Write Addr = %08" PRIx32
" Data = ERROR ON WRITE (retrying)", addr
);
332 goto begin_ejtag_dma_write_b
;
334 LOG_ERROR("DMA Write Addr = %08" PRIx32
" Data = ERROR ON WRITE", addr
);
335 return ERROR_JTAG_DEVICE_ERROR
;
341 int mips32_dmaacc_read_mem(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int size
, int count
, void *buf
)
345 return mips32_dmaacc_read_mem8(ejtag_info
, addr
, count
, (uint8_t *)buf
);
347 return mips32_dmaacc_read_mem16(ejtag_info
, addr
, count
, (uint16_t *)buf
);
349 return mips32_dmaacc_read_mem32(ejtag_info
, addr
, count
, (uint32_t *)buf
);
355 static int mips32_dmaacc_read_mem32(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int count
, uint32_t *buf
)
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
)
369 static int mips32_dmaacc_read_mem16(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int count
, uint16_t *buf
)
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
)
383 static int mips32_dmaacc_read_mem8(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int count
, uint8_t *buf
)
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
)
397 int mips32_dmaacc_write_mem(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int size
, int count
, const void *buf
)
401 return mips32_dmaacc_write_mem8(ejtag_info
, addr
, count
, buf
);
403 return mips32_dmaacc_write_mem16(ejtag_info
, addr
, count
, buf
);
405 return mips32_dmaacc_write_mem32(ejtag_info
, addr
, count
, buf
);
411 static int mips32_dmaacc_write_mem32(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int count
, const uint32_t *buf
)
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
)
425 static int mips32_dmaacc_write_mem16(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int count
, const uint16_t *buf
)
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
)
439 static int mips32_dmaacc_write_mem8(struct mips_ejtag
*ejtag_info
, uint32_t addr
, int count
, const uint8_t *buf
)
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
)