remove warnings.
[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 int i = 0;
165 u32 offset = 0;
166 bank->num_sectors=bank->size/sectorSize;
167 bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
168 for (i = 0; i < bank->num_sectors; i++)
169 {
170 bank->sectors[i].offset = offset;
171 bank->sectors[i].size = sectorSize;
172 offset += bank->sectors[i].size;
173 bank->sectors[i].is_erased = -1;
174 bank->sectors[i].is_protected = 0;
175 }
176
177 info->target = get_target_by_num(strtoul(args[5], NULL, 0));
178 if (info->target == NULL)
179 {
180 ERROR("no target '%i' configured", (int)strtoul(args[5], NULL, 0));
181 exit(-1);
182 }
183 return ERROR_OK;
184 }
185
186
187 int loadDriver(ecosflash_flash_bank_t *info)
188 {
189 u32 buf_cnt;
190 u32 image_size;
191 image_t image;
192
193 image.base_address_set = 0;
194 image.start_address_set = 0;
195 target_t *target=info->target;
196
197 if (image_open(&image, info->driverPath, NULL) != ERROR_OK)
198 {
199 return ERROR_FLASH_BANK_INVALID;
200 }
201
202 info->start_address=image.start_address;
203
204 image_size = 0x0;
205 int i;
206 for (i = 0; i < image.num_sections; i++)
207 {
208 void *buffer = malloc(image.sections[i].size);
209 int retval;
210 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
211 {
212 ERROR("image_read_section failed with error code: %i", retval);
213 free(buffer);
214 image_close(&image);
215 return ERROR_FLASH_BANK_INVALID;
216 }
217 target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
218 image_size += buf_cnt;
219 DEBUG("%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
220
221 free(buffer);
222 }
223
224 image_close(&image);
225
226 return ERROR_OK;
227 }
228
229
230 static int const OFFSET_ERASE=0x0;
231 static int const OFFSET_ERASE_SIZE=0x8;
232 static int const OFFSET_FLASH=0xc;
233 static int const OFFSET_FLASH_SIZE=0x8;
234 static int const OFFSET_GET_WORKAREA=0x18;
235 static int const OFFSET_GET_WORKAREA_SIZE=0x4;
236
237
238 int runCode(ecosflash_flash_bank_t *info,
239 u32 codeStart, u32 codeStop, u32 r0, u32 r1, u32 r2,
240 u32 *result,
241 // timeout in ms
242 int timeout)
243 {
244 target_t *target=info->target;
245
246 reg_param_t reg_params[3];
247 armv4_5_algorithm_t armv4_5_info;
248 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
249 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
250 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
251
252 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
253 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
254 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
255
256 buf_set_u32(reg_params[0].value, 0, 32, r0);
257 buf_set_u32(reg_params[1].value, 0, 32, r1);
258 buf_set_u32(reg_params[2].value, 0, 32, r2);
259
260 int retval;
261 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
262 codeStart,
263 codeStop, timeout,
264 &armv4_5_info)) != ERROR_OK)
265 {
266 ERROR("error executing eCos flash algorithm");
267 return retval;
268 }
269
270 *result=buf_get_u32(reg_params[0].value, 0, 32);
271
272 destroy_reg_param(&reg_params[0]);
273 destroy_reg_param(&reg_params[1]);
274 destroy_reg_param(&reg_params[2]);
275
276 return ERROR_OK;
277 }
278
279 int eCosBoard_erase(ecosflash_flash_bank_t *info, u32 address, u32 len)
280 {
281 int retval;
282 int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/
283
284 retval=loadDriver(info);
285 if (retval!=ERROR_OK)
286 return retval;
287
288 u32 flashErr;
289 retval=runCode(info,
290 info->start_address+OFFSET_ERASE,
291 info->start_address+OFFSET_ERASE+OFFSET_ERASE_SIZE,
292 address,
293 len,
294 0,
295 &flashErr,
296 timeout
297 );
298 if (retval!=ERROR_OK)
299 return retval;
300
301 if (flashErr != 0x0)
302 {
303 ERROR("Flash erase failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
304 return ERROR_JTAG_DEVICE_ERROR;
305 }
306
307 return ERROR_OK;
308 }
309
310 int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, u32 address, u32 len)
311 {
312 target_t *target=info->target;
313 const int chunk=8192;
314 int retval=ERROR_OK;
315 int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
316
317 retval=loadDriver(info);
318 if (retval!=ERROR_OK)
319 return retval;
320
321 u32 buffer;
322 retval=runCode(info,
323 info->start_address+OFFSET_GET_WORKAREA,
324 info->start_address+OFFSET_GET_WORKAREA+OFFSET_GET_WORKAREA_SIZE,
325 0,
326 0,
327 0,
328 &buffer,
329 1000);
330 if (retval!=ERROR_OK)
331 return retval;
332
333
334 int i;
335 for (i=0; i<len; i+=chunk)
336 {
337 int t=len-i;
338 if (t>chunk)
339 {
340 t=chunk;
341 }
342
343 int retval;
344 retval=target_write_buffer(target, buffer, t, ((char *)data)+i);
345 if (retval != ERROR_OK)
346 return retval;
347
348 u32 flashErr;
349 retval=runCode(info,
350 info->start_address+OFFSET_FLASH,
351 info->start_address+OFFSET_FLASH+OFFSET_FLASH_SIZE,
352 buffer,
353 address+i,
354 t,
355 &flashErr,
356 timeout);
357 if (retval != ERROR_OK)
358 return retval;
359
360 if (flashErr != 0x0)
361 {
362 ERROR("Flash prog failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
363 return ERROR_JTAG_DEVICE_ERROR;
364 }
365 }
366 return ERROR_OK;
367 }
368
369
370 int ecosflash_probe(struct flash_bank_s *bank)
371 {
372 return ERROR_OK;
373 }
374
375
376 int ecosflash_register_commands(struct command_context_s *cmd_ctx)
377 {
378 register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL);
379
380 return ERROR_OK;
381 }
382
383 /*
384 static void command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
385 {
386 ecosflash_flash_bank_t *info = bank->driver_priv;
387 int i;
388
389 if (info->target->endianness == TARGET_LITTLE_ENDIAN)
390 {
391 for (i = bank->bus_width; i > 0; i--)
392 {
393 *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
394 }
395 }
396 else
397 {
398 for (i = 1; i <= bank->bus_width; i++)
399 {
400 *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
401 }
402 }
403 }
404 */
405
406 u32 ecosflash_address(struct flash_bank_s *bank, u32 address)
407 {
408 u32 retval = 0;
409 switch(bank->bus_width)
410 {
411 case 4:
412 retval = address & 0xfffffffc;
413 case 2:
414 retval = address & 0xfffffffe;
415 case 1:
416 retval = address;
417 }
418
419 return retval + bank->base;
420 }
421
422
423 int ecosflash_erase(struct flash_bank_s *bank, int first, int last)
424 {
425 struct flash_bank_s *c=bank;
426 ecosflash_flash_bank_t *info = bank->driver_priv;
427 return eCosBoard_erase(info, c->base+first*sectorSize, sectorSize*(last-first+1));
428 }
429
430 int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last)
431 {
432 return ERROR_OK;
433 }
434
435
436 int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
437 {
438 ecosflash_flash_bank_t *info = bank->driver_priv;
439 struct flash_bank_s *c=bank;
440 return eCosBoard_flash(info, buffer, c->base+offset, count);
441 }
442
443
444 int ecosflash_erase_check(struct flash_bank_s *bank)
445 {
446 return ERROR_OK;
447 }
448
449 int ecosflash_protect_check(struct flash_bank_s *bank)
450 {
451 return ERROR_OK;
452 }
453
454 int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size)
455 {
456 ecosflash_flash_bank_t *info = bank->driver_priv;
457 snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath);
458 return ERROR_OK;
459 }
460
461
462 u32 ecosflash_get_flash_status(flash_bank_t *bank)
463 {
464 return ERROR_OK;
465 }
466
467 void ecosflash_set_flash_mode(flash_bank_t *bank,int mode)
468 {
469
470 }
471
472 u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
473 {
474 return ERROR_OK;
475 }
476
477 int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
478 {
479 return ERROR_OK;
480 }
481
482
483
484

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)