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

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)