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

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)