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.
 
 
 
 
 
 

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