Improve str9xpec command argument parsing.
[openocd.git] / src / flash / str9xpec.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "str9xpec.h"
28 #include "arm7_9_common.h"
29
30
31 static int str9xpec_register_commands(struct command_context_s *cmd_ctx);
32 static int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
33 static int str9xpec_erase(struct flash_bank_s *bank, int first, int last);
34 static int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last);
35 static int str9xpec_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
36 static int str9xpec_probe(struct flash_bank_s *bank);
37 static int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
38 static int str9xpec_protect_check(struct flash_bank_s *bank);
39 static int str9xpec_erase_check(struct flash_bank_s *bank);
40 static int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size);
41
42 static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
43 static int str9xpec_set_address(struct flash_bank_s *bank, uint8_t sector);
44 static int str9xpec_write_options(struct flash_bank_s *bank);
45
46 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
48 static int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
49 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 static int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 static int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 static int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 static int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56
57 flash_driver_t str9xpec_flash =
58 {
59 .name = "str9xpec",
60 .register_commands = str9xpec_register_commands,
61 .flash_bank_command = str9xpec_flash_bank_command,
62 .erase = str9xpec_erase,
63 .protect = str9xpec_protect,
64 .write = str9xpec_write,
65 .probe = str9xpec_probe,
66 .auto_probe = str9xpec_probe,
67 .erase_check = str9xpec_erase_check,
68 .protect_check = str9xpec_protect_check,
69 .info = str9xpec_info
70 };
71
72 static int str9xpec_register_commands(struct command_context_s *cmd_ctx)
73 {
74 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
75
76 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
77 "enable str9xpec turbo mode");
78 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
79 "disable str9xpec turbo mode");
80 register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
81 "configure str9xpec boot sector");
82 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
83 "configure str9xpec lvd threshold");
84 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
85 "configure str9xpec lvd selection");
86 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
87 "configure str9xpec lvd warning");
88 register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
89 "read str9xpec options");
90 register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
91 "write str9xpec options");
92 register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
93 "lock str9xpec device");
94 register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
95 "unlock str9xpec device");
96 register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
97 "print part id of str9xpec flash bank <num>");
98
99 return ERROR_OK;
100 }
101
102 int str9xpec_set_instr(jtag_tap_t *tap, uint32_t new_instr, tap_state_t end_state)
103 {
104 if (tap == NULL) {
105 return ERROR_TARGET_INVALID;
106 }
107
108 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
109 {
110 scan_field_t field;
111
112 field.tap = tap;
113 field.num_bits = tap->ir_length;
114 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
115 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
116 field.in_value = NULL;
117
118 jtag_add_ir_scan(1, &field, end_state);
119
120 free(field.out_value);
121 }
122
123 return ERROR_OK;
124 }
125
126 static uint8_t str9xpec_isc_status(jtag_tap_t *tap)
127 {
128 scan_field_t field;
129 uint8_t status;
130
131 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
132 return ISC_STATUS_ERROR;
133
134 field.tap = tap;
135 field.num_bits = 8;
136 field.out_value = NULL;
137 field.in_value = &status;
138
139
140 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
141 jtag_execute_queue();
142
143 LOG_DEBUG("status: 0x%2.2x", status);
144
145 if (status & ISC_STATUS_SECURITY)
146 LOG_INFO("Device Security Bit Set");
147
148 return status;
149 }
150
151 static int str9xpec_isc_enable(struct flash_bank_s *bank)
152 {
153 uint8_t status;
154 jtag_tap_t *tap;
155 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
156
157 tap = str9xpec_info->tap;
158
159 if (str9xpec_info->isc_enable)
160 return ERROR_OK;
161
162 /* enter isc mode */
163 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
164 return ERROR_TARGET_INVALID;
165
166 /* check ISC status */
167 status = str9xpec_isc_status(tap);
168 if (status & ISC_STATUS_MODE)
169 {
170 /* we have entered isc mode */
171 str9xpec_info->isc_enable = 1;
172 LOG_DEBUG("ISC_MODE Enabled");
173 }
174
175 return ERROR_OK;
176 }
177
178 static int str9xpec_isc_disable(struct flash_bank_s *bank)
179 {
180 uint8_t status;
181 jtag_tap_t *tap;
182 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
183
184 tap = str9xpec_info->tap;
185
186 if (!str9xpec_info->isc_enable)
187 return ERROR_OK;
188
189 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
190 return ERROR_TARGET_INVALID;
191
192 /* delay to handle aborts */
193 jtag_add_sleep(50);
194
195 /* check ISC status */
196 status = str9xpec_isc_status(tap);
197 if (!(status & ISC_STATUS_MODE))
198 {
199 /* we have left isc mode */
200 str9xpec_info->isc_enable = 0;
201 LOG_DEBUG("ISC_MODE Disabled");
202 }
203
204 return ERROR_OK;
205 }
206
207 static int str9xpec_read_config(struct flash_bank_s *bank)
208 {
209 scan_field_t field;
210 uint8_t status;
211 jtag_tap_t *tap;
212
213 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
214
215 tap = str9xpec_info->tap;
216
217 LOG_DEBUG("ISC_CONFIGURATION");
218
219 /* execute ISC_CONFIGURATION command */
220 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
221
222 field.tap = tap;
223 field.num_bits = 64;
224 field.out_value = NULL;
225 field.in_value = str9xpec_info->options;
226
227
228 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
229 jtag_execute_queue();
230
231 status = str9xpec_isc_status(tap);
232
233 return status;
234 }
235
236 static int str9xpec_build_block_list(struct flash_bank_s *bank)
237 {
238 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
239
240 int i;
241 int num_sectors;
242 int b0_sectors = 0, b1_sectors = 0;
243 uint32_t offset = 0;
244 int b1_size = 0x2000;
245
246 switch (bank->size)
247 {
248 case (256 * 1024):
249 b0_sectors = 4;
250 break;
251 case (512 * 1024):
252 b0_sectors = 8;
253 break;
254 case (1024 * 1024):
255 b0_sectors = 16;
256 break;
257 case (2048 * 1024):
258 b0_sectors = 32;
259 break;
260 case (128 * 1024):
261 b1_size = 0x4000;
262 b1_sectors = 8;
263 break;
264 case (32 * 1024):
265 b1_sectors = 4;
266 break;
267 default:
268 LOG_ERROR("BUG: unknown bank->size encountered");
269 exit(-1);
270 }
271
272 num_sectors = b0_sectors + b1_sectors;
273
274 bank->num_sectors = num_sectors;
275 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
276 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
277
278 num_sectors = 0;
279
280 for (i = 0; i < b0_sectors; i++)
281 {
282 bank->sectors[num_sectors].offset = offset;
283 bank->sectors[num_sectors].size = 0x10000;
284 offset += bank->sectors[i].size;
285 bank->sectors[num_sectors].is_erased = -1;
286 bank->sectors[num_sectors].is_protected = 1;
287 str9xpec_info->sector_bits[num_sectors++] = i;
288 }
289
290 for (i = 0; i < b1_sectors; i++)
291 {
292 bank->sectors[num_sectors].offset = offset;
293 bank->sectors[num_sectors].size = b1_size;
294 offset += bank->sectors[i].size;
295 bank->sectors[num_sectors].is_erased = -1;
296 bank->sectors[num_sectors].is_protected = 1;
297 str9xpec_info->sector_bits[num_sectors++] = i + 32;
298 }
299
300 return ERROR_OK;
301 }
302
303 /* flash bank str9x <base> <size> 0 0 <target#>
304 */
305 static int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
306 {
307 str9xpec_flash_controller_t *str9xpec_info;
308 armv4_5_common_t *armv4_5 = NULL;
309 arm7_9_common_t *arm7_9 = NULL;
310 arm_jtag_t *jtag_info = NULL;
311
312 if (argc < 6)
313 {
314 LOG_WARNING("incomplete flash_bank str9x configuration");
315 return ERROR_FLASH_BANK_INVALID;
316 }
317
318 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
319 bank->driver_priv = str9xpec_info;
320
321 /* REVISIT verify that the jtag position of flash controller is
322 * right after *THIS* core, which must be a STR9xx core ...
323 */
324 armv4_5 = bank->target->arch_info;
325 arm7_9 = armv4_5->arch_info;
326 jtag_info = &arm7_9->jtag_info;
327
328 str9xpec_info->tap = bank->target->tap;
329 str9xpec_info->isc_enable = 0;
330
331 str9xpec_build_block_list(bank);
332
333 /* clear option byte register */
334 buf_set_u32(str9xpec_info->options, 0, 64, 0);
335
336 return ERROR_OK;
337 }
338
339 static int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
340 {
341 scan_field_t field;
342 uint8_t status;
343 jtag_tap_t *tap;
344 int i;
345 uint8_t *buffer = NULL;
346
347 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
348
349 tap = str9xpec_info->tap;
350
351 if (!str9xpec_info->isc_enable) {
352 str9xpec_isc_enable(bank);
353 }
354
355 if (!str9xpec_info->isc_enable) {
356 return ERROR_FLASH_OPERATION_FAILED;
357 }
358
359 buffer = calloc(CEIL(64, 8), 1);
360
361 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
362
363 for (i = first; i <= last; i++) {
364 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
365 }
366
367 /* execute ISC_BLANK_CHECK command */
368 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
369
370 field.tap = tap;
371 field.num_bits = 64;
372 field.out_value = buffer;
373 field.in_value = NULL;
374
375 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
376 jtag_add_sleep(40000);
377
378 /* read blank check result */
379 field.tap = tap;
380 field.num_bits = 64;
381 field.out_value = NULL;
382 field.in_value = buffer;
383
384 jtag_add_dr_scan(1, &field, TAP_IRPAUSE);
385 jtag_execute_queue();
386
387 status = str9xpec_isc_status(tap);
388
389 for (i = first; i <= last; i++)
390 {
391 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
392 bank->sectors[i].is_erased = 0;
393 else
394 bank->sectors[i].is_erased = 1;
395 }
396
397 free(buffer);
398
399 str9xpec_isc_disable(bank);
400
401 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
402 return ERROR_FLASH_OPERATION_FAILED;
403 return ERROR_OK;
404 }
405
406 static int str9xpec_protect_check(struct flash_bank_s *bank)
407 {
408 uint8_t status;
409 int i;
410
411 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
412
413 status = str9xpec_read_config(bank);
414
415 for (i = 0; i < bank->num_sectors; i++)
416 {
417 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
418 bank->sectors[i].is_protected = 1;
419 else
420 bank->sectors[i].is_protected = 0;
421 }
422
423 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
424 return ERROR_FLASH_OPERATION_FAILED;
425 return ERROR_OK;
426 }
427
428 static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
429 {
430 scan_field_t field;
431 uint8_t status;
432 jtag_tap_t *tap;
433 int i;
434 uint8_t *buffer = NULL;
435
436 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
437
438 tap = str9xpec_info->tap;
439
440 if (!str9xpec_info->isc_enable) {
441 str9xpec_isc_enable(bank);
442 }
443
444 if (!str9xpec_info->isc_enable) {
445 return ISC_STATUS_ERROR;
446 }
447
448 buffer = calloc(CEIL(64, 8), 1);
449
450 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
451
452 /* last bank: 0xFF signals a full erase (unlock complete device) */
453 /* last bank: 0xFE signals a option byte erase */
454 if (last == 0xFF)
455 {
456 for (i = 0; i < 64; i++) {
457 buf_set_u32(buffer, i, 1, 1);
458 }
459 }
460 else if (last == 0xFE)
461 {
462 buf_set_u32(buffer, 49, 1, 1);
463 }
464 else
465 {
466 for (i = first; i <= last; i++) {
467 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
468 }
469 }
470
471 LOG_DEBUG("ISC_ERASE");
472
473 /* execute ISC_ERASE command */
474 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
475
476 field.tap = tap;
477 field.num_bits = 64;
478 field.out_value = buffer;
479 field.in_value = NULL;
480
481 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
482 jtag_execute_queue();
483
484 jtag_add_sleep(10);
485
486 /* wait for erase completion */
487 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
488 alive_sleep(1);
489 }
490
491 free(buffer);
492
493 str9xpec_isc_disable(bank);
494
495 return status;
496 }
497
498 static int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
499 {
500 int status;
501
502 status = str9xpec_erase_area(bank, first, last);
503
504 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
505 return ERROR_FLASH_OPERATION_FAILED;
506
507 return ERROR_OK;
508 }
509
510 static int str9xpec_lock_device(struct flash_bank_s *bank)
511 {
512 scan_field_t field;
513 uint8_t status;
514 jtag_tap_t *tap;
515 str9xpec_flash_controller_t *str9xpec_info = NULL;
516
517 str9xpec_info = bank->driver_priv;
518 tap = str9xpec_info->tap;
519
520 if (!str9xpec_info->isc_enable) {
521 str9xpec_isc_enable(bank);
522 }
523
524 if (!str9xpec_info->isc_enable) {
525 return ISC_STATUS_ERROR;
526 }
527
528 /* set security address */
529 str9xpec_set_address(bank, 0x80);
530
531 /* execute ISC_PROGRAM command */
532 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
533
534 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
535
536 do {
537 field.tap = tap;
538 field.num_bits = 8;
539 field.out_value = NULL;
540 field.in_value = &status;
541
542 jtag_add_dr_scan(1, &field, jtag_get_end_state());
543 jtag_execute_queue();
544
545 } while (!(status & ISC_STATUS_BUSY));
546
547 str9xpec_isc_disable(bank);
548
549 return status;
550 }
551
552 static int str9xpec_unlock_device(struct flash_bank_s *bank)
553 {
554 uint8_t status;
555
556 status = str9xpec_erase_area(bank, 0, 255);
557
558 return status;
559 }
560
561 static int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
562 {
563 uint8_t status;
564 int i;
565
566 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
567
568 status = str9xpec_read_config(bank);
569
570 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
571 return ERROR_FLASH_OPERATION_FAILED;
572
573 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
574
575 /* last bank: 0xFF signals a full device protect */
576 if (last == 0xFF)
577 {
578 if (set)
579 {
580 status = str9xpec_lock_device(bank);
581 }
582 else
583 {
584 /* perform full erase to unlock device */
585 status = str9xpec_unlock_device(bank);
586 }
587 }
588 else
589 {
590 for (i = first; i <= last; i++)
591 {
592 if (set)
593 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
594 else
595 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
596 }
597
598 status = str9xpec_write_options(bank);
599 }
600
601 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
602 return ERROR_FLASH_OPERATION_FAILED;
603
604 return ERROR_OK;
605 }
606
607 static int str9xpec_set_address(struct flash_bank_s *bank, uint8_t sector)
608 {
609 jtag_tap_t *tap;
610 scan_field_t field;
611 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
612
613 tap = str9xpec_info->tap;
614
615 /* set flash controller address */
616 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
617
618 field.tap = tap;
619 field.num_bits = 8;
620 field.out_value = &sector;
621 field.in_value = NULL;
622
623 jtag_add_dr_scan(1, &field, jtag_get_end_state());
624
625 return ERROR_OK;
626 }
627
628 static int str9xpec_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
629 {
630 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
631 uint32_t dwords_remaining = (count / 8);
632 uint32_t bytes_remaining = (count & 0x00000007);
633 uint32_t bytes_written = 0;
634 uint8_t status;
635 uint32_t check_address = offset;
636 jtag_tap_t *tap;
637 scan_field_t field;
638 uint8_t *scanbuf;
639 int i;
640 int first_sector = 0;
641 int last_sector = 0;
642
643 tap = str9xpec_info->tap;
644
645 if (!str9xpec_info->isc_enable) {
646 str9xpec_isc_enable(bank);
647 }
648
649 if (!str9xpec_info->isc_enable) {
650 return ERROR_FLASH_OPERATION_FAILED;
651 }
652
653 if (offset & 0x7)
654 {
655 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
656 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
657 }
658
659 for (i = 0; i < bank->num_sectors; i++)
660 {
661 uint32_t sec_start = bank->sectors[i].offset;
662 uint32_t sec_end = sec_start + bank->sectors[i].size;
663
664 /* check if destination falls within the current sector */
665 if ((check_address >= sec_start) && (check_address < sec_end))
666 {
667 /* check if destination ends in the current sector */
668 if (offset + count < sec_end)
669 check_address = offset + count;
670 else
671 check_address = sec_end;
672 }
673
674 if ((offset >= sec_start) && (offset < sec_end)) {
675 first_sector = i;
676 }
677
678 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
679 last_sector = i;
680 }
681 }
682
683 if (check_address != offset + count)
684 return ERROR_FLASH_DST_OUT_OF_BANK;
685
686 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
687
688 scanbuf = calloc(CEIL(64, 8), 1);
689
690 LOG_DEBUG("ISC_PROGRAM");
691
692 for (i = first_sector; i <= last_sector; i++)
693 {
694 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
695
696 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
697
698 while (dwords_remaining > 0)
699 {
700 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
701
702 field.tap = tap;
703 field.num_bits = 64;
704 field.out_value = (buffer + bytes_written);
705 field.in_value = NULL;
706
707 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
708
709 /* small delay before polling */
710 jtag_add_sleep(50);
711
712 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
713
714 do {
715 field.tap = tap;
716 field.num_bits = 8;
717 field.out_value = NULL;
718 field.in_value = scanbuf;
719
720 jtag_add_dr_scan(1, &field, jtag_get_end_state());
721 jtag_execute_queue();
722
723 status = buf_get_u32(scanbuf, 0, 8);
724
725 } while (!(status & ISC_STATUS_BUSY));
726
727 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
728 return ERROR_FLASH_OPERATION_FAILED;
729
730 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
731 return ERROR_FLASH_OPERATION_FAILED; */
732
733 dwords_remaining--;
734 bytes_written += 8;
735 }
736 }
737
738 if (bytes_remaining)
739 {
740 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
741 int i = 0;
742
743 while (bytes_remaining > 0)
744 {
745 last_dword[i++] = *(buffer + bytes_written);
746 bytes_remaining--;
747 bytes_written++;
748 }
749
750 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
751
752 field.tap = tap;
753 field.num_bits = 64;
754 field.out_value = last_dword;
755 field.in_value = NULL;
756
757 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
758
759 /* small delay before polling */
760 jtag_add_sleep(50);
761
762 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
763
764 do {
765 field.tap = tap;
766 field.num_bits = 8;
767 field.out_value = NULL;
768 field.in_value = scanbuf;
769
770 jtag_add_dr_scan(1, &field, jtag_get_end_state());
771 jtag_execute_queue();
772
773 status = buf_get_u32(scanbuf, 0, 8);
774
775 } while (!(status & ISC_STATUS_BUSY));
776
777 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
778 return ERROR_FLASH_OPERATION_FAILED;
779
780 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
781 return ERROR_FLASH_OPERATION_FAILED; */
782 }
783
784 free(scanbuf);
785
786 str9xpec_isc_disable(bank);
787
788 return ERROR_OK;
789 }
790
791 static int str9xpec_probe(struct flash_bank_s *bank)
792 {
793 return ERROR_OK;
794 }
795
796 static int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
797 {
798 scan_field_t field;
799 uint8_t *buffer = NULL;
800 jtag_tap_t *tap;
801 uint32_t idcode;
802 str9xpec_flash_controller_t *str9xpec_info = NULL;
803
804 if (argc < 1)
805 return ERROR_COMMAND_SYNTAX_ERROR;
806
807 flash_bank_t *bank;
808 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
809 if (ERROR_OK != retval)
810 return retval;
811
812 str9xpec_info = bank->driver_priv;
813 tap = str9xpec_info->tap;
814
815 buffer = calloc(CEIL(32, 8), 1);
816
817 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
818
819 field.tap = tap;
820 field.num_bits = 32;
821 field.out_value = NULL;
822 field.in_value = buffer;
823
824 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
825 jtag_execute_queue();
826
827 idcode = buf_get_u32(buffer, 0, 32);
828
829 command_print(cmd_ctx, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
830
831 free(buffer);
832
833 return ERROR_OK;
834 }
835
836 static int str9xpec_erase_check(struct flash_bank_s *bank)
837 {
838 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
839 }
840
841 static int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
842 {
843 snprintf(buf, buf_size, "str9xpec flash driver info");
844 return ERROR_OK;
845 }
846
847 static int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
848 {
849 uint8_t status;
850 str9xpec_flash_controller_t *str9xpec_info = NULL;
851
852 if (argc < 1)
853 {
854 command_print(cmd_ctx, "str9xpec options_read <bank>");
855 return ERROR_OK;
856 }
857
858 flash_bank_t *bank;
859 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
860 if (ERROR_OK != retval)
861 return retval;
862
863 str9xpec_info = bank->driver_priv;
864
865 status = str9xpec_read_config(bank);
866
867 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
868 return ERROR_FLASH_OPERATION_FAILED;
869
870 /* boot bank */
871 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
872 command_print(cmd_ctx, "CS Map: bank1");
873 else
874 command_print(cmd_ctx, "CS Map: bank0");
875
876 /* OTP lock */
877 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
878 command_print(cmd_ctx, "OTP Lock: OTP Locked");
879 else
880 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
881
882 /* LVD Threshold */
883 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
884 command_print(cmd_ctx, "LVD Threshold: 2.7v");
885 else
886 command_print(cmd_ctx, "LVD Threshold: 2.4v");
887
888 /* LVD reset warning */
889 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
890 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
891 else
892 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
893
894 /* LVD reset select */
895 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
896 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
897 else
898 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
899
900 return ERROR_OK;
901 }
902
903 static int str9xpec_write_options(struct flash_bank_s *bank)
904 {
905 scan_field_t field;
906 uint8_t status;
907 jtag_tap_t *tap;
908 str9xpec_flash_controller_t *str9xpec_info = NULL;
909
910 str9xpec_info = bank->driver_priv;
911 tap = str9xpec_info->tap;
912
913 /* erase config options first */
914 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
915
916 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
917 return status;
918
919 if (!str9xpec_info->isc_enable) {
920 str9xpec_isc_enable(bank);
921 }
922
923 if (!str9xpec_info->isc_enable) {
924 return ISC_STATUS_ERROR;
925 }
926
927 /* according to data 64th bit has to be set */
928 buf_set_u32(str9xpec_info->options, 63, 1, 1);
929
930 /* set option byte address */
931 str9xpec_set_address(bank, 0x50);
932
933 /* execute ISC_PROGRAM command */
934 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
935
936 field.tap = tap;
937 field.num_bits = 64;
938 field.out_value = str9xpec_info->options;
939 field.in_value = NULL;
940
941 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
942
943 /* small delay before polling */
944 jtag_add_sleep(50);
945
946 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
947
948 do {
949 field.tap = tap;
950 field.num_bits = 8;
951 field.out_value = NULL;
952 field.in_value = &status;
953
954 jtag_add_dr_scan(1, &field, jtag_get_end_state());
955 jtag_execute_queue();
956
957 } while (!(status & ISC_STATUS_BUSY));
958
959 str9xpec_isc_disable(bank);
960
961 return status;
962 }
963
964 static int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
965 {
966 uint8_t status;
967
968 if (argc < 1)
969 {
970 command_print(cmd_ctx, "str9xpec options_write <bank>");
971 return ERROR_OK;
972 }
973
974 flash_bank_t *bank;
975 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
976 if (ERROR_OK != retval)
977 return retval;
978
979 status = str9xpec_write_options(bank);
980
981 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
982 return ERROR_FLASH_OPERATION_FAILED;
983
984 return ERROR_OK;
985 }
986
987 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
988 {
989 str9xpec_flash_controller_t *str9xpec_info = NULL;
990
991 if (argc < 2)
992 {
993 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0 | bank1>");
994 return ERROR_OK;
995 }
996
997 flash_bank_t *bank;
998 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
999 if (ERROR_OK != retval)
1000 return retval;
1001
1002 str9xpec_info = bank->driver_priv;
1003
1004 if (strcmp(args[1], "bank1") == 0)
1005 {
1006 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1007 }
1008 else
1009 {
1010 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1011 }
1012
1013 return ERROR_OK;
1014 }
1015
1016 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1017 {
1018 str9xpec_flash_controller_t *str9xpec_info = NULL;
1019
1020 if (argc < 2)
1021 {
1022 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
1023 return ERROR_OK;
1024 }
1025
1026 flash_bank_t *bank;
1027 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1028 if (ERROR_OK != retval)
1029 return retval;
1030
1031 str9xpec_info = bank->driver_priv;
1032
1033 if (strcmp(args[1], "2.7v") == 0)
1034 {
1035 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1036 }
1037 else
1038 {
1039 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1040 }
1041
1042 return ERROR_OK;
1043 }
1044
1045 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1046 {
1047 str9xpec_flash_controller_t *str9xpec_info = NULL;
1048
1049 if (argc < 2)
1050 {
1051 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1052 return ERROR_OK;
1053 }
1054
1055 flash_bank_t *bank;
1056 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1057 if (ERROR_OK != retval)
1058 return retval;
1059
1060 str9xpec_info = bank->driver_priv;
1061
1062 if (strcmp(args[1], "vdd_vddq") == 0)
1063 {
1064 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1065 }
1066 else
1067 {
1068 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1069 }
1070
1071 return ERROR_OK;
1072 }
1073
1074 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1075 {
1076 str9xpec_flash_controller_t *str9xpec_info = NULL;
1077
1078 if (argc < 2)
1079 {
1080 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1081 return ERROR_OK;
1082 }
1083
1084 flash_bank_t *bank;
1085 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1086 if (ERROR_OK != retval)
1087 return retval;
1088
1089 str9xpec_info = bank->driver_priv;
1090
1091 if (strcmp(args[1], "vdd_vddq") == 0)
1092 {
1093 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1094 }
1095 else
1096 {
1097 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1098 }
1099
1100 return ERROR_OK;
1101 }
1102
1103 static int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1104 {
1105 uint8_t status;
1106
1107 if (argc < 1)
1108 {
1109 command_print(cmd_ctx, "str9xpec lock <bank>");
1110 return ERROR_OK;
1111 }
1112
1113 flash_bank_t *bank;
1114 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1115 if (ERROR_OK != retval)
1116 return retval;
1117
1118 status = str9xpec_lock_device(bank);
1119
1120 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1121 return ERROR_FLASH_OPERATION_FAILED;
1122
1123 return ERROR_OK;
1124 }
1125
1126 static int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1127 {
1128 uint8_t status;
1129
1130 if (argc < 1)
1131 {
1132 command_print(cmd_ctx, "str9xpec unlock <bank>");
1133 return ERROR_OK;
1134 }
1135
1136 flash_bank_t *bank;
1137 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1138 if (ERROR_OK != retval)
1139 return retval;
1140
1141 status = str9xpec_unlock_device(bank);
1142
1143 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1144 return ERROR_FLASH_OPERATION_FAILED;
1145
1146 return ERROR_OK;
1147 }
1148
1149 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1150 {
1151 jtag_tap_t *tap0;
1152 jtag_tap_t *tap1;
1153 jtag_tap_t *tap2;
1154 str9xpec_flash_controller_t *str9xpec_info = NULL;
1155
1156 if (argc < 1)
1157 {
1158 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1159 return ERROR_OK;
1160 }
1161
1162 flash_bank_t *bank;
1163 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1164 if (ERROR_OK != retval)
1165 return retval;
1166
1167 str9xpec_info = bank->driver_priv;
1168
1169 tap0 = str9xpec_info->tap;
1170
1171 /* remove arm core from chain - enter turbo mode */
1172 tap1 = tap0->next_tap;
1173 if (tap1 == NULL)
1174 {
1175 /* things are *WRONG* */
1176 command_print(cmd_ctx,"**STR9FLASH** (tap1) invalid chain?");
1177 return ERROR_OK;
1178 }
1179 tap2 = tap1->next_tap;
1180 if (tap2 == NULL)
1181 {
1182 /* things are *WRONG* */
1183 command_print(cmd_ctx,"**STR9FLASH** (tap2) invalid chain?");
1184 return ERROR_OK;
1185 }
1186
1187 /* enable turbo mode - TURBO-PROG-ENABLE */
1188 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1189 if ((retval = jtag_execute_queue()) != ERROR_OK)
1190 return retval;
1191
1192 /* modify scan chain - str9 core has been removed */
1193 tap1->enabled = 0;
1194
1195 return ERROR_OK;
1196 }
1197
1198 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1199 {
1200 jtag_tap_t *tap;
1201 str9xpec_flash_controller_t *str9xpec_info = NULL;
1202
1203 if (argc < 1)
1204 {
1205 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1206 return ERROR_OK;
1207 }
1208
1209 flash_bank_t *bank;
1210 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1211 if (ERROR_OK != retval)
1212 return retval;
1213
1214 str9xpec_info = bank->driver_priv;
1215 tap = str9xpec_info->tap;
1216
1217 if (tap == NULL)
1218 return ERROR_FAIL;
1219
1220 /* exit turbo mode via RESET */
1221 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1222 jtag_add_tlr();
1223 jtag_execute_queue();
1224
1225 /* restore previous scan chain */
1226 if (tap->next_tap) {
1227 tap->next_tap->enabled = 1;
1228 }
1229
1230 return ERROR_OK;
1231 }

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)