flash/nor/driver.h: typo fix
[openocd.git] / src / flash / nor / str7x.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2010 Øyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "imp.h"
32 #include <target/arm.h>
33 #include <helper/binarybuffer.h>
34 #include <target/algorithm.h>
35
36 /* Flash registers */
37
38 #define FLASH_CR0 0x00000000
39 #define FLASH_CR1 0x00000004
40 #define FLASH_DR0 0x00000008
41 #define FLASH_DR1 0x0000000C
42 #define FLASH_AR 0x00000010
43 #define FLASH_ER 0x00000014
44 #define FLASH_NVWPAR 0x0000DFB0
45 #define FLASH_NVAPR0 0x0000DFB8
46 #define FLASH_NVAPR1 0x0000DFBC
47
48 /* FLASH_CR0 register bits */
49
50 #define FLASH_WMS 0x80000000
51 #define FLASH_SUSP 0x40000000
52 #define FLASH_WPG 0x20000000
53 #define FLASH_DWPG 0x10000000
54 #define FLASH_SER 0x08000000
55 #define FLASH_SPR 0x01000000
56 #define FLASH_BER 0x04000000
57 #define FLASH_MER 0x02000000
58 #define FLASH_LOCK 0x00000010
59 #define FLASH_BSYA1 0x00000004
60 #define FLASH_BSYA0 0x00000002
61
62 /* FLASH_CR1 register bits */
63
64 #define FLASH_B1S 0x02000000
65 #define FLASH_B0S 0x01000000
66 #define FLASH_B1F1 0x00020000
67 #define FLASH_B1F0 0x00010000
68 #define FLASH_B0F7 0x00000080
69 #define FLASH_B0F6 0x00000040
70 #define FLASH_B0F5 0x00000020
71 #define FLASH_B0F4 0x00000010
72 #define FLASH_B0F3 0x00000008
73 #define FLASH_B0F2 0x00000004
74 #define FLASH_B0F1 0x00000002
75 #define FLASH_B0F0 0x00000001
76
77 /* FLASH_ER register bits */
78
79 #define FLASH_WPF 0x00000100
80 #define FLASH_RESER 0x00000080
81 #define FLASH_SEQER 0x00000040
82 #define FLASH_10ER 0x00000008
83 #define FLASH_PGER 0x00000004
84 #define FLASH_ERER 0x00000002
85 #define FLASH_ERR 0x00000001
86
87
88 struct str7x_flash_bank {
89 uint32_t *sector_bits;
90 uint32_t disable_bit;
91 uint32_t busy_bits;
92 uint32_t register_base;
93 struct working_area *write_algorithm;
94 };
95
96 struct str7x_mem_layout {
97 uint32_t sector_start;
98 uint32_t sector_size;
99 uint32_t sector_bit;
100 };
101
102 enum str7x_status_codes {
103 STR7X_CMD_SUCCESS = 0,
104 STR7X_INVALID_COMMAND = 1,
105 STR7X_SRC_ADDR_ERROR = 2,
106 STR7X_DST_ADDR_ERROR = 3,
107 STR7X_SRC_ADDR_NOT_MAPPED = 4,
108 STR7X_DST_ADDR_NOT_MAPPED = 5,
109 STR7X_COUNT_ERROR = 6,
110 STR7X_INVALID_SECTOR = 7,
111 STR7X_SECTOR_NOT_BLANK = 8,
112 STR7X_SECTOR_NOT_PREPARED = 9,
113 STR7X_COMPARE_ERROR = 10,
114 STR7X_BUSY = 11
115 };
116
117 static struct str7x_mem_layout mem_layout_str7bank0[] = {
118 {0x00000000, 0x02000, 0x01},
119 {0x00002000, 0x02000, 0x02},
120 {0x00004000, 0x02000, 0x04},
121 {0x00006000, 0x02000, 0x08},
122 {0x00008000, 0x08000, 0x10},
123 {0x00010000, 0x10000, 0x20},
124 {0x00020000, 0x10000, 0x40},
125 {0x00030000, 0x10000, 0x80}
126 };
127
128 static struct str7x_mem_layout mem_layout_str7bank1[] = {
129 {0x00000000, 0x02000, 0x10000},
130 {0x00002000, 0x02000, 0x20000}
131 };
132
133 static int str7x_get_flash_adr(struct flash_bank *bank, uint32_t reg)
134 {
135 struct str7x_flash_bank *str7x_info = bank->driver_priv;
136 return str7x_info->register_base | reg;
137 }
138
139 static int str7x_build_block_list(struct flash_bank *bank)
140 {
141 struct str7x_flash_bank *str7x_info = bank->driver_priv;
142
143 int i;
144 int num_sectors;
145 int b0_sectors = 0, b1_sectors = 0;
146
147 switch (bank->size) {
148 case 16 * 1024:
149 b1_sectors = 2;
150 break;
151 case 64 * 1024:
152 b0_sectors = 5;
153 break;
154 case 128 * 1024:
155 b0_sectors = 6;
156 break;
157 case 256 * 1024:
158 b0_sectors = 8;
159 break;
160 default:
161 LOG_ERROR("BUG: unknown bank->size encountered");
162 exit(-1);
163 }
164
165 num_sectors = b0_sectors + b1_sectors;
166
167 bank->num_sectors = num_sectors;
168 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
169 str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
170
171 num_sectors = 0;
172
173 for (i = 0; i < b0_sectors; i++) {
174 bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
175 bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
176 bank->sectors[num_sectors].is_erased = -1;
177 /* the reset_init handler marks all the sectors unprotected,
178 * matching hardware after reset; keep the driver in sync
179 */
180 bank->sectors[num_sectors].is_protected = 0;
181 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
182 }
183
184 for (i = 0; i < b1_sectors; i++) {
185 bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
186 bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
187 bank->sectors[num_sectors].is_erased = -1;
188 /* the reset_init handler marks all the sectors unprotected,
189 * matching hardware after reset; keep the driver in sync
190 */
191 bank->sectors[num_sectors].is_protected = 0;
192 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
193 }
194
195 return ERROR_OK;
196 }
197
198 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
199 */
200 FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
201 {
202 struct str7x_flash_bank *str7x_info;
203
204 if (CMD_ARGC < 7)
205 return ERROR_COMMAND_SYNTAX_ERROR;
206
207 str7x_info = malloc(sizeof(struct str7x_flash_bank));
208 bank->driver_priv = str7x_info;
209
210 /* set default bits for str71x flash */
211 str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
212 str7x_info->disable_bit = (1 << 1);
213
214 if (strcmp(CMD_ARGV[6], "STR71x") == 0)
215 str7x_info->register_base = 0x40100000;
216 else if (strcmp(CMD_ARGV[6], "STR73x") == 0) {
217 str7x_info->register_base = 0x80100000;
218 str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
219 } else if (strcmp(CMD_ARGV[6], "STR75x") == 0) {
220 str7x_info->register_base = 0x20100000;
221 str7x_info->disable_bit = (1 << 0);
222 } else {
223 LOG_ERROR("unknown STR7x variant: '%s'", CMD_ARGV[6]);
224 free(str7x_info);
225 return ERROR_FLASH_BANK_INVALID;
226 }
227
228 str7x_build_block_list(bank);
229
230 str7x_info->write_algorithm = NULL;
231
232 return ERROR_OK;
233 }
234
235 /* wait for flash to become idle or report errors.
236
237 FIX!!! what's the maximum timeout??? The documentation doesn't
238 state any maximum time.... by inspection it seems > 1000ms is to be
239 expected.
240
241 10000ms is long enough that it should cover anything, yet not
242 quite be equivalent to an infinite loop.
243
244 */
245 static int str7x_waitbusy(struct flash_bank *bank)
246 {
247 int err;
248 int i;
249 struct target *target = bank->target;
250 struct str7x_flash_bank *str7x_info = bank->driver_priv;
251
252 for (i = 0 ; i < 10000; i++) {
253 uint32_t retval;
254 err = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
255 if (err != ERROR_OK)
256 return err;
257
258 if ((retval & str7x_info->busy_bits) == 0)
259 return ERROR_OK;
260
261 alive_sleep(1);
262 }
263 LOG_ERROR("Timed out waiting for str7x flash");
264 return ERROR_FAIL;
265 }
266
267
268 static int str7x_result(struct flash_bank *bank)
269 {
270 struct target *target = bank->target;
271 uint32_t flash_flags;
272
273 int retval;
274 retval = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &flash_flags);
275 if (retval != ERROR_OK)
276 return retval;
277
278 if (flash_flags & FLASH_WPF) {
279 LOG_ERROR("str7x hw write protection set");
280 retval = ERROR_FAIL;
281 }
282 if (flash_flags & FLASH_RESER) {
283 LOG_ERROR("str7x suspended program erase not resumed");
284 retval = ERROR_FAIL;
285 }
286 if (flash_flags & FLASH_10ER) {
287 LOG_ERROR("str7x trying to set bit to 1 when it is already 0");
288 retval = ERROR_FAIL;
289 }
290 if (flash_flags & FLASH_PGER) {
291 LOG_ERROR("str7x program error");
292 retval = ERROR_FAIL;
293 }
294 if (flash_flags & FLASH_ERER) {
295 LOG_ERROR("str7x erase error");
296 retval = ERROR_FAIL;
297 }
298 if (retval == ERROR_OK) {
299 if (flash_flags & FLASH_ERR) {
300 /* this should always be set if one of the others are set... */
301 LOG_ERROR("str7x write operation failed / bad setup");
302 retval = ERROR_FAIL;
303 }
304 }
305
306 return retval;
307 }
308
309 static int str7x_protect_check(struct flash_bank *bank)
310 {
311 struct str7x_flash_bank *str7x_info = bank->driver_priv;
312 struct target *target = bank->target;
313
314 int i;
315 uint32_t flash_flags;
316
317 if (bank->target->state != TARGET_HALTED) {
318 LOG_ERROR("Target not halted");
319 return ERROR_TARGET_NOT_HALTED;
320 }
321
322 int retval;
323 retval = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &flash_flags);
324 if (retval != ERROR_OK)
325 return retval;
326
327 for (i = 0; i < bank->num_sectors; i++) {
328 if (flash_flags & str7x_info->sector_bits[i])
329 bank->sectors[i].is_protected = 0;
330 else
331 bank->sectors[i].is_protected = 1;
332 }
333
334 return ERROR_OK;
335 }
336
337 static int str7x_erase(struct flash_bank *bank, int first, int last)
338 {
339 struct str7x_flash_bank *str7x_info = bank->driver_priv;
340 struct target *target = bank->target;
341
342 int i;
343 uint32_t cmd;
344 uint32_t sectors = 0;
345 int err;
346
347 if (bank->target->state != TARGET_HALTED) {
348 LOG_ERROR("Target not halted");
349 return ERROR_TARGET_NOT_HALTED;
350 }
351
352 for (i = first; i <= last; i++)
353 sectors |= str7x_info->sector_bits[i];
354
355 LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
356
357 /* clear FLASH_ER register */
358 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
359 if (err != ERROR_OK)
360 return err;
361
362 cmd = FLASH_SER;
363 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
364 if (err != ERROR_OK)
365 return err;
366
367 cmd = sectors;
368 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
369 if (err != ERROR_OK)
370 return err;
371
372 cmd = FLASH_SER | FLASH_WMS;
373 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
374 if (err != ERROR_OK)
375 return err;
376
377 err = str7x_waitbusy(bank);
378 if (err != ERROR_OK)
379 return err;
380
381 err = str7x_result(bank);
382 if (err != ERROR_OK)
383 return err;
384
385 for (i = first; i <= last; i++)
386 bank->sectors[i].is_erased = 1;
387
388 return ERROR_OK;
389 }
390
391 static int str7x_protect(struct flash_bank *bank, int set, int first, int last)
392 {
393 struct str7x_flash_bank *str7x_info = bank->driver_priv;
394 struct target *target = bank->target;
395 int i;
396 uint32_t cmd;
397 uint32_t protect_blocks;
398
399 if (bank->target->state != TARGET_HALTED) {
400 LOG_ERROR("Target not halted");
401 return ERROR_TARGET_NOT_HALTED;
402 }
403
404 protect_blocks = 0xFFFFFFFF;
405
406 if (set) {
407 for (i = first; i <= last; i++)
408 protect_blocks &= ~(str7x_info->sector_bits[i]);
409 }
410
411 /* clear FLASH_ER register */
412 int err;
413 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
414 if (err != ERROR_OK)
415 return err;
416
417 cmd = FLASH_SPR;
418 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
419 if (err != ERROR_OK)
420 return err;
421
422 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
423 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
424 if (err != ERROR_OK)
425 return err;
426
427 cmd = protect_blocks;
428 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
429 if (err != ERROR_OK)
430 return err;
431
432 cmd = FLASH_SPR | FLASH_WMS;
433 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
434 if (err != ERROR_OK)
435 return err;
436
437 err = str7x_waitbusy(bank);
438 if (err != ERROR_OK)
439 return err;
440
441 err = str7x_result(bank);
442 if (err != ERROR_OK)
443 return err;
444
445 return ERROR_OK;
446 }
447
448 static int str7x_write_block(struct flash_bank *bank, uint8_t *buffer,
449 uint32_t offset, uint32_t count)
450 {
451 struct str7x_flash_bank *str7x_info = bank->driver_priv;
452 struct target *target = bank->target;
453 uint32_t buffer_size = 32768;
454 struct working_area *source;
455 uint32_t address = bank->base + offset;
456 struct reg_param reg_params[6];
457 struct arm_algorithm arm_algo;
458 int retval = ERROR_OK;
459
460 /* see contib/loaders/flash/str7x.s for src */
461
462 static const uint32_t str7x_flash_write_code[] = {
463 /* write: */
464 0xe3a04201, /* mov r4, #0x10000000 */
465 0xe5824000, /* str r4, [r2, #0x0] */
466 0xe5821010, /* str r1, [r2, #0x10] */
467 0xe4904004, /* ldr r4, [r0], #4 */
468 0xe5824008, /* str r4, [r2, #0x8] */
469 0xe4904004, /* ldr r4, [r0], #4 */
470 0xe582400c, /* str r4, [r2, #0xc] */
471 0xe3a04209, /* mov r4, #0x90000000 */
472 0xe5824000, /* str r4, [r2, #0x0] */
473 /* busy: */
474 0xe5924000, /* ldr r4, [r2, #0x0] */
475 0xe1140005, /* tst r4, r5 */
476 0x1afffffc, /* bne busy */
477 0xe5924014, /* ldr r4, [r2, #0x14] */
478 0xe31400ff, /* tst r4, #0xff */
479 0x03140c01, /* tsteq r4, #0x100 */
480 0x1a000002, /* bne exit */
481 0xe2811008, /* add r1, r1, #0x8 */
482 0xe2533001, /* subs r3, r3, #1 */
483 0x1affffec, /* bne write */
484 /* exit: */
485 0xeafffffe, /* b exit */
486 };
487
488 /* flash write code */
489 if (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),
490 &str7x_info->write_algorithm) != ERROR_OK) {
491 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
492 };
493
494 target_write_buffer(target, str7x_info->write_algorithm->address,
495 sizeof(str7x_flash_write_code),
496 (uint8_t *)str7x_flash_write_code);
497
498 /* memory buffer */
499 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
500 buffer_size /= 2;
501 if (buffer_size <= 256) {
502 /* if we already allocated the writing code, but failed to get a
503 * buffer, free the algorithm */
504 if (str7x_info->write_algorithm)
505 target_free_working_area(target, str7x_info->write_algorithm);
506
507 LOG_WARNING("no large enough working area available, can't do block memory writes");
508 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
509 }
510 }
511
512 arm_algo.common_magic = ARM_COMMON_MAGIC;
513 arm_algo.core_mode = ARM_MODE_SVC;
514 arm_algo.core_state = ARM_STATE_ARM;
515
516 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
517 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
518 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
519 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
520 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
521 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
522
523 while (count > 0) {
524 uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
525
526 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
527
528 buf_set_u32(reg_params[0].value, 0, 32, source->address);
529 buf_set_u32(reg_params[1].value, 0, 32, address);
530 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
531 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
532 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
533
534 retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
535 str7x_info->write_algorithm->address,
536 str7x_info->write_algorithm->address + (sizeof(str7x_flash_write_code) - 4),
537 10000, &arm_algo);
538 if (retval != ERROR_OK)
539 break;
540
541 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00) {
542 retval = str7x_result(bank);
543 break;
544 }
545
546 buffer += thisrun_count * 8;
547 address += thisrun_count * 8;
548 count -= thisrun_count;
549 }
550
551 target_free_working_area(target, source);
552 target_free_working_area(target, str7x_info->write_algorithm);
553
554 destroy_reg_param(&reg_params[0]);
555 destroy_reg_param(&reg_params[1]);
556 destroy_reg_param(&reg_params[2]);
557 destroy_reg_param(&reg_params[3]);
558 destroy_reg_param(&reg_params[4]);
559 destroy_reg_param(&reg_params[5]);
560
561 return retval;
562 }
563
564 static int str7x_write(struct flash_bank *bank, uint8_t *buffer,
565 uint32_t offset, uint32_t count)
566 {
567 struct target *target = bank->target;
568 uint32_t dwords_remaining = (count / 8);
569 uint32_t bytes_remaining = (count & 0x00000007);
570 uint32_t address = bank->base + offset;
571 uint32_t bytes_written = 0;
572 uint32_t cmd;
573 int retval;
574 uint32_t check_address = offset;
575 int i;
576
577 if (bank->target->state != TARGET_HALTED) {
578 LOG_ERROR("Target not halted");
579 return ERROR_TARGET_NOT_HALTED;
580 }
581
582 if (offset & 0x7) {
583 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
584 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
585 }
586
587 for (i = 0; i < bank->num_sectors; i++) {
588 uint32_t sec_start = bank->sectors[i].offset;
589 uint32_t sec_end = sec_start + bank->sectors[i].size;
590
591 /* check if destination falls within the current sector */
592 if ((check_address >= sec_start) && (check_address < sec_end)) {
593 /* check if destination ends in the current sector */
594 if (offset + count < sec_end)
595 check_address = offset + count;
596 else
597 check_address = sec_end;
598 }
599 }
600
601 if (check_address != offset + count)
602 return ERROR_FLASH_DST_OUT_OF_BANK;
603
604 /* clear FLASH_ER register */
605 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
606
607 /* multiple dwords (8-byte) to be programmed? */
608 if (dwords_remaining > 0) {
609 /* try using a block write */
610 retval = str7x_write_block(bank, buffer, offset, dwords_remaining);
611 if (retval != ERROR_OK) {
612 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
613 /* if block write failed (no sufficient working area),
614 * we use normal (slow) single dword accesses */
615 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
616 } else {
617 return retval;
618 }
619 } else {
620 buffer += dwords_remaining * 8;
621 address += dwords_remaining * 8;
622 dwords_remaining = 0;
623 }
624 }
625
626 while (dwords_remaining > 0) {
627 /* command */
628 cmd = FLASH_DWPG;
629 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
630
631 /* address */
632 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
633
634 /* data word 1 */
635 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
636 4, 1, buffer + bytes_written);
637 bytes_written += 4;
638
639 /* data word 2 */
640 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
641 4, 1, buffer + bytes_written);
642 bytes_written += 4;
643
644 /* start programming cycle */
645 cmd = FLASH_DWPG | FLASH_WMS;
646 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
647
648 int err;
649 err = str7x_waitbusy(bank);
650 if (err != ERROR_OK)
651 return err;
652
653 err = str7x_result(bank);
654 if (err != ERROR_OK)
655 return err;
656
657 dwords_remaining--;
658 address += 8;
659 }
660
661 if (bytes_remaining) {
662 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
663
664 /* copy the last remaining bytes into the write buffer */
665 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
666
667 /* command */
668 cmd = FLASH_DWPG;
669 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
670
671 /* address */
672 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
673
674 /* data word 1 */
675 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
676 4, 1, last_dword);
677
678 /* data word 2 */
679 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
680 4, 1, last_dword + 4);
681
682 /* start programming cycle */
683 cmd = FLASH_DWPG | FLASH_WMS;
684 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
685
686 int err;
687 err = str7x_waitbusy(bank);
688 if (err != ERROR_OK)
689 return err;
690
691 err = str7x_result(bank);
692 if (err != ERROR_OK)
693 return err;
694 }
695
696 return ERROR_OK;
697 }
698
699 static int str7x_probe(struct flash_bank *bank)
700 {
701 return ERROR_OK;
702 }
703
704 #if 0
705 COMMAND_HANDLER(str7x_handle_part_id_command)
706 {
707 return ERROR_OK;
708 }
709 #endif
710
711 static int get_str7x_info(struct flash_bank *bank, char *buf, int buf_size)
712 {
713 snprintf(buf, buf_size, "str7x flash driver info");
714 /* STR7x flash doesn't support sector protection interrogation.
715 * FLASH_NVWPAR acts as a write only register; its read value
716 * doesn't reflect the actual protection state of the sectors.
717 */
718 LOG_WARNING("STR7x flash lock information might not be correct "
719 "due to hardware limitations.");
720 return ERROR_OK;
721 }
722
723 COMMAND_HANDLER(str7x_handle_disable_jtag_command)
724 {
725 struct target *target = NULL;
726 struct str7x_flash_bank *str7x_info = NULL;
727
728 uint32_t flash_cmd;
729 uint16_t ProtectionLevel = 0;
730 uint16_t ProtectionRegs;
731
732 if (CMD_ARGC < 1)
733 return ERROR_COMMAND_SYNTAX_ERROR;
734
735 struct flash_bank *bank;
736 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
737 if (ERROR_OK != retval)
738 return retval;
739
740 str7x_info = bank->driver_priv;
741
742 target = bank->target;
743
744 if (target->state != TARGET_HALTED) {
745 LOG_ERROR("Target not halted");
746 return ERROR_TARGET_NOT_HALTED;
747 }
748
749 /* first we get protection status */
750 uint32_t reg;
751 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);
752
753 if (!(reg & str7x_info->disable_bit))
754 ProtectionLevel = 1;
755
756 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);
757 ProtectionRegs = ~(reg >> 16);
758
759 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16)) {
760 ProtectionRegs >>= 1;
761 ProtectionLevel++;
762 }
763
764 if (ProtectionLevel == 0) {
765 flash_cmd = FLASH_SPR;
766 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
767 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
768 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
769 flash_cmd = FLASH_SPR | FLASH_WMS;
770 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
771 } else {
772 flash_cmd = FLASH_SPR;
773 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
774 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
775 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),
776 ~(1 << (15 + ProtectionLevel)));
777 flash_cmd = FLASH_SPR | FLASH_WMS;
778 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
779 }
780
781 return ERROR_OK;
782 }
783
784 static const struct command_registration str7x_exec_command_handlers[] = {
785 {
786 .name = "disable_jtag",
787 .usage = "<bank>",
788 .handler = str7x_handle_disable_jtag_command,
789 .mode = COMMAND_EXEC,
790 .help = "disable jtag access",
791 },
792 COMMAND_REGISTRATION_DONE
793 };
794
795 static const struct command_registration str7x_command_handlers[] = {
796 {
797 .name = "str7x",
798 .mode = COMMAND_ANY,
799 .help = "str7x flash command group",
800 .usage = "",
801 .chain = str7x_exec_command_handlers,
802 },
803 COMMAND_REGISTRATION_DONE
804 };
805
806 struct flash_driver str7x_flash = {
807 .name = "str7x",
808 .commands = str7x_command_handlers,
809 .flash_bank_command = str7x_flash_bank_command,
810 .erase = str7x_erase,
811 .protect = str7x_protect,
812 .write = str7x_write,
813 .read = default_flash_read,
814 .probe = str7x_probe,
815 .auto_probe = str7x_probe,
816 .erase_check = default_flash_blank_check,
817 .protect_check = str7x_protect_check,
818 .info = get_str7x_info,
819 };

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)