1 /***************************************************************************
2 * Copyright (C) 2005, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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 ***************************************************************************/
24 #include "replacements.h"
33 #include "algorithm.h"
34 #include "binarybuffer.h"
41 int cfi_register_commands(struct command_context_s
*cmd_ctx
);
42 int cfi_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
43 int cfi_erase(struct flash_bank_s
*bank
, int first
, int last
);
44 int cfi_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
45 int cfi_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
46 int cfi_probe(struct flash_bank_s
*bank
);
47 int cfi_auto_probe(struct flash_bank_s
*bank
);
48 int cfi_protect_check(struct flash_bank_s
*bank
);
49 int cfi_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
51 int cfi_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 #define CFI_MAX_BUS_WIDTH 4
54 #define CFI_MAX_CHIP_WIDTH 4
56 /* defines internal maximum size for code fragment in cfi_intel_write_block() */
57 #define CFI_MAX_INTEL_CODESIZE 256
59 flash_driver_t cfi_flash
=
62 .register_commands
= cfi_register_commands
,
63 .flash_bank_command
= cfi_flash_bank_command
,
65 .protect
= cfi_protect
,
68 .auto_probe
= cfi_auto_probe
,
69 .erase_check
= default_flash_blank_check
,
70 .protect_check
= cfi_protect_check
,
74 cfi_unlock_addresses_t cfi_unlock_addresses
[] =
76 [CFI_UNLOCK_555_2AA
] = { .unlock1
= 0x555, .unlock2
= 0x2aa },
77 [CFI_UNLOCK_5555_2AAA
] = { .unlock1
= 0x5555, .unlock2
= 0x2aaa },
80 /* CFI fixups foward declarations */
81 void cfi_fixup_0002_erase_regions(flash_bank_t
*flash
, void *param
);
82 void cfi_fixup_0002_unlock_addresses(flash_bank_t
*flash
, void *param
);
83 void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t
*flash
, void *param
);
85 /* fixup after identifying JEDEC manufactuer and ID */
86 cfi_fixup_t cfi_jedec_fixups
[] = {
87 {CFI_MFR_SST
, 0x00D4, cfi_fixup_non_cfi
, NULL
},
88 {CFI_MFR_SST
, 0x00D5, cfi_fixup_non_cfi
, NULL
},
89 {CFI_MFR_SST
, 0x00D6, cfi_fixup_non_cfi
, NULL
},
90 {CFI_MFR_SST
, 0x00D7, cfi_fixup_non_cfi
, NULL
},
91 {CFI_MFR_SST
, 0x2780, cfi_fixup_non_cfi
, NULL
},
92 {CFI_MFR_ST
, 0x00D5, cfi_fixup_non_cfi
, NULL
},
93 {CFI_MFR_ST
, 0x00D6, cfi_fixup_non_cfi
, NULL
},
94 {CFI_MFR_AMD
, 0x2223, cfi_fixup_non_cfi
, NULL
},
95 {CFI_MFR_AMD
, 0x22ab, cfi_fixup_non_cfi
, NULL
},
96 {CFI_MFR_FUJITSU
, 0x226b, cfi_fixup_non_cfi
, NULL
},
97 {CFI_MFR_AMIC
, 0xb31a, cfi_fixup_non_cfi
, NULL
},
101 /* fixup after reading cmdset 0002 primary query table */
102 cfi_fixup_t cfi_0002_fixups
[] = {
103 {CFI_MFR_SST
, 0x00D4, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_5555_2AAA
]},
104 {CFI_MFR_SST
, 0x00D5, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_5555_2AAA
]},
105 {CFI_MFR_SST
, 0x00D6, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_5555_2AAA
]},
106 {CFI_MFR_SST
, 0x00D7, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_5555_2AAA
]},
107 {CFI_MFR_SST
, 0x2780, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_5555_2AAA
]},
108 {CFI_MFR_ATMEL
, 0x00C8, cfi_fixup_atmel_reversed_erase_regions
, NULL
},
109 {CFI_MFR_FUJITSU
, 0x226b, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_5555_2AAA
]},
110 {CFI_MFR_AMIC
, 0xb31a, cfi_fixup_0002_unlock_addresses
, &cfi_unlock_addresses
[CFI_UNLOCK_555_2AA
]},
111 {CFI_MFR_ANY
, CFI_ID_ANY
, cfi_fixup_0002_erase_regions
, NULL
},
115 /* fixup after reading cmdset 0001 primary query table */
116 cfi_fixup_t cfi_0001_fixups
[] = {
120 void cfi_fixup(flash_bank_t
*bank
, cfi_fixup_t
*fixups
)
122 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
125 for (f
= fixups
; f
->fixup
; f
++)
127 if (((f
->mfr
== CFI_MFR_ANY
) || (f
->mfr
== cfi_info
->manufacturer
)) &&
128 ((f
->id
== CFI_ID_ANY
) || (f
->id
== cfi_info
->device_id
)))
130 f
->fixup(bank
, f
->param
);
135 /* inline u32 flash_address(flash_bank_t *bank, int sector, u32 offset) */
136 __inline__ u32
flash_address(flash_bank_t
*bank
, int sector
, u32 offset
)
138 /* while the sector list isn't built, only accesses to sector 0 work */
140 return bank
->base
+ offset
* bank
->bus_width
;
145 LOG_ERROR("BUG: sector list not yet built");
148 return bank
->base
+ bank
->sectors
[sector
].offset
+ offset
* bank
->bus_width
;
153 void cfi_command(flash_bank_t
*bank
, u8 cmd
, u8
*cmd_buf
)
157 /* clear whole buffer, to ensure bits that exceed the bus_width
160 for (i
= 0; i
< CFI_MAX_BUS_WIDTH
; i
++)
163 if (bank
->target
->endianness
== TARGET_LITTLE_ENDIAN
)
165 for (i
= bank
->bus_width
; i
> 0; i
--)
167 *cmd_buf
++ = (i
& (bank
->chip_width
- 1)) ? 0x0 : cmd
;
172 for (i
= 1; i
<= bank
->bus_width
; i
++)
174 *cmd_buf
++ = (i
& (bank
->chip_width
- 1)) ? 0x0 : cmd
;
179 /* read unsigned 8-bit value from the bank
180 * flash banks are expected to be made of similar chips
181 * the query result should be the same for all
183 u8
cfi_query_u8(flash_bank_t
*bank
, int sector
, u32 offset
)
185 target_t
*target
= bank
->target
;
186 u8 data
[CFI_MAX_BUS_WIDTH
];
188 target
->type
->read_memory(target
, flash_address(bank
, sector
, offset
), bank
->bus_width
, 1, data
);
190 if (bank
->target
->endianness
== TARGET_LITTLE_ENDIAN
)
193 return data
[bank
->bus_width
- 1];
196 /* read unsigned 8-bit value from the bank
197 * in case of a bank made of multiple chips,
198 * the individual values are ORed
200 u8
cfi_get_u8(flash_bank_t
*bank
, int sector
, u32 offset
)
202 target_t
*target
= bank
->target
;
203 u8 data
[CFI_MAX_BUS_WIDTH
];
206 target
->type
->read_memory(target
, flash_address(bank
, sector
, offset
), bank
->bus_width
, 1, data
);
208 if (bank
->target
->endianness
== TARGET_LITTLE_ENDIAN
)
210 for (i
= 0; i
< bank
->bus_width
/ bank
->chip_width
; i
++)
218 for (i
= 0; i
< bank
->bus_width
/ bank
->chip_width
; i
++)
219 value
|= data
[bank
->bus_width
- 1 - i
];
225 u16
cfi_query_u16(flash_bank_t
*bank
, int sector
, u32 offset
)
227 target_t
*target
= bank
->target
;
228 u8 data
[CFI_MAX_BUS_WIDTH
* 2];
230 target
->type
->read_memory(target
, flash_address(bank
, sector
, offset
), bank
->bus_width
, 2, data
);
232 if (bank
->target
->endianness
== TARGET_LITTLE_ENDIAN
)
233 return data
[0] | data
[bank
->bus_width
] << 8;
235 return data
[bank
->bus_width
- 1] | data
[(2 * bank
->bus_width
) - 1] << 8;
238 u32
cfi_query_u32(flash_bank_t
*bank
, int sector
, u32 offset
)
240 target_t
*target
= bank
->target
;
241 u8 data
[CFI_MAX_BUS_WIDTH
* 4];
243 target
->type
->read_memory(target
, flash_address(bank
, sector
, offset
), bank
->bus_width
, 4, data
);
245 if (bank
->target
->endianness
== TARGET_LITTLE_ENDIAN
)
246 return data
[0] | data
[bank
->bus_width
] << 8 | data
[bank
->bus_width
* 2] << 16 | data
[bank
->bus_width
* 3] << 24;
248 return data
[bank
->bus_width
- 1] | data
[(2* bank
->bus_width
) - 1] << 8 |
249 data
[(3 * bank
->bus_width
) - 1] << 16 | data
[(4 * bank
->bus_width
) - 1] << 24;
252 void cfi_intel_clear_status_register(flash_bank_t
*bank
)
254 target_t
*target
= bank
->target
;
257 if (target
->state
!= TARGET_HALTED
)
259 LOG_ERROR("BUG: attempted to clear status register while target wasn't halted");
263 cfi_command(bank
, 0x50, command
);
264 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
267 u8
cfi_intel_wait_status_busy(flash_bank_t
*bank
, int timeout
)
271 while ((!((status
= cfi_get_u8(bank
, 0, 0x0)) & 0x80)) && (timeout
-- > 0))
273 LOG_DEBUG("status: 0x%x", status
);
277 /* mask out bit 0 (reserved) */
278 status
= status
& 0xfe;
280 LOG_DEBUG("status: 0x%x", status
);
282 if ((status
& 0x80) != 0x80)
284 LOG_ERROR("timeout while waiting for WSM to become ready");
286 else if (status
!= 0x80)
288 LOG_ERROR("status register: 0x%x", status
);
290 LOG_ERROR("Block Lock-Bit Detected, Operation Abort");
292 LOG_ERROR("Program suspended");
294 LOG_ERROR("Low Programming Voltage Detected, Operation Aborted");
296 LOG_ERROR("Program Error / Error in Setting Lock-Bit");
298 LOG_ERROR("Error in Block Erasure or Clear Lock-Bits");
300 LOG_ERROR("Block Erase Suspended");
302 cfi_intel_clear_status_register(bank
);
308 int cfi_spansion_wait_status_busy(flash_bank_t
*bank
, int timeout
)
310 u8 status
, oldstatus
;
312 oldstatus
= cfi_get_u8(bank
, 0, 0x0);
315 status
= cfi_get_u8(bank
, 0, 0x0);
316 if ((status
^ oldstatus
) & 0x40) {
318 oldstatus
= cfi_get_u8(bank
, 0, 0x0);
319 status
= cfi_get_u8(bank
, 0, 0x0);
320 if ((status
^ oldstatus
) & 0x40) {
321 LOG_ERROR("dq5 timeout, status: 0x%x", status
);
322 return(ERROR_FLASH_OPERATION_FAILED
);
324 LOG_DEBUG("status: 0x%x", status
);
329 LOG_DEBUG("status: 0x%x", status
);
335 } while (timeout
-- > 0);
337 LOG_ERROR("timeout, status: 0x%x", status
);
339 return(ERROR_FLASH_BUSY
);
342 int cfi_read_intel_pri_ext(flash_bank_t
*bank
)
344 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
345 cfi_intel_pri_ext_t
*pri_ext
= malloc(sizeof(cfi_intel_pri_ext_t
));
346 target_t
*target
= bank
->target
;
349 cfi_info
->pri_ext
= pri_ext
;
351 pri_ext
->pri
[0] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0);
352 pri_ext
->pri
[1] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 1);
353 pri_ext
->pri
[2] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 2);
355 if ((pri_ext
->pri
[0] != 'P') || (pri_ext
->pri
[1] != 'R') || (pri_ext
->pri
[2] != 'I'))
357 cfi_command(bank
, 0xf0, command
);
358 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
359 cfi_command(bank
, 0xff, command
);
360 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
361 LOG_ERROR("Could not read bank flash bank information");
362 return ERROR_FLASH_BANK_INVALID
;
365 pri_ext
->major_version
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 3);
366 pri_ext
->minor_version
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 4);
368 LOG_DEBUG("pri: '%c%c%c', version: %c.%c", pri_ext
->pri
[0], pri_ext
->pri
[1], pri_ext
->pri
[2], pri_ext
->major_version
, pri_ext
->minor_version
);
370 pri_ext
->feature_support
= cfi_query_u32(bank
, 0, cfi_info
->pri_addr
+ 5);
371 pri_ext
->suspend_cmd_support
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 9);
372 pri_ext
->blk_status_reg_mask
= cfi_query_u16(bank
, 0, cfi_info
->pri_addr
+ 0xa);
374 LOG_DEBUG("feature_support: 0x%x, suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x", pri_ext
->feature_support
, pri_ext
->suspend_cmd_support
, pri_ext
->blk_status_reg_mask
);
376 pri_ext
->vcc_optimal
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0xc);
377 pri_ext
->vpp_optimal
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0xd);
379 LOG_DEBUG("Vcc opt: %1.1x.%1.1x, Vpp opt: %1.1x.%1.1x",
380 (pri_ext
->vcc_optimal
& 0xf0) >> 4, pri_ext
->vcc_optimal
& 0x0f,
381 (pri_ext
->vpp_optimal
& 0xf0) >> 4, pri_ext
->vpp_optimal
& 0x0f);
383 pri_ext
->num_protection_fields
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0xe);
384 if (pri_ext
->num_protection_fields
!= 1)
386 LOG_WARNING("expected one protection register field, but found %i", pri_ext
->num_protection_fields
);
389 pri_ext
->prot_reg_addr
= cfi_query_u16(bank
, 0, cfi_info
->pri_addr
+ 0xf);
390 pri_ext
->fact_prot_reg_size
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0x11);
391 pri_ext
->user_prot_reg_size
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0x12);
393 LOG_DEBUG("protection_fields: %i, prot_reg_addr: 0x%x, factory pre-programmed: %i, user programmable: %i", pri_ext
->num_protection_fields
, pri_ext
->prot_reg_addr
, 1 << pri_ext
->fact_prot_reg_size
, 1 << pri_ext
->user_prot_reg_size
);
398 int cfi_read_spansion_pri_ext(flash_bank_t
*bank
)
400 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
401 cfi_spansion_pri_ext_t
*pri_ext
= malloc(sizeof(cfi_spansion_pri_ext_t
));
402 target_t
*target
= bank
->target
;
405 cfi_info
->pri_ext
= pri_ext
;
407 pri_ext
->pri
[0] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0);
408 pri_ext
->pri
[1] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 1);
409 pri_ext
->pri
[2] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 2);
411 if ((pri_ext
->pri
[0] != 'P') || (pri_ext
->pri
[1] != 'R') || (pri_ext
->pri
[2] != 'I'))
413 cfi_command(bank
, 0xf0, command
);
414 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
415 LOG_ERROR("Could not read spansion bank information");
416 return ERROR_FLASH_BANK_INVALID
;
419 pri_ext
->major_version
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 3);
420 pri_ext
->minor_version
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 4);
422 LOG_DEBUG("pri: '%c%c%c', version: %c.%c", pri_ext
->pri
[0], pri_ext
->pri
[1], pri_ext
->pri
[2], pri_ext
->major_version
, pri_ext
->minor_version
);
424 pri_ext
->SiliconRevision
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 5);
425 pri_ext
->EraseSuspend
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 6);
426 pri_ext
->BlkProt
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 7);
427 pri_ext
->TmpBlkUnprotect
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 8);
428 pri_ext
->BlkProtUnprot
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 9);
429 pri_ext
->SimultaneousOps
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 10);
430 pri_ext
->BurstMode
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 11);
431 pri_ext
->PageMode
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 12);
432 pri_ext
->VppMin
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 13);
433 pri_ext
->VppMax
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 14);
434 pri_ext
->TopBottom
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 15);
436 LOG_DEBUG("Silicon Revision: 0x%x, Erase Suspend: 0x%x, Block protect: 0x%x", pri_ext
->SiliconRevision
,
437 pri_ext
->EraseSuspend
, pri_ext
->BlkProt
);
439 LOG_DEBUG("Temporary Unprotect: 0x%x, Block Protect Scheme: 0x%x, Simultaneous Ops: 0x%x", pri_ext
->TmpBlkUnprotect
,
440 pri_ext
->BlkProtUnprot
, pri_ext
->SimultaneousOps
);
442 LOG_DEBUG("Burst Mode: 0x%x, Page Mode: 0x%x, ", pri_ext
->BurstMode
, pri_ext
->PageMode
);
445 LOG_DEBUG("Vpp min: %2.2d.%1.1d, Vpp max: %2.2d.%1.1x",
446 (pri_ext
->VppMin
& 0xf0) >> 4, pri_ext
->VppMin
& 0x0f,
447 (pri_ext
->VppMax
& 0xf0) >> 4, pri_ext
->VppMax
& 0x0f);
449 LOG_DEBUG("WP# protection 0x%x", pri_ext
->TopBottom
);
451 /* default values for implementation specific workarounds */
452 pri_ext
->_unlock1
= cfi_unlock_addresses
[CFI_UNLOCK_555_2AA
].unlock1
;
453 pri_ext
->_unlock2
= cfi_unlock_addresses
[CFI_UNLOCK_555_2AA
].unlock2
;
454 pri_ext
->_reversed_geometry
= 0;
459 int cfi_read_atmel_pri_ext(flash_bank_t
*bank
)
461 cfi_atmel_pri_ext_t atmel_pri_ext
;
462 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
463 cfi_spansion_pri_ext_t
*pri_ext
= malloc(sizeof(cfi_spansion_pri_ext_t
));
464 target_t
*target
= bank
->target
;
467 /* ATMEL devices use the same CFI primary command set (0x2) as AMD/Spansion,
468 * but a different primary extended query table.
469 * We read the atmel table, and prepare a valid AMD/Spansion query table.
472 memset(pri_ext
, 0, sizeof(cfi_spansion_pri_ext_t
));
474 cfi_info
->pri_ext
= pri_ext
;
476 atmel_pri_ext
.pri
[0] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 0);
477 atmel_pri_ext
.pri
[1] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 1);
478 atmel_pri_ext
.pri
[2] = cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 2);
480 if ((atmel_pri_ext
.pri
[0] != 'P') || (atmel_pri_ext
.pri
[1] != 'R') || (atmel_pri_ext
.pri
[2] != 'I'))
482 cfi_command(bank
, 0xf0, command
);
483 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
484 LOG_ERROR("Could not read atmel bank information");
485 return ERROR_FLASH_BANK_INVALID
;
488 pri_ext
->pri
[0] = atmel_pri_ext
.pri
[0];
489 pri_ext
->pri
[1] = atmel_pri_ext
.pri
[1];
490 pri_ext
->pri
[2] = atmel_pri_ext
.pri
[2];
492 atmel_pri_ext
.major_version
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 3);
493 atmel_pri_ext
.minor_version
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 4);
495 LOG_DEBUG("pri: '%c%c%c', version: %c.%c", atmel_pri_ext
.pri
[0], atmel_pri_ext
.pri
[1], atmel_pri_ext
.pri
[2], atmel_pri_ext
.major_version
, atmel_pri_ext
.minor_version
);
497 pri_ext
->major_version
= atmel_pri_ext
.major_version
;
498 pri_ext
->minor_version
= atmel_pri_ext
.minor_version
;
500 atmel_pri_ext
.features
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 5);
501 atmel_pri_ext
.bottom_boot
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 6);
502 atmel_pri_ext
.burst_mode
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 7);
503 atmel_pri_ext
.page_mode
= cfi_query_u8(bank
, 0, cfi_info
->pri_addr
+ 8);
505 LOG_DEBUG("features: 0x%2.2x, bottom_boot: 0x%2.2x, burst_mode: 0x%2.2x, page_mode: 0x%2.2x",
506 atmel_pri_ext
.features
, atmel_pri_ext
.bottom_boot
, atmel_pri_ext
.burst_mode
, atmel_pri_ext
.page_mode
);
508 if (atmel_pri_ext
.features
& 0x02)
509 pri_ext
->EraseSuspend
= 2;
511 if (atmel_pri_ext
.bottom_boot
)
512 pri_ext
->TopBottom
= 2;
514 pri_ext
->TopBottom
= 3;
516 pri_ext
->_unlock1
= cfi_unlock_addresses
[CFI_UNLOCK_555_2AA
].unlock1
;
517 pri_ext
->_unlock2
= cfi_unlock_addresses
[CFI_UNLOCK_555_2AA
].unlock2
;
522 int cfi_read_0002_pri_ext(flash_bank_t
*bank
)
524 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
526 if (cfi_info
->manufacturer
== CFI_MFR_ATMEL
)
528 return cfi_read_atmel_pri_ext(bank
);
532 return cfi_read_spansion_pri_ext(bank
);
536 int cfi_spansion_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
539 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
540 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
542 printed
= snprintf(buf
, buf_size
, "\nSpansion primary algorithm extend information:\n");
546 printed
= snprintf(buf
, buf_size
, "pri: '%c%c%c', version: %c.%c\n", pri_ext
->pri
[0],
547 pri_ext
->pri
[1], pri_ext
->pri
[2],
548 pri_ext
->major_version
, pri_ext
->minor_version
);
552 printed
= snprintf(buf
, buf_size
, "Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\n",
553 (pri_ext
->SiliconRevision
) >> 2,
554 (pri_ext
->SiliconRevision
) & 0x03);
558 printed
= snprintf(buf
, buf_size
, "Erase Suspend: 0x%x, Sector Protect: 0x%x\n",
559 pri_ext
->EraseSuspend
,
564 printed
= snprintf(buf
, buf_size
, "VppMin: %2.2d.%1.1x, VppMax: %2.2d.%1.1x\n",
565 (pri_ext
->VppMin
& 0xf0) >> 4, pri_ext
->VppMin
& 0x0f,
566 (pri_ext
->VppMax
& 0xf0) >> 4, pri_ext
->VppMax
& 0x0f);
571 int cfi_intel_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
574 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
575 cfi_intel_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
577 printed
= snprintf(buf
, buf_size
, "\nintel primary algorithm extend information:\n");
581 printed
= snprintf(buf
, buf_size
, "pri: '%c%c%c', version: %c.%c\n", pri_ext
->pri
[0], pri_ext
->pri
[1], pri_ext
->pri
[2], pri_ext
->major_version
, pri_ext
->minor_version
);
585 printed
= snprintf(buf
, buf_size
, "feature_support: 0x%x, suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x\n", pri_ext
->feature_support
, pri_ext
->suspend_cmd_support
, pri_ext
->blk_status_reg_mask
);
589 printed
= snprintf(buf
, buf_size
, "Vcc opt: %1.1x.%1.1x, Vpp opt: %1.1x.%1.1x\n",
590 (pri_ext
->vcc_optimal
& 0xf0) >> 4, pri_ext
->vcc_optimal
& 0x0f,
591 (pri_ext
->vpp_optimal
& 0xf0) >> 4, pri_ext
->vpp_optimal
& 0x0f);
595 printed
= snprintf(buf
, buf_size
, "protection_fields: %i, prot_reg_addr: 0x%x, factory pre-programmed: %i, user programmable: %i\n", pri_ext
->num_protection_fields
, pri_ext
->prot_reg_addr
, 1 << pri_ext
->fact_prot_reg_size
, 1 << pri_ext
->user_prot_reg_size
);
600 int cfi_register_commands(struct command_context_s
*cmd_ctx
)
602 /*command_t *cfi_cmd = */
603 register_command(cmd_ctx
, NULL
, "cfi", NULL
, COMMAND_ANY
, "flash bank cfi <base> <size> <chip_width> <bus_width> <targetNum> [jedec_probe/x16_as_x8]");
605 register_command(cmd_ctx, cfi_cmd, "part_id", cfi_handle_part_id_command, COMMAND_EXEC,
606 "print part id of cfi flash bank <num>");
611 /* flash_bank cfi <base> <size> <chip_width> <bus_width> <target#> [options]
613 int cfi_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
615 cfi_flash_bank_t
*cfi_info
;
620 LOG_WARNING("incomplete flash_bank cfi configuration");
621 return ERROR_FLASH_BANK_INVALID
;
624 if ((strtoul(args
[4], NULL
, 0) > CFI_MAX_CHIP_WIDTH
)
625 || (strtoul(args
[3], NULL
, 0) > CFI_MAX_BUS_WIDTH
))
627 LOG_ERROR("chip and bus width have to specified in bytes");
628 return ERROR_FLASH_BANK_INVALID
;
631 cfi_info
= malloc(sizeof(cfi_flash_bank_t
));
632 cfi_info
->probed
= 0;
633 bank
->driver_priv
= cfi_info
;
635 cfi_info
->write_algorithm
= NULL
;
637 cfi_info
->x16_as_x8
= 0;
638 cfi_info
->jedec_probe
= 0;
639 cfi_info
->not_cfi
= 0;
641 for (i
= 6; i
< argc
; i
++)
643 if (strcmp(args
[i
], "x16_as_x8") == 0)
645 cfi_info
->x16_as_x8
= 1;
647 else if (strcmp(args
[i
], "jedec_probe") == 0)
649 cfi_info
->jedec_probe
= 1;
653 cfi_info
->write_algorithm
= NULL
;
655 /* bank wasn't probed yet */
656 cfi_info
->qry
[0] = -1;
661 int cfi_intel_erase(struct flash_bank_s
*bank
, int first
, int last
)
663 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
664 target_t
*target
= bank
->target
;
668 cfi_intel_clear_status_register(bank
);
670 for (i
= first
; i
<= last
; i
++)
672 cfi_command(bank
, 0x20, command
);
673 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
675 cfi_command(bank
, 0xd0, command
);
676 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
678 if (cfi_intel_wait_status_busy(bank
, 1000 * (1 << cfi_info
->block_erase_timeout_typ
)) == 0x80)
679 bank
->sectors
[i
].is_erased
= 1;
682 cfi_command(bank
, 0xff, command
);
683 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
685 LOG_ERROR("couldn't erase block %i of flash bank at base 0x%x", i
, bank
->base
);
686 return ERROR_FLASH_OPERATION_FAILED
;
690 cfi_command(bank
, 0xff, command
);
691 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
696 int cfi_spansion_erase(struct flash_bank_s
*bank
, int first
, int last
)
698 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
699 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
700 target_t
*target
= bank
->target
;
704 for (i
= first
; i
<= last
; i
++)
706 cfi_command(bank
, 0xaa, command
);
707 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
709 cfi_command(bank
, 0x55, command
);
710 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock2
), bank
->bus_width
, 1, command
);
712 cfi_command(bank
, 0x80, command
);
713 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
715 cfi_command(bank
, 0xaa, command
);
716 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
718 cfi_command(bank
, 0x55, command
);
719 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock2
), bank
->bus_width
, 1, command
);
721 cfi_command(bank
, 0x30, command
);
722 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
724 if (cfi_spansion_wait_status_busy(bank
, 1000 * (1 << cfi_info
->block_erase_timeout_typ
)) == ERROR_OK
)
725 bank
->sectors
[i
].is_erased
= 1;
728 cfi_command(bank
, 0xf0, command
);
729 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
731 LOG_ERROR("couldn't erase block %i of flash bank at base 0x%x", i
, bank
->base
);
732 return ERROR_FLASH_OPERATION_FAILED
;
736 cfi_command(bank
, 0xf0, command
);
737 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
742 int cfi_erase(struct flash_bank_s
*bank
, int first
, int last
)
744 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
746 if (bank
->target
->state
!= TARGET_HALTED
)
748 return ERROR_TARGET_NOT_HALTED
;
751 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
753 return ERROR_FLASH_SECTOR_INVALID
;
756 if (cfi_info
->qry
[0] != 'Q')
757 return ERROR_FLASH_BANK_NOT_PROBED
;
759 switch(cfi_info
->pri_id
)
763 return cfi_intel_erase(bank
, first
, last
);
766 return cfi_spansion_erase(bank
, first
, last
);
769 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
776 int cfi_intel_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
778 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
779 cfi_intel_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
780 target_t
*target
= bank
->target
;
785 /* if the device supports neither legacy lock/unlock (bit 3) nor
786 * instant individual block locking (bit 5).
788 if (!(pri_ext
->feature_support
& 0x28))
789 return ERROR_FLASH_OPERATION_FAILED
;
791 cfi_intel_clear_status_register(bank
);
793 for (i
= first
; i
<= last
; i
++)
795 cfi_command(bank
, 0x60, command
);
796 LOG_DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank
, i
, 0x0), target_buffer_get_u32(target
, command
));
797 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
800 cfi_command(bank
, 0x01, command
);
801 LOG_DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank
, i
, 0x0), target_buffer_get_u32(target
, command
));
802 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
803 bank
->sectors
[i
].is_protected
= 1;
807 cfi_command(bank
, 0xd0, command
);
808 LOG_DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank
, i
, 0x0), target_buffer_get_u32(target
, command
));
809 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
810 bank
->sectors
[i
].is_protected
= 0;
813 /* instant individual block locking doesn't require reading of the status register */
814 if (!(pri_ext
->feature_support
& 0x20))
816 /* Clear lock bits operation may take up to 1.4s */
817 cfi_intel_wait_status_busy(bank
, 1400);
822 /* read block lock bit, to verify status */
823 cfi_command(bank
, 0x90, command
);
824 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x55), bank
->bus_width
, 1, command
);
825 block_status
= cfi_get_u8(bank
, i
, 0x2);
827 if ((block_status
& 0x1) != set
)
829 LOG_ERROR("couldn't change block lock status (set = %i, block_status = 0x%2.2x)", set
, block_status
);
830 cfi_command(bank
, 0x70, command
);
831 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x55), bank
->bus_width
, 1, command
);
832 cfi_intel_wait_status_busy(bank
, 10);
835 return ERROR_FLASH_OPERATION_FAILED
;
845 /* if the device doesn't support individual block lock bits set/clear,
846 * all blocks have been unlocked in parallel, so we set those that should be protected
848 if ((!set
) && (!(pri_ext
->feature_support
& 0x20)))
850 for (i
= 0; i
< bank
->num_sectors
; i
++)
852 if (bank
->sectors
[i
].is_protected
== 1)
854 cfi_intel_clear_status_register(bank
);
856 cfi_command(bank
, 0x60, command
);
857 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
859 cfi_command(bank
, 0x01, command
);
860 target
->type
->write_memory(target
, flash_address(bank
, i
, 0x0), bank
->bus_width
, 1, command
);
862 cfi_intel_wait_status_busy(bank
, 100);
867 cfi_command(bank
, 0xff, command
);
868 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
873 int cfi_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
875 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
877 if (bank
->target
->state
!= TARGET_HALTED
)
879 return ERROR_TARGET_NOT_HALTED
;
882 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
884 return ERROR_FLASH_SECTOR_INVALID
;
887 if (cfi_info
->qry
[0] != 'Q')
888 return ERROR_FLASH_BANK_NOT_PROBED
;
890 switch(cfi_info
->pri_id
)
894 cfi_intel_protect(bank
, set
, first
, last
);
897 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
904 /* FIXME Replace this by a simple memcpy() - still unsure about sideeffects */
905 static void cfi_add_byte(struct flash_bank_s
*bank
, u8
*word
, u8 byte
)
907 /* target_t *target = bank->target; */
912 * The data to flash must not be changed in endian! We write a bytestrem in
913 * target byte order already. Only the control and status byte lane of the flash
914 * WSM is interpreted by the CPU in different ways, when read a u16 or u32
915 * word (data seems to be in the upper or lower byte lane for u16 accesses).
919 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
923 for (i
= 0; i
< bank
->bus_width
- 1; i
++)
924 word
[i
] = word
[i
+ 1];
925 word
[bank
->bus_width
- 1] = byte
;
931 for (i
= bank
->bus_width
- 1; i
> 0; i
--)
932 word
[i
] = word
[i
- 1];
938 /* Convert code image to target endian */
939 /* FIXME create general block conversion fcts in target.c?) */
940 static void cfi_fix_code_endian(target_t
*target
, u8
*dest
, const u32
*src
, u32 count
)
943 for (i
=0; i
< count
; i
++)
945 target_buffer_set_u32(target
, dest
, *src
);
951 u32
cfi_command_val(flash_bank_t
*bank
, u8 cmd
)
953 target_t
*target
= bank
->target
;
955 u8 buf
[CFI_MAX_BUS_WIDTH
];
956 cfi_command(bank
, cmd
, buf
);
957 switch (bank
->bus_width
)
963 return target_buffer_get_u16(target
, buf
);
966 return target_buffer_get_u32(target
, buf
);
969 LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank
->bus_width
);
974 int cfi_intel_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 address
, u32 count
)
976 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
977 target_t
*target
= bank
->target
;
978 reg_param_t reg_params
[7];
979 armv4_5_algorithm_t armv4_5_info
;
980 working_area_t
*source
;
981 u32 buffer_size
= 32768;
982 u32 write_command_val
, busy_pattern_val
, error_pattern_val
;
984 /* algorithm register usage:
985 * r0: source address (in RAM)
986 * r1: target address (in Flash)
988 * r3: flash write command
989 * r4: status byte (returned to host)
990 * r5: busy test pattern
991 * r6: error test pattern
994 static const u32 word_32_code
[] = {
995 0xe4904004, /* loop: ldr r4, [r0], #4 */
996 0xe5813000, /* str r3, [r1] */
997 0xe5814000, /* str r4, [r1] */
998 0xe5914000, /* busy: ldr r4, [r1] */
999 0xe0047005, /* and r7, r4, r5 */
1000 0xe1570005, /* cmp r7, r5 */
1001 0x1afffffb, /* bne busy */
1002 0xe1140006, /* tst r4, r6 */
1003 0x1a000003, /* bne done */
1004 0xe2522001, /* subs r2, r2, #1 */
1005 0x0a000001, /* beq done */
1006 0xe2811004, /* add r1, r1 #4 */
1007 0xeafffff2, /* b loop */
1008 0xeafffffe /* done: b -2 */
1011 static const u32 word_16_code
[] = {
1012 0xe0d040b2, /* loop: ldrh r4, [r0], #2 */
1013 0xe1c130b0, /* strh r3, [r1] */
1014 0xe1c140b0, /* strh r4, [r1] */
1015 0xe1d140b0, /* busy ldrh r4, [r1] */
1016 0xe0047005, /* and r7, r4, r5 */
1017 0xe1570005, /* cmp r7, r5 */
1018 0x1afffffb, /* bne busy */
1019 0xe1140006, /* tst r4, r6 */
1020 0x1a000003, /* bne done */
1021 0xe2522001, /* subs r2, r2, #1 */
1022 0x0a000001, /* beq done */
1023 0xe2811002, /* add r1, r1 #2 */
1024 0xeafffff2, /* b loop */
1025 0xeafffffe /* done: b -2 */
1028 static const u32 word_8_code
[] = {
1029 0xe4d04001, /* loop: ldrb r4, [r0], #1 */
1030 0xe5c13000, /* strb r3, [r1] */
1031 0xe5c14000, /* strb r4, [r1] */
1032 0xe5d14000, /* busy ldrb r4, [r1] */
1033 0xe0047005, /* and r7, r4, r5 */
1034 0xe1570005, /* cmp r7, r5 */
1035 0x1afffffb, /* bne busy */
1036 0xe1140006, /* tst r4, r6 */
1037 0x1a000003, /* bne done */
1038 0xe2522001, /* subs r2, r2, #1 */
1039 0x0a000001, /* beq done */
1040 0xe2811001, /* add r1, r1 #1 */
1041 0xeafffff2, /* b loop */
1042 0xeafffffe /* done: b -2 */
1044 u8 target_code
[4*CFI_MAX_INTEL_CODESIZE
];
1045 const u32
*target_code_src
;
1046 int target_code_size
;
1047 int retval
= ERROR_OK
;
1050 cfi_intel_clear_status_register(bank
);
1052 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
1053 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
1054 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
1056 /* If we are setting up the write_algorith, we need target_code_src */
1057 /* if not we only need target_code_size. */
1059 /* However, we don't want to create multiple code paths, so we */
1060 /* do the unecessary evaluation of target_code_src, which the */
1061 /* compiler will probably nicely optimize away if not needed */
1063 /* prepare algorithm code for target endian */
1064 switch (bank
->bus_width
)
1067 target_code_src
= word_8_code
;
1068 target_code_size
= sizeof(word_8_code
);
1071 target_code_src
= word_16_code
;
1072 target_code_size
= sizeof(word_16_code
);
1075 target_code_src
= word_32_code
;
1076 target_code_size
= sizeof(word_32_code
);
1079 LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank
->bus_width
);
1080 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1083 /* flash write code */
1084 if (!cfi_info
->write_algorithm
)
1086 if ( target_code_size
> sizeof(target_code
) )
1088 LOG_WARNING("Internal error - target code buffer to small. Increase CFI_MAX_INTEL_CODESIZE and recompile.");
1089 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1091 cfi_fix_code_endian(target
, target_code
, target_code_src
, target_code_size
/ 4);
1093 /* Get memory for block write handler */
1094 retval
= target_alloc_working_area(target
, target_code_size
, &cfi_info
->write_algorithm
);
1095 if (retval
!= ERROR_OK
)
1097 LOG_WARNING("No working area available, can't do block memory writes");
1098 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1101 /* write algorithm code to working area */
1102 retval
= target_write_buffer(target
, cfi_info
->write_algorithm
->address
, target_code_size
, target_code
);
1103 if (retval
!= ERROR_OK
)
1105 LOG_ERROR("Unable to write block write code to target");
1110 /* Get a workspace buffer for the data to flash starting with 32k size.
1111 Half size until buffer would be smaller 256 Bytem then fail back */
1112 /* FIXME Why 256 bytes, why not 32 bytes (smallest flash write page */
1113 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
1116 if (buffer_size
<= 256)
1118 LOG_WARNING("no large enough working area available, can't do block memory writes");
1119 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1124 /* setup algo registers */
1125 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
1126 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
1127 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
1128 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
1129 init_reg_param(®_params
[4], "r4", 32, PARAM_IN
);
1130 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
);
1131 init_reg_param(®_params
[6], "r6", 32, PARAM_OUT
);
1133 /* prepare command and status register patterns */
1134 write_command_val
= cfi_command_val(bank
, 0x40);
1135 busy_pattern_val
= cfi_command_val(bank
, 0x80);
1136 error_pattern_val
= cfi_command_val(bank
, 0x7e);
1138 LOG_INFO("Using target buffer at 0x%08x and of size 0x%04x", source
->address
, buffer_size
);
1140 /* Programming main loop */
1143 u32 thisrun_count
= (count
> buffer_size
) ? buffer_size
: count
;
1146 target_write_buffer(target
, source
->address
, thisrun_count
, buffer
);
1148 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
1149 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
1150 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
/ bank
->bus_width
);
1152 buf_set_u32(reg_params
[3].value
, 0, 32, write_command_val
);
1153 buf_set_u32(reg_params
[5].value
, 0, 32, busy_pattern_val
);
1154 buf_set_u32(reg_params
[6].value
, 0, 32, error_pattern_val
);
1156 LOG_INFO("Write 0x%04x bytes to flash at 0x%08x", thisrun_count
, address
);
1158 /* Execute algorithm, assume breakpoint for last instruction */
1159 retval
= target
->type
->run_algorithm(target
, 0, NULL
, 7, reg_params
,
1160 cfi_info
->write_algorithm
->address
,
1161 cfi_info
->write_algorithm
->address
+ target_code_size
- sizeof(u32
),
1162 10000, /* 10s should be enough for max. 32k of data */
1165 /* On failure try a fall back to direct word writes */
1166 if (retval
!= ERROR_OK
)
1168 cfi_intel_clear_status_register(bank
);
1169 LOG_ERROR("Execution of flash algorythm failed. Can't fall back. Please report.");
1170 retval
= ERROR_FLASH_OPERATION_FAILED
;
1171 /* retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; */
1172 /* FIXME To allow fall back or recovery, we must save the actual status
1173 somewhere, so that a higher level code can start recovery. */
1177 /* Check return value from algo code */
1178 wsm_error
= buf_get_u32(reg_params
[4].value
, 0, 32) & error_pattern_val
;
1181 /* read status register (outputs debug inforation) */
1182 cfi_intel_wait_status_busy(bank
, 100);
1183 cfi_intel_clear_status_register(bank
);
1184 retval
= ERROR_FLASH_OPERATION_FAILED
;
1188 buffer
+= thisrun_count
;
1189 address
+= thisrun_count
;
1190 count
-= thisrun_count
;
1193 /* free up resources */
1196 target_free_working_area(target
, source
);
1198 if (cfi_info
->write_algorithm
)
1200 target_free_working_area(target
, cfi_info
->write_algorithm
);
1201 cfi_info
->write_algorithm
= NULL
;
1204 destroy_reg_param(®_params
[0]);
1205 destroy_reg_param(®_params
[1]);
1206 destroy_reg_param(®_params
[2]);
1207 destroy_reg_param(®_params
[3]);
1208 destroy_reg_param(®_params
[4]);
1209 destroy_reg_param(®_params
[5]);
1210 destroy_reg_param(®_params
[6]);
1215 int cfi_spansion_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 address
, u32 count
)
1217 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1218 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
1219 target_t
*target
= bank
->target
;
1220 reg_param_t reg_params
[10];
1221 armv4_5_algorithm_t armv4_5_info
;
1222 working_area_t
*source
;
1223 u32 buffer_size
= 32768;
1226 int exit_code
= ERROR_OK
;
1228 /* input parameters - */
1229 /* R0 = source address */
1230 /* R1 = destination address */
1231 /* R2 = number of writes */
1232 /* R3 = flash write command */
1233 /* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */
1234 /* output parameters - */
1235 /* R5 = 0x80 ok 0x00 bad */
1236 /* temp registers - */
1237 /* R6 = value read from flash to test status */
1238 /* R7 = holding register */
1239 /* unlock registers - */
1240 /* R8 = unlock1_addr */
1241 /* R9 = unlock1_cmd */
1242 /* R10 = unlock2_addr */
1243 /* R11 = unlock2_cmd */
1245 static const u32 word_32_code
[] = {
1246 /* 00008100 <sp_32_code>: */
1247 0xe4905004, /* ldr r5, [r0], #4 */
1248 0xe5889000, /* str r9, [r8] */
1249 0xe58ab000, /* str r11, [r10] */
1250 0xe5883000, /* str r3, [r8] */
1251 0xe5815000, /* str r5, [r1] */
1252 0xe1a00000, /* nop */
1254 /* 00008110 <sp_32_busy>: */
1255 0xe5916000, /* ldr r6, [r1] */
1256 0xe0257006, /* eor r7, r5, r6 */
1257 0xe0147007, /* ands r7, r4, r7 */
1258 0x0a000007, /* beq 8140 <sp_32_cont> ; b if DQ7 == Data7 */
1259 0xe0166124, /* ands r6, r6, r4, lsr #2 */
1260 0x0afffff9, /* beq 8110 <sp_32_busy> ; b if DQ5 low */
1261 0xe5916000, /* ldr r6, [r1] */
1262 0xe0257006, /* eor r7, r5, r6 */
1263 0xe0147007, /* ands r7, r4, r7 */
1264 0x0a000001, /* beq 8140 <sp_32_cont> ; b if DQ7 == Data7 */
1265 0xe3a05000, /* mov r5, #0 ; 0x0 - return 0x00, error */
1266 0x1a000004, /* bne 8154 <sp_32_done> */
1268 /* 00008140 <sp_32_cont>: */
1269 0xe2522001, /* subs r2, r2, #1 ; 0x1 */
1270 0x03a05080, /* moveq r5, #128 ; 0x80 */
1271 0x0a000001, /* beq 8154 <sp_32_done> */
1272 0xe2811004, /* add r1, r1, #4 ; 0x4 */
1273 0xeaffffe8, /* b 8100 <sp_32_code> */
1275 /* 00008154 <sp_32_done>: */
1276 0xeafffffe /* b 8154 <sp_32_done> */
1279 static const u32 word_16_code
[] = {
1280 /* 00008158 <sp_16_code>: */
1281 0xe0d050b2, /* ldrh r5, [r0], #2 */
1282 0xe1c890b0, /* strh r9, [r8] */
1283 0xe1cab0b0, /* strh r11, [r10] */
1284 0xe1c830b0, /* strh r3, [r8] */
1285 0xe1c150b0, /* strh r5, [r1] */
1286 0xe1a00000, /* nop (mov r0,r0) */
1288 /* 00008168 <sp_16_busy>: */
1289 0xe1d160b0, /* ldrh r6, [r1] */
1290 0xe0257006, /* eor r7, r5, r6 */
1291 0xe0147007, /* ands r7, r4, r7 */
1292 0x0a000007, /* beq 8198 <sp_16_cont> */
1293 0xe0166124, /* ands r6, r6, r4, lsr #2 */
1294 0x0afffff9, /* beq 8168 <sp_16_busy> */
1295 0xe1d160b0, /* ldrh r6, [r1] */
1296 0xe0257006, /* eor r7, r5, r6 */
1297 0xe0147007, /* ands r7, r4, r7 */
1298 0x0a000001, /* beq 8198 <sp_16_cont> */
1299 0xe3a05000, /* mov r5, #0 ; 0x0 */
1300 0x1a000004, /* bne 81ac <sp_16_done> */
1302 /* 00008198 <sp_16_cont>: */
1303 0xe2522001, /* subs r2, r2, #1 ; 0x1 */
1304 0x03a05080, /* moveq r5, #128 ; 0x80 */
1305 0x0a000001, /* beq 81ac <sp_16_done> */
1306 0xe2811002, /* add r1, r1, #2 ; 0x2 */
1307 0xeaffffe8, /* b 8158 <sp_16_code> */
1309 /* 000081ac <sp_16_done>: */
1310 0xeafffffe /* b 81ac <sp_16_done> */
1313 static const u32 word_8_code
[] = {
1314 /* 000081b0 <sp_16_code_end>: */
1315 0xe4d05001, /* ldrb r5, [r0], #1 */
1316 0xe5c89000, /* strb r9, [r8] */
1317 0xe5cab000, /* strb r11, [r10] */
1318 0xe5c83000, /* strb r3, [r8] */
1319 0xe5c15000, /* strb r5, [r1] */
1320 0xe1a00000, /* nop (mov r0,r0) */
1322 /* 000081c0 <sp_8_busy>: */
1323 0xe5d16000, /* ldrb r6, [r1] */
1324 0xe0257006, /* eor r7, r5, r6 */
1325 0xe0147007, /* ands r7, r4, r7 */
1326 0x0a000007, /* beq 81f0 <sp_8_cont> */
1327 0xe0166124, /* ands r6, r6, r4, lsr #2 */
1328 0x0afffff9, /* beq 81c0 <sp_8_busy> */
1329 0xe5d16000, /* ldrb r6, [r1] */
1330 0xe0257006, /* eor r7, r5, r6 */
1331 0xe0147007, /* ands r7, r4, r7 */
1332 0x0a000001, /* beq 81f0 <sp_8_cont> */
1333 0xe3a05000, /* mov r5, #0 ; 0x0 */
1334 0x1a000004, /* bne 8204 <sp_8_done> */
1336 /* 000081f0 <sp_8_cont>: */
1337 0xe2522001, /* subs r2, r2, #1 ; 0x1 */
1338 0x03a05080, /* moveq r5, #128 ; 0x80 */
1339 0x0a000001, /* beq 8204 <sp_8_done> */
1340 0xe2811001, /* add r1, r1, #1 ; 0x1 */
1341 0xeaffffe8, /* b 81b0 <sp_16_code_end> */
1343 /* 00008204 <sp_8_done>: */
1344 0xeafffffe /* b 8204 <sp_8_done> */
1347 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
1348 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
1349 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
1351 /* flash write code */
1352 if (!cfi_info
->write_algorithm
)
1355 int target_code_size
;
1358 /* convert bus-width dependent algorithm code to correct endiannes */
1359 switch (bank
->bus_width
)
1363 target_code_size
= sizeof(word_8_code
);
1367 target_code_size
= sizeof(word_16_code
);
1371 target_code_size
= sizeof(word_32_code
);
1374 LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank
->bus_width
);
1375 return ERROR_FLASH_OPERATION_FAILED
;
1377 target_code
= malloc(target_code_size
);
1378 cfi_fix_code_endian(target
, target_code
, src
, target_code_size
/ 4);
1380 /* allocate working area */
1381 retval
=target_alloc_working_area(target
, target_code_size
,
1382 &cfi_info
->write_algorithm
);
1383 if (retval
!= ERROR_OK
)
1386 /* write algorithm code to working area */
1387 target_write_buffer(target
, cfi_info
->write_algorithm
->address
,
1388 target_code_size
, target_code
);
1392 /* the following code still assumes target code is fixed 24*4 bytes */
1394 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
1397 if (buffer_size
<= 256)
1399 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
1400 if (cfi_info
->write_algorithm
)
1401 target_free_working_area(target
, cfi_info
->write_algorithm
);
1403 LOG_WARNING("not enough working area available, can't do block memory writes");
1404 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1408 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
1409 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
1410 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
1411 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
1412 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
1413 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
);
1414 init_reg_param(®_params
[6], "r8", 32, PARAM_OUT
);
1415 init_reg_param(®_params
[7], "r9", 32, PARAM_OUT
);
1416 init_reg_param(®_params
[8], "r10", 32, PARAM_OUT
);
1417 init_reg_param(®_params
[9], "r11", 32, PARAM_OUT
);
1421 u32 thisrun_count
= (count
> buffer_size
) ? buffer_size
: count
;
1423 target_write_buffer(target
, source
->address
, thisrun_count
, buffer
);
1425 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
1426 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
1427 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
/ bank
->bus_width
);
1428 buf_set_u32(reg_params
[3].value
, 0, 32, cfi_command_val(bank
, 0xA0));
1429 buf_set_u32(reg_params
[4].value
, 0, 32, cfi_command_val(bank
, 0x80));
1430 buf_set_u32(reg_params
[6].value
, 0, 32, flash_address(bank
, 0, pri_ext
->_unlock1
));
1431 buf_set_u32(reg_params
[7].value
, 0, 32, 0xaaaaaaaa);
1432 buf_set_u32(reg_params
[8].value
, 0, 32, flash_address(bank
, 0, pri_ext
->_unlock2
));
1433 buf_set_u32(reg_params
[9].value
, 0, 32, 0x55555555);
1435 retval
= target
->type
->run_algorithm(target
, 0, NULL
, 10, reg_params
,
1436 cfi_info
->write_algorithm
->address
,
1437 cfi_info
->write_algorithm
->address
+ ((24 * 4) - 4),
1438 10000, &armv4_5_info
);
1440 status
= buf_get_u32(reg_params
[5].value
, 0, 32);
1442 if ((retval
!= ERROR_OK
) || status
!= 0x80)
1444 LOG_DEBUG("status: 0x%x", status
);
1445 exit_code
= ERROR_FLASH_OPERATION_FAILED
;
1449 buffer
+= thisrun_count
;
1450 address
+= thisrun_count
;
1451 count
-= thisrun_count
;
1454 target_free_working_area(target
, source
);
1456 destroy_reg_param(®_params
[0]);
1457 destroy_reg_param(®_params
[1]);
1458 destroy_reg_param(®_params
[2]);
1459 destroy_reg_param(®_params
[3]);
1460 destroy_reg_param(®_params
[4]);
1461 destroy_reg_param(®_params
[5]);
1462 destroy_reg_param(®_params
[6]);
1463 destroy_reg_param(®_params
[7]);
1464 destroy_reg_param(®_params
[8]);
1465 destroy_reg_param(®_params
[9]);
1470 int cfi_intel_write_word(struct flash_bank_s
*bank
, u8
*word
, u32 address
)
1472 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1473 target_t
*target
= bank
->target
;
1476 cfi_intel_clear_status_register(bank
);
1477 cfi_command(bank
, 0x40, command
);
1478 target
->type
->write_memory(target
, address
, bank
->bus_width
, 1, command
);
1480 target
->type
->write_memory(target
, address
, bank
->bus_width
, 1, word
);
1482 if (cfi_intel_wait_status_busy(bank
, 1000 * (1 << cfi_info
->word_write_timeout_max
)) != 0x80)
1484 cfi_command(bank
, 0xff, command
);
1485 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
1487 LOG_ERROR("couldn't write word at base 0x%x, address %x", bank
->base
, address
);
1488 return ERROR_FLASH_OPERATION_FAILED
;
1494 int cfi_intel_write_words(struct flash_bank_s
*bank
, u8
*word
, u32 wordcount
, u32 address
)
1496 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1497 target_t
*target
= bank
->target
;
1500 /* Calculate buffer size and boundary mask */
1501 u32 buffersize
= 1UL << cfi_info
->max_buf_write_size
;
1502 u32 buffermask
= buffersize
-1;
1505 /* Check for valid range */
1506 if (address
& buffermask
)
1508 LOG_ERROR("Write address at base 0x%x, address %x not aligned to 2^%d boundary", bank
->base
, address
, cfi_info
->max_buf_write_size
);
1509 return ERROR_FLASH_OPERATION_FAILED
;
1511 switch(bank
->chip_width
)
1513 case 4 : bufferwsize
= buffersize
/ 4; break;
1514 case 2 : bufferwsize
= buffersize
/ 2; break;
1515 case 1 : bufferwsize
= buffersize
; break;
1517 LOG_ERROR("Unsupported chip width %d", bank
->chip_width
);
1518 return ERROR_FLASH_OPERATION_FAILED
;
1521 /* Check for valid size */
1522 if (wordcount
> bufferwsize
)
1524 LOG_ERROR("Number of data words %d exceeds available buffersize %d", wordcount
, buffersize
);
1525 return ERROR_FLASH_OPERATION_FAILED
;
1528 /* Write to flash buffer */
1529 cfi_intel_clear_status_register(bank
);
1531 /* Initiate buffer operation _*/
1532 cfi_command(bank
, 0xE8, command
);
1533 target
->type
->write_memory(target
, address
, bank
->bus_width
, 1, command
);
1534 if (cfi_intel_wait_status_busy(bank
, 1000 * (1 << cfi_info
->buf_write_timeout_max
)) != 0x80)
1536 cfi_command(bank
, 0xff, command
);
1537 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
1539 LOG_ERROR("couldn't start buffer write operation at base 0x%x, address %x", bank
->base
, address
);
1540 return ERROR_FLASH_OPERATION_FAILED
;
1543 /* Write buffer wordcount-1 and data words */
1544 cfi_command(bank
, bufferwsize
-1, command
);
1545 target
->type
->write_memory(target
, address
, bank
->bus_width
, 1, command
);
1547 target
->type
->write_memory(target
, address
, bank
->bus_width
, bufferwsize
, word
);
1549 /* Commit write operation */
1550 cfi_command(bank
, 0xd0, command
);
1551 target
->type
->write_memory(target
, address
, bank
->bus_width
, 1, command
);
1552 if (cfi_intel_wait_status_busy(bank
, 1000 * (1 << cfi_info
->buf_write_timeout_max
)) != 0x80)
1554 cfi_command(bank
, 0xff, command
);
1555 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
1557 LOG_ERROR("Buffer write at base 0x%x, address %x failed.", bank
->base
, address
);
1558 return ERROR_FLASH_OPERATION_FAILED
;
1564 int cfi_spansion_write_word(struct flash_bank_s
*bank
, u8
*word
, u32 address
)
1566 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1567 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
1568 target_t
*target
= bank
->target
;
1571 cfi_command(bank
, 0xaa, command
);
1572 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
1574 cfi_command(bank
, 0x55, command
);
1575 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock2
), bank
->bus_width
, 1, command
);
1577 cfi_command(bank
, 0xa0, command
);
1578 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
1580 target
->type
->write_memory(target
, address
, bank
->bus_width
, 1, word
);
1582 if (cfi_spansion_wait_status_busy(bank
, 1000 * (1 << cfi_info
->word_write_timeout_max
)) != ERROR_OK
)
1584 cfi_command(bank
, 0xf0, command
);
1585 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
1587 LOG_ERROR("couldn't write word at base 0x%x, address %x", bank
->base
, address
);
1588 return ERROR_FLASH_OPERATION_FAILED
;
1594 int cfi_write_word(struct flash_bank_s
*bank
, u8
*word
, u32 address
)
1596 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1598 switch(cfi_info
->pri_id
)
1602 return cfi_intel_write_word(bank
, word
, address
);
1605 return cfi_spansion_write_word(bank
, word
, address
);
1608 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
1612 return ERROR_FLASH_OPERATION_FAILED
;
1615 int cfi_write_words(struct flash_bank_s
*bank
, u8
*word
, u32 wordcount
, u32 address
)
1617 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1619 switch(cfi_info
->pri_id
)
1623 return cfi_intel_write_words(bank
, word
, wordcount
, address
);
1626 /* return cfi_spansion_write_words(bank, word, address); */
1627 LOG_ERROR("cfi primary command set %i unimplemented - FIXME", cfi_info
->pri_id
);
1630 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
1634 return ERROR_FLASH_OPERATION_FAILED
;
1637 int cfi_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
1639 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1640 target_t
*target
= bank
->target
;
1641 u32 address
= bank
->base
+ offset
; /* address of first byte to be programmed */
1642 u32 write_p
, copy_p
;
1643 int align
; /* number of unaligned bytes */
1644 int blk_count
; /* number of bus_width bytes for block copy */
1645 u8 current_word
[CFI_MAX_BUS_WIDTH
* 4]; /* word (bus_width size) currently being programmed */
1649 if (bank
->target
->state
!= TARGET_HALTED
)
1650 return ERROR_TARGET_NOT_HALTED
;
1652 if (offset
+ count
> bank
->size
)
1653 return ERROR_FLASH_DST_OUT_OF_BANK
;
1655 if (cfi_info
->qry
[0] != 'Q')
1656 return ERROR_FLASH_BANK_NOT_PROBED
;
1658 /* start at the first byte of the first word (bus_width size) */
1659 write_p
= address
& ~(bank
->bus_width
- 1);
1660 if ((align
= address
- write_p
) != 0)
1662 LOG_INFO("Fixup %d unaligned head bytes", align
);
1664 for (i
= 0; i
< bank
->bus_width
; i
++)
1665 current_word
[i
] = 0;
1668 /* copy bytes before the first write address */
1669 for (i
= 0; i
< align
; ++i
, ++copy_p
)
1672 target
->type
->read_memory(target
, copy_p
, 1, 1, &byte
);
1673 cfi_add_byte(bank
, current_word
, byte
);
1676 /* add bytes from the buffer */
1677 for (; (i
< bank
->bus_width
) && (count
> 0); i
++)
1679 cfi_add_byte(bank
, current_word
, *buffer
++);
1684 /* if the buffer is already finished, copy bytes after the last write address */
1685 for (; (count
== 0) && (i
< bank
->bus_width
); ++i
, ++copy_p
)
1688 target
->type
->read_memory(target
, copy_p
, 1, 1, &byte
);
1689 cfi_add_byte(bank
, current_word
, byte
);
1692 retval
= cfi_write_word(bank
, current_word
, write_p
);
1693 if (retval
!= ERROR_OK
)
1698 /* handle blocks of bus_size aligned bytes */
1699 blk_count
= count
& ~(bank
->bus_width
- 1); /* round down, leave tail bytes */
1700 switch(cfi_info
->pri_id
)
1702 /* try block writes (fails without working area) */
1705 retval
= cfi_intel_write_block(bank
, buffer
, write_p
, blk_count
);
1708 retval
= cfi_spansion_write_block(bank
, buffer
, write_p
, blk_count
);
1711 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
1712 retval
= ERROR_FLASH_OPERATION_FAILED
;
1715 if (retval
== ERROR_OK
)
1717 /* Increment pointers and decrease count on succesful block write */
1718 buffer
+= blk_count
;
1719 write_p
+= blk_count
;
1724 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1726 u32 buffersize
= 1UL << cfi_info
->max_buf_write_size
;
1727 u32 buffermask
= buffersize
-1;
1730 switch(bank
->chip_width
)
1732 case 4 : bufferwsize
= buffersize
/ 4; break;
1733 case 2 : bufferwsize
= buffersize
/ 2; break;
1734 case 1 : bufferwsize
= buffersize
; break;
1736 LOG_ERROR("Unsupported chip width %d", bank
->chip_width
);
1737 return ERROR_FLASH_OPERATION_FAILED
;
1740 /* fall back to memory writes */
1741 while (count
>= bank
->bus_width
)
1744 if ((write_p
& 0xff) == 0)
1746 LOG_INFO("Programming at %08x, count %08x bytes remaining", write_p
, count
);
1749 if ((bufferwsize
> 0) && (count
>= buffersize
) && !(write_p
& buffermask
))
1751 retval
= cfi_write_words(bank
, buffer
, bufferwsize
, write_p
);
1752 if (retval
== ERROR_OK
)
1754 buffer
+= buffersize
;
1755 write_p
+= buffersize
;
1756 count
-= buffersize
;
1760 /* try the slow way? */
1763 for (i
= 0; i
< bank
->bus_width
; i
++)
1764 current_word
[i
] = 0;
1766 for (i
= 0; i
< bank
->bus_width
; i
++)
1768 cfi_add_byte(bank
, current_word
, *buffer
++);
1771 retval
= cfi_write_word(bank
, current_word
, write_p
);
1772 if (retval
!= ERROR_OK
)
1775 write_p
+= bank
->bus_width
;
1776 count
-= bank
->bus_width
;
1784 /* return to read array mode, so we can read from flash again for padding */
1785 cfi_command(bank
, 0xf0, current_word
);
1786 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, current_word
);
1787 cfi_command(bank
, 0xff, current_word
);
1788 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, current_word
);
1790 /* handle unaligned tail bytes */
1793 LOG_INFO("Fixup %d unaligned tail bytes", count
);
1796 for (i
= 0; i
< bank
->bus_width
; i
++)
1797 current_word
[i
] = 0;
1799 for (i
= 0; (i
< bank
->bus_width
) && (count
> 0); ++i
, ++copy_p
)
1801 cfi_add_byte(bank
, current_word
, *buffer
++);
1804 for (; i
< bank
->bus_width
; ++i
, ++copy_p
)
1807 target
->type
->read_memory(target
, copy_p
, 1, 1, &byte
);
1808 cfi_add_byte(bank
, current_word
, byte
);
1810 retval
= cfi_write_word(bank
, current_word
, write_p
);
1811 if (retval
!= ERROR_OK
)
1815 /* return to read array mode */
1816 cfi_command(bank
, 0xf0, current_word
);
1817 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, current_word
);
1818 cfi_command(bank
, 0xff, current_word
);
1819 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, current_word
);
1824 void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t
*bank
, void *param
)
1826 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1827 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
1829 pri_ext
->_reversed_geometry
= 1;
1832 void cfi_fixup_0002_erase_regions(flash_bank_t
*bank
, void *param
)
1835 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1836 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
1838 if ((pri_ext
->_reversed_geometry
) || (pri_ext
->TopBottom
== 3))
1840 LOG_DEBUG("swapping reversed erase region information on cmdset 0002 device");
1842 for (i
= 0; i
< cfi_info
->num_erase_regions
/ 2; i
++)
1844 int j
= (cfi_info
->num_erase_regions
- 1) - i
;
1847 swap
= cfi_info
->erase_region_info
[i
];
1848 cfi_info
->erase_region_info
[i
] = cfi_info
->erase_region_info
[j
];
1849 cfi_info
->erase_region_info
[j
] = swap
;
1854 void cfi_fixup_0002_unlock_addresses(flash_bank_t
*bank
, void *param
)
1856 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1857 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
1858 cfi_unlock_addresses_t
*unlock_addresses
= param
;
1860 pri_ext
->_unlock1
= unlock_addresses
->unlock1
;
1861 pri_ext
->_unlock2
= unlock_addresses
->unlock2
;
1864 int cfi_probe(struct flash_bank_s
*bank
)
1866 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
1867 target_t
*target
= bank
->target
;
1869 int num_sectors
= 0;
1873 u32 unlock1
= 0x555;
1874 u32 unlock2
= 0x2aa;
1876 if (bank
->target
->state
!= TARGET_HALTED
)
1878 return ERROR_TARGET_NOT_HALTED
;
1881 cfi_info
->probed
= 0;
1883 /* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses,
1884 * while CFI compatible AMD/Spansion flashes use 0x555 and 0x2aa
1886 if (cfi_info
->jedec_probe
)
1892 /* switch to read identifier codes mode ("AUTOSELECT") */
1893 cfi_command(bank
, 0xaa, command
);
1894 target
->type
->write_memory(target
, flash_address(bank
, 0, unlock1
), bank
->bus_width
, 1, command
);
1895 cfi_command(bank
, 0x55, command
);
1896 target
->type
->write_memory(target
, flash_address(bank
, 0, unlock2
), bank
->bus_width
, 1, command
);
1897 cfi_command(bank
, 0x90, command
);
1898 target
->type
->write_memory(target
, flash_address(bank
, 0, unlock1
), bank
->bus_width
, 1, command
);
1900 if (bank
->chip_width
== 1)
1902 u8 manufacturer
, device_id
;
1903 target_read_u8(target
, bank
->base
+ 0x0, &manufacturer
);
1904 target_read_u8(target
, bank
->base
+ 0x1, &device_id
);
1905 cfi_info
->manufacturer
= manufacturer
;
1906 cfi_info
->device_id
= device_id
;
1908 else if (bank
->chip_width
== 2)
1910 target_read_u16(target
, bank
->base
+ 0x0, &cfi_info
->manufacturer
);
1911 target_read_u16(target
, bank
->base
+ 0x2, &cfi_info
->device_id
);
1914 /* switch back to read array mode */
1915 cfi_command(bank
, 0xf0, command
);
1916 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x00), bank
->bus_width
, 1, command
);
1917 cfi_command(bank
, 0xff, command
);
1918 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x00), bank
->bus_width
, 1, command
);
1920 cfi_fixup(bank
, cfi_jedec_fixups
);
1922 /* query only if this is a CFI compatible flash,
1923 * otherwise the relevant info has already been filled in
1925 if (cfi_info
->not_cfi
== 0)
1927 /* enter CFI query mode
1928 * according to JEDEC Standard No. 68.01,
1929 * a single bus sequence with address = 0x55, data = 0x98 should put
1930 * the device into CFI query mode.
1932 * SST flashes clearly violate this, and we will consider them incompatbile for now
1934 cfi_command(bank
, 0x98, command
);
1935 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x55), bank
->bus_width
, 1, command
);
1937 cfi_info
->qry
[0] = cfi_query_u8(bank
, 0, 0x10);
1938 cfi_info
->qry
[1] = cfi_query_u8(bank
, 0, 0x11);
1939 cfi_info
->qry
[2] = cfi_query_u8(bank
, 0, 0x12);
1941 LOG_DEBUG("CFI qry returned: 0x%2.2x 0x%2.2x 0x%2.2x", cfi_info
->qry
[0], cfi_info
->qry
[1], cfi_info
->qry
[2]);
1943 if ((cfi_info
->qry
[0] != 'Q') || (cfi_info
->qry
[1] != 'R') || (cfi_info
->qry
[2] != 'Y'))
1945 cfi_command(bank
, 0xf0, command
);
1946 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
1947 cfi_command(bank
, 0xff, command
);
1948 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
1949 LOG_ERROR("Could not probe bank");
1950 return ERROR_FLASH_BANK_INVALID
;
1953 cfi_info
->pri_id
= cfi_query_u16(bank
, 0, 0x13);
1954 cfi_info
->pri_addr
= cfi_query_u16(bank
, 0, 0x15);
1955 cfi_info
->alt_id
= cfi_query_u16(bank
, 0, 0x17);
1956 cfi_info
->alt_addr
= cfi_query_u16(bank
, 0, 0x19);
1958 LOG_DEBUG("qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x", cfi_info
->qry
[0], cfi_info
->qry
[1], cfi_info
->qry
[2], cfi_info
->pri_id
, cfi_info
->pri_addr
, cfi_info
->alt_id
, cfi_info
->alt_addr
);
1960 cfi_info
->vcc_min
= cfi_query_u8(bank
, 0, 0x1b);
1961 cfi_info
->vcc_max
= cfi_query_u8(bank
, 0, 0x1c);
1962 cfi_info
->vpp_min
= cfi_query_u8(bank
, 0, 0x1d);
1963 cfi_info
->vpp_max
= cfi_query_u8(bank
, 0, 0x1e);
1964 cfi_info
->word_write_timeout_typ
= cfi_query_u8(bank
, 0, 0x1f);
1965 cfi_info
->buf_write_timeout_typ
= cfi_query_u8(bank
, 0, 0x20);
1966 cfi_info
->block_erase_timeout_typ
= cfi_query_u8(bank
, 0, 0x21);
1967 cfi_info
->chip_erase_timeout_typ
= cfi_query_u8(bank
, 0, 0x22);
1968 cfi_info
->word_write_timeout_max
= cfi_query_u8(bank
, 0, 0x23);
1969 cfi_info
->buf_write_timeout_max
= cfi_query_u8(bank
, 0, 0x24);
1970 cfi_info
->block_erase_timeout_max
= cfi_query_u8(bank
, 0, 0x25);
1971 cfi_info
->chip_erase_timeout_max
= cfi_query_u8(bank
, 0, 0x26);
1973 LOG_DEBUG("Vcc min: %1.1x.%1.1x, Vcc max: %1.1x.%1.1x, Vpp min: %1.1x.%1.1x, Vpp max: %1.1x.%1.1x",
1974 (cfi_info
->vcc_min
& 0xf0) >> 4, cfi_info
->vcc_min
& 0x0f,
1975 (cfi_info
->vcc_max
& 0xf0) >> 4, cfi_info
->vcc_max
& 0x0f,
1976 (cfi_info
->vpp_min
& 0xf0) >> 4, cfi_info
->vpp_min
& 0x0f,
1977 (cfi_info
->vpp_max
& 0xf0) >> 4, cfi_info
->vpp_max
& 0x0f);
1978 LOG_DEBUG("typ. word write timeout: %u, typ. buf write timeout: %u, typ. block erase timeout: %u, typ. chip erase timeout: %u", 1 << cfi_info
->word_write_timeout_typ
, 1 << cfi_info
->buf_write_timeout_typ
,
1979 1 << cfi_info
->block_erase_timeout_typ
, 1 << cfi_info
->chip_erase_timeout_typ
);
1980 LOG_DEBUG("max. word write timeout: %u, max. buf write timeout: %u, max. block erase timeout: %u, max. chip erase timeout: %u", (1 << cfi_info
->word_write_timeout_max
) * (1 << cfi_info
->word_write_timeout_typ
),
1981 (1 << cfi_info
->buf_write_timeout_max
) * (1 << cfi_info
->buf_write_timeout_typ
),
1982 (1 << cfi_info
->block_erase_timeout_max
) * (1 << cfi_info
->block_erase_timeout_typ
),
1983 (1 << cfi_info
->chip_erase_timeout_max
) * (1 << cfi_info
->chip_erase_timeout_typ
));
1985 cfi_info
->dev_size
= cfi_query_u8(bank
, 0, 0x27);
1986 cfi_info
->interface_desc
= cfi_query_u16(bank
, 0, 0x28);
1987 cfi_info
->max_buf_write_size
= cfi_query_u16(bank
, 0, 0x2a);
1988 cfi_info
->num_erase_regions
= cfi_query_u8(bank
, 0, 0x2c);
1990 LOG_DEBUG("size: 0x%x, interface desc: %i, max buffer write size: %x", 1 << cfi_info
->dev_size
, cfi_info
->interface_desc
, (1 << cfi_info
->max_buf_write_size
));
1992 if (((1 << cfi_info
->dev_size
) * bank
->bus_width
/ bank
->chip_width
) != bank
->size
)
1994 LOG_WARNING("configuration specifies 0x%x size, but a 0x%x size flash was found", bank
->size
, 1 << cfi_info
->dev_size
);
1997 if (cfi_info
->num_erase_regions
)
1999 cfi_info
->erase_region_info
= malloc(4 * cfi_info
->num_erase_regions
);
2000 for (i
= 0; i
< cfi_info
->num_erase_regions
; i
++)
2002 cfi_info
->erase_region_info
[i
] = cfi_query_u32(bank
, 0, 0x2d + (4 * i
));
2003 LOG_DEBUG("erase region[%i]: %i blocks of size 0x%x", i
, (cfi_info
->erase_region_info
[i
] & 0xffff) + 1, (cfi_info
->erase_region_info
[i
] >> 16) * 256);
2008 cfi_info
->erase_region_info
= NULL
;
2011 /* We need to read the primary algorithm extended query table before calculating
2012 * the sector layout to be able to apply fixups
2014 switch(cfi_info
->pri_id
)
2016 /* Intel command set (standard and extended) */
2019 cfi_read_intel_pri_ext(bank
);
2021 /* AMD/Spansion, Atmel, ... command set */
2023 cfi_read_0002_pri_ext(bank
);
2026 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
2030 /* return to read array mode
2031 * we use both reset commands, as some Intel flashes fail to recognize the 0xF0 command
2033 cfi_command(bank
, 0xf0, command
);
2034 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
2035 cfi_command(bank
, 0xff, command
);
2036 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
2039 /* apply fixups depending on the primary command set */
2040 switch(cfi_info
->pri_id
)
2042 /* Intel command set (standard and extended) */
2045 cfi_fixup(bank
, cfi_0001_fixups
);
2047 /* AMD/Spansion, Atmel, ... command set */
2049 cfi_fixup(bank
, cfi_0002_fixups
);
2052 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
2056 if (cfi_info
->num_erase_regions
== 0)
2058 /* a device might have only one erase block, spanning the whole device */
2059 bank
->num_sectors
= 1;
2060 bank
->sectors
= malloc(sizeof(flash_sector_t
));
2062 bank
->sectors
[sector
].offset
= 0x0;
2063 bank
->sectors
[sector
].size
= bank
->size
;
2064 bank
->sectors
[sector
].is_erased
= -1;
2065 bank
->sectors
[sector
].is_protected
= -1;
2069 for (i
= 0; i
< cfi_info
->num_erase_regions
; i
++)
2071 num_sectors
+= (cfi_info
->erase_region_info
[i
] & 0xffff) + 1;
2074 bank
->num_sectors
= num_sectors
;
2075 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
2077 for (i
= 0; i
< cfi_info
->num_erase_regions
; i
++)
2080 for (j
= 0; j
< (cfi_info
->erase_region_info
[i
] & 0xffff) + 1; j
++)
2082 bank
->sectors
[sector
].offset
= offset
;
2083 bank
->sectors
[sector
].size
= ((cfi_info
->erase_region_info
[i
] >> 16) * 256) * bank
->bus_width
/ bank
->chip_width
;
2084 offset
+= bank
->sectors
[sector
].size
;
2085 bank
->sectors
[sector
].is_erased
= -1;
2086 bank
->sectors
[sector
].is_protected
= -1;
2092 cfi_info
->probed
= 1;
2097 int cfi_auto_probe(struct flash_bank_s
*bank
)
2099 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
2100 if (cfi_info
->probed
)
2102 return cfi_probe(bank
);
2106 int cfi_intel_protect_check(struct flash_bank_s
*bank
)
2108 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
2109 cfi_intel_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
2110 target_t
*target
= bank
->target
;
2111 u8 command
[CFI_MAX_BUS_WIDTH
];
2114 /* check if block lock bits are supported on this device */
2115 if (!(pri_ext
->blk_status_reg_mask
& 0x1))
2116 return ERROR_FLASH_OPERATION_FAILED
;
2118 cfi_command(bank
, 0x90, command
);
2119 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x55), bank
->bus_width
, 1, command
);
2121 for (i
= 0; i
< bank
->num_sectors
; i
++)
2123 u8 block_status
= cfi_get_u8(bank
, i
, 0x2);
2125 if (block_status
& 1)
2126 bank
->sectors
[i
].is_protected
= 1;
2128 bank
->sectors
[i
].is_protected
= 0;
2131 cfi_command(bank
, 0xff, command
);
2132 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
2137 int cfi_spansion_protect_check(struct flash_bank_s
*bank
)
2139 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
2140 cfi_spansion_pri_ext_t
*pri_ext
= cfi_info
->pri_ext
;
2141 target_t
*target
= bank
->target
;
2145 cfi_command(bank
, 0xaa, command
);
2146 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
2148 cfi_command(bank
, 0x55, command
);
2149 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock2
), bank
->bus_width
, 1, command
);
2151 cfi_command(bank
, 0x90, command
);
2152 target
->type
->write_memory(target
, flash_address(bank
, 0, pri_ext
->_unlock1
), bank
->bus_width
, 1, command
);
2154 for (i
= 0; i
< bank
->num_sectors
; i
++)
2156 u8 block_status
= cfi_get_u8(bank
, i
, 0x2);
2158 if (block_status
& 1)
2159 bank
->sectors
[i
].is_protected
= 1;
2161 bank
->sectors
[i
].is_protected
= 0;
2164 cfi_command(bank
, 0xf0, command
);
2165 target
->type
->write_memory(target
, flash_address(bank
, 0, 0x0), bank
->bus_width
, 1, command
);
2170 int cfi_protect_check(struct flash_bank_s
*bank
)
2172 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
2174 if (bank
->target
->state
!= TARGET_HALTED
)
2176 return ERROR_TARGET_NOT_HALTED
;
2179 if (cfi_info
->qry
[0] != 'Q')
2180 return ERROR_FLASH_BANK_NOT_PROBED
;
2182 switch(cfi_info
->pri_id
)
2186 return cfi_intel_protect_check(bank
);
2189 return cfi_spansion_protect_check(bank
);
2192 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
2199 int cfi_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
2202 cfi_flash_bank_t
*cfi_info
= bank
->driver_priv
;
2204 if (cfi_info
->qry
[0] == (char)-1)
2206 printed
= snprintf(buf
, buf_size
, "\ncfi flash bank not probed yet\n");
2210 if (cfi_info
->not_cfi
== 0)
2211 printed
= snprintf(buf
, buf_size
, "\ncfi information:\n");
2213 printed
= snprintf(buf
, buf_size
, "\nnon-cfi flash:\n");
2215 buf_size
-= printed
;
2217 printed
= snprintf(buf
, buf_size
, "\nmfr: 0x%4.4x, id:0x%4.4x\n",
2218 cfi_info
->manufacturer
, cfi_info
->device_id
);
2220 buf_size
-= printed
;
2222 if (cfi_info
->not_cfi
== 0)
2224 printed
= snprintf(buf
, buf_size
, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x\n", cfi_info
->qry
[0], cfi_info
->qry
[1], cfi_info
->qry
[2], cfi_info
->pri_id
, cfi_info
->pri_addr
, cfi_info
->alt_id
, cfi_info
->alt_addr
);
2226 buf_size
-= printed
;
2228 printed
= snprintf(buf
, buf_size
, "Vcc min: %1.1x.%1.1x, Vcc max: %1.1x.%1.1x, Vpp min: %1.1x.%1.1x, Vpp max: %1.1x.%1.1x\n",
2229 (cfi_info
->vcc_min
& 0xf0) >> 4, cfi_info
->vcc_min
& 0x0f,
2230 (cfi_info
->vcc_max
& 0xf0) >> 4, cfi_info
->vcc_max
& 0x0f,
2231 (cfi_info
->vpp_min
& 0xf0) >> 4, cfi_info
->vpp_min
& 0x0f,
2232 (cfi_info
->vpp_max
& 0xf0) >> 4, cfi_info
->vpp_max
& 0x0f);
2234 buf_size
-= printed
;
2236 printed
= snprintf(buf
, buf_size
, "typ. word write timeout: %u, typ. buf write timeout: %u, typ. block erase timeout: %u, typ. chip erase timeout: %u\n",
2237 1 << cfi_info
->word_write_timeout_typ
,
2238 1 << cfi_info
->buf_write_timeout_typ
,
2239 1 << cfi_info
->block_erase_timeout_typ
,
2240 1 << cfi_info
->chip_erase_timeout_typ
);
2242 buf_size
-= printed
;
2244 printed
= snprintf(buf
, buf_size
, "max. word write timeout: %u, max. buf write timeout: %u, max. block erase timeout: %u, max. chip erase timeout: %u\n",
2245 (1 << cfi_info
->word_write_timeout_max
) * (1 << cfi_info
->word_write_timeout_typ
),
2246 (1 << cfi_info
->buf_write_timeout_max
) * (1 << cfi_info
->buf_write_timeout_typ
),
2247 (1 << cfi_info
->block_erase_timeout_max
) * (1 << cfi_info
->block_erase_timeout_typ
),
2248 (1 << cfi_info
->chip_erase_timeout_max
) * (1 << cfi_info
->chip_erase_timeout_typ
));
2250 buf_size
-= printed
;
2252 printed
= snprintf(buf
, buf_size
, "size: 0x%x, interface desc: %i, max buffer write size: %x\n",
2253 1 << cfi_info
->dev_size
,
2254 cfi_info
->interface_desc
,
2255 cfi_info
->max_buf_write_size
);
2257 buf_size
-= printed
;
2259 switch(cfi_info
->pri_id
)
2263 cfi_intel_info(bank
, buf
, buf_size
);
2266 cfi_spansion_info(bank
, buf
, buf_size
);
2269 LOG_ERROR("cfi primary command set %i unsupported", cfi_info
->pri_id
);
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)