You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

461 lines
13 KiB

  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. #include <string.h>
  29. #include "log.h"
  30. #include "mips32.h"
  31. #include "mips32_dmaacc.h"
  32. /*
  33. * The following logic shamelessly cloned from HairyDairyMaid's wrt54g_debrick
  34. * to support the Broadcom BCM5352 SoC in the Linksys WRT54GL wireless router
  35. * (and any others that support EJTAG DMA transfers).
  36. * Note: This only supports memory read/write. Since the BCM5352 doesn't
  37. * appear to support PRACC accesses, all debug functions except halt
  38. * do not work. Still, this does allow erasing/writing flash as well as
  39. * displaying/modifying memory and memory mapped registers.
  40. */
  41. static int ejtag_dma_read(mips_ejtag_t *ejtag_info, u32 addr, u32 *data)
  42. {
  43. u32 v;
  44. u32 ejtag_ctrl;
  45. int retries = RETRY_ATTEMPTS;
  46. begin_ejtag_dma_read:
  47. /* Setup Address */
  48. v = addr;
  49. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
  50. mips_ejtag_drscan_32(ejtag_info, &v);
  51. /* Initiate DMA Read & set DSTRT */
  52. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  53. ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
  54. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  55. /* Wait for DSTRT to Clear */
  56. do {
  57. ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
  58. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  59. } while(ejtag_ctrl & EJTAG_CTRL_DSTRT);
  60. /* Read Data */
  61. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
  62. mips_ejtag_drscan_32(ejtag_info, data);
  63. /* Clear DMA & Check DERR */
  64. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  65. ejtag_ctrl = ejtag_info->ejtag_ctrl;
  66. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  67. if (ejtag_ctrl & EJTAG_CTRL_DERR)
  68. {
  69. if (retries--) {
  70. LOG_ERROR("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
  71. goto begin_ejtag_dma_read;
  72. }
  73. else
  74. LOG_ERROR("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
  75. return ERROR_JTAG_DEVICE_ERROR;
  76. }
  77. return ERROR_OK;
  78. }
  79. static int ejtag_dma_read_h(mips_ejtag_t *ejtag_info, u32 addr, u16 *data)
  80. {
  81. u32 v;
  82. u32 ejtag_ctrl;
  83. int retries = RETRY_ATTEMPTS;
  84. begin_ejtag_dma_read_h:
  85. /* Setup Address */
  86. v = addr;
  87. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
  88. mips_ejtag_drscan_32(ejtag_info, &v);
  89. /* Initiate DMA Read & set DSTRT */
  90. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  91. ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
  92. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  93. /* Wait for DSTRT to Clear */
  94. do {
  95. ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
  96. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  97. } while(ejtag_ctrl & EJTAG_CTRL_DSTRT);
  98. /* Read Data */
  99. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
  100. mips_ejtag_drscan_32(ejtag_info, &v);
  101. /* Clear DMA & Check DERR */
  102. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  103. ejtag_ctrl = ejtag_info->ejtag_ctrl;
  104. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  105. if (ejtag_ctrl & EJTAG_CTRL_DERR)
  106. {
  107. if (retries--) {
  108. LOG_ERROR("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
  109. goto begin_ejtag_dma_read_h;
  110. }
  111. else
  112. LOG_ERROR("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
  113. return ERROR_JTAG_DEVICE_ERROR;
  114. }
  115. /* Handle the bigendian/littleendian */
  116. if (addr & 0x2)
  117. *data = (v >> 16) & 0xffff;
  118. else
  119. *data = (v & 0x0000ffff);
  120. return ERROR_OK;
  121. }
  122. static int ejtag_dma_read_b(mips_ejtag_t *ejtag_info, u32 addr, u8 *data)
  123. {
  124. u32 v;
  125. u32 ejtag_ctrl;
  126. int retries = RETRY_ATTEMPTS;
  127. begin_ejtag_dma_read_b:
  128. /* Setup Address */
  129. v = addr;
  130. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
  131. mips_ejtag_drscan_32(ejtag_info, &v);
  132. /* Initiate DMA Read & set DSTRT */
  133. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  134. ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
  135. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  136. /* Wait for DSTRT to Clear */
  137. do {
  138. ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
  139. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  140. } while(ejtag_ctrl & EJTAG_CTRL_DSTRT);
  141. /* Read Data */
  142. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
  143. mips_ejtag_drscan_32(ejtag_info, &v);
  144. /* Clear DMA & Check DERR */
  145. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  146. ejtag_ctrl = ejtag_info->ejtag_ctrl;
  147. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  148. if (ejtag_ctrl & EJTAG_CTRL_DERR)
  149. {
  150. if (retries--) {
  151. LOG_ERROR("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
  152. goto begin_ejtag_dma_read_b;
  153. }
  154. else
  155. LOG_ERROR("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
  156. return ERROR_JTAG_DEVICE_ERROR;
  157. }
  158. /* Handle the bigendian/littleendian */
  159. switch (addr & 0x3) {
  160. case 0:
  161. *data = v & 0xff;
  162. break;
  163. case 1:
  164. *data = (v >> 8) & 0xff;
  165. break;
  166. case 2:
  167. *data = (v >> 16) & 0xff;
  168. break;
  169. case 3:
  170. *data = (v >> 24) & 0xff;
  171. break;
  172. }
  173. return ERROR_OK;
  174. }
  175. static int ejtag_dma_write(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
  176. {
  177. u32 v;
  178. u32 ejtag_ctrl;
  179. int retries = RETRY_ATTEMPTS;
  180. begin_ejtag_dma_write:
  181. /* Setup Address */
  182. v = addr;
  183. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
  184. mips_ejtag_drscan_32(ejtag_info, &v);
  185. /* Setup Data */
  186. v = data;
  187. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
  188. mips_ejtag_drscan_32(ejtag_info, &v);
  189. /* Initiate DMA Write & set DSTRT */
  190. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  191. ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
  192. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  193. /* Wait for DSTRT to Clear */
  194. do {
  195. ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
  196. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  197. } while(ejtag_ctrl & EJTAG_CTRL_DSTRT);
  198. /* Clear DMA & Check DERR */
  199. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  200. ejtag_ctrl = ejtag_info->ejtag_ctrl;
  201. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  202. if (ejtag_ctrl & EJTAG_CTRL_DERR)
  203. {
  204. if (retries--) {
  205. LOG_ERROR("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
  206. goto begin_ejtag_dma_write;
  207. }
  208. else
  209. LOG_ERROR("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
  210. return ERROR_JTAG_DEVICE_ERROR;
  211. }
  212. return ERROR_OK;
  213. }
  214. static int ejtag_dma_write_h(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
  215. {
  216. u32 v;
  217. u32 ejtag_ctrl;
  218. int retries = RETRY_ATTEMPTS;
  219. /* Handle the bigendian/littleendian */
  220. data &= 0xffff;
  221. data |= data << 16;
  222. begin_ejtag_dma_write_h:
  223. /* Setup Address */
  224. v = addr;
  225. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
  226. mips_ejtag_drscan_32(ejtag_info, &v);
  227. /* Setup Data */
  228. v = data;
  229. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
  230. mips_ejtag_drscan_32(ejtag_info, &v);
  231. /* Initiate DMA Write & set DSTRT */
  232. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  233. ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
  234. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  235. /* Wait for DSTRT to Clear */
  236. do {
  237. ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
  238. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  239. } while(ejtag_ctrl & EJTAG_CTRL_DSTRT);
  240. /* Clear DMA & Check DERR */
  241. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  242. ejtag_ctrl = ejtag_info->ejtag_ctrl;
  243. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  244. if (ejtag_ctrl & EJTAG_CTRL_DERR)
  245. {
  246. if (retries--) {
  247. LOG_ERROR("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
  248. goto begin_ejtag_dma_write_h;
  249. }
  250. else
  251. LOG_ERROR("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
  252. return ERROR_JTAG_DEVICE_ERROR;
  253. }
  254. return ERROR_OK;
  255. }
  256. static int ejtag_dma_write_b(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
  257. {
  258. u32 v;
  259. u32 ejtag_ctrl;
  260. int retries = RETRY_ATTEMPTS;
  261. /* Handle the bigendian/littleendian */
  262. data &= 0xff;
  263. data |= data << 8;
  264. data |= data << 16;
  265. begin_ejtag_dma_write_b:
  266. /* Setup Address*/
  267. v = addr;
  268. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
  269. mips_ejtag_drscan_32(ejtag_info, &v);
  270. /* Setup Data */
  271. v = data;
  272. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
  273. mips_ejtag_drscan_32(ejtag_info, &v);
  274. /* Initiate DMA Write & set DSTRT */
  275. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  276. ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
  277. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  278. /* Wait for DSTRT to Clear */
  279. do {
  280. ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;
  281. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  282. } while(ejtag_ctrl & EJTAG_CTRL_DSTRT);
  283. /* Clear DMA & Check DERR */
  284. mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
  285. ejtag_ctrl = ejtag_info->ejtag_ctrl;
  286. mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
  287. if (ejtag_ctrl & EJTAG_CTRL_DERR)
  288. {
  289. if (retries--) {
  290. LOG_ERROR("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
  291. goto begin_ejtag_dma_write_b;
  292. }
  293. else
  294. LOG_ERROR("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
  295. return ERROR_JTAG_DEVICE_ERROR;
  296. }
  297. return ERROR_OK;
  298. }
  299. int mips32_dmaacc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
  300. {
  301. switch (size)
  302. {
  303. case 1:
  304. return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (u8*)buf);
  305. case 2:
  306. return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (u16*)buf);
  307. case 4:
  308. return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (u32*)buf);
  309. }
  310. return ERROR_OK;
  311. }
  312. int mips32_dmaacc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
  313. {
  314. int i;
  315. int retval;
  316. for (i=0; i<count; i++) {
  317. if ((retval = ejtag_dma_read(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
  318. return retval;
  319. }
  320. return ERROR_OK;
  321. }
  322. int mips32_dmaacc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
  323. {
  324. int i;
  325. int retval;
  326. for (i=0; i<count; i++) {
  327. if ((retval = ejtag_dma_read_h(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
  328. return retval;
  329. }
  330. return ERROR_OK;
  331. }
  332. int mips32_dmaacc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
  333. {
  334. int i;
  335. int retval;
  336. for (i=0; i<count; i++) {
  337. if ((retval = ejtag_dma_read_b(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
  338. return retval;
  339. }
  340. return ERROR_OK;
  341. }
  342. int mips32_dmaacc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
  343. {
  344. switch (size)
  345. {
  346. case 1:
  347. return mips32_dmaacc_write_mem8(ejtag_info, addr, count, (u8*)buf);
  348. case 2:
  349. return mips32_dmaacc_write_mem16(ejtag_info, addr, count,(u16*)buf);
  350. case 4:
  351. return mips32_dmaacc_write_mem32(ejtag_info, addr, count, (u32*)buf);
  352. }
  353. return ERROR_OK;
  354. }
  355. int mips32_dmaacc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
  356. {
  357. int i;
  358. int retval;
  359. for (i=0; i<count; i++) {
  360. if ((retval = ejtag_dma_write(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
  361. return retval;
  362. }
  363. return ERROR_OK;
  364. }
  365. int mips32_dmaacc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
  366. {
  367. int i;
  368. int retval;
  369. for (i=0; i<count; i++) {
  370. if ((retval = ejtag_dma_write_h(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
  371. return retval;
  372. }
  373. return ERROR_OK;
  374. }
  375. int mips32_dmaacc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
  376. {
  377. int i;
  378. int retval;
  379. for (i=0; i<count; i++) {
  380. if ((retval = ejtag_dma_write_b(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
  381. return retval;
  382. }
  383. return ERROR_OK;
  384. }