- remove build warnings from mips_m4k.c and arm11.c
[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, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 ***************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <string.h>
30 #include "log.h"
31 #include "mips32.h"
32 #include "mips32_dmaacc.h"
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_read(mips_ejtag_t *ejtag_info, u32 addr, u32 *data)
45 {
46 u32 v;
47 u32 ctrl_reg;
48 int retries = RETRY_ATTEMPTS;
49
50 begin_ejtag_dma_read:
51
52 // Setup Address
53 v = addr;
54 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
55 mips_ejtag_drscan_32(ejtag_info, &v);
56
57 // Initiate DMA Read & set DSTRT
58 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
59 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
60 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
61
62 // Wait for DSTRT to Clear
63 do {
64 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
65 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
66 } while(ctrl_reg & EJTAG_CTRL_DSTRT);
67
68 // Read Data
69 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
70 mips_ejtag_drscan_32(ejtag_info, data);
71
72 // Clear DMA & Check DERR
73 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
74 ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
75 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
76 if (ctrl_reg & EJTAG_CTRL_DERR)
77 {
78 if (retries--) {
79 printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
80 goto begin_ejtag_dma_read;
81 } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
82 return ERROR_JTAG_DEVICE_ERROR;
83 }
84
85 return ERROR_OK;
86 }
87
88 static int ejtag_dma_read_h(mips_ejtag_t *ejtag_info, u32 addr, u16 *data)
89 {
90 u32 v;
91 u32 ctrl_reg;
92 int retries = RETRY_ATTEMPTS;
93
94 begin_ejtag_dma_read_h:
95
96 // Setup Address
97 v = addr;
98 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
99 mips_ejtag_drscan_32(ejtag_info, &v);
100
101 // Initiate DMA Read & set DSTRT
102 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
103 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
104 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
105
106 // Wait for DSTRT to Clear
107 do {
108 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
109 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
110 } while(ctrl_reg & EJTAG_CTRL_DSTRT);
111
112 // Read Data
113 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
114 mips_ejtag_drscan_32(ejtag_info, &v);
115
116 // Clear DMA & Check DERR
117 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
118 ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
119 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
120 if (ctrl_reg & EJTAG_CTRL_DERR)
121 {
122 if (retries--) {
123 printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
124 goto begin_ejtag_dma_read_h;
125 } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
126 return ERROR_JTAG_DEVICE_ERROR;
127 }
128
129 // Handle the bigendian/littleendian
130 if ( addr & 0x2 ) *data = (v>>16)&0xffff ;
131 else *data = (v&0x0000ffff) ;
132
133 return ERROR_OK;
134 }
135
136 static int ejtag_dma_read_b(mips_ejtag_t *ejtag_info, u32 addr, u8 *data)
137 {
138 u32 v;
139 u32 ctrl_reg;
140 int retries = RETRY_ATTEMPTS;
141
142 begin_ejtag_dma_read_b:
143
144 // Setup Address
145 v = addr;
146 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
147 mips_ejtag_drscan_32(ejtag_info, &v);
148
149 // Initiate DMA Read & set DSTRT
150 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
151 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
152 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
153
154 // Wait for DSTRT to Clear
155 do {
156 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
157 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
158 } while(ctrl_reg & EJTAG_CTRL_DSTRT);
159
160 // Read Data
161 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
162 mips_ejtag_drscan_32(ejtag_info, &v);
163
164 // Clear DMA & Check DERR
165 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
166 ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
167 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
168 if (ctrl_reg & EJTAG_CTRL_DERR)
169 {
170 if (retries--) {
171 printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
172 goto begin_ejtag_dma_read_b;
173 } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
174 return ERROR_JTAG_DEVICE_ERROR;
175 }
176
177 // Handle the bigendian/littleendian
178 switch(addr & 0x3) {
179 case 0: *data = v & 0xff; break;
180 case 1: *data = (v>>8) & 0xff; break;
181 case 2: *data = (v>>16) & 0xff; break;
182 case 3: *data = (v>>24) & 0xff; break;
183 }
184
185 return ERROR_OK;
186 }
187
188 static int ejtag_dma_write(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
189 {
190 u32 v;
191 u32 ctrl_reg;
192 int retries = RETRY_ATTEMPTS;
193
194 begin_ejtag_dma_write:
195
196 // Setup Address
197 v = addr;
198 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
199 mips_ejtag_drscan_32(ejtag_info, &v);
200
201 // Setup Data
202 v = data;
203 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
204 mips_ejtag_drscan_32(ejtag_info, &v);
205
206 // Initiate DMA Write & set DSTRT
207 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
208 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
209 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
210
211 // Wait for DSTRT to Clear
212 do {
213 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
214 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
215 } while(ctrl_reg & EJTAG_CTRL_DSTRT);
216
217 // Clear DMA & Check DERR
218 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
219 ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
220 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
221 if (ctrl_reg & EJTAG_CTRL_DERR)
222 {
223 if (retries--) {
224 printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
225 goto begin_ejtag_dma_write;
226 } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
227 return ERROR_JTAG_DEVICE_ERROR;
228 }
229
230 return ERROR_OK;
231 }
232
233 static int ejtag_dma_write_h(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
234 {
235 u32 v;
236 u32 ctrl_reg;
237 int retries = RETRY_ATTEMPTS;
238
239
240 // Handle the bigendian/littleendian
241 data &= 0xffff;
242 data |= data<<16;
243
244 begin_ejtag_dma_write_h:
245
246 // Setup Address
247 v = addr;
248 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
249 mips_ejtag_drscan_32(ejtag_info, &v);
250
251 // Setup Data
252 v = data;
253 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
254 mips_ejtag_drscan_32(ejtag_info, &v);
255
256 // Initiate DMA Write & set DSTRT
257 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
258 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
259 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
260
261 // Wait for DSTRT to Clear
262 do {
263 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
264 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
265 } while(ctrl_reg & EJTAG_CTRL_DSTRT);
266
267 // Clear DMA & Check DERR
268 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
269 ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
270 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
271 if (ctrl_reg & EJTAG_CTRL_DERR)
272 {
273 if (retries--) {
274 printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
275 goto begin_ejtag_dma_write_h;
276 } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
277 return ERROR_JTAG_DEVICE_ERROR;
278 }
279
280 return ERROR_OK;
281 }
282
283 static int ejtag_dma_write_b(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
284 {
285 u32 v;
286 u32 ctrl_reg;
287 int retries = RETRY_ATTEMPTS;
288
289
290 // Handle the bigendian/littleendian
291 data &= 0xff;
292 data |= data<<8;
293 data |= data<<16;
294
295 begin_ejtag_dma_write_b:
296
297 // Setup Address
298 v = addr;
299 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
300 mips_ejtag_drscan_32(ejtag_info, &v);
301
302 // Setup Data
303 v = data;
304 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
305 mips_ejtag_drscan_32(ejtag_info, &v);
306
307 // Initiate DMA Write & set DSTRT
308 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
309 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
310 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
311
312 // Wait for DSTRT to Clear
313 do {
314 ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
315 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
316 } while(ctrl_reg & EJTAG_CTRL_DSTRT);
317
318 // Clear DMA & Check DERR
319 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
320 ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
321 mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
322 if (ctrl_reg & EJTAG_CTRL_DERR)
323 {
324 if (retries--) {
325 printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
326 goto begin_ejtag_dma_write_b;
327 } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
328 return ERROR_JTAG_DEVICE_ERROR;
329 }
330
331 return ERROR_OK;
332 }
333
334 int mips32_dmaacc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
335 {
336 switch (size)
337 {
338 case 1:
339 return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (u8*)buf);
340 case 2:
341 return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (u16*)buf);
342 case 4:
343 return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (u32*)buf);
344 }
345
346 return ERROR_OK;
347 }
348
349 int mips32_dmaacc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
350 {
351 int i;
352 int retval;
353
354 for(i=0; i<count; i++) {
355 if((retval=ejtag_dma_read(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
356 return retval;
357 }
358
359 return ERROR_OK;
360 }
361
362 int mips32_dmaacc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
363 {
364 int i;
365 int retval;
366
367 for(i=0; i<count; i++) {
368 if((retval=ejtag_dma_read_h(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
369 return retval;
370 }
371
372 return ERROR_OK;
373 }
374
375 int mips32_dmaacc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
376 {
377 int i;
378 int retval;
379
380 for(i=0; i<count; i++) {
381 if((retval=ejtag_dma_read_b(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
382 return retval;
383 }
384
385 return ERROR_OK;
386 }
387
388 int mips32_dmaacc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
389 {
390 switch (size)
391 {
392 case 1:
393 return mips32_dmaacc_write_mem8(ejtag_info, addr, count, (u8*)buf);
394 case 2:
395 return mips32_dmaacc_write_mem16(ejtag_info, addr, count,(u16*)buf);
396 case 4:
397 return mips32_dmaacc_write_mem32(ejtag_info, addr, count, (u32*)buf);
398 }
399
400 return ERROR_OK;
401 }
402
403 int mips32_dmaacc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
404 {
405 int i;
406 int retval;
407
408 for(i=0; i<count; i++) {
409 if((retval=ejtag_dma_write(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
410 return retval;
411 }
412
413 return ERROR_OK;
414 }
415
416 int mips32_dmaacc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
417 {
418 int i;
419 int retval;
420
421 for(i=0; i<count; i++) {
422 if((retval=ejtag_dma_write_h(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
423 return retval;
424 }
425
426 return ERROR_OK;
427 }
428
429 int mips32_dmaacc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
430 {
431 int i;
432 int retval;
433
434 for(i=0; i<count; i++) {
435 if((retval=ejtag_dma_write_b(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
436 return retval;
437 }
438
439 return ERROR_OK;
440 }

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)