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

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)