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