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.
 
 
 
 
 
 

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