Remove whitespace that occurs before ')'.
[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 /* find out jtag position of flash controller
322 * it is always after the arm966 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 = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
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 flash_bank_t *bank;
799 scan_field_t field;
800 uint8_t *buffer = NULL;
801 jtag_tap_t *tap;
802 uint32_t idcode;
803 str9xpec_flash_controller_t *str9xpec_info = NULL;
804
805 if (argc < 1)
806 {
807 return ERROR_COMMAND_SYNTAX_ERROR;
808 }
809
810 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
811 if (!bank)
812 {
813 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
814 return ERROR_OK;
815 }
816
817 str9xpec_info = bank->driver_priv;
818 tap = str9xpec_info->tap;
819
820 buffer = calloc(CEIL(32, 8), 1);
821
822 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
823
824 field.tap = tap;
825 field.num_bits = 32;
826 field.out_value = NULL;
827 field.in_value = buffer;
828
829 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
830 jtag_execute_queue();
831
832 idcode = buf_get_u32(buffer, 0, 32);
833
834 command_print(cmd_ctx, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
835
836 free(buffer);
837
838 return ERROR_OK;
839 }
840
841 static int str9xpec_erase_check(struct flash_bank_s *bank)
842 {
843 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
844 }
845
846 static int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
847 {
848 snprintf(buf, buf_size, "str9xpec flash driver info");
849 return ERROR_OK;
850 }
851
852 static int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
853 {
854 flash_bank_t *bank;
855 uint8_t status;
856 str9xpec_flash_controller_t *str9xpec_info = NULL;
857
858 if (argc < 1)
859 {
860 command_print(cmd_ctx, "str9xpec options_read <bank>");
861 return ERROR_OK;
862 }
863
864 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
865 if (!bank)
866 {
867 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
868 return ERROR_OK;
869 }
870
871 str9xpec_info = bank->driver_priv;
872
873 status = str9xpec_read_config(bank);
874
875 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
876 return ERROR_FLASH_OPERATION_FAILED;
877
878 /* boot bank */
879 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
880 command_print(cmd_ctx, "CS Map: bank1");
881 else
882 command_print(cmd_ctx, "CS Map: bank0");
883
884 /* OTP lock */
885 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
886 command_print(cmd_ctx, "OTP Lock: OTP Locked");
887 else
888 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
889
890 /* LVD Threshold */
891 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
892 command_print(cmd_ctx, "LVD Threshold: 2.7v");
893 else
894 command_print(cmd_ctx, "LVD Threshold: 2.4v");
895
896 /* LVD reset warning */
897 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
898 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
899 else
900 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
901
902 /* LVD reset select */
903 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
904 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
905 else
906 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
907
908 return ERROR_OK;
909 }
910
911 static int str9xpec_write_options(struct flash_bank_s *bank)
912 {
913 scan_field_t field;
914 uint8_t status;
915 jtag_tap_t *tap;
916 str9xpec_flash_controller_t *str9xpec_info = NULL;
917
918 str9xpec_info = bank->driver_priv;
919 tap = str9xpec_info->tap;
920
921 /* erase config options first */
922 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
923
924 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
925 return status;
926
927 if (!str9xpec_info->isc_enable) {
928 str9xpec_isc_enable(bank);
929 }
930
931 if (!str9xpec_info->isc_enable) {
932 return ISC_STATUS_ERROR;
933 }
934
935 /* according to data 64th bit has to be set */
936 buf_set_u32(str9xpec_info->options, 63, 1, 1);
937
938 /* set option byte address */
939 str9xpec_set_address(bank, 0x50);
940
941 /* execute ISC_PROGRAM command */
942 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
943
944 field.tap = tap;
945 field.num_bits = 64;
946 field.out_value = str9xpec_info->options;
947 field.in_value = NULL;
948
949 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
950
951 /* small delay before polling */
952 jtag_add_sleep(50);
953
954 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
955
956 do {
957 field.tap = tap;
958 field.num_bits = 8;
959 field.out_value = NULL;
960 field.in_value = &status;
961
962 jtag_add_dr_scan(1, &field, jtag_get_end_state());
963 jtag_execute_queue();
964
965 } while (!(status & ISC_STATUS_BUSY));
966
967 str9xpec_isc_disable(bank);
968
969 return status;
970 }
971
972 static int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
973 {
974 flash_bank_t *bank;
975 uint8_t status;
976
977 if (argc < 1)
978 {
979 command_print(cmd_ctx, "str9xpec options_write <bank>");
980 return ERROR_OK;
981 }
982
983 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
984 if (!bank)
985 {
986 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
987 return ERROR_OK;
988 }
989
990 status = str9xpec_write_options(bank);
991
992 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
993 return ERROR_FLASH_OPERATION_FAILED;
994
995 return ERROR_OK;
996 }
997
998 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
999 {
1000 flash_bank_t *bank;
1001 str9xpec_flash_controller_t *str9xpec_info = NULL;
1002
1003 if (argc < 2)
1004 {
1005 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0 | bank1>");
1006 return ERROR_OK;
1007 }
1008
1009 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1010 if (!bank)
1011 {
1012 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1013 return ERROR_OK;
1014 }
1015
1016 str9xpec_info = bank->driver_priv;
1017
1018 if (strcmp(args[1], "bank1") == 0)
1019 {
1020 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1021 }
1022 else
1023 {
1024 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1025 }
1026
1027 return ERROR_OK;
1028 }
1029
1030 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1031 {
1032 flash_bank_t *bank;
1033 str9xpec_flash_controller_t *str9xpec_info = NULL;
1034
1035 if (argc < 2)
1036 {
1037 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
1038 return ERROR_OK;
1039 }
1040
1041 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1042 if (!bank)
1043 {
1044 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1045 return ERROR_OK;
1046 }
1047
1048 str9xpec_info = bank->driver_priv;
1049
1050 if (strcmp(args[1], "2.7v") == 0)
1051 {
1052 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1053 }
1054 else
1055 {
1056 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1057 }
1058
1059 return ERROR_OK;
1060 }
1061
1062 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1063 {
1064 flash_bank_t *bank;
1065 str9xpec_flash_controller_t *str9xpec_info = NULL;
1066
1067 if (argc < 2)
1068 {
1069 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1070 return ERROR_OK;
1071 }
1072
1073 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1074 if (!bank)
1075 {
1076 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1077 return ERROR_OK;
1078 }
1079
1080 str9xpec_info = bank->driver_priv;
1081
1082 if (strcmp(args[1], "vdd_vddq") == 0)
1083 {
1084 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1085 }
1086 else
1087 {
1088 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1089 }
1090
1091 return ERROR_OK;
1092 }
1093
1094 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1095 {
1096 flash_bank_t *bank;
1097 str9xpec_flash_controller_t *str9xpec_info = NULL;
1098
1099 if (argc < 2)
1100 {
1101 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1102 return ERROR_OK;
1103 }
1104
1105 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1106 if (!bank)
1107 {
1108 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1109 return ERROR_OK;
1110 }
1111
1112 str9xpec_info = bank->driver_priv;
1113
1114 if (strcmp(args[1], "vdd_vddq") == 0)
1115 {
1116 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1117 }
1118 else
1119 {
1120 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1121 }
1122
1123 return ERROR_OK;
1124 }
1125
1126 static int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1127 {
1128 uint8_t status;
1129 flash_bank_t *bank;
1130
1131 if (argc < 1)
1132 {
1133 command_print(cmd_ctx, "str9xpec lock <bank>");
1134 return ERROR_OK;
1135 }
1136
1137 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1138 if (!bank)
1139 {
1140 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1141 return ERROR_OK;
1142 }
1143
1144 status = str9xpec_lock_device(bank);
1145
1146 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1147 return ERROR_FLASH_OPERATION_FAILED;
1148
1149 return ERROR_OK;
1150 }
1151
1152 static int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1153 {
1154 uint8_t status;
1155 flash_bank_t *bank;
1156
1157 if (argc < 1)
1158 {
1159 command_print(cmd_ctx, "str9xpec unlock <bank>");
1160 return ERROR_OK;
1161 }
1162
1163 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1164 if (!bank)
1165 {
1166 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1167 return ERROR_OK;
1168 }
1169
1170 status = str9xpec_unlock_device(bank);
1171
1172 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1173 return ERROR_FLASH_OPERATION_FAILED;
1174
1175 return ERROR_OK;
1176 }
1177
1178 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1179 {
1180 int retval;
1181 flash_bank_t *bank;
1182 jtag_tap_t *tap0;
1183 jtag_tap_t *tap1;
1184 jtag_tap_t *tap2;
1185 str9xpec_flash_controller_t *str9xpec_info = NULL;
1186
1187 if (argc < 1)
1188 {
1189 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1190 return ERROR_OK;
1191 }
1192
1193 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1194 if (!bank)
1195 {
1196 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1197 return ERROR_OK;
1198 }
1199
1200 str9xpec_info = bank->driver_priv;
1201
1202 tap0 = str9xpec_info->tap;
1203
1204 /* remove arm core from chain - enter turbo mode */
1205 tap1 = tap0->next_tap;
1206 if (tap1 == NULL)
1207 {
1208 /* things are *WRONG* */
1209 command_print(cmd_ctx,"**STR9FLASH** (tap1) invalid chain?");
1210 return ERROR_OK;
1211 }
1212 tap2 = tap1->next_tap;
1213 if (tap2 == NULL)
1214 {
1215 /* things are *WRONG* */
1216 command_print(cmd_ctx,"**STR9FLASH** (tap2) invalid chain?");
1217 return ERROR_OK;
1218 }
1219
1220 /* enable turbo mode - TURBO-PROG-ENABLE */
1221 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1222 if ((retval = jtag_execute_queue()) != ERROR_OK)
1223 return retval;
1224
1225 /* modify scan chain - str9 core has been removed */
1226 tap1->enabled = 0;
1227
1228 return ERROR_OK;
1229 }
1230
1231 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1232 {
1233 flash_bank_t *bank;
1234 jtag_tap_t *tap;
1235 str9xpec_flash_controller_t *str9xpec_info = NULL;
1236
1237 if (argc < 1)
1238 {
1239 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1240 return ERROR_OK;
1241 }
1242
1243 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1244 if (!bank)
1245 {
1246 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1247 return ERROR_OK;
1248 }
1249
1250 str9xpec_info = bank->driver_priv;
1251 tap = str9xpec_info->tap;
1252
1253 if (tap == NULL)
1254 return ERROR_FAIL;
1255
1256 /* exit turbo mode via RESET */
1257 str9xpec_set_instr(tap, ISC_NOOP, TAP_RESET);
1258 jtag_execute_queue();
1259
1260 /* restore previous scan chain */
1261 if (tap->next_tap) {
1262 tap->next_tap->enabled = 1;
1263 }
1264
1265 return ERROR_OK;
1266 }

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)