- added mingw elf patches from Vincent Palatin
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sat, 16 Jun 2007 14:45:55 +0000 (14:45 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sat, 16 Jun 2007 14:45:55 +0000 (14:45 +0000)
- added str9x programming using flash controller tap (str9xpec), including option bytes and device lock/unlock
- inttypes.h now used for long long printf style declarations

git-svn-id: svn://svn.berlios.de/openocd/trunk@174 b42882b7-edfa-0310-969c-e2dbd0fdcd60

16 files changed:
configure.in
src/flash/Makefile.am
src/flash/flash.c
src/flash/nand.c
src/flash/str9xpec.c [new file with mode: 0644]
src/flash/str9xpec.h [new file with mode: 0644]
src/helper/replacements.h
src/helper/time_support.c
src/pld/pld.c
src/server/server.c
src/target/arm720t.c
src/target/arm720t.h
src/target/image.c
src/target/image.h
src/target/target.c
src/target/xscale.c

index 69b1510ef6d6412a82d24ff10857014532225629..7111b82adbda987e188400674064eded884a79e0 100644 (file)
@@ -5,6 +5,7 @@ AC_SEARCH_LIBS([ioperm], [ioperm])
 AC_CANONICAL_HOST
 
 AC_CHECK_HEADERS(sys/param.h)
+AC_CHECK_HEADERS(elf.h)
 
 AC_C_BIGENDIAN
 
index 8d30790b45ff4b3bf007b8af41b012e8d76edbc0..7b5c52222dd0ecad8642843522e9e2914e1d370d 100644 (file)
@@ -1,5 +1,5 @@
 INCLUDES = -I$(top_srcdir)/src/helper -I$(top_srcdir)/src/jtag -I$(top_srcdir)/src/target $(all_includes)
 METASOURCES = AUTO
 noinst_LIBRARIES = libflash.a
-libflash_a_SOURCES = flash.c lpc2000.c cfi.c non_cfi.c at91sam7.c str7x.c str9x.c nand.c lpc3180_nand_controller.c stellaris.c
-noinst_HEADERS = flash.h lpc2000.h cfi.h non_cfi.h at91sam7.h str7x.h str9x.h nand.h lpc3180_nand_controller.h stellaris.h
+libflash_a_SOURCES = flash.c lpc2000.c cfi.c non_cfi.c at91sam7.c str7x.c str9x.c nand.c lpc3180_nand_controller.c stellaris.c str9xpec.c
+noinst_HEADERS = flash.h lpc2000.h cfi.h non_cfi.h at91sam7.h str7x.h str9x.h nand.h lpc3180_nand_controller.h stellaris.h str9xpec.h
index 3c368f3f3532552295fbf1efc369fc006e39f7f5..eaa1e17eecb2011a67768fddcd388d2c8b51d711 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "flash.h"
 #include "command.h"
-#include "log.h"
 #include "target.h"
 #include "time_support.h"
 
@@ -36,6 +35,7 @@
 
 #include <fileio.h>
 #include <image.h>
+#include "log.h"
 
 /* command handlers */
 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@@ -56,6 +56,7 @@ extern flash_driver_t at91sam7_flash;
 extern flash_driver_t str7x_flash;
 extern flash_driver_t str9x_flash;
 extern flash_driver_t stellaris_flash;
+extern flash_driver_t str9xpec_flash;
 
 flash_driver_t *flash_drivers[] =
 {
@@ -65,6 +66,7 @@ flash_driver_t *flash_drivers[] =
        &str7x_flash,
        &str9x_flash,
        &stellaris_flash,
+       &str9xpec_flash,
        NULL,
 };
 
@@ -373,9 +375,10 @@ int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, cha
                int last = strtoul(args[2], NULL, 0);
                int retval;
                flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
-               struct timeval start, end, duration;
-
-               gettimeofday(&start, NULL);
+               duration_t duration;
+               char *duration_text;
+       
+               duration_start_measure(&duration);
        
                if (!p)
                {
@@ -411,10 +414,10 @@ int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, cha
                }
                else
                {
-                       gettimeofday(&end, NULL);       
-                       timeval_subtract(&duration, &end, &start);
-               
-                       command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %is %ius", first, last, strtoul(args[0], 0, 0), duration.tv_sec, duration.tv_usec);
+                       duration_stop_measure(&duration, &duration_text);       
+                       
+                       command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text);
+                       free(duration_text);
                }
        }
        else
index 7ff73512d922a529c266997bd131309f92ca2739..d06a232cc948339ba1ad51b654da0ebd101794de 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <inttypes.h>
 
 #include <errno.h>
 
@@ -1387,7 +1388,7 @@ int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char
                        fileio_close(&fileio);
 
                        duration_stop_measure(&duration, &duration_text);
-                       command_print(cmd_ctx, "dumped %lli byte in %s", fileio.size, duration_text);
+                       command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);
                        free(duration_text);
                }
                else
diff --git a/src/flash/str9xpec.c b/src/flash/str9xpec.c
new file mode 100644 (file)
index 0000000..f26a763
--- /dev/null
@@ -0,0 +1,1368 @@
+/***************************************************************************
+ *   Copyright (C) 2005 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
+#include "str9xpec.h"
+#include "flash.h"
+#include "target.h"
+#include "log.h"
+#include "armv4_5.h"
+#include "arm7_9_common.h"
+#include "jtag.h"
+#include "binarybuffer.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+str9xpec_mem_layout_t mem_layout_str9pec[] = {
+       {0x00000000, 0x10000, 0},
+       {0x00010000, 0x10000, 1},
+       {0x00020000, 0x10000, 2},
+       {0x00030000, 0x10000, 3},
+       {0x00040000, 0x10000, 4},
+       {0x00050000, 0x10000, 5},
+       {0x00060000, 0x10000, 6},
+       {0x00070000, 0x10000, 7},
+       {0x00080000, 0x02000, 32},
+       {0x00082000, 0x02000, 33},
+       {0x00084000, 0x02000, 34},
+       {0x00086000, 0x02000, 35}
+};
+
+int str9xpec_register_commands(struct command_context_s *cmd_ctx);
+int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
+int str9xpec_erase(struct flash_bank_s *bank, int first, int last);
+int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last);
+int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
+int str9xpec_probe(struct flash_bank_s *bank);
+int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_protect_check(struct flash_bank_s *bank);
+int str9xpec_erase_check(struct flash_bank_s *bank);
+int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size);
+
+int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
+int str9xpec_set_address(struct flash_bank_s *bank, u8 sector);
+int str9xpec_write_options(struct flash_bank_s *bank);
+
+int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+flash_driver_t str9xpec_flash =
+{
+       .name = "str9xpec",
+       .register_commands = str9xpec_register_commands,
+       .flash_bank_command = str9xpec_flash_bank_command,
+       .erase = str9xpec_erase,
+       .protect = str9xpec_protect,
+       .write = str9xpec_write,
+       .probe = str9xpec_probe,
+       .erase_check = str9xpec_erase_check,
+       .protect_check = str9xpec_protect_check,
+       .info = str9xpec_info
+};
+
+int str9xpec_register_commands(struct command_context_s *cmd_ctx)
+{
+       command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
+       
+       register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
+                                        "enable str9xpec turbo mode");
+       register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
+                                        "disable str9xpec turbo mode");
+       register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
+                                        "configure str9xpec boot sector");
+       register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
+                                        "configure str9xpec lvd threshold");
+       register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
+                                        "configure str9xpec lvd selection");
+       register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
+                                        "configure str9xpec lvd warning");
+       register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
+                                        "read str9xpec options");
+       register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
+                                        "write str9xpec options");
+       register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
+                                        "lock str9xpec device");
+       register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
+                                        "unlock str9xpec device");
+       register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
+                                        "print part id of str9xpec flash bank <num>");
+       
+       return ERROR_OK;
+}
+
+int str9xpec_set_instr(int chain_pos, u32 new_instr, enum tap_state end_state)
+{
+       jtag_device_t *device = jtag_get_device(chain_pos);
+               
+       if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
+       {
+               scan_field_t field;
+                               
+               field.device = chain_pos;
+               field.num_bits = device->ir_length;
+               field.out_value = calloc(CEIL(field.num_bits, 8), 1);
+               buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
+               field.out_mask = NULL;
+               field.in_value = NULL;
+               field.in_check_value = NULL;
+               field.in_check_mask = NULL;
+               field.in_handler = NULL;
+               field.in_handler_priv = NULL;
+               
+               jtag_add_ir_scan(1, &field, end_state, NULL);
+               
+               free(field.out_value);
+       }
+       
+       return ERROR_OK;
+}
+
+u8 str9xpec_isc_status(int chain_pos)
+{
+       scan_field_t field;
+       u8 status;
+       
+       str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
+       
+       field.device = chain_pos;
+       field.num_bits = 8;
+       field.out_value = NULL;
+       field.out_mask = NULL;
+       field.in_value = &status;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+       jtag_execute_queue();
+       
+       DEBUG("status: 0x%2.2x", status);
+       
+       if (status & ISC_STATUS_SECURITY)
+               INFO("Device Security Bit Set");
+       
+       return status;
+}
+
+int str9xpec_isc_enable(struct flash_bank_s *bank)
+{
+       u8 status;
+       u32 chain_pos;
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       if (str9xpec_info->isc_enable)
+               return ERROR_OK;
+       
+       /* enter isc mode */
+       str9xpec_set_instr(chain_pos, ISC_ENABLE, TAP_RTI);
+       
+       /* check ISC status */
+       status = str9xpec_isc_status(chain_pos);
+       if (status & ISC_STATUS_MODE)
+       {
+               /* we have entered isc mode */
+               str9xpec_info->isc_enable = 1;
+               DEBUG("ISC_MODE Enabled");
+       }
+       
+       return ERROR_OK;
+}
+
+int str9xpec_isc_disable(struct flash_bank_s *bank)
+{
+       u8 status;
+       u32 chain_pos;
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       if (!str9xpec_info->isc_enable)
+               return ERROR_OK;
+       
+       str9xpec_set_instr(chain_pos, ISC_DISABLE, TAP_RTI);
+       
+       /* delay to handle aborts */
+       jtag_add_sleep(50);
+       
+       /* check ISC status */
+       status = str9xpec_isc_status(chain_pos);
+       if (!(status & ISC_STATUS_MODE))
+       {
+               /* we have left isc mode */
+               str9xpec_info->isc_enable = 0;
+               DEBUG("ISC_MODE Disabled");
+       }
+       
+       return ERROR_OK;
+}
+
+int str9xpec_read_config(struct flash_bank_s *bank)
+{
+       scan_field_t field;
+       u8 status;
+       u32 chain_pos;
+               
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       DEBUG("ISC_CONFIGURATION");
+       
+       /* execute ISC_CONFIGURATION command */
+       str9xpec_set_instr(chain_pos, ISC_CONFIGURATION, TAP_PI);
+       
+       field.device = chain_pos;
+       field.num_bits = 64;
+       field.out_value = NULL;
+       field.out_mask = NULL;
+       field.in_value = str9xpec_info->options;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+       jtag_execute_queue();
+       
+       status = str9xpec_isc_status(chain_pos);
+       
+       return status;
+}
+
+int str9xpec_build_block_list(struct flash_bank_s *bank)
+{
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       int i;
+       int num_sectors = 0, b0_sectors = 0;
+               
+       switch (bank->size)
+       {
+               case 256 * 1024:
+                       b0_sectors = 4;
+                       break;
+               case 512 * 1024:
+                       b0_sectors = 8;
+                       break;
+               default:
+                       ERROR("BUG: unknown bank->size encountered");
+                       exit(-1);
+       }
+       
+       num_sectors = b0_sectors + 4;
+       
+       bank->num_sectors = num_sectors;
+       bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
+       str9xpec_info->sector_bits = malloc(sizeof(u32) * num_sectors);
+       
+       num_sectors = 0;
+       
+       for (i = 0; i < b0_sectors; i++)
+       {
+               bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
+               bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
+               bank->sectors[num_sectors].is_erased = -1;
+               bank->sectors[num_sectors].is_protected = 1;
+               str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
+       }
+       
+       for (i = 8; i < 12; i++)
+       {
+               bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
+               bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
+               bank->sectors[num_sectors].is_erased = -1;
+               bank->sectors[num_sectors].is_protected = 1;
+               str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
+       }
+       
+       return ERROR_OK;
+}
+
+/* flash bank str9x <base> <size> 0 0 <target#>
+ */
+int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
+{
+       str9xpec_flash_controller_t *str9xpec_info;
+       armv4_5_common_t *armv4_5 = NULL;
+       arm7_9_common_t *arm7_9 = NULL;
+       arm_jtag_t *jtag_info = NULL;
+       
+       if (argc < 6)
+       {
+               WARNING("incomplete flash_bank str9x configuration");
+               return ERROR_FLASH_BANK_INVALID;
+       }
+       
+       str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
+       bank->driver_priv = str9xpec_info;
+       
+       if (bank->base != 0x00000000)
+       {
+               WARNING("overriding flash base address for STR91x device with 0x00000000");
+               bank->base = 0x00000000;
+       }
+       
+       str9xpec_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
+       if (!str9xpec_info->target)
+       {
+               ERROR("no target '%s' configured", args[5]);
+               exit(-1);
+       }
+
+       /* find out jtag position of flash controller
+        * it is always after the arm966 core */
+       
+       armv4_5 = str9xpec_info->target->arch_info;
+       arm7_9 = armv4_5->arch_info;
+       jtag_info = &arm7_9->jtag_info;
+       
+       str9xpec_info->chain_pos = (jtag_info->chain_pos - 1);
+       str9xpec_info->isc_enable = 0;
+       str9xpec_info->devarm = NULL;
+       
+       str9xpec_build_block_list(bank);
+       
+       /* clear option byte register */
+       buf_set_u32(str9xpec_info->options, 0, 64, 0);
+       
+       return ERROR_OK;
+}
+
+int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
+{
+       scan_field_t field;
+       u8 status;
+       u32 chain_pos;
+       int i;
+       u8 *buffer = NULL;
+               
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       if (!str9xpec_info->isc_enable) {
+               str9xpec_isc_enable( bank );
+       }
+       
+       if (!str9xpec_info->isc_enable) {
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+       
+       buffer = calloc(CEIL(64, 8), 1);
+
+       DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
+       
+       for (i = first; i <= last; i++) {
+               buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
+       }
+       
+       /* execute ISC_BLANK_CHECK command */
+       str9xpec_set_instr(chain_pos, ISC_BLANK_CHECK, TAP_PI);
+       
+       field.device = chain_pos;
+       field.num_bits = 64;
+       field.out_value = buffer;
+       field.out_mask = NULL;
+       field.in_value = NULL;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+       jtag_add_sleep(40000);
+       
+       /* read blank check result */
+       field.device = chain_pos;
+       field.num_bits = 64;
+       field.out_value = NULL;
+       field.out_mask = NULL;
+       field.in_value = buffer;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_PI, NULL);
+       jtag_execute_queue();
+       
+       status = str9xpec_isc_status(chain_pos);
+       
+       for (i = first; i <= last; i++)
+       {
+               if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
+                       bank->sectors[i].is_erased = 0;
+               else
+                       bank->sectors[i].is_erased = 1;
+       }
+       
+       free(buffer);
+       
+       str9xpec_isc_disable(bank);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED; 
+       return ERROR_OK;
+}
+
+int str9xpec_protect_check(struct flash_bank_s *bank)
+{
+       u8 status;
+       int i;
+               
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       status = str9xpec_read_config(bank);
+       
+       for (i = 0; i < bank->num_sectors; i++)
+       {
+               if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
+                       bank->sectors[i].is_protected = 1;
+               else
+                       bank->sectors[i].is_protected = 0;
+       }
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       return ERROR_OK;
+}
+
+int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
+{
+       scan_field_t field;
+       u8 status;
+       u32 chain_pos;
+       int i;
+       u8 *buffer = NULL;
+       
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       if (!str9xpec_info->isc_enable) {
+               str9xpec_isc_enable( bank );
+       }
+       
+       if (!str9xpec_info->isc_enable) {
+               return ISC_STATUS_ERROR;
+       }
+       
+       buffer = calloc(CEIL(64, 8), 1);
+       
+       DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
+       
+       /* last bank: 0xFF signals a full erase (unlock complete device) */
+       /* last bank: 0xFE signals a option byte erase */
+       if (last == 0xFF)
+       {
+               for (i = 0; i < 64; i++) {
+                       buf_set_u32(buffer, i, 1, 1);
+               }       
+       }
+       else if (last == 0xFE)
+       {
+               buf_set_u32(buffer, 49, 1, 1);
+       }
+       else
+       {       
+               for (i = first; i <= last; i++) {
+                       buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
+               }
+       }
+       
+       DEBUG("ISC_ERASE");
+       
+       /* execute ISC_ERASE command */
+       str9xpec_set_instr(chain_pos, ISC_ERASE, TAP_PI);
+       
+       field.device = chain_pos;
+       field.num_bits = 64;
+       field.out_value = buffer;
+       field.out_mask = NULL;
+       field.in_value = NULL;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+       jtag_execute_queue();
+       
+       jtag_add_sleep(10);
+       
+       /* wait for erase completion */
+       while (!((status = str9xpec_isc_status(chain_pos)) & ISC_STATUS_BUSY)) {
+               usleep(1000);
+       }
+       
+       free(buffer);
+       
+       str9xpec_isc_disable(bank);
+       
+       return status;
+}
+
+int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
+{
+       int status;
+       
+       status = str9xpec_erase_area(bank, first, last);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       
+       return ERROR_OK;
+}
+
+int str9xpec_lock_device(struct flash_bank_s *bank)
+{
+       scan_field_t field;
+       u8 status;
+       u32 chain_pos;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       str9xpec_info = bank->driver_priv;
+       chain_pos = str9xpec_info->chain_pos;
+       
+       if (!str9xpec_info->isc_enable) {
+               str9xpec_isc_enable( bank );
+       }
+       
+       if (!str9xpec_info->isc_enable) {
+               return ISC_STATUS_ERROR;
+       }
+       
+       /* set security address */
+       str9xpec_set_address(bank, 0x80);
+       
+       /* execute ISC_PROGRAM command */
+       str9xpec_set_instr(chain_pos, ISC_PROGRAM_SECURITY, TAP_RTI);
+       
+       str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
+       
+       do {
+               field.device = chain_pos;
+               field.num_bits = 8;
+               field.out_value = NULL;
+               field.out_mask = NULL;
+               field.in_value = &status;
+               field.in_check_value = NULL;
+               field.in_check_mask = NULL;
+               field.in_handler = NULL;
+               field.in_handler_priv = NULL;
+               
+               jtag_add_dr_scan(1, &field, -1, NULL);
+               jtag_execute_queue();
+               
+       } while(!(status & ISC_STATUS_BUSY));
+       
+       str9xpec_isc_disable(bank);
+       
+       return status;
+}
+
+int str9xpec_unlock_device(struct flash_bank_s *bank)
+{
+       u8 status;
+       //u32 chain_pos;
+       //jtag_device_t* dev0;
+       //jtag_device_t* dev1;
+       //jtag_device_t* dev2;
+       
+       //str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       //chain_pos = str9xpec_info->chain_pos;
+       
+       /* remove arm core from chain - enter turbo mode */
+       
+       //str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
+       //jtag_execute_queue();
+       
+       /* modify scan chain - arm9 has been removed */
+       //dev0 = jtag_get_device(chain_pos);
+       //dev1 = jtag_get_device(chain_pos+1);
+       //dev2 = jtag_get_device(chain_pos+2);
+       //dev0->next = dev2;
+       //jtag_num_devices--;
+       
+       status = str9xpec_erase_area(bank, 0, 255);
+       
+       /* exit turbo mode via TLR */
+       //str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
+       //jtag_execute_queue();
+       
+       /* restore previous scan chain */
+       //dev0->next = dev1;
+       //jtag_num_devices++;
+       
+       return status;
+}
+
+int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
+{
+       u8 status;
+       int i;
+       
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       status = str9xpec_read_config(bank);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+
+       DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
+       
+       /* last bank: 0xFF signals a full device protect */
+       if (last == 0xFF)
+       {
+               if( set )
+               {
+                       status = str9xpec_lock_device(bank);
+               }
+               else
+               {
+                       /* perform full erase to unlock device */
+                       status = str9xpec_unlock_device(bank);
+               }
+       }
+       else
+       {       
+               for (i = first; i <= last; i++)
+               {
+                       if( set )
+                               buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
+                       else
+                               buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
+               }
+               
+               status = str9xpec_write_options(bank);
+       }
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       
+       return ERROR_OK;
+}
+
+int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
+{
+       u32 chain_pos;
+       scan_field_t field;
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       /* set flash controller address */
+       str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
+       
+       field.device = chain_pos;
+       field.num_bits = 8;
+       field.out_value = &sector;
+       field.out_mask = NULL;
+       field.in_value = NULL;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, -1, NULL);
+               
+       return ERROR_OK;
+}
+
+int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
+{
+       str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
+       u32 dwords_remaining = (count / 8);
+       u32 bytes_remaining = (count & 0x00000007);
+       u32 bytes_written = 0;
+       u8 status;
+       u32 check_address = offset;
+       u32 chain_pos;
+       scan_field_t field;
+       u8 *scanbuf;
+       int i;
+       u32 first_sector = 0;
+       u32 last_sector = 0;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       if (!str9xpec_info->isc_enable) {
+               str9xpec_isc_enable(bank);
+       }
+       
+       if (!str9xpec_info->isc_enable) {
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+       
+       if (offset & 0x7)
+       {
+               WARNING("offset 0x%x breaks required 8-byte alignment", offset);
+               return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+       }
+       
+       for (i = 0; i < bank->num_sectors; i++)
+       {
+               u32 sec_start = bank->sectors[i].offset;
+               u32 sec_end = sec_start + bank->sectors[i].size;
+               
+               /* check if destination falls within the current sector */
+               if ((check_address >= sec_start) && (check_address < sec_end))
+               {
+                       /* check if destination ends in the current sector */
+                       if (offset + count < sec_end)
+                               check_address = offset + count;
+                       else
+                               check_address = sec_end;
+               }
+               
+               if ((offset >= sec_start) && (offset < sec_end)){
+                       first_sector = i;
+               }
+               
+               if ((offset + count >= sec_start) && (offset + count < sec_end)){
+                       last_sector = i;
+               }
+       }
+       
+       if (check_address != offset + count)
+               return ERROR_FLASH_DST_OUT_OF_BANK;
+
+       DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
+       
+       scanbuf = calloc(CEIL(64, 8), 1);
+       
+       DEBUG("ISC_PROGRAM");
+       
+       for (i = first_sector; i <= last_sector; i++)
+       {
+               str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
+               
+               dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
+
+               while (dwords_remaining > 0)
+               {       
+                       str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
+                       
+                       field.device = chain_pos;
+                       field.num_bits = 64;
+                       field.out_value = (buffer + bytes_written);
+                       field.out_mask = NULL;
+                       field.in_value = NULL;
+                       field.in_check_value = NULL;
+                       field.in_check_mask = NULL;
+                       field.in_handler = NULL;
+                       field.in_handler_priv = NULL;
+                       
+                       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+                       
+                       /* small delay before polling */
+                       jtag_add_sleep(50);
+                       
+                       str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
+                       
+                       do {
+                               field.device = chain_pos;
+                               field.num_bits = 8;
+                               field.out_value = NULL;
+                               field.out_mask = NULL;
+                               field.in_value = scanbuf;
+                               field.in_check_value = NULL;
+                               field.in_check_mask = NULL;
+                               field.in_handler = NULL;
+                               field.in_handler_priv = NULL;
+                               
+                               jtag_add_dr_scan(1, &field, -1, NULL);
+                               jtag_execute_queue();
+                               
+                               status = buf_get_u32(scanbuf, 0, 8);
+                               
+                       } while(!(status & ISC_STATUS_BUSY));
+                       
+                       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+                               return ERROR_FLASH_OPERATION_FAILED; 
+                       
+                       //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
+                       //      return ERROR_FLASH_OPERATION_FAILED; 
+               
+                       dwords_remaining--;
+                       bytes_written += 8;
+               }
+       }
+       
+       if (bytes_remaining)
+       {
+               u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+               int i = 0;
+                               
+               while(bytes_remaining > 0)
+               {
+                       last_dword[i++] = *(buffer + bytes_written); 
+                       bytes_remaining--;
+                       bytes_written++;
+               }
+               
+               str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
+               
+               field.device = chain_pos;
+               field.num_bits = 64;
+               field.out_value = last_dword;
+               field.out_mask = NULL;
+               field.in_value = NULL;
+               field.in_check_value = NULL;
+               field.in_check_mask = NULL;
+               field.in_handler = NULL;
+               field.in_handler_priv = NULL;
+               
+               jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+               
+               /* small delay before polling */
+               jtag_add_sleep(50);
+               
+               str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
+               
+               do {
+                       field.device = chain_pos;
+                       field.num_bits = 8;
+                       field.out_value = NULL;
+                       field.out_mask = NULL;
+                       field.in_value = scanbuf;
+                       field.in_check_value = NULL;
+                       field.in_check_mask = NULL;
+                       field.in_handler = NULL;
+                       field.in_handler_priv = NULL;
+                       
+                       jtag_add_dr_scan(1, &field, -1, NULL);
+                       jtag_execute_queue();
+                       
+                       status = buf_get_u32(scanbuf, 0, 8);
+                       
+               } while(!(status & ISC_STATUS_BUSY));
+               
+               if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+                       return ERROR_FLASH_OPERATION_FAILED;
+               
+               //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
+               //      return ERROR_FLASH_OPERATION_FAILED; 
+       }
+
+       free(scanbuf);
+
+       str9xpec_isc_disable(bank);
+                               
+       return ERROR_OK;
+}
+
+int str9xpec_probe(struct flash_bank_s *bank)
+{
+       return ERROR_OK;
+}
+
+int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       scan_field_t field;
+       u8 *buffer = NULL;
+       u32 chain_pos;
+       u32 idcode;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "usage: str9xpec part_id <num>");
+               return ERROR_OK;
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       chain_pos = str9xpec_info->chain_pos;
+       
+       buffer = calloc(CEIL(32, 8), 1);
+       
+       str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
+       
+       field.device = chain_pos;
+       field.num_bits = 32;
+       field.out_value = NULL;
+       field.out_mask = NULL;
+       field.in_value = buffer;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+       jtag_execute_queue();
+       
+       idcode = buf_get_u32(buffer, 0, 32);
+       
+       command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
+       
+       free(buffer);
+       
+       return ERROR_OK;
+}
+
+int str9xpec_erase_check(struct flash_bank_s *bank)
+{
+       return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
+}
+
+int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
+{
+       snprintf(buf, buf_size, "str9xpec flash driver info" );
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       u8 status;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str9xpec options_read <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       status = str9xpec_read_config(bank);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       
+       /* boot bank */
+       if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
+               command_print(cmd_ctx, "CS Map: bank1");
+       else
+               command_print(cmd_ctx, "CS Map: bank0");
+       
+       /* OTP lock */
+       if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
+               command_print(cmd_ctx, "OTP Lock: OTP Locked");
+       else
+               command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
+       
+       /* LVD Threshold */
+       if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
+               command_print(cmd_ctx, "LVD Threshold: 2.7v");
+       else
+               command_print(cmd_ctx, "LVD Threshold: 2.4v");
+       
+       /* LVD reset warning */
+       if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
+               command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
+       else
+               command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
+       
+       /* LVD reset select */
+       if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
+               command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
+       else
+               command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
+       
+       return ERROR_OK;
+}
+
+int str9xpec_write_options(struct flash_bank_s *bank)
+{
+       scan_field_t field;
+       u8 status;
+       u32 chain_pos;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       str9xpec_info = bank->driver_priv;
+       chain_pos = str9xpec_info->chain_pos;
+       
+       /* erase config options first */
+       str9xpec_erase_area( bank, 0xFE, 0xFE );
+       
+       if (!str9xpec_info->isc_enable) {
+               str9xpec_isc_enable( bank );
+       }
+       
+       if (!str9xpec_info->isc_enable) {
+               return ISC_STATUS_ERROR;
+       }
+       
+       /* according to data 64th bit has to be set */
+       buf_set_u32(str9xpec_info->options, 63, 1, 1);
+       
+       /* set option byte address */
+       str9xpec_set_address(bank, 0x50);
+       
+       /* execute ISC_PROGRAM command */
+       str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
+               
+       field.device = chain_pos;
+       field.num_bits = 64;
+       field.out_value = str9xpec_info->options;
+       field.out_mask = NULL;
+       field.in_value = NULL;
+       field.in_check_value = NULL;
+       field.in_check_mask = NULL;
+       field.in_handler = NULL;
+       field.in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
+       
+       /* small delay before polling */
+       jtag_add_sleep(50);
+       
+       str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
+       
+       do {
+               field.device = chain_pos;
+               field.num_bits = 8;
+               field.out_value = NULL;
+               field.out_mask = NULL;
+               field.in_value = &status;
+               field.in_check_value = NULL;
+               field.in_check_mask = NULL;
+               field.in_handler = NULL;
+               field.in_handler_priv = NULL;
+               
+               jtag_add_dr_scan(1, &field, -1, NULL);
+               jtag_execute_queue();
+               
+       } while(!(status & ISC_STATUS_BUSY));
+       
+       str9xpec_isc_disable(bank);
+       
+       return status;
+}
+
+int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       u8 status;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str9xpec options_write <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       status = str9xpec_write_options(bank);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 2)
+       {
+               command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       if (stricmp(args[1], "bank1") == 0)
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
+       }
+       else
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
+       }
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 2)
+       {
+               command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       if (stricmp(args[1], "2.7v") == 0)
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
+       }
+       else
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
+       }
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 2)
+       {
+               command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       if (stricmp(args[1], "vdd_vddq") == 0)
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
+       }
+       else
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
+       }
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 2)
+       {
+               command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       if (stricmp(args[1], "vdd_vddq") == 0)
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
+       }
+       else
+       {
+               buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
+       }
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       u8 status;
+       flash_bank_t *bank;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str9xpec lock <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       status = str9xpec_lock_device(bank);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       u8 status;
+       flash_bank_t *bank;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str9xpec unlock <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       status = str9xpec_unlock_device(bank);
+       
+       if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
+               return ERROR_FLASH_OPERATION_FAILED;
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       u32 chain_pos;
+       jtag_device_t* dev0;
+       jtag_device_t* dev2;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       /* remove arm core from chain - enter turbo mode */
+       
+       str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
+       jtag_execute_queue();
+       
+       /* modify scan chain - str9 core has been removed */
+       dev0 = jtag_get_device(chain_pos);
+       str9xpec_info->devarm = jtag_get_device(chain_pos+1);
+       dev2 = jtag_get_device(chain_pos+2);
+       dev0->next = dev2;
+       jtag_num_devices--;
+       
+       return ERROR_OK;
+}
+
+int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       u32 chain_pos;
+       jtag_device_t* dev0;
+       str9xpec_flash_controller_t *str9xpec_info = NULL;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+               return ERROR_OK;
+       }
+       
+       str9xpec_info = bank->driver_priv;
+       
+       chain_pos = str9xpec_info->chain_pos;
+       
+       dev0 = jtag_get_device(chain_pos);
+       
+       /* exit turbo mode via TLR */
+       str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
+       jtag_execute_queue();
+       
+       /* restore previous scan chain */
+       if( str9xpec_info->devarm ) {
+               dev0->next = str9xpec_info->devarm;
+               jtag_num_devices++;
+       }
+       
+       return ERROR_OK;
+}
diff --git a/src/flash/str9xpec.h b/src/flash/str9xpec.h
new file mode 100644 (file)
index 0000000..3d1b006
--- /dev/null
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *   Copyright (C) 2005 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef STR9XPEC_H
+#define STR9XPEC_H
+
+#include "flash.h"
+#include "target.h"
+#include "jtag.h"
+
+typedef struct str9xpec_flash_controller_s
+{
+       struct target_s *target;
+       u32 *sector_bits;
+       int chain_pos;
+       int isc_enable;
+       jtag_device_t* devarm;
+       u8 options[8];
+} str9xpec_flash_controller_t;
+
+enum str9xpec_status_codes
+{
+       STR9XPEC_INVALID_COMMAND = 1,
+       STR9XPEC_ISC_SUCCESS = 2,
+       STR9XPEC_ISC_DISABLED = 3,
+       STR9XPEC_ISC_INTFAIL = 32,
+};
+
+/* ISC commands */
+
+#define ISC_IDCODE                             0xFE
+#define ISC_MFG_READ                   0x4C
+#define ISC_CONFIGURATION              0x07
+#define ISC_ENABLE                             0x0C
+#define ISC_DISABLE                            0x0F
+#define ISC_NOOP                               0x10
+#define ISC_ADDRESS_SHIFT              0x11
+#define ISC_CLR_STATUS                 0x13
+#define ISC_PROGRAM                            0x20
+#define ISC_PROGRAM_SECURITY   0x22
+#define ISC_PROGRAM_UC                 0x23
+#define ISC_ERASE                              0x30
+#define ISC_READ                               0x50
+#define ISC_BLANK_CHECK                        0x60
+
+/* ISC_DEFAULT bit definitions */
+
+#define ISC_STATUS_SECURITY            0x40
+#define ISC_STATUS_INT_ERROR   0x30
+#define ISC_STATUS_MODE                        0x08
+#define ISC_STATUS_BUSY                        0x04
+#define ISC_STATUS_ERROR               0x03
+
+typedef struct mem_layout_str9pec {
+       u32 sector_start;
+       u32 sector_size;
+       u32 sector_bit;
+} str9xpec_mem_layout_t;
+
+/* Option bytes definitions */
+
+#define STR9XPEC_OPT_CSMAPBIT          48
+#define STR9XPEC_OPT_LVDTHRESBIT       49
+#define STR9XPEC_OPT_LVDSELBIT         50
+#define STR9XPEC_OPT_LVDWARNBIT                51
+#define STR9XPEC_OPT_OTPBIT                    63
+
+#endif /* STR9XPEC_H */
+
index 0b132d778fd8bc75f55c09395427a5d7d56e0f3f..ca042d6059707e06d500877f6c87ed485cf02e51 100644 (file)
@@ -24,6 +24,8 @@
 #include "config.h"
 #endif
 
+#include "types.h"
+
 /* include necessary headers for socket functionality */
 #ifdef _WIN32
 #include <winsock2.h>
@@ -152,4 +154,51 @@ static __inline void socket_nonblock(int fd)
 #endif
 }
 
+#ifndef HAVE_ELF_H
+
+typedef struct
+{
+       unsigned char   e_ident[16];    /* Magic number and other info */
+       u16     e_type;                 /* Object file type */
+       u16     e_machine;              /* Architecture */
+       u32     e_version;              /* Object file version */
+       u32 e_entry;            /* Entry point virtual address */
+       u32 e_phoff;            /* Program header table file offset */
+       u32     e_shoff;                /* Section header table file offset */
+       u32     e_flags;                /* Processor-specific flags */
+       u16     e_ehsize;               /* ELF header size in bytes */
+       u16     e_phentsize;            /* Program header table entry size */
+       u16     e_phnum;                /* Program header table entry count */
+       u16     e_shentsize;            /* Section header table entry size */
+       u16     e_shnum;                /* Section header table entry count */
+       u16     e_shstrndx;             /* Section header string table index */
+} Elf32_Ehdr;
+
+#define        ELFMAG          "\177ELF"
+#define        SELFMAG         4
+
+#define EI_CLASS       4               /* File class byte index */
+#define ELFCLASS32     1               /* 32-bit objects */
+#define ELFCLASS64     2               /* 64-bit objects */
+
+#define EI_DATA                5               /* Data encoding byte index */
+#define ELFDATA2LSB    1               /* 2's complement, little endian */
+#define ELFDATA2MSB    2               /* 2's complement, big endian */
+
+typedef struct
+{
+       u32     p_type;                 /* Segment type */
+       u32  p_offset;          /* Segment file offset */
+       u32     p_vaddr;                /* Segment virtual address */
+       u32     p_paddr;                /* Segment physical address */
+       u32     p_filesz;               /* Segment size in file */
+       u32     p_memsz;                /* Segment size in memory */
+       u32     p_flags;                /* Segment flags */
+       u32     p_align;                /* Segment alignment */
+} Elf32_Phdr;
+
+#define PT_LOAD                1               /* Loadable program segment */
+
+#endif /* HAVE_ELF_H */
+
 #endif /* REPLACEMENTS_H */
index 9615817fc591cc04964fdded03a425ab4dea2e61..de48fce842a85769c5285a20c12b8f7f784fe202 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #endif
 
+#include "replacements.h"
 #include "time_support.h"
 #include "log.h"
 
index a20f9d94430a210ab897b30da6d685c5541f7e9d..6f08ee1983a964e99f2f398461cce3c1e46ac9f0 100644 (file)
@@ -21,6 +21,8 @@
 #include "config.h"
 #endif
 
+#include "replacements.h"
+
 #include "pld.h"
 
 #include "jtag.h"
index 951be45053b4159764affb5985a50da7863f3318..ac5e17e56981a4fc8835929b85b69259fd5fba0b 100644 (file)
@@ -301,7 +301,7 @@ int server_loop(command_context_t *command_context)
                                FD_ZERO(&read_fds);
                        else
                        {
-                               ERROR("error during select: %d", strerror(errno));
+                               ERROR("error during select: %s", strerror(errno));
                                exit(-1);
                        }
 #else
index a3c40d6f6a60bd181b6ae7c087b54f2d8cb28243..b5c9752b26bc0337fc3964be27647c38c6173c96 100644 (file)
@@ -241,8 +241,8 @@ void arm720t_post_debug_entry(target_t *target)
        arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
 
        /* save i/d fault status and address register */
-       arm720t_read_cp15(target, 0xee150f10, &arm720t->fsr);
-       arm720t_read_cp15(target, 0xee160f10, &arm720t->far);
+       arm720t_read_cp15(target, 0xee150f10, &arm720t->fsr_reg);
+       arm720t_read_cp15(target, 0xee160f10, &arm720t->far_reg);
        jtag_execute_queue();
 }
 
@@ -254,8 +254,8 @@ void arm720t_pre_restore_context(target_t *target)
        arm720t_common_t *arm720t = arm7tdmi->arch_info;
        
        /* restore i/d fault status and address register */
-       arm720t_write_cp15(target, 0xee050f10, arm720t->fsr);
-       arm720t_write_cp15(target, 0xee060f10, arm720t->far);
+       arm720t_write_cp15(target, 0xee050f10, arm720t->fsr_reg);
+       arm720t_write_cp15(target, 0xee060f10, arm720t->far_reg);
 }
 
 int arm720t_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm7tdmi_common_t **arm7tdmi_p, arm720t_common_t **arm720t_p)
index 2479b5485e47304951faab0e82c457fb4a1a5fab..d16e3e6b5d73e6065d48991b9bd04be6807bead3 100644 (file)
@@ -36,8 +36,8 @@ typedef struct arm720t_common_s
        armv4_5_mmu_common_t armv4_5_mmu;
        arm7tdmi_common_t arm7tdmi_common;
        u32 cp15_control_reg;
-       u32 fsr;
-       u32 far;
+       u32 fsr_reg;
+       u32 far_reg;
 } arm720t_common_t;
 
 #endif /* ARM720T_H */
index 6239b994986341a32a49a64ae272dc03f9b9bcf2..833381b2c70016f8a8ce2634db2f2f586a695b1b 100644 (file)
@@ -23,7 +23,9 @@
 
 #include <stdlib.h>
 #include <string.h>
+#ifdef HAVE_ELF_H
 #include <elf.h>
+#endif
 
 #include "image.h"
 
@@ -320,8 +322,8 @@ int image_elf_read_headers(image_t *image)
 
 
        elf->endianness = elf->header->e_ident[EI_DATA];
-       if ((elf->endianness==ELFDATANONE)
-                ||(elf->endianness>=ELFDATANUM))
+       if ((elf->endianness!=ELFDATA2LSB)
+                &&(elf->endianness!=ELFDATA2MSB))
        {
                ERROR("invalid ELF file, unknown endianess setting");
                return ERROR_IMAGE_FORMAT_ERROR;
index 7aa119caa55b25c7bc9b20a7d04ae8ed3fa61ad9..07931472ec525a7e990ec4aa51fcecf4921fe605 100644 (file)
 #ifndef IMAGE_H
 #define IMAGE_H
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ELF_H
 #include <elf.h>
+#endif
+#include "replacements.h"
 #include "fileio.h"
 #include "target.h"
 
index e7fb3ec8783e91dff133f24a4f51da2488d8bd8f..2eeb2bfc5cd6418fcba028ea05ff1ae9fa08b92a 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1776,7 +1777,7 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
        fileio_close(&fileio);
 
        duration_stop_measure(&duration, &duration_text);
-       command_print(cmd_ctx, "dumped %lli byte in %s", fileio.size, duration_text);
+       command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);
        free(duration_text);
        
        return ERROR_OK;
index 334924f307b95708b5423ed78091899f3483189f..311e53bc98d99c9f610a4275db83b98a8c3416b7 100644 (file)
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+#ifdef HAVE_CONFIG_H
 #include "config.h"
+#endif
+
+#include "replacements.h"
 
 #include "xscale.h"
 

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)