d16d15e95e6f69ff49c2106587798e42971901ba
[openocd.git] / src / flash / ecos.c
1 /***************************************************************************
2 * Copyright (C) 2007,2008 Øyvind Harboe *
3 * oyvind.harboe@zylin.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <string.h>
25
26 #include "replacements.h"
27
28
29 #include "flash.h"
30
31 #include "target.h"
32
33 #include "flash.h"
34 #include "target.h"
35 #include "log.h"
36 #include "binarybuffer.h"
37 #include "../target/embeddedice.h"
38 #include "types.h"
39
40
41
42 int ecosflash_register_commands(struct command_context_s *cmd_ctx);
43 int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
44 int ecosflash_erase(struct flash_bank_s *bank, int first, int last);
45 int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last);
46 int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
47 int ecosflash_probe(struct flash_bank_s *bank);
48 int ecosflash_protect_check(struct flash_bank_s *bank);
49 int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size);
50
51 u32 ecosflash_get_flash_status(flash_bank_t *bank);
52 void ecosflash_set_flash_mode(flash_bank_t *bank,int mode);
53 u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
54 int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55
56 flash_driver_t ecosflash_flash =
57 {
58 .name = "ecosflash",
59 .register_commands = ecosflash_register_commands,
60 .flash_bank_command = ecosflash_flash_bank_command,
61 .erase = ecosflash_erase,
62 .protect = ecosflash_protect,
63 .write = ecosflash_write,
64 .probe = ecosflash_probe,
65 .auto_probe = ecosflash_probe,
66 .erase_check = default_flash_blank_check,
67 .protect_check = ecosflash_protect_check,
68 .info = ecosflash_info
69 };
70
71 typedef struct ecosflash_flash_bank_s
72 {
73 struct target_s *target;
74 working_area_t *write_algorithm;
75 working_area_t *erase_check_algorithm;
76 char *driverPath;
77 u32 start_address;
78 } ecosflash_flash_bank_t;
79
80 static const int sectorSize=0x10000;
81
82 char *
83 flash_errmsg(int err);
84
85 #ifndef __ECOS
86 #define FLASH_ERR_OK 0x00 /* No error - operation complete */
87 #define FLASH_ERR_INVALID 0x01 /* Invalid FLASH address */
88 #define FLASH_ERR_ERASE 0x02 /* Error trying to erase */
89 #define FLASH_ERR_LOCK 0x03 /* Error trying to lock/unlock */
90 #define FLASH_ERR_PROGRAM 0x04 /* Error trying to program */
91 #define FLASH_ERR_PROTOCOL 0x05 /* Generic error */
92 #define FLASH_ERR_PROTECT 0x06 /* Device/region is write-protected */
93 #define FLASH_ERR_NOT_INIT 0x07 /* FLASH info not yet initialized */
94 #define FLASH_ERR_HWR 0x08 /* Hardware (configuration?) problem */
95 #define FLASH_ERR_ERASE_SUSPEND 0x09 /* Device is in erase suspend mode */
96 #define FLASH_ERR_PROGRAM_SUSPEND 0x0a /* Device is in in program suspend mode */
97 #define FLASH_ERR_DRV_VERIFY 0x0b /* Driver failed to verify data */
98 #define FLASH_ERR_DRV_TIMEOUT 0x0c /* Driver timed out waiting for device */
99 #define FLASH_ERR_DRV_WRONG_PART 0x0d /* Driver does not support device */
100 #define FLASH_ERR_LOW_VOLTAGE 0x0e /* Not enough juice to complete job */
101
102
103 char *
104 flash_errmsg(int err)
105 {
106 switch (err) {
107 case FLASH_ERR_OK:
108 return "No error - operation complete";
109 case FLASH_ERR_ERASE_SUSPEND:
110 return "Device is in erase suspend state";
111 case FLASH_ERR_PROGRAM_SUSPEND:
112 return "Device is in program suspend state";
113 case FLASH_ERR_INVALID:
114 return "Invalid FLASH address";
115 case FLASH_ERR_ERASE:
116 return "Error trying to erase";
117 case FLASH_ERR_LOCK:
118 return "Error trying to lock/unlock";
119 case FLASH_ERR_PROGRAM:
120 return "Error trying to program";
121 case FLASH_ERR_PROTOCOL:
122 return "Generic error";
123 case FLASH_ERR_PROTECT:
124 return "Device/region is write-protected";
125 case FLASH_ERR_NOT_INIT:
126 return "FLASH sub-system not initialized";
127 case FLASH_ERR_DRV_VERIFY:
128 return "Data verify failed after operation";
129 case FLASH_ERR_DRV_TIMEOUT:
130 return "Driver timed out waiting for device";
131 case FLASH_ERR_DRV_WRONG_PART:
132 return "Driver does not support device";
133 case FLASH_ERR_LOW_VOLTAGE:
134 return "Device reports low voltage";
135 default:
136 return "Unknown error";
137 }
138 }
139 #endif
140
141 /* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath>
142 */
143 int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
144 {
145 ecosflash_flash_bank_t *info;
146
147 if (argc < 7)
148 {
149 LOG_WARNING("incomplete flash_bank ecosflash configuration");
150 return ERROR_FLASH_BANK_INVALID;
151 }
152
153 info = malloc(sizeof(ecosflash_flash_bank_t));
154 if(info == NULL)
155 {
156 LOG_ERROR("no memory for flash bank info");
157 exit(-1);
158 }
159 bank->driver_priv = info;
160 info->driverPath=strdup(args[6]);
161
162 /* eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as
163 * a way to improve impeadance matach between OpenOCD and eCos flash
164 * driver.
165 */
166 int i = 0;
167 u32 offset = 0;
168 bank->num_sectors=bank->size/sectorSize;
169 bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
170 for (i = 0; i < bank->num_sectors; i++)
171 {
172 bank->sectors[i].offset = offset;
173 bank->sectors[i].size = sectorSize;
174 offset += bank->sectors[i].size;
175 bank->sectors[i].is_erased = -1;
176 bank->sectors[i].is_protected = 0;
177 }
178
179 info->target = get_target_by_num(strtoul(args[5], NULL, 0));
180 if (info->target == NULL)
181 {
182 LOG_ERROR("no target '%i' configured", (int)strtoul(args[5], NULL, 0));
183 exit(-1);
184 }
185 return ERROR_OK;
186 }
187
188
189 int loadDriver(ecosflash_flash_bank_t *info)
190 {
191 u32 buf_cnt;
192 u32 image_size;
193 image_t image;
194
195 image.base_address_set = 0;
196 image.start_address_set = 0;
197 target_t *target=info->target;
198 int retval;
199
200 if ((retval=image_open(&image, info->driverPath, NULL)) != ERROR_OK)
201 {
202 return retval;
203 }
204
205 info->start_address=image.start_address;
206
207 image_size = 0x0;
208 int i;
209 for (i = 0; i < image.num_sections; i++)
210 {
211 void *buffer = malloc(image.sections[i].size);
212 int retval;
213 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
214 {
215 free(buffer);
216 image_close(&image);
217 return retval;
218 }
219 target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
220 image_size += buf_cnt;
221 LOG_DEBUG("%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
222
223 free(buffer);
224 }
225
226 image_close(&image);
227
228 return ERROR_OK;
229 }
230
231
232 static int const OFFSET_ERASE=0x0;
233 static int const OFFSET_ERASE_SIZE=0x8;
234 static int const OFFSET_FLASH=0xc;
235 static int const OFFSET_FLASH_SIZE=0x8;
236 static int const OFFSET_GET_WORKAREA=0x18;
237 static int const OFFSET_GET_WORKAREA_SIZE=0x4;
238
239
240 int runCode(ecosflash_flash_bank_t *info,
241 u32 codeStart, u32 codeStop, u32 r0, u32 r1, u32 r2,
242 u32 *result,
243 /* timeout in ms */
244 int timeout)
245 {
246 target_t *target=info->target;
247
248 reg_param_t reg_params[3];
249 armv4_5_algorithm_t armv4_5_info;
250 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
251 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
252 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
253
254 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
255 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
256 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
257
258 buf_set_u32(reg_params[0].value, 0, 32, r0);
259 buf_set_u32(reg_params[1].value, 0, 32, r1);
260 buf_set_u32(reg_params[2].value, 0, 32, r2);
261
262 int retval;
263 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
264 codeStart,
265 codeStop, timeout,
266 &armv4_5_info)) != ERROR_OK)
267 {
268 LOG_ERROR("error executing eCos flash algorithm");
269 return retval;
270 }
271
272 *result=buf_get_u32(reg_params[0].value, 0, 32);
273
274 destroy_reg_param(&reg_params[0]);
275 destroy_reg_param(&reg_params[1]);
276 destroy_reg_param(&reg_params[2]);
277
278 return ERROR_OK;
279 }
280
281 int eCosBoard_erase(ecosflash_flash_bank_t *info, u32 address, u32 len)
282 {
283 int retval;
284 int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/
285
286 retval=loadDriver(info);
287 if (retval!=ERROR_OK)
288 return retval;
289
290 u32 flashErr;
291 retval=runCode(info,
292 info->start_address+OFFSET_ERASE,
293 info->start_address+OFFSET_ERASE+OFFSET_ERASE_SIZE,
294 address,
295 len,
296 0,
297 &flashErr,
298 timeout
299 );
300 if (retval!=ERROR_OK)
301 return retval;
302
303 if (flashErr != 0x0)
304 {
305 LOG_ERROR("Flash erase failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
306 return ERROR_FAIL;
307 }
308
309 return ERROR_OK;
310 }
311
312 int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, u32 address, u32 len)
313 {
314 target_t *target=info->target;
315 const int chunk=8192;
316 int retval=ERROR_OK;
317 int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
318
319 retval=loadDriver(info);
320 if (retval!=ERROR_OK)
321 return retval;
322
323 u32 buffer;
324 retval=runCode(info,
325 info->start_address+OFFSET_GET_WORKAREA,
326 info->start_address+OFFSET_GET_WORKAREA+OFFSET_GET_WORKAREA_SIZE,
327 0,
328 0,
329 0,
330 &buffer,
331 1000);
332 if (retval!=ERROR_OK)
333 return retval;
334
335
336 int i;
337 for (i=0; i<len; i+=chunk)
338 {
339 int t=len-i;
340 if (t>chunk)
341 {
342 t=chunk;
343 }
344
345 int retval;
346 retval=target_write_buffer(target, buffer, t, ((u8 *)data)+i);
347 if (retval != ERROR_OK)
348 return retval;
349
350 u32 flashErr;
351 retval=runCode(info,
352 info->start_address+OFFSET_FLASH,
353 info->start_address+OFFSET_FLASH+OFFSET_FLASH_SIZE,
354 buffer,
355 address+i,
356 t,
357 &flashErr,
358 timeout);
359 if (retval != ERROR_OK)
360 return retval;
361
362 if (flashErr != 0x0)
363 {
364 LOG_ERROR("Flash prog failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
365 return ERROR_FAIL;
366 }
367 }
368 return ERROR_OK;
369 }
370
371
372 int ecosflash_probe(struct flash_bank_s *bank)
373 {
374 return ERROR_OK;
375 }
376
377
378 int ecosflash_register_commands(struct command_context_s *cmd_ctx)
379 {
380 register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL);
381
382 return ERROR_OK;
383 }
384
385 /*
386 static void command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
387 {
388 ecosflash_flash_bank_t *info = bank->driver_priv;
389 int i;
390
391 if (info->target->endianness == TARGET_LITTLE_ENDIAN)
392 {
393 for (i = bank->bus_width; i > 0; i--)
394 {
395 *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
396 }
397 }
398 else
399 {
400 for (i = 1; i <= bank->bus_width; i++)
401 {
402 *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
403 }
404 }
405 }
406 */
407
408 u32 ecosflash_address(struct flash_bank_s *bank, u32 address)
409 {
410 u32 retval = 0;
411 switch(bank->bus_width)
412 {
413 case 4:
414 retval = address & 0xfffffffc;
415 case 2:
416 retval = address & 0xfffffffe;
417 case 1:
418 retval = address;
419 }
420
421 return retval + bank->base;
422 }
423
424
425 int ecosflash_erase(struct flash_bank_s *bank, int first, int last)
426 {
427 struct flash_bank_s *c=bank;
428 ecosflash_flash_bank_t *info = bank->driver_priv;
429 return eCosBoard_erase(info, c->base+first*sectorSize, sectorSize*(last-first+1));
430 }
431
432 int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last)
433 {
434 return ERROR_OK;
435 }
436
437
438 int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
439 {
440 ecosflash_flash_bank_t *info = bank->driver_priv;
441 struct flash_bank_s *c=bank;
442 return eCosBoard_flash(info, buffer, c->base+offset, count);
443 }
444
445
446 int ecosflash_protect_check(struct flash_bank_s *bank)
447 {
448 return ERROR_OK;
449 }
450
451 int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size)
452 {
453 ecosflash_flash_bank_t *info = bank->driver_priv;
454 snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath);
455 return ERROR_OK;
456 }
457
458
459 u32 ecosflash_get_flash_status(flash_bank_t *bank)
460 {
461 return ERROR_OK;
462 }
463
464 void ecosflash_set_flash_mode(flash_bank_t *bank,int mode)
465 {
466
467 }
468
469 u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
470 {
471 return ERROR_OK;
472 }
473
474 int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
475 {
476 return ERROR_OK;
477 }
478
479
480
481

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)