- added autoprobe functionality
[openocd.git] / src / flash / str9xpec.c
bloba9a24bfb58bb5a74dd9301e79b1b8f6f4f1eff70
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "replacements.h"
26 #include "str9xpec.h"
27 #include "flash.h"
28 #include "target.h"
29 #include "log.h"
30 #include "armv4_5.h"
31 #include "arm7_9_common.h"
32 #include "jtag.h"
33 #include "binarybuffer.h"
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <getopt.h>
40 str9xpec_mem_layout_t mem_layout_str9pec[] = {
41 {0x00000000, 0x10000, 0},
42 {0x00010000, 0x10000, 1},
43 {0x00020000, 0x10000, 2},
44 {0x00030000, 0x10000, 3},
45 {0x00040000, 0x10000, 4},
46 {0x00050000, 0x10000, 5},
47 {0x00060000, 0x10000, 6},
48 {0x00070000, 0x10000, 7},
49 {0x00080000, 0x02000, 32},
50 {0x00082000, 0x02000, 33},
51 {0x00084000, 0x02000, 34},
52 {0x00086000, 0x02000, 35}
55 int str9xpec_register_commands(struct command_context_s *cmd_ctx);
56 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
57 int str9xpec_erase(struct flash_bank_s *bank, int first, int last);
58 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last);
59 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
60 int str9xpec_probe(struct flash_bank_s *bank);
61 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
62 int str9xpec_protect_check(struct flash_bank_s *bank);
63 int str9xpec_erase_check(struct flash_bank_s *bank);
64 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size);
66 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
67 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector);
68 int str9xpec_write_options(struct flash_bank_s *bank);
70 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
71 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
72 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
73 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
74 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
75 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
76 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
77 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
78 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
79 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
81 flash_driver_t str9xpec_flash =
83 .name = "str9xpec",
84 .register_commands = str9xpec_register_commands,
85 .flash_bank_command = str9xpec_flash_bank_command,
86 .erase = str9xpec_erase,
87 .protect = str9xpec_protect,
88 .write = str9xpec_write,
89 .probe = str9xpec_probe,
90 .auto_probe = str9xpec_probe,
91 .erase_check = str9xpec_erase_check,
92 .protect_check = str9xpec_protect_check,
93 .info = str9xpec_info
96 int str9xpec_register_commands(struct command_context_s *cmd_ctx)
98 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
100 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
101 "enable str9xpec turbo mode");
102 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
103 "disable str9xpec turbo mode");
104 register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
105 "configure str9xpec boot sector");
106 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
107 "configure str9xpec lvd threshold");
108 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
109 "configure str9xpec lvd selection");
110 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
111 "configure str9xpec lvd warning");
112 register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
113 "read str9xpec options");
114 register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
115 "write str9xpec options");
116 register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
117 "lock str9xpec device");
118 register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
119 "unlock str9xpec device");
120 register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
121 "print part id of str9xpec flash bank <num>");
123 return ERROR_OK;
126 int str9xpec_set_instr(int chain_pos, u32 new_instr, enum tap_state end_state)
128 jtag_device_t *device = jtag_get_device(chain_pos);
130 if (device == NULL)
132 DEBUG("Invalid Target");
133 return ERROR_TARGET_INVALID;
136 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
138 scan_field_t field;
140 field.device = chain_pos;
141 field.num_bits = device->ir_length;
142 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
143 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
144 field.out_mask = NULL;
145 field.in_value = NULL;
146 field.in_check_value = NULL;
147 field.in_check_mask = NULL;
148 field.in_handler = NULL;
149 field.in_handler_priv = NULL;
151 jtag_add_ir_scan(1, &field, end_state, NULL);
153 free(field.out_value);
156 return ERROR_OK;
159 u8 str9xpec_isc_status(int chain_pos)
161 scan_field_t field;
162 u8 status;
164 if (str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI) != ERROR_OK)
165 return ISC_STATUS_ERROR;
167 field.device = chain_pos;
168 field.num_bits = 8;
169 field.out_value = NULL;
170 field.out_mask = NULL;
171 field.in_value = &status;
172 field.in_check_value = NULL;
173 field.in_check_mask = NULL;
174 field.in_handler = NULL;
175 field.in_handler_priv = NULL;
177 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
178 jtag_execute_queue();
180 DEBUG("status: 0x%2.2x", status);
182 if (status & ISC_STATUS_SECURITY)
183 INFO("Device Security Bit Set");
185 return status;
188 int str9xpec_isc_enable(struct flash_bank_s *bank)
190 u8 status;
191 u32 chain_pos;
192 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
194 chain_pos = str9xpec_info->chain_pos;
196 if (str9xpec_info->isc_enable)
197 return ERROR_OK;
199 /* enter isc mode */
200 if (str9xpec_set_instr(chain_pos, ISC_ENABLE, TAP_RTI) != ERROR_OK)
201 return ERROR_TARGET_INVALID;
203 /* check ISC status */
204 status = str9xpec_isc_status(chain_pos);
205 if (status & ISC_STATUS_MODE)
207 /* we have entered isc mode */
208 str9xpec_info->isc_enable = 1;
209 DEBUG("ISC_MODE Enabled");
212 return ERROR_OK;
215 int str9xpec_isc_disable(struct flash_bank_s *bank)
217 u8 status;
218 u32 chain_pos;
219 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
221 chain_pos = str9xpec_info->chain_pos;
223 if (!str9xpec_info->isc_enable)
224 return ERROR_OK;
226 if (str9xpec_set_instr(chain_pos, ISC_DISABLE, TAP_RTI) != ERROR_OK)
227 return ERROR_TARGET_INVALID;
229 /* delay to handle aborts */
230 jtag_add_sleep(50);
232 /* check ISC status */
233 status = str9xpec_isc_status(chain_pos);
234 if (!(status & ISC_STATUS_MODE))
236 /* we have left isc mode */
237 str9xpec_info->isc_enable = 0;
238 DEBUG("ISC_MODE Disabled");
241 return ERROR_OK;
244 int str9xpec_read_config(struct flash_bank_s *bank)
246 scan_field_t field;
247 u8 status;
248 u32 chain_pos;
250 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
252 chain_pos = str9xpec_info->chain_pos;
254 DEBUG("ISC_CONFIGURATION");
256 /* execute ISC_CONFIGURATION command */
257 str9xpec_set_instr(chain_pos, ISC_CONFIGURATION, TAP_PI);
259 field.device = chain_pos;
260 field.num_bits = 64;
261 field.out_value = NULL;
262 field.out_mask = NULL;
263 field.in_value = str9xpec_info->options;
264 field.in_check_value = NULL;
265 field.in_check_mask = NULL;
266 field.in_handler = NULL;
267 field.in_handler_priv = NULL;
269 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
270 jtag_execute_queue();
272 status = str9xpec_isc_status(chain_pos);
274 return status;
277 int str9xpec_build_block_list(struct flash_bank_s *bank)
279 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
281 int i;
282 int num_sectors = 0, b0_sectors = 0;
284 switch (bank->size)
286 case (256 * 1024):
287 b0_sectors = 4;
288 break;
289 case (512 * 1024):
290 b0_sectors = 8;
291 break;
292 default:
293 ERROR("BUG: unknown bank->size encountered");
294 exit(-1);
297 /* include bank 1 sectors */
298 num_sectors = b0_sectors + 4;
299 bank->size += (32 * 1024);
301 bank->num_sectors = num_sectors;
302 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
303 str9xpec_info->sector_bits = malloc(sizeof(u32) * num_sectors);
305 num_sectors = 0;
307 for (i = 0; i < b0_sectors; i++)
309 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
310 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
311 bank->sectors[num_sectors].is_erased = -1;
312 bank->sectors[num_sectors].is_protected = 1;
313 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
316 for (i = 8; i < 12; i++)
318 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
319 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
320 bank->sectors[num_sectors].is_erased = -1;
321 bank->sectors[num_sectors].is_protected = 1;
322 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
325 return ERROR_OK;
328 /* flash bank str9x <base> <size> 0 0 <target#>
330 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
332 str9xpec_flash_controller_t *str9xpec_info;
333 armv4_5_common_t *armv4_5 = NULL;
334 arm7_9_common_t *arm7_9 = NULL;
335 arm_jtag_t *jtag_info = NULL;
337 if (argc < 6)
339 WARNING("incomplete flash_bank str9x configuration");
340 return ERROR_FLASH_BANK_INVALID;
343 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
344 bank->driver_priv = str9xpec_info;
346 if (bank->base != 0x00000000)
348 WARNING("overriding flash base address for STR91x device with 0x00000000");
349 bank->base = 0x00000000;
352 /* find out jtag position of flash controller
353 * it is always after the arm966 core */
355 armv4_5 = bank->target->arch_info;
356 arm7_9 = armv4_5->arch_info;
357 jtag_info = &arm7_9->jtag_info;
359 str9xpec_info->chain_pos = (jtag_info->chain_pos - 1);
360 str9xpec_info->isc_enable = 0;
361 str9xpec_info->devarm = NULL;
363 str9xpec_build_block_list(bank);
365 /* clear option byte register */
366 buf_set_u32(str9xpec_info->options, 0, 64, 0);
368 return ERROR_OK;
371 int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
373 scan_field_t field;
374 u8 status;
375 u32 chain_pos;
376 int i;
377 u8 *buffer = NULL;
379 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
381 chain_pos = str9xpec_info->chain_pos;
383 if (!str9xpec_info->isc_enable) {
384 str9xpec_isc_enable( bank );
387 if (!str9xpec_info->isc_enable) {
388 return ERROR_FLASH_OPERATION_FAILED;
391 buffer = calloc(CEIL(64, 8), 1);
393 DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
395 for (i = first; i <= last; i++) {
396 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
399 /* execute ISC_BLANK_CHECK command */
400 str9xpec_set_instr(chain_pos, ISC_BLANK_CHECK, TAP_PI);
402 field.device = chain_pos;
403 field.num_bits = 64;
404 field.out_value = buffer;
405 field.out_mask = NULL;
406 field.in_value = NULL;
407 field.in_check_value = NULL;
408 field.in_check_mask = NULL;
409 field.in_handler = NULL;
410 field.in_handler_priv = NULL;
412 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
413 jtag_add_sleep(40000);
415 /* read blank check result */
416 field.device = chain_pos;
417 field.num_bits = 64;
418 field.out_value = NULL;
419 field.out_mask = NULL;
420 field.in_value = buffer;
421 field.in_check_value = NULL;
422 field.in_check_mask = NULL;
423 field.in_handler = NULL;
424 field.in_handler_priv = NULL;
426 jtag_add_dr_scan(1, &field, TAP_PI, NULL);
427 jtag_execute_queue();
429 status = str9xpec_isc_status(chain_pos);
431 for (i = first; i <= last; i++)
433 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
434 bank->sectors[i].is_erased = 0;
435 else
436 bank->sectors[i].is_erased = 1;
439 free(buffer);
441 str9xpec_isc_disable(bank);
443 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
444 return ERROR_FLASH_OPERATION_FAILED;
445 return ERROR_OK;
448 int str9xpec_protect_check(struct flash_bank_s *bank)
450 u8 status;
451 int i;
453 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
455 status = str9xpec_read_config(bank);
457 for (i = 0; i < bank->num_sectors; i++)
459 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
460 bank->sectors[i].is_protected = 1;
461 else
462 bank->sectors[i].is_protected = 0;
465 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
466 return ERROR_FLASH_OPERATION_FAILED;
467 return ERROR_OK;
470 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
472 scan_field_t field;
473 u8 status;
474 u32 chain_pos;
475 int i;
476 u8 *buffer = NULL;
478 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
480 chain_pos = str9xpec_info->chain_pos;
482 if (!str9xpec_info->isc_enable) {
483 str9xpec_isc_enable( bank );
486 if (!str9xpec_info->isc_enable) {
487 return ISC_STATUS_ERROR;
490 buffer = calloc(CEIL(64, 8), 1);
492 DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
494 /* last bank: 0xFF signals a full erase (unlock complete device) */
495 /* last bank: 0xFE signals a option byte erase */
496 if (last == 0xFF)
498 for (i = 0; i < 64; i++) {
499 buf_set_u32(buffer, i, 1, 1);
502 else if (last == 0xFE)
504 buf_set_u32(buffer, 49, 1, 1);
506 else
508 for (i = first; i <= last; i++) {
509 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
513 DEBUG("ISC_ERASE");
515 /* execute ISC_ERASE command */
516 str9xpec_set_instr(chain_pos, ISC_ERASE, TAP_PI);
518 field.device = chain_pos;
519 field.num_bits = 64;
520 field.out_value = buffer;
521 field.out_mask = NULL;
522 field.in_value = NULL;
523 field.in_check_value = NULL;
524 field.in_check_mask = NULL;
525 field.in_handler = NULL;
526 field.in_handler_priv = NULL;
528 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
529 jtag_execute_queue();
531 jtag_add_sleep(10);
533 /* wait for erase completion */
534 while (!((status = str9xpec_isc_status(chain_pos)) & ISC_STATUS_BUSY)) {
535 usleep(1000);
538 free(buffer);
540 str9xpec_isc_disable(bank);
542 return status;
545 int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
547 int status;
549 status = str9xpec_erase_area(bank, first, last);
551 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
552 return ERROR_FLASH_OPERATION_FAILED;
554 return ERROR_OK;
557 int str9xpec_lock_device(struct flash_bank_s *bank)
559 scan_field_t field;
560 u8 status;
561 u32 chain_pos;
562 str9xpec_flash_controller_t *str9xpec_info = NULL;
564 str9xpec_info = bank->driver_priv;
565 chain_pos = str9xpec_info->chain_pos;
567 if (!str9xpec_info->isc_enable) {
568 str9xpec_isc_enable( bank );
571 if (!str9xpec_info->isc_enable) {
572 return ISC_STATUS_ERROR;
575 /* set security address */
576 str9xpec_set_address(bank, 0x80);
578 /* execute ISC_PROGRAM command */
579 str9xpec_set_instr(chain_pos, ISC_PROGRAM_SECURITY, TAP_RTI);
581 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
583 do {
584 field.device = chain_pos;
585 field.num_bits = 8;
586 field.out_value = NULL;
587 field.out_mask = NULL;
588 field.in_value = &status;
589 field.in_check_value = NULL;
590 field.in_check_mask = NULL;
591 field.in_handler = NULL;
592 field.in_handler_priv = NULL;
594 jtag_add_dr_scan(1, &field, -1, NULL);
595 jtag_execute_queue();
597 } while(!(status & ISC_STATUS_BUSY));
599 str9xpec_isc_disable(bank);
601 return status;
604 int str9xpec_unlock_device(struct flash_bank_s *bank)
606 u8 status;
608 status = str9xpec_erase_area(bank, 0, 255);
610 return status;
613 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
615 u8 status;
616 int i;
618 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
620 status = str9xpec_read_config(bank);
622 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
623 return ERROR_FLASH_OPERATION_FAILED;
625 DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
627 /* last bank: 0xFF signals a full device protect */
628 if (last == 0xFF)
630 if( set )
632 status = str9xpec_lock_device(bank);
634 else
636 /* perform full erase to unlock device */
637 status = str9xpec_unlock_device(bank);
640 else
642 for (i = first; i <= last; i++)
644 if( set )
645 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
646 else
647 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
650 status = str9xpec_write_options(bank);
653 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
654 return ERROR_FLASH_OPERATION_FAILED;
656 return ERROR_OK;
659 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
661 u32 chain_pos;
662 scan_field_t field;
663 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
665 chain_pos = str9xpec_info->chain_pos;
667 /* set flash controller address */
668 str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
670 field.device = chain_pos;
671 field.num_bits = 8;
672 field.out_value = &sector;
673 field.out_mask = NULL;
674 field.in_value = NULL;
675 field.in_check_value = NULL;
676 field.in_check_mask = NULL;
677 field.in_handler = NULL;
678 field.in_handler_priv = NULL;
680 jtag_add_dr_scan(1, &field, -1, NULL);
682 return ERROR_OK;
685 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
687 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
688 u32 dwords_remaining = (count / 8);
689 u32 bytes_remaining = (count & 0x00000007);
690 u32 bytes_written = 0;
691 u8 status;
692 u32 check_address = offset;
693 u32 chain_pos;
694 scan_field_t field;
695 u8 *scanbuf;
696 int i;
697 u32 first_sector = 0;
698 u32 last_sector = 0;
700 chain_pos = str9xpec_info->chain_pos;
702 if (!str9xpec_info->isc_enable) {
703 str9xpec_isc_enable(bank);
706 if (!str9xpec_info->isc_enable) {
707 return ERROR_FLASH_OPERATION_FAILED;
710 if (offset & 0x7)
712 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
713 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
716 for (i = 0; i < bank->num_sectors; i++)
718 u32 sec_start = bank->sectors[i].offset;
719 u32 sec_end = sec_start + bank->sectors[i].size;
721 /* check if destination falls within the current sector */
722 if ((check_address >= sec_start) && (check_address < sec_end))
724 /* check if destination ends in the current sector */
725 if (offset + count < sec_end)
726 check_address = offset + count;
727 else
728 check_address = sec_end;
731 if ((offset >= sec_start) && (offset < sec_end)){
732 first_sector = i;
735 if ((offset + count >= sec_start) && (offset + count < sec_end)){
736 last_sector = i;
740 if (check_address != offset + count)
741 return ERROR_FLASH_DST_OUT_OF_BANK;
743 DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
745 scanbuf = calloc(CEIL(64, 8), 1);
747 DEBUG("ISC_PROGRAM");
749 for (i = first_sector; i <= last_sector; i++)
751 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
753 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
755 while (dwords_remaining > 0)
757 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
759 field.device = chain_pos;
760 field.num_bits = 64;
761 field.out_value = (buffer + bytes_written);
762 field.out_mask = NULL;
763 field.in_value = NULL;
764 field.in_check_value = NULL;
765 field.in_check_mask = NULL;
766 field.in_handler = NULL;
767 field.in_handler_priv = NULL;
769 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
771 /* small delay before polling */
772 jtag_add_sleep(50);
774 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
776 do {
777 field.device = chain_pos;
778 field.num_bits = 8;
779 field.out_value = NULL;
780 field.out_mask = NULL;
781 field.in_value = scanbuf;
782 field.in_check_value = NULL;
783 field.in_check_mask = NULL;
784 field.in_handler = NULL;
785 field.in_handler_priv = NULL;
787 jtag_add_dr_scan(1, &field, -1, NULL);
788 jtag_execute_queue();
790 status = buf_get_u32(scanbuf, 0, 8);
792 } while(!(status & ISC_STATUS_BUSY));
794 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
795 return ERROR_FLASH_OPERATION_FAILED;
797 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
798 // return ERROR_FLASH_OPERATION_FAILED;
800 dwords_remaining--;
801 bytes_written += 8;
805 if (bytes_remaining)
807 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
808 int i = 0;
810 while(bytes_remaining > 0)
812 last_dword[i++] = *(buffer + bytes_written);
813 bytes_remaining--;
814 bytes_written++;
817 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
819 field.device = chain_pos;
820 field.num_bits = 64;
821 field.out_value = last_dword;
822 field.out_mask = NULL;
823 field.in_value = NULL;
824 field.in_check_value = NULL;
825 field.in_check_mask = NULL;
826 field.in_handler = NULL;
827 field.in_handler_priv = NULL;
829 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
831 /* small delay before polling */
832 jtag_add_sleep(50);
834 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
836 do {
837 field.device = chain_pos;
838 field.num_bits = 8;
839 field.out_value = NULL;
840 field.out_mask = NULL;
841 field.in_value = scanbuf;
842 field.in_check_value = NULL;
843 field.in_check_mask = NULL;
844 field.in_handler = NULL;
845 field.in_handler_priv = NULL;
847 jtag_add_dr_scan(1, &field, -1, NULL);
848 jtag_execute_queue();
850 status = buf_get_u32(scanbuf, 0, 8);
852 } while(!(status & ISC_STATUS_BUSY));
854 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
855 return ERROR_FLASH_OPERATION_FAILED;
857 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
858 // return ERROR_FLASH_OPERATION_FAILED;
861 free(scanbuf);
863 str9xpec_isc_disable(bank);
865 return ERROR_OK;
868 int str9xpec_probe(struct flash_bank_s *bank)
870 return ERROR_OK;
873 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
875 flash_bank_t *bank;
876 scan_field_t field;
877 u8 *buffer = NULL;
878 u32 chain_pos;
879 u32 idcode;
880 str9xpec_flash_controller_t *str9xpec_info = NULL;
882 if (argc < 1)
884 command_print(cmd_ctx, "usage: str9xpec part_id <num>");
885 return ERROR_OK;
888 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
889 if (!bank)
891 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
892 return ERROR_OK;
895 str9xpec_info = bank->driver_priv;
896 chain_pos = str9xpec_info->chain_pos;
898 buffer = calloc(CEIL(32, 8), 1);
900 str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
902 field.device = chain_pos;
903 field.num_bits = 32;
904 field.out_value = NULL;
905 field.out_mask = NULL;
906 field.in_value = buffer;
907 field.in_check_value = NULL;
908 field.in_check_mask = NULL;
909 field.in_handler = NULL;
910 field.in_handler_priv = NULL;
912 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
913 jtag_execute_queue();
915 idcode = buf_get_u32(buffer, 0, 32);
917 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
919 free(buffer);
921 return ERROR_OK;
924 int str9xpec_erase_check(struct flash_bank_s *bank)
926 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
929 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
931 snprintf(buf, buf_size, "str9xpec flash driver info" );
932 return ERROR_OK;
935 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
937 flash_bank_t *bank;
938 u8 status;
939 str9xpec_flash_controller_t *str9xpec_info = NULL;
941 if (argc < 1)
943 command_print(cmd_ctx, "str9xpec options_read <bank>");
944 return ERROR_OK;
947 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
948 if (!bank)
950 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
951 return ERROR_OK;
954 str9xpec_info = bank->driver_priv;
956 status = str9xpec_read_config(bank);
958 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
959 return ERROR_FLASH_OPERATION_FAILED;
961 /* boot bank */
962 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
963 command_print(cmd_ctx, "CS Map: bank1");
964 else
965 command_print(cmd_ctx, "CS Map: bank0");
967 /* OTP lock */
968 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
969 command_print(cmd_ctx, "OTP Lock: OTP Locked");
970 else
971 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
973 /* LVD Threshold */
974 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
975 command_print(cmd_ctx, "LVD Threshold: 2.7v");
976 else
977 command_print(cmd_ctx, "LVD Threshold: 2.4v");
979 /* LVD reset warning */
980 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
981 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
982 else
983 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
985 /* LVD reset select */
986 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
987 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
988 else
989 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
991 return ERROR_OK;
994 int str9xpec_write_options(struct flash_bank_s *bank)
996 scan_field_t field;
997 u8 status;
998 u32 chain_pos;
999 str9xpec_flash_controller_t *str9xpec_info = NULL;
1001 str9xpec_info = bank->driver_priv;
1002 chain_pos = str9xpec_info->chain_pos;
1004 /* erase config options first */
1005 status = str9xpec_erase_area( bank, 0xFE, 0xFE );
1007 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1008 return status;
1010 if (!str9xpec_info->isc_enable) {
1011 str9xpec_isc_enable( bank );
1014 if (!str9xpec_info->isc_enable) {
1015 return ISC_STATUS_ERROR;
1018 /* according to data 64th bit has to be set */
1019 buf_set_u32(str9xpec_info->options, 63, 1, 1);
1021 /* set option byte address */
1022 str9xpec_set_address(bank, 0x50);
1024 /* execute ISC_PROGRAM command */
1025 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
1027 field.device = chain_pos;
1028 field.num_bits = 64;
1029 field.out_value = str9xpec_info->options;
1030 field.out_mask = NULL;
1031 field.in_value = NULL;
1032 field.in_check_value = NULL;
1033 field.in_check_mask = NULL;
1034 field.in_handler = NULL;
1035 field.in_handler_priv = NULL;
1037 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
1039 /* small delay before polling */
1040 jtag_add_sleep(50);
1042 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
1044 do {
1045 field.device = chain_pos;
1046 field.num_bits = 8;
1047 field.out_value = NULL;
1048 field.out_mask = NULL;
1049 field.in_value = &status;
1050 field.in_check_value = NULL;
1051 field.in_check_mask = NULL;
1052 field.in_handler = NULL;
1053 field.in_handler_priv = NULL;
1055 jtag_add_dr_scan(1, &field, -1, NULL);
1056 jtag_execute_queue();
1058 } while(!(status & ISC_STATUS_BUSY));
1060 str9xpec_isc_disable(bank);
1062 return status;
1065 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1067 flash_bank_t *bank;
1068 u8 status;
1070 if (argc < 1)
1072 command_print(cmd_ctx, "str9xpec options_write <bank>");
1073 return ERROR_OK;
1076 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1077 if (!bank)
1079 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1080 return ERROR_OK;
1083 status = str9xpec_write_options(bank);
1085 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1086 return ERROR_FLASH_OPERATION_FAILED;
1088 return ERROR_OK;
1091 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1093 flash_bank_t *bank;
1094 str9xpec_flash_controller_t *str9xpec_info = NULL;
1096 if (argc < 2)
1098 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1099 return ERROR_OK;
1102 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1103 if (!bank)
1105 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1106 return ERROR_OK;
1109 str9xpec_info = bank->driver_priv;
1111 if (strcmp(args[1], "bank1") == 0)
1113 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1115 else
1117 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1120 return ERROR_OK;
1123 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1125 flash_bank_t *bank;
1126 str9xpec_flash_controller_t *str9xpec_info = NULL;
1128 if (argc < 2)
1130 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1131 return ERROR_OK;
1134 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1135 if (!bank)
1137 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1138 return ERROR_OK;
1141 str9xpec_info = bank->driver_priv;
1143 if (strcmp(args[1], "2.7v") == 0)
1145 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1147 else
1149 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1152 return ERROR_OK;
1155 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1157 flash_bank_t *bank;
1158 str9xpec_flash_controller_t *str9xpec_info = NULL;
1160 if (argc < 2)
1162 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1163 return ERROR_OK;
1166 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1167 if (!bank)
1169 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1170 return ERROR_OK;
1173 str9xpec_info = bank->driver_priv;
1175 if (strcmp(args[1], "vdd_vddq") == 0)
1177 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1179 else
1181 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1184 return ERROR_OK;
1187 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1189 flash_bank_t *bank;
1190 str9xpec_flash_controller_t *str9xpec_info = NULL;
1192 if (argc < 2)
1194 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1195 return ERROR_OK;
1198 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1199 if (!bank)
1201 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1202 return ERROR_OK;
1205 str9xpec_info = bank->driver_priv;
1207 if (strcmp(args[1], "vdd_vddq") == 0)
1209 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1211 else
1213 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1216 return ERROR_OK;
1219 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1221 u8 status;
1222 flash_bank_t *bank;
1224 if (argc < 1)
1226 command_print(cmd_ctx, "str9xpec lock <bank>");
1227 return ERROR_OK;
1230 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1231 if (!bank)
1233 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1234 return ERROR_OK;
1237 status = str9xpec_lock_device(bank);
1239 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1240 return ERROR_FLASH_OPERATION_FAILED;
1242 return ERROR_OK;
1245 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1247 u8 status;
1248 flash_bank_t *bank;
1250 if (argc < 1)
1252 command_print(cmd_ctx, "str9xpec unlock <bank>");
1253 return ERROR_OK;
1256 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1257 if (!bank)
1259 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1260 return ERROR_OK;
1263 status = str9xpec_unlock_device(bank);
1265 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1266 return ERROR_FLASH_OPERATION_FAILED;
1268 return ERROR_OK;
1271 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1273 flash_bank_t *bank;
1274 u32 chain_pos;
1275 jtag_device_t* dev0;
1276 jtag_device_t* dev2;
1277 str9xpec_flash_controller_t *str9xpec_info = NULL;
1279 if (argc < 1)
1281 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1282 return ERROR_OK;
1285 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1286 if (!bank)
1288 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1289 return ERROR_OK;
1292 str9xpec_info = bank->driver_priv;
1294 chain_pos = str9xpec_info->chain_pos;
1296 /* remove arm core from chain - enter turbo mode */
1298 str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
1299 jtag_execute_queue();
1301 /* modify scan chain - str9 core has been removed */
1302 dev0 = jtag_get_device(chain_pos);
1303 str9xpec_info->devarm = jtag_get_device(chain_pos+1);
1304 dev2 = jtag_get_device(chain_pos+2);
1305 dev0->next = dev2;
1306 jtag_num_devices--;
1308 return ERROR_OK;
1311 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1313 flash_bank_t *bank;
1314 u32 chain_pos;
1315 jtag_device_t* dev0;
1316 str9xpec_flash_controller_t *str9xpec_info = NULL;
1318 if (argc < 1)
1320 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1321 return ERROR_OK;
1324 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1325 if (!bank)
1327 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1328 return ERROR_OK;
1331 str9xpec_info = bank->driver_priv;
1333 chain_pos = str9xpec_info->chain_pos;
1335 dev0 = jtag_get_device(chain_pos);
1337 /* exit turbo mode via TLR */
1338 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
1339 jtag_execute_queue();
1341 /* restore previous scan chain */
1342 if( str9xpec_info->devarm ) {
1343 dev0->next = str9xpec_info->devarm;
1344 jtag_num_devices++;
1345 str9xpec_info->devarm = NULL;
1348 return ERROR_OK;