2b3e47fd15c8a8a9e3d71cce7a60d1c5dd849ea5
[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 .erase_check = str7x_erase_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 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 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 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 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 WARNING("overriding flash base address for STR75x device with 0x20000000");
205 bank->base = 0x20000000;
206 }
207 }
208 else
209 {
210 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 int str7x_blank_check(struct flash_bank_s *bank, int first, int last)
243 {
244 target_t *target = bank->target;
245 u8 *buffer;
246 int i;
247 int nBytes;
248
249 if ((first < 0) || (last > bank->num_sectors))
250 return ERROR_FLASH_SECTOR_INVALID;
251
252 if (bank->target->state != TARGET_HALTED)
253 {
254 return ERROR_TARGET_NOT_HALTED;
255 }
256
257 buffer = malloc(256);
258
259 for (i = first; i <= last; i++)
260 {
261 bank->sectors[i].is_erased = 1;
262
263 target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer);
264
265 for (nBytes = 0; nBytes < 256; nBytes++)
266 {
267 if (buffer[nBytes] != 0xFF)
268 {
269 bank->sectors[i].is_erased = 0;
270 break;
271 }
272 }
273 }
274
275 free(buffer);
276
277 return ERROR_OK;
278 }
279
280 int str7x_protect_check(struct flash_bank_s *bank)
281 {
282 str7x_flash_bank_t *str7x_info = bank->driver_priv;
283 target_t *target = bank->target;
284
285 int i;
286 u32 retval;
287
288 if (bank->target->state != TARGET_HALTED)
289 {
290 return ERROR_TARGET_NOT_HALTED;
291 }
292
293 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
294
295 for (i = 0; i < bank->num_sectors; i++)
296 {
297 if (retval & str7x_info->sector_bits[i])
298 bank->sectors[i].is_protected = 0;
299 else
300 bank->sectors[i].is_protected = 1;
301 }
302
303 return ERROR_OK;
304 }
305
306 int str7x_erase(struct flash_bank_s *bank, int first, int last)
307 {
308 str7x_flash_bank_t *str7x_info = bank->driver_priv;
309 target_t *target = bank->target;
310
311 int i;
312 u32 cmd;
313 u32 retval;
314 u32 b0_sectors = 0, b1_sectors = 0;
315
316 if (bank->target->state != TARGET_HALTED)
317 {
318 return ERROR_TARGET_NOT_HALTED;
319 }
320
321 for (i = first; i <= last; i++)
322 {
323 if (str7x_info->sector_bank[i] == 0)
324 b0_sectors |= str7x_info->sector_bits[i];
325 else if (str7x_info->sector_bank[i] == 1)
326 b1_sectors |= str7x_info->sector_bits[i];
327 else
328 ERROR("BUG: str7x_info->sector_bank[i] neither 0 nor 1 (%i)", str7x_info->sector_bank[i]);
329 }
330
331 if (b0_sectors)
332 {
333 DEBUG("b0_sectors: 0x%x", b0_sectors);
334
335 /* clear FLASH_ER register */
336 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
337
338 cmd = FLASH_SER;
339 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
340
341 cmd = b0_sectors;
342 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
343
344 cmd = FLASH_SER|FLASH_WMS;
345 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
346
347 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
348 usleep(1000);
349 }
350
351 retval = str7x_result(bank);
352
353 if (retval)
354 {
355 ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
356 return ERROR_FLASH_OPERATION_FAILED;
357 }
358 }
359
360 if (b1_sectors)
361 {
362 DEBUG("b1_sectors: 0x%x", b1_sectors);
363
364 /* clear FLASH_ER register */
365 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
366
367 cmd = FLASH_SER;
368 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
369
370 cmd = b1_sectors;
371 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
372
373 cmd = FLASH_SER|FLASH_WMS;
374 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
375
376 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
377 usleep(1000);
378 }
379
380 retval = str7x_result(bank);
381
382 if (retval)
383 {
384 ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
385 return ERROR_FLASH_OPERATION_FAILED;
386 }
387 }
388
389 for (i = first; i <= last; i++)
390 bank->sectors[i].is_erased = 1;
391
392 return ERROR_OK;
393 }
394
395 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
396 {
397 str7x_flash_bank_t *str7x_info = bank->driver_priv;
398 target_t *target = bank->target;
399 int i;
400 u32 cmd;
401 u32 retval;
402 u32 protect_blocks;
403
404 if (bank->target->state != TARGET_HALTED)
405 {
406 return ERROR_TARGET_NOT_HALTED;
407 }
408
409 protect_blocks = 0xFFFFFFFF;
410
411 if (set)
412 {
413 for (i = first; i <= last; i++)
414 protect_blocks &= ~(str7x_info->sector_bits[i]);
415 }
416
417 /* clear FLASH_ER register */
418 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
419
420 cmd = FLASH_SPR;
421 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
422
423 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
424 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
425
426 cmd = protect_blocks;
427 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
428
429 cmd = FLASH_SPR|FLASH_WMS;
430 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
431
432 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
433 usleep(1000);
434 }
435
436 retval = str7x_result(bank);
437
438 DEBUG("retval: 0x%8.8x", retval);
439
440 if (retval & FLASH_ERER)
441 return ERROR_FLASH_SECTOR_NOT_ERASED;
442 else if (retval & FLASH_WPF)
443 return ERROR_FLASH_OPERATION_FAILED;
444
445 return ERROR_OK;
446 }
447
448 int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
449 {
450 str7x_flash_bank_t *str7x_info = bank->driver_priv;
451 target_t *target = bank->target;
452 u32 buffer_size = 8192;
453 working_area_t *source;
454 u32 address = bank->base + offset;
455 reg_param_t reg_params[6];
456 armv4_5_algorithm_t armv4_5_info;
457 int retval = ERROR_OK;
458
459 u32 str7x_flash_write_code[] = {
460 /* write: */
461 0xe3a04201, /* mov r4, #0x10000000 */
462 0xe5824000, /* str r4, [r2, #0x0] */
463 0xe5821010, /* str r1, [r2, #0x10] */
464 0xe4904004, /* ldr r4, [r0], #4 */
465 0xe5824008, /* str r4, [r2, #0x8] */
466 0xe4904004, /* ldr r4, [r0], #4 */
467 0xe582400c, /* str r4, [r2, #0xc] */
468 0xe3a04209, /* mov r4, #0x90000000 */
469 0xe5824000, /* str r4, [r2, #0x0] */
470 /* busy: */
471 0xe5924000, /* ldr r4, [r2, #0x0] */
472 0xe1140005, /* tst r4, r5 */
473 0x1afffffc, /* bne busy */
474 0xe5924014, /* ldr r4, [r2, #0x14] */
475 0xe31400ff, /* tst r4, #0xff */
476 0x03140c01, /* tsteq r4, #0x100 */
477 0x1a000002, /* bne exit */
478 0xe2811008, /* add r1, r1, #0x8 */
479 0xe2533001, /* subs r3, r3, #1 */
480 0x1affffec, /* bne write */
481 /* exit: */
482 0xeafffffe, /* b exit */
483 };
484
485 /* flash write code */
486 if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
487 {
488 WARNING("no working area available, can't do block memory writes");
489 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
490 };
491
492 target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (u8*)str7x_flash_write_code);
493
494 /* memory buffer */
495 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
496 {
497 buffer_size /= 2;
498 if (buffer_size <= 256)
499 {
500 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
501 if (str7x_info->write_algorithm)
502 target_free_working_area(target, str7x_info->write_algorithm);
503
504 WARNING("no large enough working area available, can't do block memory writes");
505 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
506 }
507 }
508
509 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
510 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
511 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
512
513 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
514 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
515 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
516 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
517 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
518 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
519
520 while (count > 0)
521 {
522 u32 thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
523
524 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
525
526 buf_set_u32(reg_params[0].value, 0, 32, source->address);
527 buf_set_u32(reg_params[1].value, 0, 32, address);
528 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
529 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
530 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
531
532 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)
533 {
534 ERROR("error executing str7x flash write algorithm");
535 break;
536 }
537
538 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
539 {
540 retval = ERROR_FLASH_OPERATION_FAILED;
541 break;
542 }
543
544 buffer += thisrun_count * 8;
545 address += thisrun_count * 8;
546 count -= thisrun_count;
547 }
548
549 target_free_working_area(target, source);
550 target_free_working_area(target, str7x_info->write_algorithm);
551
552 destroy_reg_param(&reg_params[0]);
553 destroy_reg_param(&reg_params[1]);
554 destroy_reg_param(&reg_params[2]);
555 destroy_reg_param(&reg_params[3]);
556 destroy_reg_param(&reg_params[4]);
557 destroy_reg_param(&reg_params[5]);
558
559 return retval;
560 }
561
562 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
563 {
564 target_t *target = bank->target;
565 str7x_flash_bank_t *str7x_info = bank->driver_priv;
566 u32 dwords_remaining = (count / 8);
567 u32 bytes_remaining = (count & 0x00000007);
568 u32 address = bank->base + offset;
569 u32 bytes_written = 0;
570 u32 cmd;
571 u32 retval;
572 u32 check_address = offset;
573 int i;
574
575 if (bank->target->state != TARGET_HALTED)
576 {
577 return ERROR_TARGET_NOT_HALTED;
578 }
579
580 if (offset & 0x7)
581 {
582 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
583 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
584 }
585
586 for (i = 0; i < bank->num_sectors; i++)
587 {
588 u32 sec_start = bank->sectors[i].offset;
589 u32 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 {
594 /* check if destination ends in the current sector */
595 if (offset + count < sec_end)
596 check_address = offset + count;
597 else
598 check_address = sec_end;
599 }
600 }
601
602 if (check_address != offset + count)
603 return ERROR_FLASH_DST_OUT_OF_BANK;
604
605 /* clear FLASH_ER register */
606 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
607
608 /* multiple dwords (8-byte) to be programmed? */
609 if (dwords_remaining > 0)
610 {
611 /* try using a block write */
612 if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
613 {
614 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
615 {
616 /* if block write failed (no sufficient working area),
617 * we use normal (slow) single dword accesses */
618 WARNING("couldn't use block writes, falling back to single memory accesses");
619 }
620 else if (retval == ERROR_FLASH_OPERATION_FAILED)
621 {
622 /* if an error occured, we examine the reason, and quit */
623 retval = str7x_result(bank);
624
625 ERROR("flash writing failed with error code: 0x%x", retval);
626 return ERROR_FLASH_OPERATION_FAILED;
627 }
628 }
629 else
630 {
631 buffer += dwords_remaining * 8;
632 address += dwords_remaining * 8;
633 dwords_remaining = 0;
634 }
635 }
636
637 while (dwords_remaining > 0)
638 {
639 // command
640 cmd = FLASH_DWPG;
641 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
642
643 // address
644 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
645
646 // data word 1
647 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
648 bytes_written += 4;
649
650 // data word 2
651 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
652 bytes_written += 4;
653
654 /* start programming cycle */
655 cmd = FLASH_DWPG | FLASH_WMS;
656 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
657
658 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
659 {
660 usleep(1000);
661 }
662
663 retval = str7x_result(bank);
664
665 if (retval & FLASH_PGER)
666 return ERROR_FLASH_OPERATION_FAILED;
667 else if (retval & FLASH_WPF)
668 return ERROR_FLASH_OPERATION_FAILED;
669
670 dwords_remaining--;
671 address += 8;
672 }
673
674 if (bytes_remaining)
675 {
676 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
677 int i = 0;
678
679 while(bytes_remaining > 0)
680 {
681 last_dword[i++] = *(buffer + bytes_written);
682 bytes_remaining--;
683 bytes_written++;
684 }
685
686 // command
687 cmd = FLASH_DWPG;
688 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
689
690 // address
691 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
692
693 // data word 1
694 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
695 bytes_written += 4;
696
697 // data word 2
698 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
699 bytes_written += 4;
700
701 /* start programming cycle */
702 cmd = FLASH_DWPG | FLASH_WMS;
703 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
704
705 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
706 {
707 usleep(1000);
708 }
709
710 retval = str7x_result(bank);
711
712 if (retval & FLASH_PGER)
713 return ERROR_FLASH_OPERATION_FAILED;
714 else if (retval & FLASH_WPF)
715 return ERROR_FLASH_OPERATION_FAILED;
716 }
717
718 return ERROR_OK;
719 }
720
721 int str7x_probe(struct flash_bank_s *bank)
722 {
723 return ERROR_OK;
724 }
725
726 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
727 {
728 return ERROR_OK;
729 }
730
731 int str7x_erase_check(struct flash_bank_s *bank)
732 {
733 return str7x_blank_check(bank, 0, bank->num_sectors - 1);
734 }
735
736 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
737 {
738 snprintf(buf, buf_size, "str7x flash driver info" );
739 return ERROR_OK;
740 }
741
742 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
743 {
744 flash_bank_t *bank;
745 target_t *target = NULL;
746 str7x_flash_bank_t *str7x_info = NULL;
747
748 u32 flash_cmd;
749 u32 retval;
750 u16 ProtectionLevel = 0;
751 u16 ProtectionRegs;
752
753 if (argc < 1)
754 {
755 command_print(cmd_ctx, "str7x disable_jtag <bank>");
756 return ERROR_OK;
757 }
758
759 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
760 if (!bank)
761 {
762 command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
763 return ERROR_OK;
764 }
765
766 str7x_info = bank->driver_priv;
767
768 target = bank->target;
769
770 if (target->state != TARGET_HALTED)
771 {
772 return ERROR_TARGET_NOT_HALTED;
773 }
774
775 /* first we get protection status */
776 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
777
778 if (!(retval & str7x_info->disable_bit))
779 {
780 ProtectionLevel = 1;
781 }
782
783 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
784 ProtectionRegs = ~(retval >> 16);
785
786 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
787 {
788 ProtectionRegs >>= 1;
789 ProtectionLevel++;
790 }
791
792 if (ProtectionLevel == 0)
793 {
794 flash_cmd = FLASH_SPR;
795 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
796 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
797 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
798 flash_cmd = FLASH_SPR | FLASH_WMS;
799 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
800 }
801 else
802 {
803 flash_cmd = FLASH_SPR;
804 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
805 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
806 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1<<(15+ProtectionLevel)));
807 flash_cmd = FLASH_SPR | FLASH_WMS;
808 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
809 }
810
811 return ERROR_OK;
812 }
813

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)