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.
 
 
 
 
 
 

271 lines
8.2 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2011 by Rodrigo L. Rosa *
  3. * rodrigorosa.LG@gmail.com *
  4. * *
  5. * Based on a file written by: *
  6. * Kevin McGuire *
  7. * Marcel Wijlaars *
  8. * Michael Ashton *
  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, see <http://www.gnu.org/licenses/>. *
  22. ***************************************************************************/
  23. /**
  24. * @file dsp5680xx_flash.c
  25. * @author Rodrigo L. Rosa <rodrigorosa.LG@gmail.com>
  26. * @date Thu Jun 9 18:21:58 2011
  27. *
  28. * @brief This file implements the basic functions to run flashing commands
  29. * from the TCL interface.
  30. * It allows the user to flash the Freescale 5680xx DSP.
  31. *
  32. *
  33. */
  34. #ifdef HAVE_CONFIG_H
  35. #include "config.h"
  36. #endif
  37. #include "imp.h"
  38. #include <helper/binarybuffer.h>
  39. #include <helper/time_support.h>
  40. #include <target/algorithm.h>
  41. #include <target/dsp5680xx.h>
  42. static int dsp5680xx_build_sector_list(struct flash_bank *bank)
  43. {
  44. uint32_t offset = HFM_FLASH_BASE_ADDR;
  45. bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
  46. int i;
  47. for (i = 0; i < bank->num_sectors; ++i) {
  48. bank->sectors[i].offset = i * HFM_SECTOR_SIZE;
  49. bank->sectors[i].size = HFM_SECTOR_SIZE;
  50. offset += bank->sectors[i].size;
  51. bank->sectors[i].is_erased = -1;
  52. bank->sectors[i].is_protected = -1;
  53. }
  54. LOG_USER("%s not tested yet.", __func__);
  55. return ERROR_OK;
  56. }
  57. /* flash bank dsp5680xx 0 0 0 0 <target#> */
  58. FLASH_BANK_COMMAND_HANDLER(dsp5680xx_flash_bank_command)
  59. {
  60. bank->base = HFM_FLASH_BASE_ADDR;
  61. bank->size = HFM_SIZE_BYTES; /* top 4k not accessible */
  62. bank->num_sectors = HFM_SECTOR_COUNT;
  63. dsp5680xx_build_sector_list(bank);
  64. return ERROR_OK;
  65. }
  66. /**
  67. * A memory mapped register (PROT) holds information regarding sector protection.
  68. * Protection refers to undesired core access.
  69. * The value in this register is loaded from flash upon reset.
  70. *
  71. * @param bank
  72. *
  73. * @return
  74. */
  75. static int dsp5680xx_flash_protect_check(struct flash_bank *bank)
  76. {
  77. int retval = ERROR_OK;
  78. uint16_t protected = 0;
  79. retval = dsp5680xx_f_protect_check(bank->target, &protected);
  80. if (retval != ERROR_OK) {
  81. for (int i = 0; i < HFM_SECTOR_COUNT; i++)
  82. bank->sectors[i].is_protected = -1;
  83. return ERROR_OK;
  84. }
  85. for (int i = 0; i < HFM_SECTOR_COUNT / 2; i++) {
  86. if (protected & 1) {
  87. bank->sectors[2 * i].is_protected = 1;
  88. bank->sectors[2 * i + 1].is_protected = 1;
  89. } else {
  90. bank->sectors[2 * i].is_protected = 0;
  91. bank->sectors[2 * i + 1].is_protected = 0;
  92. }
  93. protected = (protected >> 1);
  94. }
  95. return retval;
  96. }
  97. /**
  98. * Protection funcionality is not implemented.
  99. * The current implementation applies/removes security on the chip.
  100. * The chip is effectively secured/unsecured after the first reset
  101. * following the execution of this function.
  102. *
  103. * @param bank
  104. * @param set Apply or remove security on the chip.
  105. * @param first This parameter is ignored.
  106. * @param last This parameter is ignored.
  107. *
  108. * @return
  109. */
  110. static int dsp5680xx_flash_protect(struct flash_bank *bank, int set, int first,
  111. int last)
  112. {
  113. /**
  114. * This applies security to flash module after next reset, it does
  115. * not actually apply protection (protection refers to undesired access from the core)
  116. */
  117. int retval;
  118. if (set)
  119. retval = dsp5680xx_f_lock(bank->target);
  120. else {
  121. retval = dsp5680xx_f_unlock(bank->target);
  122. if (retval == ERROR_OK) {
  123. /* mark all as erased */
  124. for (int i = 0; i <= (HFM_SECTOR_COUNT - 1); i++)
  125. /* FM does not recognize it as erased if erased via JTAG. */
  126. bank->sectors[i].is_erased = 1;
  127. }
  128. }
  129. return retval;
  130. }
  131. /**
  132. * The dsp5680xx use word addressing. The "/2" that appear in the following code
  133. * are a workaround for the fact that OpenOCD uses byte addressing.
  134. *
  135. * @param bank
  136. * @param buffer Data to write to flash.
  137. * @param offset
  138. * @param count In bytes (2 bytes per address).
  139. *
  140. * @return
  141. */
  142. static int dsp5680xx_flash_write(struct flash_bank *bank, const uint8_t* buffer,
  143. uint32_t offset, uint32_t count)
  144. {
  145. int retval;
  146. if ((offset + count / 2) > bank->size) {
  147. LOG_ERROR("%s: Flash bank cannot fit data.", __func__);
  148. return ERROR_FAIL;
  149. }
  150. if (offset % 2) {
  151. /**
  152. * Writing to odd addresses not supported.
  153. * This chip uses word addressing, Openocd only supports byte addressing.
  154. * The workaround results in disabling writing to odd byte addresses
  155. */
  156. LOG_ERROR("%s: Writing to odd addresses not supported for this target", __func__);
  157. return ERROR_FAIL;
  158. }
  159. retval = dsp5680xx_f_wr(bank->target, buffer, bank->base + offset / 2, count, 0);
  160. uint32_t addr_word;
  161. for (addr_word = bank->base + offset / 2; addr_word < count / 2;
  162. addr_word += (HFM_SECTOR_SIZE / 2)) {
  163. if (retval == ERROR_OK)
  164. bank->sectors[addr_word / (HFM_SECTOR_SIZE / 2)].is_erased = 0;
  165. else
  166. bank->sectors[addr_word / (HFM_SECTOR_SIZE / 2)].is_erased = -1;
  167. }
  168. return retval;
  169. }
  170. static int dsp5680xx_probe(struct flash_bank *bank)
  171. {
  172. LOG_DEBUG("%s not implemented", __func__);
  173. return ERROR_OK;
  174. }
  175. /**
  176. * The flash module (FM) on the dsp5680xx supports both individual sector
  177. * and mass erase of the flash memory.
  178. * If this function is called with @first == @last == 0 or if @first is the
  179. * first sector (#0) and @last is the last sector then the mass erase command
  180. * is executed (much faster than erasing each sector individually).
  181. *
  182. * @param bank
  183. * @param first
  184. * @param last
  185. *
  186. * @return
  187. */
  188. static int dsp5680xx_flash_erase(struct flash_bank *bank, int first, int last)
  189. {
  190. int retval;
  191. retval = dsp5680xx_f_erase(bank->target, (uint32_t) first, (uint32_t) last);
  192. if ((!(first | last)) || ((first == 0) && (last == (HFM_SECTOR_COUNT - 1))))
  193. last = HFM_SECTOR_COUNT - 1;
  194. if (retval == ERROR_OK)
  195. for (int i = first; i <= last; i++)
  196. bank->sectors[i].is_erased = 1;
  197. else
  198. /**
  199. * If an error occurred unknown status
  200. *is set even though some sector could have been correctly erased.
  201. */
  202. for (int i = first; i <= last; i++)
  203. bank->sectors[i].is_erased = -1;
  204. return retval;
  205. }
  206. /**
  207. * The flash module (FM) on the dsp5680xx support a blank check function.
  208. * This function executes the FM's blank check functionality on each and every sector.
  209. *
  210. * @param bank
  211. *
  212. * @return
  213. */
  214. static int dsp5680xx_flash_erase_check(struct flash_bank *bank)
  215. {
  216. int retval = ERROR_OK;
  217. uint8_t erased = 0;
  218. uint32_t i;
  219. for (i = 0; i < HFM_SECTOR_COUNT; i++) {
  220. if (bank->sectors[i].is_erased == -1) {
  221. retval = dsp5680xx_f_erase_check(bank->target, &erased, i);
  222. if (retval != ERROR_OK) {
  223. bank->sectors[i].is_erased = -1;
  224. } else {
  225. if (erased)
  226. bank->sectors[i].is_erased = 1;
  227. else
  228. bank->sectors[i].is_erased = 0;
  229. }
  230. }
  231. }
  232. return retval;
  233. }
  234. struct flash_driver dsp5680xx_flash = {
  235. .name = "dsp5680xx_flash",
  236. .flash_bank_command = dsp5680xx_flash_bank_command,
  237. .erase = dsp5680xx_flash_erase,
  238. .protect = dsp5680xx_flash_protect,
  239. .write = dsp5680xx_flash_write,
  240. /* .read = default_flash_read, */
  241. .probe = dsp5680xx_probe,
  242. .auto_probe = dsp5680xx_probe,
  243. .erase_check = dsp5680xx_flash_erase_check,
  244. .protect_check = dsp5680xx_flash_protect_check,
  245. };