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

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)