1 /***************************************************************************
2 * Copyright (C) 2007,2008 Øyvind Harboe *
3 * oyvind.harboe@zylin.com *
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. *
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. *
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 ***************************************************************************/
25 #include "embeddedice.h"
30 static uint32_t ecosflash_get_flash_status(flash_bank_t
*bank
);
31 static void ecosflash_set_flash_mode(flash_bank_t
*bank
,int mode
);
32 static uint32_t ecosflash_wait_status_busy(flash_bank_t
*bank
, uint32_t waitbits
, int timeout
);
33 static int ecosflash_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
36 typedef struct ecosflash_flash_bank_s
38 struct target_s
*target
;
39 working_area_t
*write_algorithm
;
40 working_area_t
*erase_check_algorithm
;
42 uint32_t start_address
;
43 } ecosflash_flash_bank_t
;
45 static const int sectorSize
= 0x10000;
48 flash_errmsg(int err
);
51 #define FLASH_ERR_OK 0x00 /* No error - operation complete */
52 #define FLASH_ERR_INVALID 0x01 /* Invalid FLASH address */
53 #define FLASH_ERR_ERASE 0x02 /* Error trying to erase */
54 #define FLASH_ERR_LOCK 0x03 /* Error trying to lock/unlock */
55 #define FLASH_ERR_PROGRAM 0x04 /* Error trying to program */
56 #define FLASH_ERR_PROTOCOL 0x05 /* Generic error */
57 #define FLASH_ERR_PROTECT 0x06 /* Device/region is write-protected */
58 #define FLASH_ERR_NOT_INIT 0x07 /* FLASH info not yet initialized */
59 #define FLASH_ERR_HWR 0x08 /* Hardware (configuration?) problem */
60 #define FLASH_ERR_ERASE_SUSPEND 0x09 /* Device is in erase suspend mode */
61 #define FLASH_ERR_PROGRAM_SUSPEND 0x0a /* Device is in in program suspend mode */
62 #define FLASH_ERR_DRV_VERIFY 0x0b /* Driver failed to verify data */
63 #define FLASH_ERR_DRV_TIMEOUT 0x0c /* Driver timed out waiting for device */
64 #define FLASH_ERR_DRV_WRONG_PART 0x0d /* Driver does not support device */
65 #define FLASH_ERR_LOW_VOLTAGE 0x0e /* Not enough juice to complete job */
72 return "No error - operation complete";
73 case FLASH_ERR_ERASE_SUSPEND
:
74 return "Device is in erase suspend state";
75 case FLASH_ERR_PROGRAM_SUSPEND
:
76 return "Device is in program suspend state";
77 case FLASH_ERR_INVALID
:
78 return "Invalid FLASH address";
80 return "Error trying to erase";
82 return "Error trying to lock/unlock";
83 case FLASH_ERR_PROGRAM
:
84 return "Error trying to program";
85 case FLASH_ERR_PROTOCOL
:
86 return "Generic error";
87 case FLASH_ERR_PROTECT
:
88 return "Device/region is write-protected";
89 case FLASH_ERR_NOT_INIT
:
90 return "FLASH sub-system not initialized";
91 case FLASH_ERR_DRV_VERIFY
:
92 return "Data verify failed after operation";
93 case FLASH_ERR_DRV_TIMEOUT
:
94 return "Driver timed out waiting for device";
95 case FLASH_ERR_DRV_WRONG_PART
:
96 return "Driver does not support device";
97 case FLASH_ERR_LOW_VOLTAGE
:
98 return "Device reports low voltage";
100 return "Unknown error";
105 /* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath>
107 static int ecosflash_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
109 ecosflash_flash_bank_t
*info
;
113 LOG_WARNING("incomplete flash_bank ecosflash configuration");
114 return ERROR_FLASH_BANK_INVALID
;
117 info
= malloc(sizeof(ecosflash_flash_bank_t
));
120 LOG_ERROR("no memory for flash bank info");
123 bank
->driver_priv
= info
;
124 info
->driverPath
= strdup(args
[6]);
126 /* eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as
127 * a way to improve impedance match between OpenOCD and eCos flash
132 bank
->num_sectors
= bank
->size
/sectorSize
;
133 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
134 for (i
= 0; i
< bank
->num_sectors
; i
++)
136 bank
->sectors
[i
].offset
= offset
;
137 bank
->sectors
[i
].size
= sectorSize
;
138 offset
+= bank
->sectors
[i
].size
;
139 bank
->sectors
[i
].is_erased
= -1;
140 bank
->sectors
[i
].is_protected
= 0;
143 info
->target
= get_target(args
[5]);
144 if (info
->target
== NULL
)
146 LOG_ERROR("target '%s' not defined", args
[5]);
152 static int loadDriver(ecosflash_flash_bank_t
*info
)
158 image
.base_address_set
= 0;
159 image
.start_address_set
= 0;
160 target_t
*target
= info
->target
;
163 if ((retval
= image_open(&image
, info
->driverPath
, NULL
)) != ERROR_OK
)
168 info
->start_address
= image
.start_address
;
172 for (i
= 0; i
< image
.num_sections
; i
++)
174 void *buffer
= malloc(image
.sections
[i
].size
);
176 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
182 target_write_buffer(target
, image
.sections
[i
].base_address
, buf_cnt
, buffer
);
183 image_size
+= buf_cnt
;
184 LOG_DEBUG("%" PRIu32
" byte written at address 0x%8.8" PRIx32
"", buf_cnt
, image
.sections
[i
].base_address
);
194 static int const OFFSET_ERASE
= 0x0;
195 static int const OFFSET_ERASE_SIZE
= 0x8;
196 static int const OFFSET_FLASH
= 0xc;
197 static int const OFFSET_FLASH_SIZE
= 0x8;
198 static int const OFFSET_GET_WORKAREA
= 0x18;
199 static int const OFFSET_GET_WORKAREA_SIZE
= 0x4;
201 static int runCode(ecosflash_flash_bank_t
*info
,
202 uint32_t codeStart
, uint32_t codeStop
, uint32_t r0
, uint32_t r1
, uint32_t r2
,
207 target_t
*target
= info
->target
;
209 reg_param_t reg_params
[3];
210 armv4_5_algorithm_t armv4_5_info
;
211 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
212 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
213 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
215 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
);
216 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
217 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
219 buf_set_u32(reg_params
[0].value
, 0, 32, r0
);
220 buf_set_u32(reg_params
[1].value
, 0, 32, r1
);
221 buf_set_u32(reg_params
[2].value
, 0, 32, r2
);
224 if ((retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
227 &armv4_5_info
)) != ERROR_OK
)
229 LOG_ERROR("error executing eCos flash algorithm");
233 *result
= buf_get_u32(reg_params
[0].value
, 0, 32);
235 destroy_reg_param(®_params
[0]);
236 destroy_reg_param(®_params
[1]);
237 destroy_reg_param(®_params
[2]);
242 static int eCosBoard_erase(ecosflash_flash_bank_t
*info
, uint32_t address
, uint32_t len
)
245 int timeout
= (len
/ 20480 + 1) * 1000; /*asume 20 KB/s*/
247 retval
= loadDriver(info
);
248 if (retval
!= ERROR_OK
)
252 retval
= runCode(info
,
253 info
->start_address
+ OFFSET_ERASE
,
254 info
->start_address
+ OFFSET_ERASE
+ OFFSET_ERASE_SIZE
,
261 if (retval
!= ERROR_OK
)
266 LOG_ERROR("Flash erase failed with %d (%s)\n", (int)flashErr
, flash_errmsg(flashErr
));
273 static int eCosBoard_flash(ecosflash_flash_bank_t
*info
, void *data
, uint32_t address
, uint32_t len
)
275 target_t
*target
= info
->target
;
276 const int chunk
= 8192;
277 int retval
= ERROR_OK
;
278 int timeout
= (chunk
/ 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
280 retval
= loadDriver(info
);
281 if (retval
!= ERROR_OK
)
285 retval
= runCode(info
,
286 info
->start_address
+ OFFSET_GET_WORKAREA
,
287 info
->start_address
+ OFFSET_GET_WORKAREA
+ OFFSET_GET_WORKAREA_SIZE
,
293 if (retval
!= ERROR_OK
)
298 for (i
= 0; i
< len
; i
+= chunk
)
307 retval
= target_write_buffer(target
, buffer
, t
, ((uint8_t *)data
) + i
);
308 if (retval
!= ERROR_OK
)
312 retval
= runCode(info
,
313 info
->start_address
+ OFFSET_FLASH
,
314 info
->start_address
+ OFFSET_FLASH
+ OFFSET_FLASH_SIZE
,
320 if (retval
!= ERROR_OK
)
325 LOG_ERROR("Flash prog failed with %d (%s)\n", (int)flashErr
, flash_errmsg(flashErr
));
332 static int ecosflash_probe(struct flash_bank_s
*bank
)
337 static int ecosflash_register_commands(struct command_context_s
*cmd_ctx
)
339 register_command(cmd_ctx
, NULL
, "ecosflash", NULL
, COMMAND_ANY
, NULL
);
345 static void command(flash_bank_t
*bank
, uint8_t cmd
, uint8_t *cmd_buf
)
347 ecosflash_flash_bank_t
*info
= bank
->driver_priv
;
350 if (info
->target
->endianness
== TARGET_LITTLE_ENDIAN
)
352 for (i
= bank
->bus_width
; i
> 0; i
--)
354 *cmd_buf
++ = (i
& (bank
->chip_width
- 1)) ? 0x0 : cmd
;
359 for (i
= 1; i
<= bank
->bus_width
; i
++)
361 *cmd_buf
++ = (i
& (bank
->chip_width
- 1)) ? 0x0 : cmd
;
368 static uint32_t ecosflash_address(struct flash_bank_s
*bank
, uint32_t address
)
371 switch (bank
->bus_width
)
374 retval
= address
& 0xfffffffc;
376 retval
= address
& 0xfffffffe;
381 return retval
+ bank
->base
;
385 static int ecosflash_erase(struct flash_bank_s
*bank
, int first
, int last
)
387 struct flash_bank_s
*c
= bank
;
388 ecosflash_flash_bank_t
*info
= bank
->driver_priv
;
389 return eCosBoard_erase(info
, c
->base
+ first
*sectorSize
, sectorSize
*(last
-first
+ 1));
392 static int ecosflash_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
397 static int ecosflash_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
399 ecosflash_flash_bank_t
*info
= bank
->driver_priv
;
400 struct flash_bank_s
*c
= bank
;
401 return eCosBoard_flash(info
, buffer
, c
->base
+ offset
, count
);
404 static int ecosflash_protect_check(struct flash_bank_s
*bank
)
409 static int ecosflash_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
411 ecosflash_flash_bank_t
*info
= bank
->driver_priv
;
412 snprintf(buf
, buf_size
, "eCos flash driver: %s", info
->driverPath
);
417 static uint32_t ecosflash_get_flash_status(flash_bank_t
*bank
)
422 static void ecosflash_set_flash_mode(flash_bank_t
*bank
,int mode
)
427 static uint32_t ecosflash_wait_status_busy(flash_bank_t
*bank
, uint32_t waitbits
, int timeout
)
432 static int ecosflash_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
438 flash_driver_t ecosflash_flash
= {
440 .register_commands
= &ecosflash_register_commands
,
441 .flash_bank_command
= &ecosflash_flash_bank_command
,
442 .erase
= &ecosflash_erase
,
443 .protect
= &ecosflash_protect
,
444 .write
= &ecosflash_write
,
445 .probe
= &ecosflash_probe
,
446 .auto_probe
= &ecosflash_probe
,
447 .erase_check
= &default_flash_blank_check
,
448 .protect_check
= &ecosflash_protect_check
,
449 .info
= &ecosflash_info
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)