]> git.sur5r.net Git - openocd/blob - src/flash/str9xpec.c
711ee7ae77a7ce60203ba96ea816c99c89a540ba
[openocd] / 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 }