OpenOCD
aduc702x.c
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2008 by Kevin McGuire *
3  * Copyright (C) 2008 by Marcel Wijlaars *
4  * Copyright (C) 2009 by Michael Ashton *
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation; either version 2 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18  ***************************************************************************/
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "imp.h"
25 #include <helper/binarybuffer.h>
26 #include <helper/time_support.h>
27 #include <target/algorithm.h>
28 #include <target/arm.h>
29 
30 static int aduc702x_build_sector_list(struct flash_bank *bank);
31 static int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms);
32 static int aduc702x_set_write_enable(struct target *target, int enable);
33 
34 #define ADUC702x_FLASH 0xfffff800
35 #define ADUC702x_FLASH_FEESTA (0*4)
36 #define ADUC702x_FLASH_FEEMOD (1*4)
37 #define ADUC702x_FLASH_FEECON (2*4)
38 #define ADUC702x_FLASH_FEEDAT (3*4)
39 #define ADUC702x_FLASH_FEEADR (4*4)
40 #define ADUC702x_FLASH_FEESIGN (5*4)
41 #define ADUC702x_FLASH_FEEPRO (6*4)
42 #define ADUC702x_FLASH_FEEHIDE (7*4)
43 
44 /* flash bank aduc702x 0 0 0 0 <target#>
45  * The ADC7019-28 devices all have the same flash layout */
46 FLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command)
47 {
48  bank->base = 0x80000;
49  bank->size = 0xF800; /* top 4k not accessible */
50 
52 
53  return ERROR_OK;
54 }
55 
56 static int aduc702x_build_sector_list(struct flash_bank *bank)
57 {
58  /* aduc7026_struct flash_bank *aduc7026_info = bank->driver_priv; */
59 
60  int i = 0;
61  uint32_t offset = 0;
62 
63  /* sector size is 512 */
64  bank->num_sectors = bank->size / 512;
65  bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
66  for (i = 0; i < bank->num_sectors; ++i) {
67  bank->sectors[i].offset = offset;
68  bank->sectors[i].size = 512;
69  offset += bank->sectors[i].size;
70  bank->sectors[i].is_erased = -1;
71  bank->sectors[i].is_protected = 0;
72  }
73 
74  return ERROR_OK;
75 }
76 
77 static int aduc702x_protect_check(struct flash_bank *bank)
78 {
79  printf("aduc702x_protect_check not implemented yet.\n");
80  return ERROR_OK;
81 }
82 
83 static int aduc702x_erase(struct flash_bank *bank, int first, int last)
84 {
85  /* int res; */
86  int x;
87  int count;
88  /* uint32_t v; */
89  struct target *target = bank->target;
90 
91  aduc702x_set_write_enable(target, 1);
92 
93  /* mass erase */
94  if (((first | last) == 0) || ((first == 0) && (last >= bank->num_sectors))) {
95  LOG_DEBUG("performing mass erase.");
99 
100  if (aduc702x_check_flash_completion(target, 3500) != ERROR_OK) {
101  LOG_ERROR("mass erase failed");
102  aduc702x_set_write_enable(target, 0);
104  }
105 
106  LOG_DEBUG("mass erase successful.");
107  return ERROR_OK;
108  } else {
109  unsigned long adr;
110 
111  count = last - first + 1;
112  for (x = 0; x < count; ++x) {
113  adr = bank->base + ((first + x) * 512);
114 
117 
118  if (aduc702x_check_flash_completion(target, 50) != ERROR_OK) {
119  LOG_ERROR("failed to erase sector at address 0x%08lX", adr);
120  aduc702x_set_write_enable(target, 0);
122  }
123 
124  LOG_DEBUG("erased sector at address 0x%08lX", adr);
125  }
126  }
127 
128  aduc702x_set_write_enable(target, 0);
129 
130  return ERROR_OK;
131 }
132 
133 static int aduc702x_protect(struct flash_bank *bank, int set, int first, int last)
134 {
135  printf("aduc702x_protect not implemented yet.\n");
137 }
138 
139 /* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall
140  * back to another mechanism that does not require onboard RAM
141  *
142  * Caller should not check for other return values specifically
143  */
144 static int aduc702x_write_block(struct flash_bank *bank,
145  const uint8_t *buffer,
146  uint32_t offset,
147  uint32_t count)
148 {
149  struct target *target = bank->target;
150  uint32_t buffer_size = 7000;
151  struct working_area *write_algorithm;
152  struct working_area *source;
153  uint32_t address = bank->base + offset;
154  struct reg_param reg_params[6];
155  struct arm_algorithm arm_algo;
156  int retval = ERROR_OK;
157 
158  if (((count%2) != 0) || ((offset%2) != 0)) {
159  LOG_ERROR("write block must be multiple of two bytes in offset & length");
160  return ERROR_FAIL;
161  }
162 
163  /* parameters:
164 
165  r0 - address of source data (absolute)
166  r1 - number of halfwords to be copied
167  r2 - start address in flash (offset from beginning of flash memory)
168  r3 - exit code
169  r4 - base address of flash controller (0xFFFFF800)
170 
171  registers:
172 
173  r5 - scratch
174  r6 - set to 2, used to write flash command
175 
176  */
177  static const uint32_t aduc702x_flash_write_code[] = {
178  /* <_start>: */
179  0xe3a05008, /* mov r5, #8 ; 0x8 */
180  0xe5845004, /* str r5, [r4, #4] */
181  0xe3a06002, /* mov r6, #2 ; 0x2 */
182  /* <next>: */
183  0xe1c421b0, /* strh r2, [r4, #16] */
184  0xe0d050b2, /* ldrh r5, [r0], #2 */
185  0xe1c450bc, /* strh r5, [r4, #12] */
186  0xe5c46008, /* strb r6, [r4, #8] */
187  /* <wait_complete>: */
188  0xe1d430b0, /* ldrh r3, [r4] */
189  0xe3130004, /* tst r3, #4 ; 0x4 */
190  0x1afffffc, /* bne 1001c <wait_complete> */
191  0xe2822002, /* add r2, r2, #2 ; 0x2 */
192  0xe2511001, /* subs r1, r1, #1 ; 0x1 */
193  0x0a000001, /* beq 1003c <done> */
194  0xe3130001, /* tst r3, #1 ; 0x1 */
195  0x1afffff3, /* bne 1000c <next> */
196  /* <done>: */
197  0xeafffffe /* b 1003c <done> */
198  };
199 
200  /* flash write code */
201  if (target_alloc_working_area(target, sizeof(aduc702x_flash_write_code),
202  &write_algorithm) != ERROR_OK) {
203  LOG_WARNING("no working area available, can't do block memory writes");
205  }
206 
207  uint8_t code[sizeof(aduc702x_flash_write_code)];
208  target_buffer_set_u32_array(target, code, ARRAY_SIZE(aduc702x_flash_write_code),
209  aduc702x_flash_write_code);
210  retval = target_write_buffer(target, write_algorithm->address, sizeof(code), code);
211  if (retval != ERROR_OK)
212  return retval;
213 
214  /* memory buffer */
215  while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
216  buffer_size /= 2;
217  if (buffer_size <= 256) {
218  /* we already allocated the writing code, but failed to get a buffer,
219  *free the algorithm */
220  target_free_working_area(target, write_algorithm);
221 
222  LOG_WARNING("no large enough working area available, can't do block memory writes");
224  }
225  }
226 
227  arm_algo.common_magic = ARM_COMMON_MAGIC;
228  arm_algo.core_mode = ARM_MODE_SVC;
229  arm_algo.core_state = ARM_STATE_ARM;
230 
231  init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
232  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
233  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
234  init_reg_param(&reg_params[3], "r3", 32, PARAM_IN);
235  init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
236 
237  while (count > 0) {
238  uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count;
239 
240  retval = target_write_buffer(target, source->address, thisrun_count, buffer);
241  if (retval != ERROR_OK)
242  break;
243 
244  buf_set_u32(reg_params[0].value, 0, 32, source->address);
245  buf_set_u32(reg_params[1].value, 0, 32, thisrun_count/2);
246  buf_set_u32(reg_params[2].value, 0, 32, address);
247  buf_set_u32(reg_params[4].value, 0, 32, 0xFFFFF800);
248 
249  retval = target_run_algorithm(target, 0, NULL, 5,
250  reg_params, write_algorithm->address,
251  write_algorithm->address +
252  sizeof(aduc702x_flash_write_code) - 4,
253  10000, &arm_algo);
254  if (retval != ERROR_OK) {
255  LOG_ERROR("error executing aduc702x flash write algorithm");
256  break;
257  }
258 
259  if ((buf_get_u32(reg_params[3].value, 0, 32) & 1) != 1) {
260  /* FIX!!!! what does this mean??? replace w/sensible error message */
261  LOG_ERROR("aduc702x detected error writing flash");
262  retval = ERROR_FAIL;
263  break;
264  }
265 
266  buffer += thisrun_count;
267  address += thisrun_count;
268  count -= thisrun_count;
269  }
270 
271  target_free_working_area(target, source);
272  target_free_working_area(target, write_algorithm);
273 
274  destroy_reg_param(&reg_params[0]);
275  destroy_reg_param(&reg_params[1]);
276  destroy_reg_param(&reg_params[2]);
277  destroy_reg_param(&reg_params[3]);
278  destroy_reg_param(&reg_params[4]);
279 
280  return retval;
281 }
282 
283 /* All-JTAG, single-access method. Very slow. Used only if there is no
284  * working area available. */
285 static int aduc702x_write_single(struct flash_bank *bank,
286  const uint8_t *buffer,
287  uint32_t offset,
288  uint32_t count)
289 {
290  uint32_t x;
291  uint8_t b;
292  struct target *target = bank->target;
293 
294  aduc702x_set_write_enable(target, 1);
295 
296  for (x = 0; x < count; x += 2) {
297  /* FEEADR = address */
299 
300  /* set up data */
301  if ((x + 1) == count) {
302  /* last byte */
303  target_read_u8(target, offset + x + 1, &b);
304  } else
305  b = buffer[x + 1];
306 
307  target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEDAT, buffer[x] | (b << 8));
308 
309  /* do single-write command */
311 
312  if (aduc702x_check_flash_completion(target, 1) != ERROR_OK) {
313  LOG_ERROR("single write failed for address 0x%08lX",
314  (unsigned long)(offset + x));
315  aduc702x_set_write_enable(target, 0);
317  }
318 
319  }
320  LOG_DEBUG("wrote %d bytes at address 0x%08lX", (int)count, (unsigned long)(offset + x));
321 
322  aduc702x_set_write_enable(target, 0);
323 
324  return ERROR_OK;
325 }
326 
327 static int aduc702x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
328 {
329  int retval;
330 
331  /* try using a block write */
332  retval = aduc702x_write_block(bank, buffer, offset, count);
333  if (retval != ERROR_OK) {
334  if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
335  /* if block write failed (no sufficient working area),
336  * use normal (slow) JTAG method */
337  LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
338 
339  retval = aduc702x_write_single(bank, buffer, offset, count);
340  if (retval != ERROR_OK) {
341  LOG_ERROR("slow write failed");
343  }
344  }
345  }
346 
347  return retval;
348 }
349 
350 static int aduc702x_probe(struct flash_bank *bank)
351 {
352  return ERROR_OK;
353 }
354 
355 /* sets FEEMOD bit 3
356  * enable = 1 enables writes & erases, 0 disables them */
357 static int aduc702x_set_write_enable(struct target *target, int enable)
358 {
359  /* don't bother to preserve int enable bit here */
360  target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEMOD, enable ? 8 : 0);
361 
362  return ERROR_OK;
363 }
364 
365 /* wait up to timeout_ms for controller to not be busy,
366  * then check whether the command passed or failed.
367  *
368  * this function sleeps 1ms between checks (after the first one),
369  * so in some cases may slow things down without a usleep after the first read */
370 static int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms)
371 {
372  uint8_t v = 4;
373 
374  int64_t endtime = timeval_ms() + timeout_ms;
375  while (1) {
377  if ((v & 4) == 0)
378  break;
379  alive_sleep(1);
380  if (timeval_ms() >= endtime)
381  break;
382  }
383 
384  if (v & 2)
385  return ERROR_FAIL;
386  /* if a command is ignored, both the success and fail bits may be 0 */
387  else if ((v & 3) == 0)
388  return ERROR_FAIL;
389  else
390  return ERROR_OK;
391 }
392 
394  .name = "aduc702x",
395  .flash_bank_command = aduc702x_flash_bank_command,
396  .erase = aduc702x_erase,
397  .protect = aduc702x_protect,
398  .write = aduc702x_write,
399  .read = default_flash_read,
400  .probe = aduc702x_probe,
401  .auto_probe = aduc702x_probe,
402  .erase_check = default_flash_blank_check,
403  .protect_check = aduc702x_protect_check,
404 };
static int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms)
Definition: aduc702x.c:370
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:40
#define LOG_DEBUG(expr...)
Definition: log.h:115
static int aduc702x_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: aduc702x.c:144
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
uint32_t offset
Bus offset from start of the flash chip (in bytes).
Definition: nor/core.h:43
uint32_t size
The size of this chip bank, in bytes.
Definition: nor/core.h:88
#define ADUC702x_FLASH_FEESTA
Definition: aduc702x.c:35
int target_write_u16(struct target *target, target_addr_t address, uint16_t value)
uint32_t size
Number of bytes in this flash sector.
Definition: nor/core.h:45
#define ERROR_FAIL
Definition: log.h:150
struct flash_sector * sectors
Array of sectors, allocated and initialized by the flash driver.
Definition: nor/core.h:107
Support functions to access arbitrary bits in a byte array.
int64_t timeval_ms(void)
#define ERROR_FLASH_SECTOR_NOT_ERASED
Definition: flash/common.h:44
static int aduc702x_probe(struct flash_bank *bank)
Definition: aduc702x.c:350
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
int common_magic
Definition: arm.h:218
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:40
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
static int aduc702x_set_write_enable(struct target *target, int enable)
Definition: aduc702x.c:357
int target_free_working_area(struct target *target, struct working_area *area)
enum arm_mode core_mode
Definition: arm.h:220
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:40
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
static int aduc702x_build_sector_list(struct flash_bank *bank)
Definition: aduc702x.c:56
#define ADUC702x_FLASH_FEEADR
Definition: aduc702x.c:39
static int aduc702x_protect(struct flash_bank *bank, int set, int first, int last)
Definition: aduc702x.c:133
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
Definition: nor/core.h:52
int target_read_u8(struct target *target, target_addr_t address, uint8_t *value)
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf)
static int aduc702x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: aduc702x.c:327
#define LOG_ERROR(expr...)
Definition: log.h:129
FLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command)
Definition: aduc702x.c:46
#define ARM_COMMON_MAGIC
Definition: arm.h:93
#define ADUC702x_FLASH_FEEMOD
Definition: aduc702x.c:36
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it. ...
struct target * target
Target to which this bank belongs.
Definition: nor/core.h:81
enum arm_state core_state
Definition: arm.h:221
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_write_u8(struct target *target, target_addr_t address, uint8_t value)
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:693
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word...
Definition: binarybuffer.h:107
int num_sectors
The number of sectors on this chip.
Definition: nor/core.h:105
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:78
static int aduc702x_protect_check(struct flash_bank *bank)
Definition: aduc702x.c:77
struct flash_driver aduc702x_flash
Definition: aduc702x.c:393
#define ADUC702x_FLASH_FEEDAT
Definition: aduc702x.c:38
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:69
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:48
#define ERROR_OK
Definition: log.h:144
void alive_sleep(uint64_t ms)
Definition: helper/log.c:465
static int count
Definition: helper/log.c:62
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
#define ADUC702x_FLASH_FEECON
Definition: aduc702x.c:37
static int aduc702x_write_single(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: aduc702x.c:285
#define NULL
Definition: usb.h:27
int is_protected
Indication of protection status: 0 = unprotected/unlocked, 1 = protected/locked, other = unknown...
Definition: nor/core.h:65
Holds the interface to ARM cores.
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:41
static int aduc702x_erase(struct flash_bank *bank, int first, int last)
Definition: aduc702x.c:83
#define LOG_WARNING(expr...)
Definition: log.h:126
Definition: target.h:126
uint32_t base
The base address of this bank.
Definition: nor/core.h:87
#define ADUC702x_FLASH
Definition: aduc702x.c:34
target_addr_t address
Definition: target.h:96