7f2313d8290cdea7fa734f8b04c26c691b7108a1
[openocd.git] / src / flash / cfi.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "cfi.h"
27
28 #include "flash.h"
29 #include "target.h"
30 #include "log.h"
31 #include "armv4_5.h"
32 #include "algorithm.h"
33 #include "binarybuffer.h"
34 #include "types.h"
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39
40 int cfi_register_commands(struct command_context_s *cmd_ctx);
41 int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
42 int cfi_erase(struct flash_bank_s *bank, int first, int last);
43 int cfi_protect(struct flash_bank_s *bank, int set, int first, int last);
44 int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
45 int cfi_probe(struct flash_bank_s *bank);
46 int cfi_erase_check(struct flash_bank_s *bank);
47 int cfi_protect_check(struct flash_bank_s *bank);
48 int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size);
49
50 int cfi_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51
52 #define CFI_MAX_BUS_WIDTH 4
53 #define CFI_MAX_CHIP_WIDTH 4
54
55 flash_driver_t cfi_flash =
56 {
57 .name = "cfi",
58 .register_commands = cfi_register_commands,
59 .flash_bank_command = cfi_flash_bank_command,
60 .erase = cfi_erase,
61 .protect = cfi_protect,
62 .write = cfi_write,
63 .probe = cfi_probe,
64 .erase_check = cfi_erase_check,
65 .protect_check = cfi_protect_check,
66 .info = cfi_info
67 };
68
69 inline u32 flash_address(flash_bank_t *bank, int sector, u32 offset)
70 {
71 /* while the sector list isn't built, only accesses to sector 0 work */
72 if (sector == 0)
73 return bank->base + offset * bank->bus_width;
74 else
75 {
76 if (!bank->sectors)
77 {
78 ERROR("BUG: sector list not yet built");
79 exit(-1);
80 }
81 return bank->base + bank->sectors[sector].offset + offset * bank->bus_width;
82 }
83
84 }
85
86 void cfi_command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
87 {
88 cfi_flash_bank_t *cfi_info = bank->driver_priv;
89 int i;
90
91 /* clear whole buffer, to ensure bits that exceed the bus_width
92 * are set to zero
93 */
94 for (i = 0; i < CFI_MAX_BUS_WIDTH; i++)
95 cmd_buf[i] = 0;
96
97 if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
98 {
99 for (i = bank->bus_width; i > 0; i--)
100 {
101 *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
102 }
103 }
104 else
105 {
106 for (i = 1; i <= bank->bus_width; i++)
107 {
108 *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
109 }
110 }
111 }
112
113 /* read unsigned 8-bit value from the bank
114 * flash banks are expected to be made of similar chips
115 * the query result should be the same for all
116 */
117 u8 cfi_query_u8(flash_bank_t *bank, int sector, u32 offset)
118 {
119 cfi_flash_bank_t *cfi_info = bank->driver_priv;
120 target_t *target = cfi_info->target;
121 u8 data[CFI_MAX_BUS_WIDTH];
122
123 target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data);
124
125 if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
126 return data[0];
127 else
128 return data[bank->bus_width - 1];
129 }
130
131 /* read unsigned 8-bit value from the bank
132 * in case of a bank made of multiple chips,
133 * the individual values are ORed
134 */
135 u8 cfi_get_u8(flash_bank_t *bank, int sector, u32 offset)
136 {
137 cfi_flash_bank_t *cfi_info = bank->driver_priv;
138 target_t *target = cfi_info->target;
139 u8 data[CFI_MAX_BUS_WIDTH];
140 int i;
141
142 target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data);
143
144 if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
145 {
146 for (i = 0; i < bank->bus_width / bank->chip_width; i++)
147 data[0] |= data[i];
148
149 return data[0];
150 }
151 else
152 {
153 u8 value = 0;
154 for (i = 0; i < bank->bus_width / bank->chip_width; i++)
155 value |= data[bank->bus_width - 1 - i];
156
157 return value;
158 }
159 }
160
161 u16 cfi_query_u16(flash_bank_t *bank, int sector, u32 offset)
162 {
163 cfi_flash_bank_t *cfi_info = bank->driver_priv;
164 target_t *target = cfi_info->target;
165 u8 data[CFI_MAX_BUS_WIDTH * 2];
166
167 target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 2, data);
168
169 if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
170 return data[0] | data[bank->bus_width] << 8;
171 else
172 return data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8;
173 }
174
175 u32 cfi_query_u32(flash_bank_t *bank, int sector, u32 offset)
176 {
177 cfi_flash_bank_t *cfi_info = bank->driver_priv;
178 target_t *target = cfi_info->target;
179 u8 data[CFI_MAX_BUS_WIDTH * 4];
180
181 target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 4, data);
182
183 if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
184 return data[0] | data[bank->bus_width] << 8 | data[bank->bus_width * 2] << 16 | data[bank->bus_width * 3] << 24;
185 else
186 return data[bank->bus_width - 1] | data[(2* bank->bus_width) - 1] << 8 |
187 data[(3 * bank->bus_width) - 1] << 16 | data[(4 * bank->bus_width) - 1] << 24;
188 }
189
190 void cfi_intel_clear_status_register(flash_bank_t *bank)
191 {
192 cfi_flash_bank_t *cfi_info = bank->driver_priv;
193 target_t *target = cfi_info->target;
194 u8 command[8];
195
196 if (target->state != TARGET_HALTED)
197 {
198 ERROR("BUG: attempted to clear status register while target wasn't halted");
199 exit(-1);
200 }
201
202 cfi_command(bank, 0x50, command);
203 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
204 }
205
206 u8 cfi_intel_wait_status_busy(flash_bank_t *bank, int timeout)
207 {
208 u8 status;
209
210 while ((!((status = cfi_get_u8(bank, 0, 0x0)) & 0x80)) && (timeout-- > 0))
211 {
212 DEBUG("status: 0x%x", status);
213 usleep(1000);
214 }
215
216 /* mask out bit 0 (reserved) */
217 status = status & 0xfe;
218
219 DEBUG("status: 0x%x", status);
220
221 if ((status & 0x80) != 0x80)
222 {
223 ERROR("timeout while waiting for WSM to become ready");
224 }
225 else if (status != 0x80)
226 {
227 ERROR("status register: 0x%x", status);
228 if (status & 0x2)
229 ERROR("Block Lock-Bit Detected, Operation Abort");
230 if (status & 0x4)
231 ERROR("Program suspended");
232 if (status & 0x8)
233 ERROR("Low Programming Voltage Detected, Operation Aborted");
234 if (status & 0x10)
235 ERROR("Program Error / Error in Setting Lock-Bit");
236 if (status & 0x20)
237 ERROR("Error in Block Erasure or Clear Lock-Bits");
238 if (status & 0x40)
239 ERROR("Block Erase Suspended");
240
241 cfi_intel_clear_status_register(bank);
242 }
243
244 return status;
245 }
246 int cfi_read_intel_pri_ext(flash_bank_t *bank)
247 {
248 cfi_flash_bank_t *cfi_info = bank->driver_priv;
249 cfi_intel_pri_ext_t *pri_ext = malloc(sizeof(cfi_intel_pri_ext_t));
250 target_t *target = cfi_info->target;
251 u8 command[8];
252
253 cfi_info->pri_ext = pri_ext;
254
255 pri_ext->pri[0] = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0);
256 pri_ext->pri[1] = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1);
257 pri_ext->pri[2] = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2);
258
259 if ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I'))
260 {
261 cfi_command(bank, 0xf0, command);
262 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
263 cfi_command(bank, 0xff, command);
264 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
265 return ERROR_FLASH_BANK_INVALID;
266 }
267
268 pri_ext->major_version = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3);
269 pri_ext->minor_version = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4);
270
271 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);
272
273 pri_ext->feature_support = cfi_query_u32(bank, 0, cfi_info->pri_addr + 5);
274 pri_ext->suspend_cmd_support = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9);
275 pri_ext->blk_status_reg_mask = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xa);
276
277 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);
278
279 pri_ext->vcc_optimal = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xc);
280 pri_ext->vpp_optimal = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xd);
281
282 DEBUG("Vcc opt: %1.1x.%1.1x, Vpp opt: %1.1x.%1.1x",
283 (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f,
284 (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f);
285
286 pri_ext->num_protection_fields = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xe);
287 if (pri_ext->num_protection_fields != 1)
288 {
289 WARNING("expected one protection register field, but found %i", pri_ext->num_protection_fields);
290 }
291
292 pri_ext->prot_reg_addr = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xf);
293 pri_ext->fact_prot_reg_size = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x11);
294 pri_ext->user_prot_reg_size = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x12);
295
296 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);
297
298 return ERROR_OK;
299 }
300
301 int cfi_intel_info(struct flash_bank_s *bank, char *buf, int buf_size)
302 {
303 int printed;
304 cfi_flash_bank_t *cfi_info = bank->driver_priv;
305 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
306
307 printed = snprintf(buf, buf_size, "\nintel primary algorithm extend information:\n");
308 buf += printed;
309 buf_size -= printed;
310
311 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);
312 buf += printed;
313 buf_size -= printed;
314
315 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);
316 buf += printed;
317 buf_size -= printed;
318
319 printed = snprintf(buf, buf_size, "Vcc opt: %1.1x.%1.1x, Vpp opt: %1.1x.%1.1x\n",
320 (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f,
321 (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f);
322 buf += printed;
323 buf_size -= printed;
324
325 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);
326
327 return ERROR_OK;
328 }
329
330 int cfi_register_commands(struct command_context_s *cmd_ctx)
331 {
332 command_t *cfi_cmd = register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL);
333 /*
334 register_command(cmd_ctx, cfi_cmd, "part_id", cfi_handle_part_id_command, COMMAND_EXEC,
335 "print part id of cfi flash bank <num>");
336 */
337 return ERROR_OK;
338 }
339
340 /* flash_bank cfi <base> <size> <chip_width> <bus_width> <target#>
341 */
342 int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
343 {
344 cfi_flash_bank_t *cfi_info;
345
346 if (argc < 6)
347 {
348 WARNING("incomplete flash_bank cfi configuration");
349 return ERROR_FLASH_BANK_INVALID;
350 }
351
352 if ((strtoul(args[4], NULL, 0) > CFI_MAX_CHIP_WIDTH)
353 || (strtoul(args[3], NULL, 0) > CFI_MAX_BUS_WIDTH))
354 {
355 ERROR("chip and bus width have to specified in byte");
356 return ERROR_FLASH_BANK_INVALID;
357 }
358
359 cfi_info = malloc(sizeof(cfi_flash_bank_t));
360 bank->driver_priv = cfi_info;
361
362 cfi_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
363 if (!cfi_info->target)
364 {
365 ERROR("no target '%i' configured", args[5]);
366 exit(-1);
367 }
368
369 cfi_info->write_algorithm = NULL;
370
371 /* bank wasn't probed yet */
372 cfi_info->qry[0] = -1;
373
374 return ERROR_OK;
375 }
376
377 int cfi_intel_erase(struct flash_bank_s *bank, int first, int last)
378 {
379 cfi_flash_bank_t *cfi_info = bank->driver_priv;
380 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
381 target_t *target = cfi_info->target;
382 u8 command[8];
383 int i;
384
385 cfi_intel_clear_status_register(bank);
386
387 for (i = first; i <= last; i++)
388 {
389 cfi_command(bank, 0x20, command);
390 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
391
392 cfi_command(bank, 0xd0, command);
393 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
394
395 if (cfi_intel_wait_status_busy(bank, 1000 * (1 << cfi_info->block_erase_timeout_typ)) == 0x80)
396 bank->sectors[i].is_erased = 1;
397 else
398 {
399 cfi_command(bank, 0xff, command);
400 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
401
402 ERROR("couldn't erase block %i of flash bank at base 0x%x", i, bank->base);
403 return ERROR_FLASH_OPERATION_FAILED;
404 }
405 }
406
407 cfi_command(bank, 0xff, command);
408 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
409
410 return ERROR_OK;
411 }
412
413 int cfi_erase(struct flash_bank_s *bank, int first, int last)
414 {
415 cfi_flash_bank_t *cfi_info = bank->driver_priv;
416
417 if (cfi_info->target->state != TARGET_HALTED)
418 {
419 return ERROR_TARGET_NOT_HALTED;
420 }
421
422 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
423 {
424 return ERROR_FLASH_SECTOR_INVALID;
425 }
426
427 if (cfi_info->qry[0] != 'Q')
428 return ERROR_FLASH_BANK_NOT_PROBED;
429
430 switch(cfi_info->pri_id)
431 {
432 case 1:
433 case 3:
434 return cfi_intel_erase(bank, first, last);
435 break;
436 default:
437 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
438 break;
439 }
440
441 return ERROR_OK;
442 }
443
444 int cfi_intel_protect(struct flash_bank_s *bank, int set, int first, int last)
445 {
446 cfi_flash_bank_t *cfi_info = bank->driver_priv;
447 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
448 target_t *target = cfi_info->target;
449 u8 command[8];
450 int retry = 0;
451 int i;
452
453 /* if the device supports neither legacy lock/unlock (bit 3) nor
454 * instant individual block locking (bit 5).
455 */
456 if (!(pri_ext->feature_support & 0x28))
457 return ERROR_FLASH_OPERATION_FAILED;
458
459 cfi_intel_clear_status_register(bank);
460
461 for (i = first; i <= last; i++)
462 {
463 cfi_command(bank, 0x60, command);
464 DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank, i, 0x0), target_buffer_get_u32(target, command));
465 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
466 if (set)
467 {
468 cfi_command(bank, 0x01, command);
469 DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank, i, 0x0), target_buffer_get_u32(target, command));
470 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
471 bank->sectors[i].is_protected = 1;
472 }
473 else
474 {
475 cfi_command(bank, 0xd0, command);
476 DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank, i, 0x0), target_buffer_get_u32(target, command));
477 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
478 bank->sectors[i].is_protected = 0;
479 }
480
481 /* instant individual block locking doesn't require reading of the status register */
482 if (!(pri_ext->feature_support & 0x20))
483 {
484 /* Clear lock bits operation may take up to 1.4s */
485 cfi_intel_wait_status_busy(bank, 1400);
486 }
487 else
488 {
489 u8 block_status;
490 /* read block lock bit, to verify status */
491 cfi_command(bank, 0x90, command);
492 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
493 block_status = cfi_get_u8(bank, i, 0x2);
494
495 if ((block_status & 0x1) != set)
496 {
497 ERROR("couldn't change block lock status (set = %i, block_status = 0x%2.2x)", set, block_status);
498 cfi_command(bank, 0x70, command);
499 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
500 cfi_intel_wait_status_busy(bank, 10);
501
502 if (retry > 10)
503 return ERROR_FLASH_OPERATION_FAILED;
504 else
505 {
506 i--;
507 retry++;
508 }
509 }
510 }
511 }
512
513 /* if the device doesn't support individual block lock bits set/clear,
514 * all blocks have been unlocked in parallel, so we set those that should be protected
515 */
516 if ((!set) && (!(pri_ext->feature_support & 0x20)))
517 {
518 for (i = 0; i < bank->num_sectors; i++)
519 {
520 cfi_intel_clear_status_register(bank);
521 cfi_command(bank, 0x60, command);
522 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
523 if (bank->sectors[i].is_protected == 1)
524 {
525 cfi_command(bank, 0x01, command);
526 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
527 }
528
529 cfi_intel_wait_status_busy(bank, 100);
530 }
531 }
532
533 cfi_command(bank, 0xff, command);
534 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
535
536 return ERROR_OK;
537 }
538
539 int cfi_protect(struct flash_bank_s *bank, int set, int first, int last)
540 {
541 cfi_flash_bank_t *cfi_info = bank->driver_priv;
542
543 if (cfi_info->target->state != TARGET_HALTED)
544 {
545 return ERROR_TARGET_NOT_HALTED;
546 }
547
548 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
549 {
550 return ERROR_FLASH_SECTOR_INVALID;
551 }
552
553 if (cfi_info->qry[0] != 'Q')
554 return ERROR_FLASH_BANK_NOT_PROBED;
555
556 switch(cfi_info->pri_id)
557 {
558 case 1:
559 case 3:
560 cfi_intel_protect(bank, set, first, last);
561 break;
562 default:
563 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
564 break;
565 }
566
567 return ERROR_OK;
568 }
569
570 void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte)
571 {
572 cfi_flash_bank_t *cfi_info = bank->driver_priv;
573 target_t *target = cfi_info->target;
574
575 int i;
576
577 if (target->endianness == TARGET_LITTLE_ENDIAN)
578 {
579 /* shift bytes */
580 for (i = 0; i < bank->bus_width - 1; i++)
581 word[i] = word[i + 1];
582 word[bank->bus_width - 1] = byte;
583 }
584 else
585 {
586 /* shift bytes */
587 for (i = bank->bus_width - 1; i > 0; i--)
588 word[i] = word[i - 1];
589 word[0] = byte;
590 }
591 }
592
593 int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u32 count)
594 {
595 cfi_flash_bank_t *cfi_info = bank->driver_priv;
596 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
597 target_t *target = cfi_info->target;
598 reg_param_t reg_params[7];
599 armv4_5_algorithm_t armv4_5_info;
600 working_area_t *source;
601 u32 buffer_size = 32768;
602 u8 write_command[CFI_MAX_BUS_WIDTH];
603 u8 busy_pattern[CFI_MAX_BUS_WIDTH];
604 u8 error_pattern[CFI_MAX_BUS_WIDTH];
605 int i;
606 int retval;
607
608 /* algorithm register usage:
609 * r0: source address (in RAM)
610 * r1: target address (in Flash)
611 * r2: count
612 * r3: flash write command
613 * r4: status byte (returned to host)
614 * r5: busy test pattern
615 * r6: error test pattern
616 */
617
618 u32 word_32_code[] = {
619 0xe4904004, /* loop: ldr r4, [r0], #4 */
620 0xe5813000, /* str r3, [r1] */
621 0xe5814000, /* str r4, [r1] */
622 0xe5914000, /* busy: ldr r4, [r1] */
623 0xe0047005, /* and r7, r4, r5 */
624 0xe1570005, /* cmp r7, r5 */
625 0x1afffffb, /* bne busy */
626 0xe1140006, /* tst r4, r6 */
627 0x1a000003, /* bne done */
628 0xe2522001, /* subs r2, r2, #1 */
629 0x0a000001, /* beq done */
630 0xe2811004, /* add r1, r1 #4 */
631 0xeafffff2, /* b loop */
632 0xeafffffe, /* done: b -2 */
633 };
634
635 u32 word_16_code[] = {
636 0xe0d040b2, /* loop: ldrh r4, [r0], #2 */
637 0xe1c130b0, /* strh r3, [r1] */
638 0xe1c140b0, /* strh r4, [r1] */
639 0xe1d140b0, /* busy ldrh r4, [r1] */
640 0xe0047005, /* and r7, r4, r5 */
641 0xe1570005, /* cmp r7, r5 */
642 0x1afffffb, /* bne busy */
643 0xe1140006, /* tst r4, r6 */
644 0x1a000003, /* bne done */
645 0xe2522001, /* subs r2, r2, #1 */
646 0x0a000001, /* beq done */
647 0xe2811002, /* add r1, r1 #2 */
648 0xeafffff2, /* b loop */
649 0xeafffffe, /* done: b -2 */
650 };
651
652 u32 word_8_code[] = {
653 0xe4d04001, /* loop: ldrb r4, [r0], #1 */
654 0xe5c13000, /* strb r3, [r1] */
655 0xe5c14000, /* strb r4, [r1] */
656 0xe5d14000, /* busy ldrb r4, [r1] */
657 0xe0047005, /* and r7, r4, r5 */
658 0xe1570005, /* cmp r7, r5 */
659 0x1afffffb, /* bne busy */
660 0xe1140006, /* tst r4, r6 */
661 0x1a000003, /* bne done */
662 0xe2522001, /* subs r2, r2, #1 */
663 0x0a000001, /* beq done */
664 0xe2811001, /* add r1, r1 #1 */
665 0xeafffff2, /* b loop */
666 0xeafffffe, /* done: b -2 */
667 };
668
669 cfi_intel_clear_status_register(bank);
670
671 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
672 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
673 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
674
675 /* flash write code */
676 if (!cfi_info->write_algorithm)
677 {
678 if (target_alloc_working_area(target, 4 * 14, &cfi_info->write_algorithm) != ERROR_OK)
679 {
680 WARNING("no working area available, can't do block memory writes");
681 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
682 };
683
684 /* write algorithm code to working area */
685 if (bank->bus_width == 1)
686 {
687 target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_8_code);
688 }
689 else if (bank->bus_width == 2)
690 {
691 target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_16_code);
692 }
693 else if (bank->bus_width == 4)
694 {
695 target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_32_code);
696 }
697 else
698 {
699 return ERROR_FLASH_OPERATION_FAILED;
700 }
701 }
702
703 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
704 {
705 buffer_size /= 2;
706 if (buffer_size <= 256)
707 {
708 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
709 if (cfi_info->write_algorithm)
710 target_free_working_area(target, cfi_info->write_algorithm);
711
712 WARNING("no large enough working area available, can't do block memory writes");
713 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
714 }
715 };
716
717 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
718 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
719 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
720 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
721 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
722 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
723 init_reg_param(&reg_params[6], "r6", 32, PARAM_OUT);
724
725 cfi_command(bank, 0x40, write_command);
726 cfi_command(bank, 0x80, busy_pattern);
727 cfi_command(bank, 0x7e, error_pattern);
728
729 while (count > 0)
730 {
731 u32 thisrun_count = (count > buffer_size) ? buffer_size : count;
732
733 target_write_buffer(target, source->address, thisrun_count, buffer);
734
735 buf_set_u32(reg_params[0].value, 0, 32, source->address);
736 buf_set_u32(reg_params[1].value, 0, 32, address);
737 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width);
738 buf_set_u32(reg_params[3].value, 0, 32, target_buffer_get_u32(target, write_command));
739 buf_set_u32(reg_params[5].value, 0, 32, target_buffer_get_u32(target, busy_pattern));
740 buf_set_u32(reg_params[6].value, 0, 32, target_buffer_get_u32(target, error_pattern));
741
742 if ((retval = target->type->run_algorithm(target, 0, NULL, 7, reg_params, cfi_info->write_algorithm->address, cfi_info->write_algorithm->address + (13 * 4), 10000, &armv4_5_info)) != ERROR_OK)
743 {
744 cfi_intel_clear_status_register(bank);
745 return ERROR_FLASH_OPERATION_FAILED;
746 }
747
748 if (buf_get_u32(reg_params[4].value, 0, 32) & target_buffer_get_u32(target, error_pattern))
749 {
750 /* read status register (outputs debug inforation) */
751 cfi_intel_wait_status_busy(bank, 100);
752 cfi_intel_clear_status_register(bank);
753 return ERROR_FLASH_OPERATION_FAILED;
754 }
755
756 buffer += thisrun_count;
757 address += thisrun_count;
758 count -= thisrun_count;
759 }
760
761 target_free_working_area(target, source);
762
763 destroy_reg_param(&reg_params[0]);
764 destroy_reg_param(&reg_params[1]);
765 destroy_reg_param(&reg_params[2]);
766 destroy_reg_param(&reg_params[3]);
767 destroy_reg_param(&reg_params[4]);
768 destroy_reg_param(&reg_params[5]);
769 destroy_reg_param(&reg_params[6]);
770
771 return ERROR_OK;
772 }
773
774 int cfi_intel_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
775 {
776 cfi_flash_bank_t *cfi_info = bank->driver_priv;
777 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
778 target_t *target = cfi_info->target;
779 u8 command[8];
780
781 cfi_intel_clear_status_register(bank);
782 cfi_command(bank, 0x40, command);
783 target->type->write_memory(target, address, bank->bus_width, 1, command);
784
785 target->type->write_memory(target, address, bank->bus_width, 1, word);
786
787 if (cfi_intel_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != 0x80)
788 {
789 cfi_command(bank, 0xff, command);
790 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
791
792 ERROR("couldn't write word at base 0x%x, address %x", bank->base, address);
793 return ERROR_FLASH_OPERATION_FAILED;
794 }
795
796 return ERROR_OK;
797 }
798
799 int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
800 {
801 cfi_flash_bank_t *cfi_info = bank->driver_priv;
802 target_t *target = cfi_info->target;
803
804 switch(cfi_info->pri_id)
805 {
806 case 1:
807 case 3:
808 return cfi_intel_write_word(bank, word, address);
809 break;
810 default:
811 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
812 break;
813 }
814
815 return ERROR_FLASH_OPERATION_FAILED;
816 }
817
818 int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
819 {
820 cfi_flash_bank_t *cfi_info = bank->driver_priv;
821 target_t *target = cfi_info->target;
822 u32 address = bank->base + offset; /* address of first byte to be programmed */
823 u32 write_p, copy_p;
824 int align; /* number of unaligned bytes */
825 u8 current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being programmed */
826 int i;
827 int retval;
828
829 if (cfi_info->target->state != TARGET_HALTED)
830 {
831 return ERROR_TARGET_NOT_HALTED;
832 }
833
834 if (offset + count > bank->size)
835 return ERROR_FLASH_DST_OUT_OF_BANK;
836
837 if (cfi_info->qry[0] != 'Q')
838 return ERROR_FLASH_BANK_NOT_PROBED;
839
840 /* start at the first byte of the first word (bus_width size) */
841 write_p = address & ~(bank->bus_width - 1);
842 if ((align = address - write_p) != 0)
843 {
844 for (i = 0; i < bank->bus_width; i++)
845 current_word[i] = 0;
846 copy_p = write_p;
847
848 /* copy bytes before the first write address */
849 for (i = 0; i < align; ++i, ++copy_p)
850 {
851 u8 byte;
852 target->type->read_memory(target, copy_p, 1, 1, &byte);
853 cfi_add_byte(bank, current_word, byte);
854 }
855
856 /* add bytes from the buffer */
857 for (; (i < bank->bus_width) && (count > 0); i++)
858 {
859 cfi_add_byte(bank, current_word, *buffer++);
860 count--;
861 copy_p++;
862 }
863
864 /* if the buffer is already finished, copy bytes after the last write address */
865 for (; (count == 0) && (i < bank->bus_width); ++i, ++copy_p)
866 {
867 u8 byte;
868 target->type->read_memory(target, copy_p, 1, 1, &byte);
869 cfi_add_byte(bank, current_word, byte);
870 }
871
872 retval = cfi_write_word(bank, current_word, write_p);
873 if (retval != ERROR_OK)
874 return retval;
875 write_p = copy_p;
876 }
877
878 /* handle blocks of bus_size aligned bytes */
879 switch(cfi_info->pri_id)
880 {
881 /* try block writes (fails without working area) */
882 case 1:
883 case 3:
884 retval = cfi_intel_write_block(bank, buffer, write_p, count);
885 break;
886 default:
887 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
888 break;
889 }
890 if (retval != ERROR_OK)
891 {
892 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
893 {
894 /* fall back to memory writes */
895 while (count > bank->bus_width)
896 {
897 for (i = 0; i < bank->bus_width; i++)
898 current_word[i] = 0;
899
900 for (i = 0; i < bank->bus_width; i++)
901 {
902 cfi_add_byte(bank, current_word, *buffer++);
903 }
904
905 retval = cfi_write_word(bank, current_word, write_p);
906 if (retval != ERROR_OK)
907 return retval;
908 write_p += bank->bus_width;
909 count -= bank->bus_width;
910 }
911 }
912 else
913 return retval;
914 }
915
916 /* handle unaligned tail bytes */
917 if (count > 0)
918 {
919 copy_p = write_p;
920 for (i = 0; i < bank->bus_width; i++)
921 current_word[i] = 0;
922
923 for (i = 0; (i < bank->bus_width) && (count > 0); ++i, ++copy_p)
924 {
925 cfi_add_byte(bank, current_word, *buffer++);
926 count--;
927 }
928 for (; i < bank->bus_width; ++i, ++copy_p)
929 {
930 u8 byte;
931 target->type->read_memory(target, copy_p, 1, 1, &byte);
932 cfi_add_byte(bank, current_word, byte);
933 }
934 retval = cfi_write_word(bank, current_word, write_p);
935 if (retval != ERROR_OK)
936 return retval;
937 }
938
939 /* return to read array mode */
940 cfi_command(bank, 0xf0, current_word);
941 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
942 cfi_command(bank, 0xff, current_word);
943 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
944
945 return ERROR_OK;
946 }
947
948 int cfi_probe(struct flash_bank_s *bank)
949 {
950 cfi_flash_bank_t *cfi_info = bank->driver_priv;
951 target_t *target = cfi_info->target;
952 u8 command[8];
953
954
955 cfi_command(bank, 0x98, command);
956 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
957
958 cfi_info->qry[0] = cfi_query_u8(bank, 0, 0x10);
959 cfi_info->qry[1] = cfi_query_u8(bank, 0, 0x11);
960 cfi_info->qry[2] = cfi_query_u8(bank, 0, 0x12);
961
962 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]);
963
964 if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y'))
965 {
966 cfi_command(bank, 0xf0, command);
967 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
968 cfi_command(bank, 0xff, command);
969 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
970 return ERROR_FLASH_BANK_INVALID;
971 }
972
973 cfi_info->pri_id = cfi_query_u16(bank, 0, 0x13);
974 cfi_info->pri_addr = cfi_query_u16(bank, 0, 0x15);
975 cfi_info->alt_id = cfi_query_u16(bank, 0, 0x17);
976 cfi_info->alt_addr = cfi_query_u16(bank, 0, 0x19);
977
978 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);
979
980 cfi_info->vcc_min = cfi_query_u8(bank, 0, 0x1b);
981 cfi_info->vcc_max = cfi_query_u8(bank, 0, 0x1c);
982 cfi_info->vpp_min = cfi_query_u8(bank, 0, 0x1d);
983 cfi_info->vpp_max = cfi_query_u8(bank, 0, 0x1e);
984 cfi_info->word_write_timeout_typ = cfi_query_u8(bank, 0, 0x1f);
985 cfi_info->buf_write_timeout_typ = cfi_query_u8(bank, 0, 0x20);
986 cfi_info->block_erase_timeout_typ = cfi_query_u8(bank, 0, 0x21);
987 cfi_info->chip_erase_timeout_typ = cfi_query_u8(bank, 0, 0x22);
988 cfi_info->word_write_timeout_max = cfi_query_u8(bank, 0, 0x23);
989 cfi_info->buf_write_timeout_max = cfi_query_u8(bank, 0, 0x24);
990 cfi_info->block_erase_timeout_max = cfi_query_u8(bank, 0, 0x25);
991 cfi_info->chip_erase_timeout_max = cfi_query_u8(bank, 0, 0x26);
992
993 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",
994 (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,
995 (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,
996 (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,
997 (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);
998 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,
999 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);
1000 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),
1001 (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),
1002 (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
1003 (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
1004
1005 cfi_info->dev_size = cfi_query_u8(bank, 0, 0x27);
1006 cfi_info->interface_desc = cfi_query_u16(bank, 0, 0x28);
1007 cfi_info->max_buf_write_size = cfi_query_u16(bank, 0, 0x2a);
1008 cfi_info->num_erase_regions = cfi_query_u8(bank, 0, 0x2c);
1009
1010 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));
1011
1012 if (((1 << cfi_info->dev_size) * bank->bus_width / bank->chip_width) != bank->size)
1013 {
1014 WARNING("configuration specifies 0x%x size, but a 0x%x size flash was found", bank->size, 1 << cfi_info->dev_size);
1015 }
1016
1017 if (cfi_info->num_erase_regions)
1018 {
1019 int i;
1020 int num_sectors = 0;
1021 int sector = 0;
1022 u32 offset = 0;
1023 cfi_info->erase_region_info = malloc(4 * cfi_info->num_erase_regions);
1024
1025 for (i = 0; i < cfi_info->num_erase_regions; i++)
1026 {
1027 cfi_info->erase_region_info[i] = cfi_query_u32(bank, 0, 0x2d + (4 * i));
1028 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);
1029
1030 num_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1;
1031 }
1032
1033 bank->num_sectors = num_sectors;
1034 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
1035 for (i = 0; i < cfi_info->num_erase_regions; i++)
1036 {
1037 int j;
1038 for (j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++)
1039 {
1040 bank->sectors[sector].offset = offset;
1041 bank->sectors[sector].size = ((cfi_info->erase_region_info[i] >> 16) * 256) * bank->bus_width / bank->chip_width;
1042 offset += bank->sectors[sector].size;
1043 bank->sectors[sector].is_erased = -1;
1044 bank->sectors[sector].is_protected = -1;
1045 sector++;
1046 }
1047 }
1048 }
1049 else
1050 {
1051 cfi_info->erase_region_info = NULL;
1052 }
1053
1054 switch(cfi_info->pri_id)
1055 {
1056 case 1:
1057 case 3:
1058 cfi_read_intel_pri_ext(bank);
1059 break;
1060 default:
1061 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
1062 break;
1063 }
1064
1065 /* return to read array mode */
1066 cfi_command(bank, 0xf0, command);
1067 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
1068 cfi_command(bank, 0xff, command);
1069 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
1070
1071 return ERROR_OK;
1072 }
1073
1074 int cfi_erase_check(struct flash_bank_s *bank)
1075 {
1076 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1077 target_t *target = cfi_info->target;
1078 int i;
1079 int retval;
1080
1081 if (!cfi_info->erase_check_algorithm)
1082 {
1083 u32 erase_check_code[] =
1084 {
1085 0xe4d03001, /* ldrb r3, [r0], #1 */
1086 0xe0022003, /* and r2, r2, r3 */
1087 0xe2511001, /* subs r1, r1, #1 */
1088 0x1afffffb, /* b -4 */
1089 0xeafffffe /* b 0 */
1090 };
1091
1092 /* make sure we have a working area */
1093 if (target_alloc_working_area(target, 20, &cfi_info->erase_check_algorithm) != ERROR_OK)
1094 {
1095 WARNING("no working area available, falling back to slow memory reads");
1096 }
1097 else
1098 {
1099 u8 erase_check_code_buf[5 * 4];
1100
1101 for (i = 0; i < 5; i++)
1102 target_buffer_set_u32(target, erase_check_code_buf + (i*4), erase_check_code[i]);
1103
1104 /* write algorithm code to working area */
1105 target->type->write_memory(target, cfi_info->erase_check_algorithm->address, 4, 5, erase_check_code_buf);
1106 }
1107 }
1108
1109 if (!cfi_info->erase_check_algorithm)
1110 {
1111 u32 *buffer = malloc(4096);
1112
1113 for (i = 0; i < bank->num_sectors; i++)
1114 {
1115 u32 address = bank->base + bank->sectors[i].offset;
1116 u32 size = bank->sectors[i].size;
1117 u32 check = 0xffffffffU;
1118 int erased = 1;
1119
1120 while (size > 0)
1121 {
1122 u32 thisrun_size = (size > 4096) ? 4096 : size;
1123 int j;
1124
1125 target->type->read_memory(target, address, 4, thisrun_size / 4, (u8*)buffer);
1126
1127 for (j = 0; j < thisrun_size / 4; j++)
1128 check &= buffer[j];
1129
1130 if (check != 0xffffffff)
1131 {
1132 erased = 0;
1133 break;
1134 }
1135
1136 size -= thisrun_size;
1137 address += thisrun_size;
1138 }
1139
1140 bank->sectors[i].is_erased = erased;
1141 }
1142
1143 free(buffer);
1144 }
1145 else
1146 {
1147 for (i = 0; i < bank->num_sectors; i++)
1148 {
1149 u32 address = bank->base + bank->sectors[i].offset;
1150 u32 size = bank->sectors[i].size;
1151
1152 reg_param_t reg_params[3];
1153 armv4_5_algorithm_t armv4_5_info;
1154
1155 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1156 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1157 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1158
1159 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1160 buf_set_u32(reg_params[0].value, 0, 32, address);
1161
1162 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1163 buf_set_u32(reg_params[1].value, 0, 32, size);
1164
1165 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1166 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1167
1168 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, cfi_info->erase_check_algorithm->address, cfi_info->erase_check_algorithm->address + 0x10, 10000, &armv4_5_info)) != ERROR_OK)
1169 return ERROR_FLASH_OPERATION_FAILED;
1170
1171 if (buf_get_u32(reg_params[2].value, 0, 32) == 0xff)
1172 bank->sectors[i].is_erased = 1;
1173 else
1174 bank->sectors[i].is_erased = 0;
1175
1176 destroy_reg_param(&reg_params[0]);
1177 destroy_reg_param(&reg_params[1]);
1178 destroy_reg_param(&reg_params[2]);
1179 }
1180 }
1181
1182 return ERROR_OK;
1183 }
1184
1185 int cfi_intel_protect_check(struct flash_bank_s *bank)
1186 {
1187 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1188 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
1189 target_t *target = cfi_info->target;
1190 u8 command[CFI_MAX_BUS_WIDTH];
1191 int i;
1192
1193 /* check if block lock bits are supported on this device */
1194 if (!(pri_ext->blk_status_reg_mask & 0x1))
1195 return ERROR_FLASH_OPERATION_FAILED;
1196
1197 cfi_command(bank, 0x90, command);
1198 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
1199
1200 for (i = 0; i < bank->num_sectors; i++)
1201 {
1202 u8 block_status = cfi_get_u8(bank, i, 0x2);
1203
1204 if (block_status & 1)
1205 bank->sectors[i].is_protected = 1;
1206 else
1207 bank->sectors[i].is_protected = 0;
1208 }
1209
1210 cfi_command(bank, 0xff, command);
1211 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
1212
1213 return ERROR_OK;
1214 }
1215
1216 int cfi_protect_check(struct flash_bank_s *bank)
1217 {
1218 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1219 target_t *target = cfi_info->target;
1220
1221 if (cfi_info->qry[0] != 'Q')
1222 return ERROR_FLASH_BANK_NOT_PROBED;
1223
1224 switch(cfi_info->pri_id)
1225 {
1226 case 1:
1227 case 3:
1228 return cfi_intel_protect_check(bank);
1229 break;
1230 default:
1231 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
1232 break;
1233 }
1234
1235 return ERROR_OK;
1236 }
1237
1238 int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
1239 {
1240 int printed;
1241 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1242
1243 if (cfi_info->qry[0] == -1)
1244 {
1245 printed = snprintf(buf, buf_size, "\ncfi flash bank not probed yet\n");
1246 return ERROR_OK;
1247 }
1248
1249 printed = snprintf(buf, buf_size, "\ncfi information:\n");
1250 buf += printed;
1251 buf_size -= printed;
1252
1253 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);
1254 buf += printed;
1255 buf_size -= printed;
1256
1257 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", (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,
1258 (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,
1259 (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,
1260 (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);
1261 buf += printed;
1262 buf_size -= printed;
1263
1264 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", 1 << cfi_info->word_write_timeout_typ, 1 << cfi_info->buf_write_timeout_typ,
1265 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);
1266 buf += printed;
1267 buf_size -= printed;
1268
1269 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", (1 << cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ),
1270 (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),
1271 (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
1272 (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
1273 buf += printed;
1274 buf_size -= printed;
1275
1276 printed = snprintf(buf, buf_size, "size: 0x%x, interface desc: %i, max buffer write size: %x\n", 1 << cfi_info->dev_size, cfi_info->interface_desc, cfi_info->max_buf_write_size);
1277 buf += printed;
1278 buf_size -= printed;
1279
1280 switch(cfi_info->pri_id)
1281 {
1282 case 1:
1283 case 3:
1284 cfi_intel_info(bank, buf, buf_size);
1285 break;
1286 default:
1287 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
1288 break;
1289 }
1290
1291 return ERROR_OK;
1292 }

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)