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.
 
 
 
 
 
 

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