- fixed arm926 cp15 command bug (thanks to Vincent Palatin for this patch)
[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 '%s' 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 target_t *target = cfi_info->target;
381 u8 command[8];
382 int i;
383
384 cfi_intel_clear_status_register(bank);
385
386 for (i = first; i <= last; i++)
387 {
388 cfi_command(bank, 0x20, command);
389 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
390
391 cfi_command(bank, 0xd0, command);
392 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
393
394 if (cfi_intel_wait_status_busy(bank, 1000 * (1 << cfi_info->block_erase_timeout_typ)) == 0x80)
395 bank->sectors[i].is_erased = 1;
396 else
397 {
398 cfi_command(bank, 0xff, command);
399 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
400
401 ERROR("couldn't erase block %i of flash bank at base 0x%x", i, bank->base);
402 return ERROR_FLASH_OPERATION_FAILED;
403 }
404 }
405
406 cfi_command(bank, 0xff, command);
407 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
408
409 return ERROR_OK;
410 }
411
412 int cfi_erase(struct flash_bank_s *bank, int first, int last)
413 {
414 cfi_flash_bank_t *cfi_info = bank->driver_priv;
415
416 if (cfi_info->target->state != TARGET_HALTED)
417 {
418 return ERROR_TARGET_NOT_HALTED;
419 }
420
421 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
422 {
423 return ERROR_FLASH_SECTOR_INVALID;
424 }
425
426 if (cfi_info->qry[0] != 'Q')
427 return ERROR_FLASH_BANK_NOT_PROBED;
428
429 switch(cfi_info->pri_id)
430 {
431 case 1:
432 case 3:
433 return cfi_intel_erase(bank, first, last);
434 break;
435 default:
436 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
437 break;
438 }
439
440 return ERROR_OK;
441 }
442
443 int cfi_intel_protect(struct flash_bank_s *bank, int set, int first, int last)
444 {
445 cfi_flash_bank_t *cfi_info = bank->driver_priv;
446 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
447 target_t *target = cfi_info->target;
448 u8 command[8];
449 int retry = 0;
450 int i;
451
452 /* if the device supports neither legacy lock/unlock (bit 3) nor
453 * instant individual block locking (bit 5).
454 */
455 if (!(pri_ext->feature_support & 0x28))
456 return ERROR_FLASH_OPERATION_FAILED;
457
458 cfi_intel_clear_status_register(bank);
459
460 for (i = first; i <= last; i++)
461 {
462 cfi_command(bank, 0x60, command);
463 DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank, i, 0x0), target_buffer_get_u32(target, command));
464 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
465 if (set)
466 {
467 cfi_command(bank, 0x01, command);
468 DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank, i, 0x0), target_buffer_get_u32(target, command));
469 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
470 bank->sectors[i].is_protected = 1;
471 }
472 else
473 {
474 cfi_command(bank, 0xd0, command);
475 DEBUG("address: 0x%4.4x, command: 0x%4.4x", flash_address(bank, i, 0x0), target_buffer_get_u32(target, command));
476 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
477 bank->sectors[i].is_protected = 0;
478 }
479
480 /* instant individual block locking doesn't require reading of the status register */
481 if (!(pri_ext->feature_support & 0x20))
482 {
483 /* Clear lock bits operation may take up to 1.4s */
484 cfi_intel_wait_status_busy(bank, 1400);
485 }
486 else
487 {
488 u8 block_status;
489 /* read block lock bit, to verify status */
490 cfi_command(bank, 0x90, command);
491 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
492 block_status = cfi_get_u8(bank, i, 0x2);
493
494 if ((block_status & 0x1) != set)
495 {
496 ERROR("couldn't change block lock status (set = %i, block_status = 0x%2.2x)", set, block_status);
497 cfi_command(bank, 0x70, command);
498 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
499 cfi_intel_wait_status_busy(bank, 10);
500
501 if (retry > 10)
502 return ERROR_FLASH_OPERATION_FAILED;
503 else
504 {
505 i--;
506 retry++;
507 }
508 }
509 }
510 }
511
512 /* if the device doesn't support individual block lock bits set/clear,
513 * all blocks have been unlocked in parallel, so we set those that should be protected
514 */
515 if ((!set) && (!(pri_ext->feature_support & 0x20)))
516 {
517 for (i = 0; i < bank->num_sectors; i++)
518 {
519 cfi_intel_clear_status_register(bank);
520 cfi_command(bank, 0x60, command);
521 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
522 if (bank->sectors[i].is_protected == 1)
523 {
524 cfi_command(bank, 0x01, command);
525 target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
526 }
527
528 cfi_intel_wait_status_busy(bank, 100);
529 }
530 }
531
532 cfi_command(bank, 0xff, command);
533 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
534
535 return ERROR_OK;
536 }
537
538 int cfi_protect(struct flash_bank_s *bank, int set, int first, int last)
539 {
540 cfi_flash_bank_t *cfi_info = bank->driver_priv;
541
542 if (cfi_info->target->state != TARGET_HALTED)
543 {
544 return ERROR_TARGET_NOT_HALTED;
545 }
546
547 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
548 {
549 return ERROR_FLASH_SECTOR_INVALID;
550 }
551
552 if (cfi_info->qry[0] != 'Q')
553 return ERROR_FLASH_BANK_NOT_PROBED;
554
555 switch(cfi_info->pri_id)
556 {
557 case 1:
558 case 3:
559 cfi_intel_protect(bank, set, first, last);
560 break;
561 default:
562 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
563 break;
564 }
565
566 return ERROR_OK;
567 }
568
569 void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte)
570 {
571 cfi_flash_bank_t *cfi_info = bank->driver_priv;
572 target_t *target = cfi_info->target;
573
574 int i;
575
576 if (target->endianness == TARGET_LITTLE_ENDIAN)
577 {
578 /* shift bytes */
579 for (i = 0; i < bank->bus_width - 1; i++)
580 word[i] = word[i + 1];
581 word[bank->bus_width - 1] = byte;
582 }
583 else
584 {
585 /* shift bytes */
586 for (i = bank->bus_width - 1; i > 0; i--)
587 word[i] = word[i - 1];
588 word[0] = byte;
589 }
590 }
591
592 int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u32 count)
593 {
594 cfi_flash_bank_t *cfi_info = bank->driver_priv;
595 target_t *target = cfi_info->target;
596 reg_param_t reg_params[7];
597 armv4_5_algorithm_t armv4_5_info;
598 working_area_t *source;
599 u32 buffer_size = 32768;
600 u8 write_command[CFI_MAX_BUS_WIDTH];
601 u8 busy_pattern[CFI_MAX_BUS_WIDTH];
602 u8 error_pattern[CFI_MAX_BUS_WIDTH];
603 int retval;
604
605 /* algorithm register usage:
606 * r0: source address (in RAM)
607 * r1: target address (in Flash)
608 * r2: count
609 * r3: flash write command
610 * r4: status byte (returned to host)
611 * r5: busy test pattern
612 * r6: error test pattern
613 */
614
615 u32 word_32_code[] = {
616 0xe4904004, /* loop: ldr r4, [r0], #4 */
617 0xe5813000, /* str r3, [r1] */
618 0xe5814000, /* str r4, [r1] */
619 0xe5914000, /* busy: ldr r4, [r1] */
620 0xe0047005, /* and r7, r4, r5 */
621 0xe1570005, /* cmp r7, r5 */
622 0x1afffffb, /* bne busy */
623 0xe1140006, /* tst r4, r6 */
624 0x1a000003, /* bne done */
625 0xe2522001, /* subs r2, r2, #1 */
626 0x0a000001, /* beq done */
627 0xe2811004, /* add r1, r1 #4 */
628 0xeafffff2, /* b loop */
629 0xeafffffe, /* done: b -2 */
630 };
631
632 u32 word_16_code[] = {
633 0xe0d040b2, /* loop: ldrh r4, [r0], #2 */
634 0xe1c130b0, /* strh r3, [r1] */
635 0xe1c140b0, /* strh r4, [r1] */
636 0xe1d140b0, /* busy ldrh r4, [r1] */
637 0xe0047005, /* and r7, r4, r5 */
638 0xe1570005, /* cmp r7, r5 */
639 0x1afffffb, /* bne busy */
640 0xe1140006, /* tst r4, r6 */
641 0x1a000003, /* bne done */
642 0xe2522001, /* subs r2, r2, #1 */
643 0x0a000001, /* beq done */
644 0xe2811002, /* add r1, r1 #2 */
645 0xeafffff2, /* b loop */
646 0xeafffffe, /* done: b -2 */
647 };
648
649 u32 word_8_code[] = {
650 0xe4d04001, /* loop: ldrb r4, [r0], #1 */
651 0xe5c13000, /* strb r3, [r1] */
652 0xe5c14000, /* strb r4, [r1] */
653 0xe5d14000, /* busy ldrb r4, [r1] */
654 0xe0047005, /* and r7, r4, r5 */
655 0xe1570005, /* cmp r7, r5 */
656 0x1afffffb, /* bne busy */
657 0xe1140006, /* tst r4, r6 */
658 0x1a000003, /* bne done */
659 0xe2522001, /* subs r2, r2, #1 */
660 0x0a000001, /* beq done */
661 0xe2811001, /* add r1, r1 #1 */
662 0xeafffff2, /* b loop */
663 0xeafffffe, /* done: b -2 */
664 };
665
666 cfi_intel_clear_status_register(bank);
667
668 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
669 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
670 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
671
672 /* flash write code */
673 if (!cfi_info->write_algorithm)
674 {
675 if (target_alloc_working_area(target, 4 * 14, &cfi_info->write_algorithm) != ERROR_OK)
676 {
677 WARNING("no working area available, can't do block memory writes");
678 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
679 };
680
681 /* write algorithm code to working area */
682 if (bank->bus_width == 1)
683 {
684 target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_8_code);
685 }
686 else if (bank->bus_width == 2)
687 {
688 target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_16_code);
689 }
690 else if (bank->bus_width == 4)
691 {
692 target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_32_code);
693 }
694 else
695 {
696 return ERROR_FLASH_OPERATION_FAILED;
697 }
698 }
699
700 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
701 {
702 buffer_size /= 2;
703 if (buffer_size <= 256)
704 {
705 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
706 if (cfi_info->write_algorithm)
707 target_free_working_area(target, cfi_info->write_algorithm);
708
709 WARNING("no large enough working area available, can't do block memory writes");
710 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
711 }
712 };
713
714 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
715 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
716 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
717 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
718 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
719 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
720 init_reg_param(&reg_params[6], "r6", 32, PARAM_OUT);
721
722 cfi_command(bank, 0x40, write_command);
723 cfi_command(bank, 0x80, busy_pattern);
724 cfi_command(bank, 0x7e, error_pattern);
725
726 while (count > 0)
727 {
728 u32 thisrun_count = (count > buffer_size) ? buffer_size : count;
729
730 target_write_buffer(target, source->address, thisrun_count, buffer);
731
732 buf_set_u32(reg_params[0].value, 0, 32, source->address);
733 buf_set_u32(reg_params[1].value, 0, 32, address);
734 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width);
735 buf_set_u32(reg_params[3].value, 0, 32, target_buffer_get_u32(target, write_command));
736 buf_set_u32(reg_params[5].value, 0, 32, target_buffer_get_u32(target, busy_pattern));
737 buf_set_u32(reg_params[6].value, 0, 32, target_buffer_get_u32(target, error_pattern));
738
739 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)
740 {
741 cfi_intel_clear_status_register(bank);
742 return ERROR_FLASH_OPERATION_FAILED;
743 }
744
745 if (buf_get_u32(reg_params[4].value, 0, 32) & target_buffer_get_u32(target, error_pattern))
746 {
747 /* read status register (outputs debug inforation) */
748 cfi_intel_wait_status_busy(bank, 100);
749 cfi_intel_clear_status_register(bank);
750 return ERROR_FLASH_OPERATION_FAILED;
751 }
752
753 buffer += thisrun_count;
754 address += thisrun_count;
755 count -= thisrun_count;
756 }
757
758 target_free_working_area(target, source);
759
760 destroy_reg_param(&reg_params[0]);
761 destroy_reg_param(&reg_params[1]);
762 destroy_reg_param(&reg_params[2]);
763 destroy_reg_param(&reg_params[3]);
764 destroy_reg_param(&reg_params[4]);
765 destroy_reg_param(&reg_params[5]);
766 destroy_reg_param(&reg_params[6]);
767
768 return ERROR_OK;
769 }
770
771 int cfi_intel_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
772 {
773 cfi_flash_bank_t *cfi_info = bank->driver_priv;
774 target_t *target = cfi_info->target;
775 u8 command[8];
776
777 cfi_intel_clear_status_register(bank);
778 cfi_command(bank, 0x40, command);
779 target->type->write_memory(target, address, bank->bus_width, 1, command);
780
781 target->type->write_memory(target, address, bank->bus_width, 1, word);
782
783 if (cfi_intel_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != 0x80)
784 {
785 cfi_command(bank, 0xff, command);
786 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
787
788 ERROR("couldn't write word at base 0x%x, address %x", bank->base, address);
789 return ERROR_FLASH_OPERATION_FAILED;
790 }
791
792 return ERROR_OK;
793 }
794
795 int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
796 {
797 cfi_flash_bank_t *cfi_info = bank->driver_priv;
798
799 switch(cfi_info->pri_id)
800 {
801 case 1:
802 case 3:
803 return cfi_intel_write_word(bank, word, address);
804 break;
805 default:
806 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
807 break;
808 }
809
810 return ERROR_FLASH_OPERATION_FAILED;
811 }
812
813 int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
814 {
815 cfi_flash_bank_t *cfi_info = bank->driver_priv;
816 target_t *target = cfi_info->target;
817 u32 address = bank->base + offset; /* address of first byte to be programmed */
818 u32 write_p, copy_p;
819 int align; /* number of unaligned bytes */
820 u8 current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being programmed */
821 int i;
822 int retval;
823
824 if (cfi_info->target->state != TARGET_HALTED)
825 {
826 return ERROR_TARGET_NOT_HALTED;
827 }
828
829 if (offset + count > bank->size)
830 return ERROR_FLASH_DST_OUT_OF_BANK;
831
832 if (cfi_info->qry[0] != 'Q')
833 return ERROR_FLASH_BANK_NOT_PROBED;
834
835 /* start at the first byte of the first word (bus_width size) */
836 write_p = address & ~(bank->bus_width - 1);
837 if ((align = address - write_p) != 0)
838 {
839 for (i = 0; i < bank->bus_width; i++)
840 current_word[i] = 0;
841 copy_p = write_p;
842
843 /* copy bytes before the first write address */
844 for (i = 0; i < align; ++i, ++copy_p)
845 {
846 u8 byte;
847 target->type->read_memory(target, copy_p, 1, 1, &byte);
848 cfi_add_byte(bank, current_word, byte);
849 }
850
851 /* add bytes from the buffer */
852 for (; (i < bank->bus_width) && (count > 0); i++)
853 {
854 cfi_add_byte(bank, current_word, *buffer++);
855 count--;
856 copy_p++;
857 }
858
859 /* if the buffer is already finished, copy bytes after the last write address */
860 for (; (count == 0) && (i < bank->bus_width); ++i, ++copy_p)
861 {
862 u8 byte;
863 target->type->read_memory(target, copy_p, 1, 1, &byte);
864 cfi_add_byte(bank, current_word, byte);
865 }
866
867 retval = cfi_write_word(bank, current_word, write_p);
868 if (retval != ERROR_OK)
869 return retval;
870 write_p = copy_p;
871 }
872
873 /* handle blocks of bus_size aligned bytes */
874 switch(cfi_info->pri_id)
875 {
876 /* try block writes (fails without working area) */
877 case 1:
878 case 3:
879 retval = cfi_intel_write_block(bank, buffer, write_p, count);
880 break;
881 default:
882 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
883 retval = ERROR_FLASH_OPERATION_FAILED;
884 break;
885 }
886 if (retval != ERROR_OK)
887 {
888 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
889 {
890 /* fall back to memory writes */
891 while (count > bank->bus_width)
892 {
893 for (i = 0; i < bank->bus_width; i++)
894 current_word[i] = 0;
895
896 for (i = 0; i < bank->bus_width; i++)
897 {
898 cfi_add_byte(bank, current_word, *buffer++);
899 }
900
901 retval = cfi_write_word(bank, current_word, write_p);
902 if (retval != ERROR_OK)
903 return retval;
904 write_p += bank->bus_width;
905 count -= bank->bus_width;
906 }
907 }
908 else
909 return retval;
910 }
911
912 /* handle unaligned tail bytes */
913 if (count > 0)
914 {
915 copy_p = write_p;
916 for (i = 0; i < bank->bus_width; i++)
917 current_word[i] = 0;
918
919 for (i = 0; (i < bank->bus_width) && (count > 0); ++i, ++copy_p)
920 {
921 cfi_add_byte(bank, current_word, *buffer++);
922 count--;
923 }
924 for (; i < bank->bus_width; ++i, ++copy_p)
925 {
926 u8 byte;
927 target->type->read_memory(target, copy_p, 1, 1, &byte);
928 cfi_add_byte(bank, current_word, byte);
929 }
930 retval = cfi_write_word(bank, current_word, write_p);
931 if (retval != ERROR_OK)
932 return retval;
933 }
934
935 /* return to read array mode */
936 cfi_command(bank, 0xf0, current_word);
937 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
938 cfi_command(bank, 0xff, current_word);
939 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
940
941 return ERROR_OK;
942 }
943
944 int cfi_probe(struct flash_bank_s *bank)
945 {
946 cfi_flash_bank_t *cfi_info = bank->driver_priv;
947 target_t *target = cfi_info->target;
948 u8 command[8];
949
950
951 cfi_command(bank, 0x98, command);
952 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
953
954 cfi_info->qry[0] = cfi_query_u8(bank, 0, 0x10);
955 cfi_info->qry[1] = cfi_query_u8(bank, 0, 0x11);
956 cfi_info->qry[2] = cfi_query_u8(bank, 0, 0x12);
957
958 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]);
959
960 if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y'))
961 {
962 cfi_command(bank, 0xf0, command);
963 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
964 cfi_command(bank, 0xff, command);
965 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
966 return ERROR_FLASH_BANK_INVALID;
967 }
968
969 cfi_info->pri_id = cfi_query_u16(bank, 0, 0x13);
970 cfi_info->pri_addr = cfi_query_u16(bank, 0, 0x15);
971 cfi_info->alt_id = cfi_query_u16(bank, 0, 0x17);
972 cfi_info->alt_addr = cfi_query_u16(bank, 0, 0x19);
973
974 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);
975
976 cfi_info->vcc_min = cfi_query_u8(bank, 0, 0x1b);
977 cfi_info->vcc_max = cfi_query_u8(bank, 0, 0x1c);
978 cfi_info->vpp_min = cfi_query_u8(bank, 0, 0x1d);
979 cfi_info->vpp_max = cfi_query_u8(bank, 0, 0x1e);
980 cfi_info->word_write_timeout_typ = cfi_query_u8(bank, 0, 0x1f);
981 cfi_info->buf_write_timeout_typ = cfi_query_u8(bank, 0, 0x20);
982 cfi_info->block_erase_timeout_typ = cfi_query_u8(bank, 0, 0x21);
983 cfi_info->chip_erase_timeout_typ = cfi_query_u8(bank, 0, 0x22);
984 cfi_info->word_write_timeout_max = cfi_query_u8(bank, 0, 0x23);
985 cfi_info->buf_write_timeout_max = cfi_query_u8(bank, 0, 0x24);
986 cfi_info->block_erase_timeout_max = cfi_query_u8(bank, 0, 0x25);
987 cfi_info->chip_erase_timeout_max = cfi_query_u8(bank, 0, 0x26);
988
989 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",
990 (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,
991 (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,
992 (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,
993 (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);
994 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,
995 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);
996 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),
997 (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),
998 (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
999 (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
1000
1001 cfi_info->dev_size = cfi_query_u8(bank, 0, 0x27);
1002 cfi_info->interface_desc = cfi_query_u16(bank, 0, 0x28);
1003 cfi_info->max_buf_write_size = cfi_query_u16(bank, 0, 0x2a);
1004 cfi_info->num_erase_regions = cfi_query_u8(bank, 0, 0x2c);
1005
1006 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));
1007
1008 if (((1 << cfi_info->dev_size) * bank->bus_width / bank->chip_width) != bank->size)
1009 {
1010 WARNING("configuration specifies 0x%x size, but a 0x%x size flash was found", bank->size, 1 << cfi_info->dev_size);
1011 }
1012
1013 if (cfi_info->num_erase_regions)
1014 {
1015 int i;
1016 int num_sectors = 0;
1017 int sector = 0;
1018 u32 offset = 0;
1019 cfi_info->erase_region_info = malloc(4 * cfi_info->num_erase_regions);
1020
1021 for (i = 0; i < cfi_info->num_erase_regions; i++)
1022 {
1023 cfi_info->erase_region_info[i] = cfi_query_u32(bank, 0, 0x2d + (4 * i));
1024 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);
1025
1026 num_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1;
1027 }
1028
1029 bank->num_sectors = num_sectors;
1030 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
1031 for (i = 0; i < cfi_info->num_erase_regions; i++)
1032 {
1033 int j;
1034 for (j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++)
1035 {
1036 bank->sectors[sector].offset = offset;
1037 bank->sectors[sector].size = ((cfi_info->erase_region_info[i] >> 16) * 256) * bank->bus_width / bank->chip_width;
1038 offset += bank->sectors[sector].size;
1039 bank->sectors[sector].is_erased = -1;
1040 bank->sectors[sector].is_protected = -1;
1041 sector++;
1042 }
1043 }
1044 }
1045 else
1046 {
1047 cfi_info->erase_region_info = NULL;
1048 }
1049
1050 switch(cfi_info->pri_id)
1051 {
1052 case 1:
1053 case 3:
1054 cfi_read_intel_pri_ext(bank);
1055 break;
1056 default:
1057 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
1058 break;
1059 }
1060
1061 /* return to read array mode */
1062 cfi_command(bank, 0xf0, command);
1063 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
1064 cfi_command(bank, 0xff, command);
1065 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
1066
1067 return ERROR_OK;
1068 }
1069
1070 int cfi_erase_check(struct flash_bank_s *bank)
1071 {
1072 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1073 target_t *target = cfi_info->target;
1074 int i;
1075 int retval;
1076
1077 if (!cfi_info->erase_check_algorithm)
1078 {
1079 u32 erase_check_code[] =
1080 {
1081 0xe4d03001, /* ldrb r3, [r0], #1 */
1082 0xe0022003, /* and r2, r2, r3 */
1083 0xe2511001, /* subs r1, r1, #1 */
1084 0x1afffffb, /* b -4 */
1085 0xeafffffe /* b 0 */
1086 };
1087
1088 /* make sure we have a working area */
1089 if (target_alloc_working_area(target, 20, &cfi_info->erase_check_algorithm) != ERROR_OK)
1090 {
1091 WARNING("no working area available, falling back to slow memory reads");
1092 }
1093 else
1094 {
1095 u8 erase_check_code_buf[5 * 4];
1096
1097 for (i = 0; i < 5; i++)
1098 target_buffer_set_u32(target, erase_check_code_buf + (i*4), erase_check_code[i]);
1099
1100 /* write algorithm code to working area */
1101 target->type->write_memory(target, cfi_info->erase_check_algorithm->address, 4, 5, erase_check_code_buf);
1102 }
1103 }
1104
1105 if (!cfi_info->erase_check_algorithm)
1106 {
1107 u32 *buffer = malloc(4096);
1108
1109 for (i = 0; i < bank->num_sectors; i++)
1110 {
1111 u32 address = bank->base + bank->sectors[i].offset;
1112 u32 size = bank->sectors[i].size;
1113 u32 check = 0xffffffffU;
1114 int erased = 1;
1115
1116 while (size > 0)
1117 {
1118 u32 thisrun_size = (size > 4096) ? 4096 : size;
1119 int j;
1120
1121 target->type->read_memory(target, address, 4, thisrun_size / 4, (u8*)buffer);
1122
1123 for (j = 0; j < thisrun_size / 4; j++)
1124 check &= buffer[j];
1125
1126 if (check != 0xffffffff)
1127 {
1128 erased = 0;
1129 break;
1130 }
1131
1132 size -= thisrun_size;
1133 address += thisrun_size;
1134 }
1135
1136 bank->sectors[i].is_erased = erased;
1137 }
1138
1139 free(buffer);
1140 }
1141 else
1142 {
1143 for (i = 0; i < bank->num_sectors; i++)
1144 {
1145 u32 address = bank->base + bank->sectors[i].offset;
1146 u32 size = bank->sectors[i].size;
1147
1148 reg_param_t reg_params[3];
1149 armv4_5_algorithm_t armv4_5_info;
1150
1151 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1152 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1153 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1154
1155 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1156 buf_set_u32(reg_params[0].value, 0, 32, address);
1157
1158 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1159 buf_set_u32(reg_params[1].value, 0, 32, size);
1160
1161 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1162 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1163
1164 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)
1165 return ERROR_FLASH_OPERATION_FAILED;
1166
1167 if (buf_get_u32(reg_params[2].value, 0, 32) == 0xff)
1168 bank->sectors[i].is_erased = 1;
1169 else
1170 bank->sectors[i].is_erased = 0;
1171
1172 destroy_reg_param(&reg_params[0]);
1173 destroy_reg_param(&reg_params[1]);
1174 destroy_reg_param(&reg_params[2]);
1175 }
1176 }
1177
1178 return ERROR_OK;
1179 }
1180
1181 int cfi_intel_protect_check(struct flash_bank_s *bank)
1182 {
1183 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1184 cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
1185 target_t *target = cfi_info->target;
1186 u8 command[CFI_MAX_BUS_WIDTH];
1187 int i;
1188
1189 /* check if block lock bits are supported on this device */
1190 if (!(pri_ext->blk_status_reg_mask & 0x1))
1191 return ERROR_FLASH_OPERATION_FAILED;
1192
1193 cfi_command(bank, 0x90, command);
1194 target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
1195
1196 for (i = 0; i < bank->num_sectors; i++)
1197 {
1198 u8 block_status = cfi_get_u8(bank, i, 0x2);
1199
1200 if (block_status & 1)
1201 bank->sectors[i].is_protected = 1;
1202 else
1203 bank->sectors[i].is_protected = 0;
1204 }
1205
1206 cfi_command(bank, 0xff, command);
1207 target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
1208
1209 return ERROR_OK;
1210 }
1211
1212 int cfi_protect_check(struct flash_bank_s *bank)
1213 {
1214 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1215
1216 if (cfi_info->qry[0] != 'Q')
1217 return ERROR_FLASH_BANK_NOT_PROBED;
1218
1219 switch(cfi_info->pri_id)
1220 {
1221 case 1:
1222 case 3:
1223 return cfi_intel_protect_check(bank);
1224 break;
1225 default:
1226 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
1227 break;
1228 }
1229
1230 return ERROR_OK;
1231 }
1232
1233 int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
1234 {
1235 int printed;
1236 cfi_flash_bank_t *cfi_info = bank->driver_priv;
1237
1238 if (cfi_info->qry[0] == -1)
1239 {
1240 printed = snprintf(buf, buf_size, "\ncfi flash bank not probed yet\n");
1241 return ERROR_OK;
1242 }
1243
1244 printed = snprintf(buf, buf_size, "\ncfi information:\n");
1245 buf += printed;
1246 buf_size -= printed;
1247
1248 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);
1249 buf += printed;
1250 buf_size -= printed;
1251
1252 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,
1253 (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,
1254 (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,
1255 (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);
1256 buf += printed;
1257 buf_size -= printed;
1258
1259 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,
1260 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);
1261 buf += printed;
1262 buf_size -= printed;
1263
1264 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),
1265 (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),
1266 (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
1267 (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
1268 buf += printed;
1269 buf_size -= printed;
1270
1271 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);
1272 buf += printed;
1273 buf_size -= printed;
1274
1275 switch(cfi_info->pri_id)
1276 {
1277 case 1:
1278 case 3:
1279 cfi_intel_info(bank, buf, buf_size);
1280 break;
1281 default:
1282 ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
1283 break;
1284 }
1285
1286 return ERROR_OK;
1287 }

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)