fix flash info - now reports erased state properly
[openocd.git] / src / flash / str7x.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 "str7x.h"
27 #include "flash.h"
28 #include "target.h"
29 #include "log.h"
30 #include "armv4_5.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 str7x_mem_layout_t mem_layout[] = {
39 {0x00000000, 0x02000, 0x01},
40 {0x00002000, 0x02000, 0x02},
41 {0x00004000, 0x02000, 0x04},
42 {0x00006000, 0x02000, 0x08},
43 {0x00008000, 0x08000, 0x10},
44 {0x00010000, 0x10000, 0x20},
45 {0x00020000, 0x10000, 0x40},
46 {0x00030000, 0x10000, 0x80},
47 {0x000C0000, 0x02000, 0x10000},
48 {0x000C2000, 0x02000, 0x20000},
49 };
50
51 int str7x_register_commands(struct command_context_s *cmd_ctx);
52 int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
53 int str7x_erase(struct flash_bank_s *bank, int first, int last);
54 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last);
55 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
56 int str7x_probe(struct flash_bank_s *bank);
57 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
58 int str7x_protect_check(struct flash_bank_s *bank);
59 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
60
61 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
62
63 flash_driver_t str7x_flash =
64 {
65 .name = "str7x",
66 .register_commands = str7x_register_commands,
67 .flash_bank_command = str7x_flash_bank_command,
68 .erase = str7x_erase,
69 .protect = str7x_protect,
70 .write = str7x_write,
71 .probe = str7x_probe,
72 .auto_probe = str7x_probe,
73 .erase_check = default_flash_blank_check,
74 .protect_check = str7x_protect_check,
75 .info = str7x_info
76 };
77
78 int str7x_register_commands(struct command_context_s *cmd_ctx)
79 {
80 command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
81
82 register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
83 "disable jtag access");
84
85 return ERROR_OK;
86 }
87
88 int str7x_get_flash_adr(struct flash_bank_s *bank, u32 reg)
89 {
90 return (bank->base | reg);
91 }
92
93 int str7x_build_block_list(struct flash_bank_s *bank)
94 {
95 str7x_flash_bank_t *str7x_info = bank->driver_priv;
96
97 int i;
98 int num_sectors = 0, b0_sectors = 0, b1_sectors = 0;
99
100 switch (bank->size)
101 {
102 case 16 * 1024:
103 b0_sectors = 2;
104 break;
105 case 64 * 1024:
106 b0_sectors = 5;
107 break;
108 case 128 * 1024:
109 b0_sectors = 6;
110 break;
111 case 256 * 1024:
112 b0_sectors = 8;
113 break;
114 default:
115 LOG_ERROR("BUG: unknown bank->size encountered");
116 exit(-1);
117 }
118
119 if( str7x_info->bank1 == 1 )
120 {
121 b1_sectors += 2;
122 }
123
124 num_sectors = b0_sectors + b1_sectors;
125
126 bank->num_sectors = num_sectors;
127 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
128 str7x_info->sector_bits = malloc(sizeof(u32) * num_sectors);
129 str7x_info->sector_bank = malloc(sizeof(u32) * num_sectors);
130
131 num_sectors = 0;
132
133 for (i = 0; i < b0_sectors; i++)
134 {
135 bank->sectors[num_sectors].offset = mem_layout[i].sector_start;
136 bank->sectors[num_sectors].size = mem_layout[i].sector_size;
137 bank->sectors[num_sectors].is_erased = -1;
138 bank->sectors[num_sectors].is_protected = 1;
139 str7x_info->sector_bank[num_sectors] = 0;
140 str7x_info->sector_bits[num_sectors++] = mem_layout[i].sector_bit;
141 }
142
143 if (b1_sectors)
144 {
145 for (i = 8; i < 10; i++)
146 {
147 bank->sectors[num_sectors].offset = mem_layout[i].sector_start;
148 bank->sectors[num_sectors].size = mem_layout[i].sector_size;
149 bank->sectors[num_sectors].is_erased = -1;
150 bank->sectors[num_sectors].is_protected = 1;
151 str7x_info->sector_bank[num_sectors] = 1;
152 str7x_info->sector_bits[num_sectors++] = mem_layout[i].sector_bit;
153 }
154 }
155
156 return ERROR_OK;
157 }
158
159 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
160 */
161 int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
162 {
163 str7x_flash_bank_t *str7x_info;
164
165 if (argc < 7)
166 {
167 LOG_WARNING("incomplete flash_bank str7x configuration");
168 return ERROR_FLASH_BANK_INVALID;
169 }
170
171 str7x_info = malloc(sizeof(str7x_flash_bank_t));
172 bank->driver_priv = str7x_info;
173
174 /* set default bits for str71x flash */
175 str7x_info->bank1 = 1;
176 str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA1|FLASH_BSYA0);
177 str7x_info->disable_bit = (1<<1);
178
179 if (strcmp(args[6], "STR71x") == 0)
180 {
181 if (bank->base != 0x40000000)
182 {
183 LOG_WARNING("overriding flash base address for STR71x device with 0x40000000");
184 bank->base = 0x40000000;
185 }
186 }
187 else if (strcmp(args[6], "STR73x") == 0)
188 {
189 str7x_info->bank1 = 0;
190 str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA0);
191
192 if (bank->base != 0x80000000)
193 {
194 LOG_WARNING("overriding flash base address for STR73x device with 0x80000000");
195 bank->base = 0x80000000;
196 }
197 }
198 else if (strcmp(args[6], "STR75x") == 0)
199 {
200 str7x_info->disable_bit = (1<<0);
201
202 if (bank->base != 0x20000000)
203 {
204 LOG_WARNING("overriding flash base address for STR75x device with 0x20000000");
205 bank->base = 0x20000000;
206 }
207 }
208 else
209 {
210 LOG_ERROR("unknown STR7x variant: '%s'", args[6]);
211 free(str7x_info);
212 return ERROR_FLASH_BANK_INVALID;
213 }
214
215 str7x_build_block_list(bank);
216
217 str7x_info->write_algorithm = NULL;
218
219 return ERROR_OK;
220 }
221
222 u32 str7x_status(struct flash_bank_s *bank)
223 {
224 target_t *target = bank->target;
225 u32 retval;
226
227 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
228
229 return retval;
230 }
231
232 u32 str7x_result(struct flash_bank_s *bank)
233 {
234 target_t *target = bank->target;
235 u32 retval;
236
237 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
238
239 return retval;
240 }
241
242
243 int str7x_protect_check(struct flash_bank_s *bank)
244 {
245 str7x_flash_bank_t *str7x_info = bank->driver_priv;
246 target_t *target = bank->target;
247
248 int i;
249 u32 retval;
250
251 if (bank->target->state != TARGET_HALTED)
252 {
253 return ERROR_TARGET_NOT_HALTED;
254 }
255
256 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
257
258 for (i = 0; i < bank->num_sectors; i++)
259 {
260 if (retval & str7x_info->sector_bits[i])
261 bank->sectors[i].is_protected = 0;
262 else
263 bank->sectors[i].is_protected = 1;
264 }
265
266 return ERROR_OK;
267 }
268
269 int str7x_erase(struct flash_bank_s *bank, int first, int last)
270 {
271 str7x_flash_bank_t *str7x_info = bank->driver_priv;
272 target_t *target = bank->target;
273
274 int i;
275 u32 cmd;
276 u32 retval;
277 u32 b0_sectors = 0, b1_sectors = 0;
278
279 if (bank->target->state != TARGET_HALTED)
280 {
281 return ERROR_TARGET_NOT_HALTED;
282 }
283
284 for (i = first; i <= last; i++)
285 {
286 if (str7x_info->sector_bank[i] == 0)
287 b0_sectors |= str7x_info->sector_bits[i];
288 else if (str7x_info->sector_bank[i] == 1)
289 b1_sectors |= str7x_info->sector_bits[i];
290 else
291 LOG_ERROR("BUG: str7x_info->sector_bank[i] neither 0 nor 1 (%i)", str7x_info->sector_bank[i]);
292 }
293
294 if (b0_sectors)
295 {
296 LOG_DEBUG("b0_sectors: 0x%x", b0_sectors);
297
298 /* clear FLASH_ER register */
299 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
300
301 cmd = FLASH_SER;
302 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
303
304 cmd = b0_sectors;
305 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
306
307 cmd = FLASH_SER|FLASH_WMS;
308 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
309
310 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
311 usleep(1000);
312 }
313
314 retval = str7x_result(bank);
315
316 if (retval)
317 {
318 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
319 return ERROR_FLASH_OPERATION_FAILED;
320 }
321 }
322
323 if (b1_sectors)
324 {
325 LOG_DEBUG("b1_sectors: 0x%x", b1_sectors);
326
327 /* clear FLASH_ER register */
328 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
329
330 cmd = FLASH_SER;
331 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
332
333 cmd = b1_sectors;
334 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
335
336 cmd = FLASH_SER|FLASH_WMS;
337 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
338
339 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
340 usleep(1000);
341 }
342
343 retval = str7x_result(bank);
344
345 if (retval)
346 {
347 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
348 return ERROR_FLASH_OPERATION_FAILED;
349 }
350 }
351
352 for (i = first; i <= last; i++)
353 bank->sectors[i].is_erased = 1;
354
355 return ERROR_OK;
356 }
357
358 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
359 {
360 str7x_flash_bank_t *str7x_info = bank->driver_priv;
361 target_t *target = bank->target;
362 int i;
363 u32 cmd;
364 u32 retval;
365 u32 protect_blocks;
366
367 if (bank->target->state != TARGET_HALTED)
368 {
369 return ERROR_TARGET_NOT_HALTED;
370 }
371
372 protect_blocks = 0xFFFFFFFF;
373
374 if (set)
375 {
376 for (i = first; i <= last; i++)
377 protect_blocks &= ~(str7x_info->sector_bits[i]);
378 }
379
380 /* clear FLASH_ER register */
381 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
382
383 cmd = FLASH_SPR;
384 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
385
386 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
387 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
388
389 cmd = protect_blocks;
390 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
391
392 cmd = FLASH_SPR|FLASH_WMS;
393 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
394
395 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
396 usleep(1000);
397 }
398
399 retval = str7x_result(bank);
400
401 LOG_DEBUG("retval: 0x%8.8x", retval);
402
403 if (retval & FLASH_ERER)
404 return ERROR_FLASH_SECTOR_NOT_ERASED;
405 else if (retval & FLASH_WPF)
406 return ERROR_FLASH_OPERATION_FAILED;
407
408 return ERROR_OK;
409 }
410
411 int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
412 {
413 str7x_flash_bank_t *str7x_info = bank->driver_priv;
414 target_t *target = bank->target;
415 u32 buffer_size = 8192;
416 working_area_t *source;
417 u32 address = bank->base + offset;
418 reg_param_t reg_params[6];
419 armv4_5_algorithm_t armv4_5_info;
420 int retval = ERROR_OK;
421
422 u32 str7x_flash_write_code[] = {
423 /* write: */
424 0xe3a04201, /* mov r4, #0x10000000 */
425 0xe5824000, /* str r4, [r2, #0x0] */
426 0xe5821010, /* str r1, [r2, #0x10] */
427 0xe4904004, /* ldr r4, [r0], #4 */
428 0xe5824008, /* str r4, [r2, #0x8] */
429 0xe4904004, /* ldr r4, [r0], #4 */
430 0xe582400c, /* str r4, [r2, #0xc] */
431 0xe3a04209, /* mov r4, #0x90000000 */
432 0xe5824000, /* str r4, [r2, #0x0] */
433 /* busy: */
434 0xe5924000, /* ldr r4, [r2, #0x0] */
435 0xe1140005, /* tst r4, r5 */
436 0x1afffffc, /* bne busy */
437 0xe5924014, /* ldr r4, [r2, #0x14] */
438 0xe31400ff, /* tst r4, #0xff */
439 0x03140c01, /* tsteq r4, #0x100 */
440 0x1a000002, /* bne exit */
441 0xe2811008, /* add r1, r1, #0x8 */
442 0xe2533001, /* subs r3, r3, #1 */
443 0x1affffec, /* bne write */
444 /* exit: */
445 0xeafffffe, /* b exit */
446 };
447
448 /* flash write code */
449 if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
450 {
451 LOG_WARNING("no working area available, can't do block memory writes");
452 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
453 };
454
455 target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (u8*)str7x_flash_write_code);
456
457 /* memory buffer */
458 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
459 {
460 buffer_size /= 2;
461 if (buffer_size <= 256)
462 {
463 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
464 if (str7x_info->write_algorithm)
465 target_free_working_area(target, str7x_info->write_algorithm);
466
467 LOG_WARNING("no large enough working area available, can't do block memory writes");
468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
469 }
470 }
471
472 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
473 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
474 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
475
476 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
477 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
478 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
479 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
480 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
481 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
482
483 while (count > 0)
484 {
485 u32 thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
486
487 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
488
489 buf_set_u32(reg_params[0].value, 0, 32, source->address);
490 buf_set_u32(reg_params[1].value, 0, 32, address);
491 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
492 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
493 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
494
495 if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
496 {
497 LOG_ERROR("error executing str7x flash write algorithm");
498 break;
499 }
500
501 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
502 {
503 retval = ERROR_FLASH_OPERATION_FAILED;
504 break;
505 }
506
507 buffer += thisrun_count * 8;
508 address += thisrun_count * 8;
509 count -= thisrun_count;
510 }
511
512 target_free_working_area(target, source);
513 target_free_working_area(target, str7x_info->write_algorithm);
514
515 destroy_reg_param(&reg_params[0]);
516 destroy_reg_param(&reg_params[1]);
517 destroy_reg_param(&reg_params[2]);
518 destroy_reg_param(&reg_params[3]);
519 destroy_reg_param(&reg_params[4]);
520 destroy_reg_param(&reg_params[5]);
521
522 return retval;
523 }
524
525 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
526 {
527 target_t *target = bank->target;
528 str7x_flash_bank_t *str7x_info = bank->driver_priv;
529 u32 dwords_remaining = (count / 8);
530 u32 bytes_remaining = (count & 0x00000007);
531 u32 address = bank->base + offset;
532 u32 bytes_written = 0;
533 u32 cmd;
534 u32 retval;
535 u32 check_address = offset;
536 int i;
537
538 if (bank->target->state != TARGET_HALTED)
539 {
540 return ERROR_TARGET_NOT_HALTED;
541 }
542
543 if (offset & 0x7)
544 {
545 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset);
546 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
547 }
548
549 for (i = 0; i < bank->num_sectors; i++)
550 {
551 u32 sec_start = bank->sectors[i].offset;
552 u32 sec_end = sec_start + bank->sectors[i].size;
553
554 /* check if destination falls within the current sector */
555 if ((check_address >= sec_start) && (check_address < sec_end))
556 {
557 /* check if destination ends in the current sector */
558 if (offset + count < sec_end)
559 check_address = offset + count;
560 else
561 check_address = sec_end;
562 }
563 }
564
565 if (check_address != offset + count)
566 return ERROR_FLASH_DST_OUT_OF_BANK;
567
568 /* clear FLASH_ER register */
569 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
570
571 /* multiple dwords (8-byte) to be programmed? */
572 if (dwords_remaining > 0)
573 {
574 /* try using a block write */
575 if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
576 {
577 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
578 {
579 /* if block write failed (no sufficient working area),
580 * we use normal (slow) single dword accesses */
581 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
582 }
583 else if (retval == ERROR_FLASH_OPERATION_FAILED)
584 {
585 /* if an error occured, we examine the reason, and quit */
586 retval = str7x_result(bank);
587
588 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
589 return ERROR_FLASH_OPERATION_FAILED;
590 }
591 }
592 else
593 {
594 buffer += dwords_remaining * 8;
595 address += dwords_remaining * 8;
596 dwords_remaining = 0;
597 }
598 }
599
600 while (dwords_remaining > 0)
601 {
602 /* command */
603 cmd = FLASH_DWPG;
604 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
605
606 /* address */
607 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
608
609 /* data word 1 */
610 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
611 bytes_written += 4;
612
613 /* data word 2 */
614 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
615 bytes_written += 4;
616
617 /* start programming cycle */
618 cmd = FLASH_DWPG | FLASH_WMS;
619 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
620
621 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
622 {
623 usleep(1000);
624 }
625
626 retval = str7x_result(bank);
627
628 if (retval & FLASH_PGER)
629 return ERROR_FLASH_OPERATION_FAILED;
630 else if (retval & FLASH_WPF)
631 return ERROR_FLASH_OPERATION_FAILED;
632
633 dwords_remaining--;
634 address += 8;
635 }
636
637 if (bytes_remaining)
638 {
639 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
640 int i = 0;
641
642 while(bytes_remaining > 0)
643 {
644 last_dword[i++] = *(buffer + bytes_written);
645 bytes_remaining--;
646 bytes_written++;
647 }
648
649 /* command */
650 cmd = FLASH_DWPG;
651 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
652
653 /* address */
654 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
655
656 /* data word 1 */
657 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
658 bytes_written += 4;
659
660 /* data word 2 */
661 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
662 bytes_written += 4;
663
664 /* start programming cycle */
665 cmd = FLASH_DWPG | FLASH_WMS;
666 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
667
668 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
669 {
670 usleep(1000);
671 }
672
673 retval = str7x_result(bank);
674
675 if (retval & FLASH_PGER)
676 return ERROR_FLASH_OPERATION_FAILED;
677 else if (retval & FLASH_WPF)
678 return ERROR_FLASH_OPERATION_FAILED;
679 }
680
681 return ERROR_OK;
682 }
683
684 int str7x_probe(struct flash_bank_s *bank)
685 {
686 return ERROR_OK;
687 }
688
689 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
690 {
691 return ERROR_OK;
692 }
693
694 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
695 {
696 snprintf(buf, buf_size, "str7x flash driver info" );
697 return ERROR_OK;
698 }
699
700 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
701 {
702 flash_bank_t *bank;
703 target_t *target = NULL;
704 str7x_flash_bank_t *str7x_info = NULL;
705
706 u32 flash_cmd;
707 u32 retval;
708 u16 ProtectionLevel = 0;
709 u16 ProtectionRegs;
710
711 if (argc < 1)
712 {
713 command_print(cmd_ctx, "str7x disable_jtag <bank>");
714 return ERROR_OK;
715 }
716
717 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
718 if (!bank)
719 {
720 command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
721 return ERROR_OK;
722 }
723
724 str7x_info = bank->driver_priv;
725
726 target = bank->target;
727
728 if (target->state != TARGET_HALTED)
729 {
730 return ERROR_TARGET_NOT_HALTED;
731 }
732
733 /* first we get protection status */
734 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
735
736 if (!(retval & str7x_info->disable_bit))
737 {
738 ProtectionLevel = 1;
739 }
740
741 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
742 ProtectionRegs = ~(retval >> 16);
743
744 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
745 {
746 ProtectionRegs >>= 1;
747 ProtectionLevel++;
748 }
749
750 if (ProtectionLevel == 0)
751 {
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), 0x4010DFB8);
755 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
756 flash_cmd = FLASH_SPR | FLASH_WMS;
757 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
758 }
759 else
760 {
761 flash_cmd = FLASH_SPR;
762 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
763 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
764 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1<<(15+ProtectionLevel)));
765 flash_cmd = FLASH_SPR | FLASH_WMS;
766 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
767 }
768
769 return ERROR_OK;
770 }
771

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)