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 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
+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 stm32x.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 stm32x.h
extern flash_driver_t str9x_flash;
extern flash_driver_t stellaris_flash;
extern flash_driver_t str9xpec_flash;
+extern flash_driver_t stm32x_flash;
flash_driver_t *flash_drivers[] =
{
&str9x_flash,
&stellaris_flash,
&str9xpec_flash,
+ &stm32x_flash,
NULL,
};
--- /dev/null
+/***************************************************************************
+ * 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 "stm32x.h"
+#include "flash.h"
+#include "target.h"
+#include "log.h"
+#include "armv7m.h"
+#include "algorithm.h"
+#include "binarybuffer.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+int stm32x_register_commands(struct command_context_s *cmd_ctx);
+int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
+int stm32x_erase(struct flash_bank_s *bank, int first, int last);
+int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last);
+int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
+int stm32x_probe(struct flash_bank_s *bank);
+int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int stm32x_protect_check(struct flash_bank_s *bank);
+int stm32x_erase_check(struct flash_bank_s *bank);
+int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size);
+
+int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+flash_driver_t stm32x_flash =
+{
+ .name = "stm32x",
+ .register_commands = stm32x_register_commands,
+ .flash_bank_command = stm32x_flash_bank_command,
+ .erase = stm32x_erase,
+ .protect = stm32x_protect,
+ .write = stm32x_write,
+ .probe = stm32x_probe,
+ .erase_check = stm32x_erase_check,
+ .protect_check = stm32x_protect_check,
+ .info = stm32x_info
+};
+
+int stm32x_register_commands(struct command_context_s *cmd_ctx)
+{
+ command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stm32x", NULL, COMMAND_ANY, "stm32x flash specific commands");
+
+ register_command(cmd_ctx, stm32x_cmd, "lock", stm32x_handle_lock_command, COMMAND_EXEC,
+ "lock device");
+ register_command(cmd_ctx, stm32x_cmd, "unlock", stm32x_handle_unlock_command, COMMAND_EXEC,
+ "unlock protected device");
+ register_command(cmd_ctx, stm32x_cmd, "mass_erase", stm32x_handle_mass_erase_command, COMMAND_EXEC,
+ "mass erase device");
+ register_command(cmd_ctx, stm32x_cmd, "options_read", stm32x_handle_options_read_command, COMMAND_EXEC,
+ "read device option bytes");
+ register_command(cmd_ctx, stm32x_cmd, "options_write", stm32x_handle_options_write_command, COMMAND_EXEC,
+ "write device option bytes");
+ return ERROR_OK;
+}
+
+int stm32x_build_block_list(struct flash_bank_s *bank)
+{
+ int i;
+ int num_sectors = 0;
+
+ switch (bank->size)
+ {
+ case 32 * 1024:
+ num_sectors = 32;
+ break;
+ case 64 * 1024:
+ num_sectors = 64;
+ break;
+ case 128 * 1024:
+ num_sectors = 128;
+ break;
+ default:
+ ERROR("BUG: unknown bank->size encountered");
+ exit(-1);
+ }
+
+ bank->num_sectors = num_sectors;
+ bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
+
+ for (i = 0; i < num_sectors; i++)
+ {
+ bank->sectors[i].offset = i * 1024;
+ bank->sectors[i].size = 1024;
+ bank->sectors[i].is_erased = -1;
+ bank->sectors[i].is_protected = 1;
+ }
+
+ return ERROR_OK;
+}
+
+/* flash bank stm32x <base> <size> 0 0 <target#>
+ */
+int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
+{
+ stm32x_flash_bank_t *stm32x_info;
+
+ if (argc < 6)
+ {
+ WARNING("incomplete flash_bank stm32x configuration");
+ return ERROR_FLASH_BANK_INVALID;
+ }
+
+ stm32x_info = malloc(sizeof(stm32x_flash_bank_t));
+ bank->driver_priv = stm32x_info;
+
+ if (bank->base != 0x08000000)
+ {
+ WARNING("overriding flash base address for STM32x device with 0x08000000");
+ bank->base = 0x08000000;
+ }
+
+ stm32x_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
+ if (!stm32x_info->target)
+ {
+ ERROR("no target '%s' configured", args[5]);
+ exit(-1);
+ }
+
+ stm32x_build_block_list(bank);
+
+ stm32x_info->write_algorithm = NULL;
+
+ return ERROR_OK;
+}
+
+u32 stm32x_get_flash_status(flash_bank_t *bank)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+ u32 status;
+
+ target_read_u32(target, STM32_FLASH_SR, &status);
+
+ return status;
+}
+
+u32 stm32x_wait_status_busy(flash_bank_t *bank, int timeout)
+{
+ u32 status;
+
+ /* wait for busy to clear */
+ while (((status = stm32x_get_flash_status(bank)) & FLASH_BSY) && (timeout-- > 0))
+ {
+ DEBUG("status: 0x%x", status);
+ usleep(1000);
+ }
+
+ return status;
+}
+
+int stm32x_blank_check(struct flash_bank_s *bank, int first, int last)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+ u8 *buffer;
+ int i;
+ int nBytes;
+
+ if ((first < 0) || (last > bank->num_sectors))
+ return ERROR_FLASH_SECTOR_INVALID;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ buffer = malloc(256);
+
+ for (i = first; i <= last; i++)
+ {
+ bank->sectors[i].is_erased = 1;
+
+ target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer);
+
+ for (nBytes = 0; nBytes < 256; nBytes++)
+ {
+ if (buffer[nBytes] != 0xFF)
+ {
+ bank->sectors[i].is_erased = 0;
+ break;
+ }
+ }
+ }
+
+ free(buffer);
+
+ return ERROR_OK;
+}
+
+int stm32x_protect_check(struct flash_bank_s *bank)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+
+ u32 protection;
+ int i, s;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ /* each bit refers to a 4bank protection */
+ target_read_u32(target, STM32_FLASH_WRPR, &protection);
+
+ for (i = 0; i < 32; i++)
+ {
+ int set = 1;
+
+ if( protection & (1 << i))
+ set = 0;
+
+ for (s = 0; s < 4; s++)
+ bank->sectors[(i * 4) + s].is_protected = set;
+ }
+
+ return ERROR_OK;
+}
+
+int stm32x_erase(struct flash_bank_s *bank, int first, int last)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+
+ int i;
+ u32 status;
+
+ /* unlock flash registers */
+ target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ for (i = first; i <= last; i++)
+ {
+ target_write_u32(target, STM32_FLASH_CR, FLASH_PER);
+ target_write_u32(target, STM32_FLASH_AR, bank->base + bank->sectors[i].offset);
+ target_write_u32(target, STM32_FLASH_CR, FLASH_PER|FLASH_STRT);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ bank->sectors[i].is_erased = 1;
+ }
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+
+ return ERROR_OK;
+}
+
+int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ return ERROR_OK;
+}
+
+int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+ u32 buffer_size = 8192;
+ working_area_t *source;
+ u32 address = bank->base + offset;
+ reg_param_t reg_params[6];
+ armv7m_algorithm_t armv7m_info;
+ int retval = ERROR_OK;
+
+ u8 stm32x_flash_write_code[] = {
+ /* write: */
+ 0xDF, 0xF8, 0x24, 0x40, /* ldr r4, STM32_FLASH_CR */
+ 0x09, 0x4D, /* ldr r5, STM32_FLASH_SR */
+ 0x4F, 0xF0, 0x01, 0x03, /* mov r3, #1 */
+ 0x23, 0x60, /* str r3, [r4, #0] */
+ 0x30, 0xF8, 0x02, 0x3B, /* ldrh r3, [r0], #2 */
+ 0x21, 0xF8, 0x02, 0x3B, /* strh r3, [r1], #2 */
+ /* busy: */
+ 0x2B, 0x68, /* ldr r3, [r5, #0] */
+ 0x13, 0xF0, 0x01, 0x0F, /* tst r3, #0x01 */
+ 0xFB, 0xD0, /* beq busy */
+ 0x13, 0xF0, 0x14, 0x0F, /* tst r3, #0x14 */
+ 0x01, 0xD1, /* bne exit */
+ 0x01, 0x3A, /* subs r2, r2, #1 */
+ 0xED, 0xD1, /* bne write */
+ /* exit: */
+ 0xFE, 0xE7, /* b exit */
+ 0x10, 0x20, 0x02, 0x40, /* STM32_FLASH_CR: .word 0x40022010 */
+ 0x0C, 0x20, 0x02, 0x40 /* STM32_FLASH_SR: .word 0x4002200C */
+ };
+
+ /* flash write code */
+ if (!stm32x_info->write_algorithm)
+ {
+ if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code), &stm32x_info->write_algorithm) != ERROR_OK)
+ {
+ WARNING("no working area available, can't do block memory writes");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ };
+
+ target_write_buffer(target, stm32x_info->write_algorithm->address, sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
+ }
+
+ /* memory buffer */
+ while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
+ {
+ buffer_size /= 2;
+ if (buffer_size <= 256)
+ {
+ /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
+ if (stm32x_info->write_algorithm)
+ target_free_working_area(target, stm32x_info->write_algorithm);
+
+ WARNING("no large enough working area available, can't do block memory writes");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ };
+
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARMV7M_MODE_ANY;
+ armv7m_info.core_state = ARMV7M_STATE_THUMB;
+
+ init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
+ init_reg_param(®_params[2], "r2", 32, PARAM_OUT);
+ init_reg_param(®_params[3], "r3", 32, PARAM_IN);
+ init_reg_param(®_params[4], "r4", 32, PARAM_IN);
+ init_reg_param(®_params[5], "r5", 32, PARAM_IN);
+
+ while (count > 0)
+ {
+ u32 thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
+
+ target_write_buffer(target, source->address, thisrun_count * 2, buffer);
+
+ buf_set_u32(reg_params[0].value, 0, 32, source->address);
+ buf_set_u32(reg_params[1].value, 0, 32, address);
+ buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
+
+ if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, stm32x_info->write_algorithm->address, \
+ stm32x_info->write_algorithm->address + (sizeof(stm32x_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
+ {
+ ERROR("error executing str7x flash write algorithm");
+ break;
+ }
+
+ if (buf_get_u32(reg_params[3].value, 0, 32) & 0x14)
+ {
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ break;
+ }
+
+ buffer += thisrun_count * 2;
+ address += thisrun_count * 2;
+ count -= thisrun_count;
+ }
+
+ target_free_working_area(target, source);
+
+ destroy_reg_param(®_params[0]);
+ destroy_reg_param(®_params[1]);
+ destroy_reg_param(®_params[2]);
+ destroy_reg_param(®_params[3]);
+ destroy_reg_param(®_params[4]);
+ destroy_reg_param(®_params[5]);
+
+ return retval;
+}
+
+int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
+{
+ stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
+ target_t *target = stm32x_info->target;
+ u32 words_remaining = (count / 2);
+ u32 bytes_remaining = (count & 0x00000001);
+ u32 address = bank->base + offset;
+ u32 bytes_written = 0;
+ u8 status;
+ u32 retval;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (offset & 0x1)
+ {
+ WARNING("offset 0x%x breaks required 2-byte alignment", offset);
+ return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+ }
+
+ /* unlock flash registers */
+ target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+ /* multiple half words (2-byte) to be programmed? */
+ if (words_remaining > 0)
+ {
+ /* try using a block write */
+ if ((retval = stm32x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
+ {
+ if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+ {
+ /* if block write failed (no sufficient working area),
+ * we use normal (slow) single dword accesses */
+ WARNING("couldn't use block writes, falling back to single memory accesses");
+ }
+ else if (retval == ERROR_FLASH_OPERATION_FAILED)
+ {
+ ERROR("flash writing failed with error code: 0x%x", retval);
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ }
+ else
+ {
+ buffer += words_remaining * 2;
+ address += words_remaining * 2;
+ words_remaining = 0;
+ }
+ }
+
+ while (words_remaining > 0)
+ {
+ target_write_u32(target, STM32_FLASH_CR, FLASH_PG);
+ target_write_u16(target, address, *(u16*)(buffer + bytes_written));
+
+ status = stm32x_wait_status_busy(bank, 5);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ bytes_written += 2;
+ words_remaining--;
+ address += 2;
+ }
+
+ if (bytes_remaining)
+ {
+ u8 last_halfword[2] = {0xff, 0xff};
+ int i = 0;
+
+ while(bytes_remaining > 0)
+ {
+ last_halfword[i++] = *(buffer + bytes_written);
+ bytes_remaining--;
+ bytes_written++;
+ }
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_PG);
+ target_write_u16(target, address, *(u16*)last_halfword);
+
+ status = stm32x_wait_status_busy(bank, 5);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+
+ return ERROR_OK;
+}
+
+int stm32x_probe(struct flash_bank_s *bank)
+{
+ return ERROR_OK;
+}
+
+int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ return ERROR_OK;
+}
+
+int stm32x_erase_check(struct flash_bank_s *bank)
+{
+ return stm32x_blank_check(bank, 0, bank->num_sectors - 1);
+}
+
+int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size)
+{
+ snprintf(buf, buf_size, "stm32x flash driver info" );
+ return ERROR_OK;
+}
+
+int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ flash_bank_t *bank;
+ u32 status;
+ target_t *target = NULL;
+ stm32x_flash_bank_t *stm32x_info = NULL;
+
+ if (argc < 1)
+ {
+ command_print(cmd_ctx, "stm32x 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;
+ }
+
+ stm32x_info = bank->driver_priv;
+
+ target = stm32x_info->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ /* unlock flash registers */
+ target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+ /* unlock option flash registers */
+ target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
+
+ /* erase option bytes */
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_OPTWRE);
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_STRT|FLASH_OPTWRE);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ /* program option bytes */
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG|FLASH_OPTWRE);
+
+ /* set readout protection */
+ target_write_u16(target, STM32_OB_ADR, 0);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+ command_print(cmd_ctx, "stm32x locked");
+
+ return ERROR_OK;
+}
+
+int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ flash_bank_t *bank;
+ u32 status;
+ target_t *target = NULL;
+ stm32x_flash_bank_t *stm32x_info = NULL;
+
+ if (argc < 1)
+ {
+ command_print(cmd_ctx, "stm32x 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;
+ }
+
+ stm32x_info = bank->driver_priv;
+
+ target = stm32x_info->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ /* unlock flash registers */
+ target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+ /* unlock option flash registers */
+ target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
+
+ /* erase option bytes */
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_OPTWRE);
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_STRT|FLASH_OPTWRE);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ /* program option bytes */
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG|FLASH_OPTWRE);
+
+ /* clear readout protection and complementary option bytes */
+ target_write_u16(target, STM32_OB_ADR, 0x5AA5);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+ command_print(cmd_ctx, "stm32x unlocked");
+
+ return ERROR_OK;
+}
+
+int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ flash_bank_t *bank;
+ u32 optionbyte;
+ target_t *target = NULL;
+ stm32x_flash_bank_t *stm32x_info = NULL;
+
+ if (argc < 1)
+ {
+ command_print(cmd_ctx, "stm32x 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;
+ }
+
+ stm32x_info = bank->driver_priv;
+
+ target = stm32x_info->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ //target_read_u32(target, STM32_OB_ADR, &optionbyte);
+ //command_print(cmd_ctx, "Option Byte 0: 0x%x", optionbyte);
+ //target_read_u32(target, STM32_OB_ADR+4, &optionbyte);
+ //command_print(cmd_ctx, "Option Byte 1: 0x%x", optionbyte);
+ //target_read_u32(target, STM32_OB_ADR+8, &optionbyte);
+ //command_print(cmd_ctx, "Option Byte 2: 0x%x", optionbyte);
+ //target_read_u32(target, STM32_OB_ADR+12, &optionbyte);
+ //command_print(cmd_ctx, "Option Byte 3: 0x%x", optionbyte);
+
+ target_read_u32(target, STM32_FLASH_OBR, &optionbyte);
+ command_print(cmd_ctx, "Option Byte: 0x%x", optionbyte);
+
+ if (buf_get_u32((u8*)&optionbyte, OPT_ERROR, 1))
+ command_print(cmd_ctx, "Option Byte Complement Error");
+
+ if (buf_get_u32((u8*)&optionbyte, OPT_READOUT, 1))
+ command_print(cmd_ctx, "Readout Protection On");
+ else
+ command_print(cmd_ctx, "Readout Protection Off");
+
+ if (buf_get_u32((u8*)&optionbyte, OPT_RDWDGSW, 1))
+ command_print(cmd_ctx, "Software Watchdog");
+ else
+ command_print(cmd_ctx, "Hardware Watchdog");
+
+ if (buf_get_u32((u8*)&optionbyte, OPT_RDRSTSTOP, 1))
+ command_print(cmd_ctx, "Stop: No reset generated");
+ else
+ command_print(cmd_ctx, "Stop: Reset generated");
+
+ if (buf_get_u32((u8*)&optionbyte, OPT_RDRSTSTDBY, 1))
+ command_print(cmd_ctx, "Standby: No reset generated");
+ else
+ command_print(cmd_ctx, "Standby: Reset generated");
+
+ return ERROR_OK;
+}
+
+int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ flash_bank_t *bank;
+ target_t *target = NULL;
+ stm32x_flash_bank_t *stm32x_info = NULL;
+ u16 optionbyte = 0xF8;
+ u32 status;
+
+ if (argc < 4)
+ {
+ command_print(cmd_ctx, "stm32x options_write <bank> <RSTSTNDBY|NORSTSTNDBY> <RSTSTOP|NORSTSTOP> <SWWDG|HWWDG>");
+ 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;
+ }
+
+ stm32x_info = bank->driver_priv;
+
+ target = stm32x_info->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (strcmp(args[1], "SWWDG") == 0)
+ {
+ optionbyte |= (1<<0);
+ }
+ else
+ {
+ optionbyte &= ~(1<<0);
+ }
+
+ if (strcmp(args[2], "NORSTSTNDBY") == 0)
+ {
+ optionbyte |= (1<<1);
+ }
+ else
+ {
+ optionbyte &= ~(1<<1);
+ }
+
+ if (strcmp(args[3], "NORSTSTOP") == 0)
+ {
+ optionbyte |= (1<<2);
+ }
+ else
+ {
+ optionbyte &= ~(1<<2);
+ }
+
+ /* unlock flash registers */
+ target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+ /* unlock option flash registers */
+ target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
+
+ /* program option bytes */
+ target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG|FLASH_OPTWRE);
+
+ /* write option byte */
+ target_write_u16(target, STM32_OB_ADR + 2, optionbyte);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+
+ return ERROR_OK;
+}
+
+int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ flash_bank_t *bank;
+ u32 status;
+ target_t *target = NULL;
+ stm32x_flash_bank_t *stm32x_info = NULL;
+
+ if (argc < 1)
+ {
+ command_print(cmd_ctx, "stm32x mass_erase <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;
+ }
+
+ stm32x_info = bank->driver_priv;
+
+ target = stm32x_info->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ /* unlock option flash registers */
+ target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+ target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+ /* mass erase flash memory */
+ target_write_u32(target, STM32_FLASH_CR, FLASH_MER);
+ target_write_u32(target, STM32_FLASH_CR, FLASH_MER|FLASH_STRT);
+
+ status = stm32x_wait_status_busy(bank, 10);
+
+ if( status & FLASH_WRPRTERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+ if( status & FLASH_PGERR )
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+
+ return ERROR_OK;
+}
--- /dev/null
+/***************************************************************************
+ * 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 STM32X_H
+#define STM32X_H
+
+#include "flash.h"
+#include "target.h"
+
+typedef struct stm32x_flash_bank_s
+{
+ struct target_s *target;
+ working_area_t *write_algorithm;
+} stm32x_flash_bank_t;
+
+/* stm32x register locations */
+
+#define STM32_FLASH_ACR 0x40022000
+#define STM32_FLASH_KEYR 0x40022004
+#define STM32_FLASH_OPTKEYR 0x40022008
+#define STM32_FLASH_SR 0x4002200C
+#define STM32_FLASH_CR 0x40022010
+#define STM32_FLASH_AR 0x40022014
+#define STM32_FLASH_OBR 0x4002201C
+#define STM32_FLASH_WRPR 0x40022020
+
+/* option byte location */
+
+#define STM32_OB_ADR 0x1FFFF800
+
+/* FLASH_CR register bits */
+
+#define FLASH_PG (1<<0)
+#define FLASH_PER (1<<1)
+#define FLASH_MER (1<<2)
+#define FLASH_OPTPG (1<<4)
+#define FLASH_OPTER (1<<5)
+#define FLASH_STRT (1<<6)
+#define FLASH_LOCK (1<<7)
+#define FLASH_OPTWRE (1<<9)
+
+/* FLASH_SR regsiter bits */
+
+#define FLASH_BSY (1<<0)
+#define FLASH_PGERR (1<<2)
+#define FLASH_WRPRTERR (1<<4)
+#define FLASH_EOP (1<<5)
+
+/* STM32_FLASH_OBR bit definitions (reading) */
+
+#define OPT_ERROR 0
+#define OPT_READOUT 1
+#define OPT_RDWDGSW 2
+#define OPT_RDRSTSTOP 3
+#define OPT_RDRSTSTDBY 4
+
+/* register unlock keys */
+
+#define KEY1 0x45670123
+#define KEY2 0xCDEF89AB
+
+typedef struct stm32x_mem_layout_s {
+ u32 sector_start;
+ u32 sector_size;
+} stm32x_mem_layout_t;
+
+#endif /* STM32X_H */
+
if (offset_12)
snprintf(offset, 32, ", #%s0x%x", (U) ? "" : "-", offset_12);
else
- snprintf(offset, 32, "");
+ snprintf(offset, 32, "%s", "");
instruction->info.load_store.offset_mode = 0;
instruction->info.load_store.offset.offset = offset_12;
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
- if (armv7m->process_context == armv7m->core_cache) return ARMV7M_PROCESS_CONTEXT;
- if (armv7m->debug_context == armv7m->core_cache) return ARMV7M_DEBUG_CONTEXT;
+ if (armv7m->process_context == armv7m->core_cache)
+ return ARMV7M_PROCESS_CONTEXT;
+ if (armv7m->debug_context == armv7m->core_cache)
+ return ARMV7M_DEBUG_CONTEXT;
ERROR("Invalid runcontext");
exit(-1);
char enamebuf[32];
char *armv7m_exception_string(int number)
{
- if ((number<0)|(number>511)) return "Invalid exception";
- if (number<16) return armv7m_exception_strings[number];
- sprintf(enamebuf,"External Interrupt(%i)",number-16);
+ if ((number < 0) | (number > 511))
+ return "Invalid exception";
+ if (number < 16)
+ return armv7m_exception_strings[number];
+ sprintf(enamebuf, "External Interrupt(%i)", number - 16);
return enamebuf;
}
if ((num < 0) || (num >= ARMV7NUMCOREREGS))
return ERROR_INVALID_ARGUMENTS;
-
reg_value = buf_get_u32(armv7m->core_cache->reg_list[num].value, 0, 32);
armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info;
retval = armv7m->store_core_reg_u32(target, armv7m_core_reg->type, armv7m_core_reg->num, reg_value);
if (retval != ERROR_OK)
{
- ERROR("JTAG failure");
- armv7m->core_cache->reg_list[num].dirty=1;
- return ERROR_JTAG_DEVICE_ERROR;
+ ERROR("JTAG failure");
+ armv7m->core_cache->reg_list[num].dirty=1;
+ return ERROR_JTAG_DEVICE_ERROR;
}
DEBUG("write core reg %i value 0x%x",num ,reg_value);
armv7m->core_cache->reg_list[num].valid=1;
armv7m->core_cache->reg_list[num].dirty=0;
return ERROR_OK;
-
}
-
-
int armv7m_invalidate_core_regs(target_t *target)
{
/* get pointers to arch-specific information */
return ERROR_OK;
}
-
int armv7m_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
{
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
int i;
-
if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
/* TODOLATER correct list of registers, names ? */
for (i = 0; i < *reg_list_size; i++)
{
- if (i<ARMV7NUMCOREREGS)
+ if (i < ARMV7NUMCOREREGS)
(*reg_list)[i] = &armv7m->process_context->reg_list[i];
//(*reg_list)[i] = &armv7m->core_cache->reg_list[i];
else
armv7m_set_core_reg(reg, reg_params[i].value);
}
- /* ARMV7M always runs in Tumb state */
+ /* ARMV7M always runs in Thumb state */
exit_breakpoint_size = 2;
if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_SOFT)) != ERROR_OK)
{
}
}
armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
- DEBUG("failed algoritm halted at 0x%x ",pc);
+ DEBUG("failed algoritm halted at 0x%x ", pc);
retval = ERROR_TARGET_TIMEOUT;
}
}
exit(-1);
}
- armv7m_core_reg_t * armv7m_core_reg = reg->arch_info;
+ armv7m_core_reg_t *armv7m_core_reg = reg->arch_info;
//armv7m->load_core_reg_u32(target, armv7m_core_reg->type, armv7m_core_reg->num, ®value);
//buf_set_u32(reg_params[i].value, 0, 32, regvalue);
buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
// armv7m->core_cache->reg_list[i].dirty = 1;
//}
-
// ????armv7m->core_state = core_state;
// ????armv7m->core_mode = core_mode;
-
return retval;
}
armv7m_common_t *armv7m = target->arch_info;
snprintf(buf, buf_size,
- "target halted in %s state due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x",
- armv7m_state_strings[armv7m->core_state],
- target_debug_reason_strings[target->debug_reason],
- armv7m_mode_strings[armv7m->core_mode],
- armv7m_exception_string(armv7m->exception_number),
- buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32),
- buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32));
+ "target halted in %s state due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x",
+ armv7m_state_strings[armv7m->core_state],
+ target_debug_reason_strings[target->debug_reason],
+ armv7m_mode_strings[armv7m->core_mode],
+ armv7m_exception_string(armv7m->exception_number),
+ buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32),
+ buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32));
return ERROR_OK;
}
reg_cache_t *armv7m_build_reg_cache(target_t *target)
{
-
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
arm_jtag_t *jtag_info = &armv7m->jtag_info;
int armv7m_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
{
-
armv7m_build_reg_cache(target);
return ERROR_OK;
-
}
int armv7m_init_arch_info(target_t *target, armv7m_common_t *armv7m)
{
-
/* register arch-specific functions */
target->arch_info = armv7m;
return ERROR_OK;
}
-
int armv7m_register_commands(struct command_context_s *cmd_ctx)
{
int retval;
return ERROR_OK;
-
}
#include "target.h"
#include "arm_jtag.h"
-
enum armv7m_mode
{
ARMV7M_MODE_HANDLER = 0,
};
extern char* armv7m_state_strings[];
+extern char* armv7m_exception_strings[];
-//#define ARMV7NUMCOREREGS 23
+extern char *armv7m_exception_string(int number);
/* offsets into armv7m core register cache */
enum
{
ARMV7M_PC = 15,
ARMV7M_xPSR = 16,
- ARMV7M_MSP ,
- ARMV7M_PSP ,
- ARMV7M_PRIMASK ,
+ ARMV7M_MSP,
+ ARMV7M_PSP,
+ ARMV7M_PRIMASK,
ARMV7M_BASEPRI,
ARMV7M_FAULTMASK,
ARMV7M_CONTROL,
extern int armv7m_invalidate_core_regs(target_t *target);
-
-
+extern enum armv7m_runcontext armv7m_get_context(target_t *target);
+extern int armv7m_use_context(target_t *target, enum armv7m_runcontext new_ctx);
+extern enum armv7m_runcontext armv7m_get_context(target_t *target);
/* Thumb mode instructions
*/
{
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[(*breakpoint_p)->type]);
- free (*breakpoint_p);
+ free((*breakpoint_p)->orig_instr);
+ free(*breakpoint_p);
*breakpoint_p = NULL;
return retval;
break;
case ERROR_TARGET_NOT_HALTED:
INFO("can't add breakpoint while target is running");
- free (*breakpoint_p);
+ free((*breakpoint_p)->orig_instr);
+ free(*breakpoint_p);
*breakpoint_p = NULL;
return retval;
break;
#include "replacements.h"
#include "cortex_m3.h"
+#include "armv7m.h"
#include "register.h"
#include "target.h"
int cortex_m3_clear_halt(target_t *target)
{
-
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
- if (!(cortex_m3->dcb_dhcsr&C_MASKINTS))
+ if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN );
ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN );
cortex_m3->dcb_dhcsr |= C_MASKINTS;
- DEBUG("");
+ DEBUG(" ");
cortex_m3_clear_halt(target);
return ERROR_OK;
ahbap_write_system_u32(swjdp, 0x20000000, opcode);
ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
cortex_m3_single_step_core(target);
- armv7m->core_cache->reg_list[15].dirty=1;
+ armv7m->core_cache->reg_list[15].dirty = 1;
retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);
}
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
cortex_m3_fp_comparator_t *fp_list = cortex_m3->fp_comparator_list;
- cortex_m3_dwt_comparator_t * dwt_list = cortex_m3->dwt_comparator_list;
+ cortex_m3_dwt_comparator_t *dwt_list = cortex_m3->dwt_comparator_list;
- DEBUG("");
+ DEBUG(" ");
/* Enable debug requests */
ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
if (!(cortex_m3->dcb_dhcsr&C_DEBUGEN))
ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
/* Enable trace and dwt */
- ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA|VC_HARDERR|VC_BUSERR|VC_CORERESET );
+ ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
/* Monitor bus faults */
ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA );
target_write_u32(target, FP_CTRL, 3);
/* Restore FPB registers */
- for (i=0;i<cortex_m3->fp_num_code+cortex_m3->fp_num_lit;i++)
+ for ( i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
{
target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
}
/* Restore DWT registers */
- for (i=0;i<cortex_m3->dwt_num_comp;i++)
+ for ( i = 0; i < cortex_m3->dwt_num_comp; i++)
{
target_write_u32(target, dwt_list[i].dwt_comparator_address, dwt_list[i].comp);
- target_write_u32(target, dwt_list[i].dwt_comparator_address|0x4, dwt_list[i].mask);
- target_write_u32(target, dwt_list[i].dwt_comparator_address|0x8, dwt_list[i].function);
+ target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x4, dwt_list[i].mask);
+ target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x8, dwt_list[i].function);
}
/* Make sure working_areas are all free */
/* only check the debug reason if we don't know it already */
if ((target->debug_reason != DBG_REASON_DBGRQ)
- && (target->debug_reason != DBG_REASON_SINGLESTEP))
+ && (target->debug_reason != DBG_REASON_SINGLESTEP))
{
/* INCOPMPLETE */
int cortex_m3_examine_exception_reason(target_t *target)
{
- u32 shcsr,except_sr,cfsr=-1,except_ar=-1;
+ u32 shcsr, except_sr, cfsr = -1, except_ar = -1;
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
break;
case 3: /* Hard Fault */
ahbap_read_system_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
- if (except_sr&0x40000000)
+ if (except_sr & 0x40000000)
{
ahbap_read_system_u32(swjdp, NVIC_CFSR, &cfsr);
}
ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
break;
case 11: /* SVCall */
-
break;
case 12: /* Debug Monitor */
ahbap_read_system_u32(swjdp, NVIC_DFSR, &except_sr);
break;
case 14: /* PendSV */
-
break;
case 15: /* SysTick */
-
break;
default:
except_sr = 0;
break;
-
}
swjdp_transaction_endcheck(swjdp);
- DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x",armv7m_exception_string(armv7m->exception_number),shcsr,except_sr,cfsr, except_ar);
+ DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \
+ shcsr, except_sr, cfsr, except_ar);
return ERROR_OK;
}
-
int cortex_m3_debug_entry(target_t *target)
{
int i, irq_is_pending;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
- DEBUG("");
+ DEBUG(" ");
if (armv7m->pre_debug_entry)
armv7m->pre_debug_entry(target);
xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
/* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
- if (xPSR&0xf00)
+ if (xPSR & 0xf00)
{
armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
- cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR&~0xff);
+ cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
}
#endif
/* Are we in an exception handler */
- armv7m->core_mode = (xPSR&0x1FF)?ARMV7M_MODE_HANDLER:ARMV7M_MODE_THREAD;
- armv7m->exception_number = xPSR&0x1FF;;
+ armv7m->core_mode = (xPSR & 0x1FF) ? ARMV7M_MODE_HANDLER : ARMV7M_MODE_THREAD;
+ armv7m->exception_number = xPSR & 0x1FF;
if (armv7m->exception_number)
{
cortex_m3_examine_exception_reason(target);
}
- DEBUG("entered debug state at PC 0x%x ", *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]);
+ DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]);
if (armv7m->post_debug_entry)
armv7m->post_debug_entry(target);
armv7m_common_t *armv7m = target->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
- DEBUG("");
+ DEBUG(" ");
if (armv7m->pre_restore_context)
armv7m->pre_restore_context(target);
return ERROR_OK;
}
-
enum target_state cortex_m3_poll(target_t *target)
{
int retval;
}
if (prev_target_state == TARGET_DEBUG_RUNNING)
{
- DEBUG("");
+ DEBUG(" ");
if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
return retval;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
}
-
}
/*
target->state = TARGET_SLEEP;
*/
-
/* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
- DEBUG("dcb_dhcsr %x, nvic_dfsr %x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);
+ DEBUG("dcb_dhcsr %x, nvic_dfsr %x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);
return target->state;
}
armv7m_common_t *armv7m = target->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
- u32 dcb_dhcsr=0;
- int retval, timeout=0;
+ u32 dcb_dhcsr = 0;
+ int retval, timeout = 0;
/* Check that we are using process_context, or change and print warning */
if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
}
/* Enter debug state on reset, cf. end_reset_event() */
- ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA|VC_HARDERR|VC_BUSERR|VC_CORERESET );
+ ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
/* Request a reset */
ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET );
if (retval == ERROR_OK)
{
ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
- if ( (dcb_dhcsr&S_HALT)&&(cortex_m3->nvic_dfsr&DFSR_VCATCH) )
+ if ((dcb_dhcsr&S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
{
- DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x",dcb_dhcsr,cortex_m3->nvic_dfsr);
+ DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr);
cortex_m3_poll(target);
return ERROR_OK;
}
else
- DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms",dcb_dhcsr,timeout);
+ DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr, timeout);
}
timeout++;
usleep(1000);
WARNING("Incorrect context in resume");
armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
}
-
-
+
target_free_all_working_areas(target);
cortex_m3_enable_breakpoints(target);
cortex_m3_enable_watchpoints(target);
/* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
-
}
dcb_dhcsr = DBGKEY | C_DEBUGEN;
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
/* Make sure we are in Thumb mode */
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
- buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32)|(1<<24));
+ buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1<<24));
}
/* current = 1: continue on current pc, otherwise continue at <address> */
}
/* Set/Clear C_MASKINTS in a separate operation */
- if ((cortex_m3->dcb_dhcsr&C_MASKINTS) != (dcb_dhcsr&C_MASKINTS))
+ if ((cortex_m3->dcb_dhcsr & C_MASKINTS) != (dcb_dhcsr & C_MASKINTS))
ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
/* Restart core */
ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
DEBUG("target debug resumed at 0x%x",resume_pc);
}
-
return ERROR_OK;
}
-int irqstepcount=0;
+//int irqstepcount=0;
int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
{
/* get pointers to arch-specific information */
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
- if (cortex_m3->dcb_dhcsr&C_MASKINTS)
+ if (cortex_m3->dcb_dhcsr & C_MASKINTS)
ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
if (breakpoint)
cortex_m3_set_breakpoint(target, breakpoint);
- DEBUG("target stepped dcb_dhcsr=0x%x nvic_icsr=0x%x",cortex_m3->dcb_dhcsr,cortex_m3->nvic_icsr);
+ DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
cortex_m3_debug_entry(target);
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
- DEBUG("target stepped dcb_dhcsr=0x%x nvic_icsr=0x%x",cortex_m3->dcb_dhcsr,cortex_m3->nvic_icsr);
+ DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
return ERROR_OK;
-
}
int cortex_m3_assert_reset(target_t *target)
armv7m_invalidate_core_regs(target);
return ERROR_OK;
-
}
int cortex_m3_deassert_reset(target_t *target)
jtag_add_reset(0, 0);
return ERROR_OK;
-
}
void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target)
{
}
+
void cortex_m3_enable_breakpoints(struct target_s *target)
{
breakpoint_t *breakpoint = target->breakpoints;
if (cortex_m3->auto_bp_type)
{
- breakpoint->type = (breakpoint->address<0x20000000)?BKPT_HARD:BKPT_SOFT;
+ breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
}
if (breakpoint->type == BKPT_HARD)
{
- while(comparator_list[fp_num].used && (fp_num<cortex_m3->fp_num_code))
+ while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
fp_num++;
- if (fp_num>=cortex_m3->fp_num_code)
+ if (fp_num >= cortex_m3->fp_num_code)
{
DEBUG("ERROR Can not find free FP Comparator");
WARNING("ERROR Can not find free FP Comparator");
exit(-1);
}
- breakpoint->set = fp_num+1;
- hilo = (breakpoint->address & 0x2)? FPCR_REPLACE_BKPT_HIGH:FPCR_REPLACE_BKPT_LOW;
+ breakpoint->set = fp_num + 1;
+ hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
comparator_list[fp_num].used = 1;
- comparator_list[fp_num].fpcr_value = breakpoint->address&0x1FFFFFFC | hilo | 1;
+ comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
- DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
+ DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
}
else if (breakpoint->type == BKPT_SOFT)
{
u8 code[4];
buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
- target->type->read_memory(target, breakpoint->address&0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
- target->type->write_memory(target, breakpoint->address&0xFFFFFFFE, breakpoint->length, 1, code);
+ target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
+ target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
breakpoint->set = 0x11; /* Any nice value but 0 */
}
return ERROR_OK;
-
}
int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
if (breakpoint->type == BKPT_HARD)
{
- int fp_num = breakpoint->set-1;
- if ((fp_num<0)||(fp_num>=cortex_m3->fp_num_code))
+ int fp_num = breakpoint->set - 1;
+ if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
{
DEBUG("Invalid FP Comparator number in breakpoint");
return ERROR_OK;
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4)
{
- target->type->write_memory(target, breakpoint->address&0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
+ target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
}
else
{
- target->type->write_memory(target, breakpoint->address&0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
+ target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
}
}
breakpoint->set = 0;
return ERROR_OK;
}
-
int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
{
/* get pointers to arch-specific information */
if (cortex_m3->auto_bp_type)
{
- breakpoint->type = (breakpoint->address<0x20000000)?BKPT_HARD:BKPT_SOFT;
+ breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
}
- if ((breakpoint->type == BKPT_HARD) && (breakpoint->address>=0x20000000))
+ if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
{
INFO("flash patch comparator requested outside code memory region");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address<0x20000000))
+ if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
{
INFO("soft breakpoint requested in code (flash) memory region");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
if (cortex_m3->auto_bp_type)
{
- breakpoint->type = (breakpoint->address<0x20000000)?BKPT_HARD:BKPT_SOFT;
+ breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
}
if (breakpoint->set)
return ERROR_OK;
}
-void cortex_m3_enable_watchpoints(struct target_s *target)
-{
- watchpoint_t *watchpoint = target->watchpoints;
-
- /* set any pending watchpoints */
- while (watchpoint)
- {
- if (watchpoint->set == 0)
- cortex_m3_set_watchpoint(target, watchpoint);
- watchpoint = watchpoint->next;
- }
-}
-
int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
int dwt_num=0;
if (watchpoint->mask == 0xffffffffu)
{
- while(comparator_list[dwt_num].used && (dwt_num<cortex_m3->dwt_num_comp))
+ while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
dwt_num++;
- if (dwt_num>=cortex_m3->dwt_num_comp)
+ if (dwt_num >= cortex_m3->dwt_num_comp)
{
DEBUG("ERROR Can not find free DWT Comparator");
WARNING("ERROR Can not find free DWT Comparator");
return -1;
}
- watchpoint->set = dwt_num+1;
+ watchpoint->set = dwt_num + 1;
mask = 0;
temp = watchpoint->length;
- while (temp>1)
+ while (temp > 1)
{
- temp = temp/2;
+ temp = temp / 2;
mask++;
}
comparator_list[dwt_num].used = 1;
comparator_list[dwt_num].comp = watchpoint->address;
comparator_list[dwt_num].mask = mask;
- comparator_list[dwt_num].function = watchpoint->rw+5;
+ comparator_list[dwt_num].function = watchpoint->rw + 5;
target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
- DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function);
+ DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function);
}
else
{
return ERROR_OK;
}
- dwt_num = watchpoint->set-1;
+ dwt_num = watchpoint->set - 1;
- if ((dwt_num<0)||(dwt_num>=cortex_m3->dwt_num_comp))
+ if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
{
DEBUG("Invalid DWT Comparator number in watchpoint");
return ERROR_OK;
return ERROR_OK;
}
-
-
int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
/* get pointers to arch-specific information */
return ERROR_OK;
}
+void cortex_m3_enable_watchpoints(struct target_s *target)
+{
+ watchpoint_t *watchpoint = target->watchpoints;
+
+ /* set any pending watchpoints */
+ while (watchpoint)
+ {
+ if (watchpoint->set == 0)
+ cortex_m3_set_watchpoint(target, watchpoint);
+ watchpoint = watchpoint->next;
+ }
+}
int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
{
ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
cortex_m3_single_step_core(target);
ahbap_read_coreregister_u32(swjdp, value, 0);
- armv7m->core_cache->reg_list[0].dirty=1;
- armv7m->core_cache->reg_list[15].dirty=1;
+ armv7m->core_cache->reg_list[0].dirty = 1;
+ armv7m->core_cache->reg_list[15].dirty = 1;
ahbap_write_system_u32(swjdp, 0x20000000, savedram);
swjdp_transaction_endcheck(swjdp);
- DEBUG("load from special reg %i value 0x%x",SYSm, *value);
+ DEBUG("load from special reg %i value 0x%x", SYSm, *value);
}
else return ERROR_INVALID_ARGUMENTS;
return ERROR_OK;
-
}
int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
retval = ahbap_write_coreregister_u32(swjdp, value, num);
if (retval != ERROR_OK)
{
- ERROR("JTAG failure %i",retval);
- armv7m->core_cache->reg_list[num].dirty=1;
+ ERROR("JTAG failure %i", retval);
+ armv7m->core_cache->reg_list[num].dirty = 1;
return ERROR_JTAG_DEVICE_ERROR;
}
- DEBUG("write core reg %i value 0x%x",num, value);
+ DEBUG("write core reg %i value 0x%x", num, value);
}
else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
{
ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
cortex_m3_single_step_core(target);
ahbap_write_coreregister_u32(swjdp, tempr0, 0);
- armv7m->core_cache->reg_list[15].dirty=1;
+ armv7m->core_cache->reg_list[15].dirty = 1;
ahbap_write_system_u32(swjdp, 0x20000000, savedram);
swjdp_transaction_endcheck(swjdp);
- DEBUG("write special reg %i value 0x%x ",SYSm, value);
+ DEBUG("write special reg %i value 0x%x ", SYSm, value);
}
else return ERROR_INVALID_ARGUMENTS;
- return ERROR_OK;
-
+ return ERROR_OK;
}
-
int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
{
-
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
case 4:
/* TODOLATER Check error return value ! */
{
- ahbap_read_buf(swjdp, buffer, 4*count, address);
+ ahbap_read_buf(swjdp, buffer, 4 * count, address);
}
break;
case 2:
{
- ahbap_read_buf(swjdp, buffer, 2*count, address);
+ ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
}
break;
case 1:
ERROR("BUG: we shouldn't get here");
exit(-1);
}
-
-
+
return ERROR_OK;
}
int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
{
-
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
case 4:
/* TODOLATER Check error return value ! */
{
- ahbap_write_buf(swjdp, buffer, 4*count, address);
+ ahbap_write_buf(swjdp, buffer, 4 * count, address);
}
break;
case 2:
{
- ahbap_write_buf(swjdp, buffer, 2*count, address);
+ ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
}
break;
case 1:
int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
{
-
- cortex_m3_write_memory(target, address, 4,count,buffer);
+ cortex_m3_write_memory(target, address, 4, count, buffer);
return ERROR_OK;
}
-
-
void cortex_m3_build_reg_cache(target_t *target)
{
armv7m_build_reg_cache(target);
cortex_m3_build_reg_cache(target);
ahbap_debugport_init(swjdp);
- /* Read from Device Identification Registers, IS THIS CORTEX OR Luminary Micro SPECIFIC ?? */
- target_read_u32(target, CPUID, &cpuid );
- if (cpuid == 0x410fc231)
- DEBUG("CORTEX-M3 processor");
- DEBUG("cpuid %x",cpuid);
- /* Probably only valid for LMI parts, move to flash/stellaris ? */
- target_read_u32(target, SYSTEM_CONTROL_BASE|0x04, &did1);
- target_read_u32(target,SYSTEM_CONTROL_BASE|0x08,&dc0);
- DEBUG("did1 %x",did1);
- DEBUG("dc0 %x",dc0);
+ /* Read from Device Identification Registers */
+ target_read_u32(target, CPUID, &cpuid);
+ if (((cpuid >> 4) & 0xc3f) == 0xc23)
+ DEBUG("CORTEX-M3 processor detected");
+ DEBUG("cpuid %x", cpuid);
- target_read_u32(target,NVIC_ICTR,&ictr);
- cortex_m3->intlinesnum = (ictr&0x1F) + 1;
- cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum,4);
- for (i=0;i<cortex_m3->intlinesnum;i++)
+ target_read_u32(target, NVIC_ICTR, &ictr);
+ cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
+ cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
+ for (i = 0; i < cortex_m3->intlinesnum; i++)
{
- target_read_u32(target,NVIC_ISE0+4*i,cortex_m3->intsetenable+i);
- DEBUG(" interrupt enable[%i]=0x%x",i,cortex_m3->intsetenable[i]);
+ target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
+ DEBUG("interrupt enable[%i] = 0x%x", i, cortex_m3->intsetenable[i]);
}
/* Setup FPB */
target_read_u32(target, FP_CTRL, &fpcr);
cortex_m3->auto_bp_type = 1;
- cortex_m3->fp_num_code = (fpcr>>4)&0xF;
- cortex_m3->fp_num_lit = (fpcr>>8)&0xF;
+ cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
+ cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
cortex_m3->fp_code_available = cortex_m3->fp_num_code;
cortex_m3->fp_comparator_list=calloc(cortex_m3->fp_num_code+cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
- for (i=0;i<cortex_m3->fp_num_code+cortex_m3->fp_num_lit;i++)
+ for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
{
- cortex_m3->fp_comparator_list[i].type = (i<cortex_m3->fp_num_code)?FPCR_CODE:FPCR_LITERAL;
- cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0+4*i;
+ cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
+ cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
}
- DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i",fpcr,cortex_m3->fp_num_code,cortex_m3->fp_num_lit);
+ DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
/* Setup DWT */
target_read_u32(target, DWT_CTRL, &dwtcr);
- cortex_m3->dwt_num_comp = (dwtcr>>28)&0xF;
+ cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
- for (i=0; i<cortex_m3->dwt_num_comp; i++)
+ for (i = 0; i < cortex_m3->dwt_num_comp; i++)
{
- cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0+0x10*i;
+ cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
}
return ERROR_OK;
armv7m_common_t *armv7m;
armv7m = &cortex_m3->armv7m;
- arm_jtag_t * jtag_info = &cortex_m3->jtag_info;
+ arm_jtag_t *jtag_info = &cortex_m3->jtag_info;
/* prepare JTAG information for the new target */
cortex_m3->jtag_info.chain_pos = chain_pos;
#define DCB_DCRDR 0xE000EDF8
#define DCB_DEMCR 0xE000EDFC
-
#define DCRSR_WnR (1<<16)
#define DWT_CTRL 0xE0001000
#define DFSR_DWTTRAP 4
#define DFSR_VCATCH 8
-
#define FPCR_CODE 0
#define FPCR_LITERAL 1
#define FPCR_REPLACE_REMAP (0<<30)
int fp_num_code;
int fp_code_available;
int auto_bp_type;
- cortex_m3_fp_comparator_t * fp_comparator_list;
+ cortex_m3_fp_comparator_t *fp_comparator_list;
/* DWT */
int dwt_num_comp;
int dwt_comp_available;
- cortex_m3_dwt_comparator_t * dwt_comparator_list;
+ cortex_m3_dwt_comparator_t *dwt_comparator_list;
/* Interrupts */
int intlinesnum;
- u32 * intsetenable;
+ u32 *intsetenable;
/*
u32 arm_bkpt;
void *arch_info;
} cortex_m3_common_t;
-
extern void cortex_m3_build_reg_cache(target_t *target);
enum target_state cortex_m3_poll(target_t *target);
* Cortex-M3â„¢ TRM, ARM DDI 0337C *
* *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include "replacements.h"
***************************************************************************/
/* Scan out and in from target ordered u8 buffers */
-int swjdp_scan(arm_jtag_t *jtag_info, u8 chain, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue, u8 *ack)
+int swjdp_scan(arm_jtag_t *jtag_info, u8 instr, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue, u8 *ack)
{
scan_field_t fields[2];
u8 out_addr_buf;
jtag_add_end_state(TAP_RTI);
- arm_jtag_set_instr(jtag_info, chain, NULL);
+ arm_jtag_set_instr(jtag_info, instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 3;
- buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr>>1)&0x6) | (RnW&0x1));
+ buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
fields[0].out_value = &out_addr_buf;
fields[0].out_mask = NULL;
fields[0].in_value = ack;
jtag_add_dr_scan(2, fields, -1, NULL);
return ERROR_OK;
-
}
/* Scan out and in from host ordered u32 variables */
-int swjdp_scan_u32(arm_jtag_t *jtag_info, u8 chain, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue, u8 *ack)
+int swjdp_scan_u32(arm_jtag_t *jtag_info, u8 instr, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue, u8 *ack)
{
scan_field_t fields[2];
u8 out_value_buf[4];
u8 out_addr_buf;
jtag_add_end_state(TAP_RTI);
- arm_jtag_set_instr(jtag_info, chain, NULL);
+ arm_jtag_set_instr(jtag_info, instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 3;
- buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr>>1)&0x6) | (RnW&0x1));
+ buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
fields[0].out_value = &out_addr_buf;
fields[0].out_mask = NULL;
fields[0].in_value = ack;
jtag_add_dr_scan(2, fields, -1, NULL);
return ERROR_OK;
-
}
/* scan_inout_check adds one extra inscan for DPAP_READ commands to read variables */
-int scan_inout_check(swjdp_common_t *swjdp, u8 chain, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue)
+int scan_inout_check(swjdp_common_t *swjdp, u8 instr, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue)
{
-
- swjdp_scan(swjdp->jtag_info, chain, reg_addr, RnW, outvalue, NULL, NULL);
- if ((RnW==DPAP_READ) && (invalue != NULL))
+ swjdp_scan(swjdp->jtag_info, instr, reg_addr, RnW, outvalue, NULL, NULL);
+ if ((RnW == DPAP_READ) && (invalue != NULL))
{
swjdp_scan(swjdp->jtag_info, SWJDP_IR_DPACC, 0xC, DPAP_READ, 0, invalue, &swjdp->ack);
}
/* In TRANS_MODE_ATOMIC all SWJDP_IR_APACC transactions wait for ack=OK/FAULT and the check CTRL_STAT */
- if ((chain == SWJDP_IR_APACC)&&(swjdp->trans_mode == TRANS_MODE_ATOMIC))
+ if ((instr == SWJDP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC))
{
return swjdp_transaction_endcheck(swjdp);
}
return ERROR_OK;
}
-int scan_inout_check_u32(swjdp_common_t *swjdp, u8 chain, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue)
+int scan_inout_check_u32(swjdp_common_t *swjdp, u8 instr, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue)
{
- swjdp_scan_u32(swjdp->jtag_info, chain, reg_addr, RnW, outvalue, NULL, NULL);
+ swjdp_scan_u32(swjdp->jtag_info, instr, reg_addr, RnW, outvalue, NULL, NULL);
if ((RnW==DPAP_READ) && (invalue != NULL))
{
swjdp_scan_u32(swjdp->jtag_info, SWJDP_IR_DPACC, 0xC, DPAP_READ, 0, invalue, &swjdp->ack);
}
/* In TRANS_MODE_ATOMIC all SWJDP_IR_APACC transactions wait for ack=OK/FAULT and the check CTRL_STAT */
- if ((chain == SWJDP_IR_APACC)&&(swjdp->trans_mode == TRANS_MODE_ATOMIC))
+ if ((instr == SWJDP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC))
{
return swjdp_transaction_endcheck(swjdp);
}
{
int waitcount = 0;
u32 ctrlstat;
- u8 ack=0;
scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
jtag_execute_queue();
- swjdp->ack = swjdp->ack&0x7;
+
+ swjdp->ack = swjdp->ack & 0x7;
+
while (swjdp->ack != 2)
{
- if (swjdp->ack==1)
+ if (swjdp->ack == 1)
{
waitcount++;
- if (waitcount>100)
+ if (waitcount > 100)
{
WARNING("Timeout waiting for ACK = OK/FAULT in SWJDP transaction");
return ERROR_JTAG_DEVICE_ERROR;
}
scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
jtag_execute_queue();
- swjdp->ack = swjdp->ack&0x7;
+ swjdp->ack = swjdp->ack & 0x7;
}
/* Check for STICKYERR and STICKYORUN */
- if (ctrlstat & (SSTICKYORUN|SSTICKYERR))
+ if (ctrlstat & (SSTICKYORUN | SSTICKYERR))
{
- DEBUG(" swjdp: CTRL/STAT error 0x%x",ctrlstat);
+ DEBUG("swjdp: CTRL/STAT error 0x%x", ctrlstat);
/* Check power to debug regions */
- if ((ctrlstat&0xf0000000)!=0xf0000000)
+ if ((ctrlstat & 0xf0000000) != 0xf0000000)
{
ahbap_debugport_init(swjdp);
}
else
{
u32 dcb_dhcsr,nvic_shcsr, nvic_bfar, nvic_cfsr;
- if (ctrlstat&SSTICKYORUN) ERROR("SWJ-DP OVERRUN - check clock or reduce jtag speed");
- if (ctrlstat&SSTICKYERR) ERROR("SWJ-DP STICKY ERROR");
+
+ if (ctrlstat & SSTICKYORUN)
+ ERROR("SWJ-DP OVERRUN - check clock or reduce jtag speed");
+
+ if (ctrlstat & SSTICKYERR)
+ ERROR("SWJ-DP STICKY ERROR");
+
/* Clear Sticky Error Bits */
- scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_WRITE, swjdp->dp_ctrl_stat|SSTICKYORUN|SSTICKYERR, NULL);
+ scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_WRITE, swjdp->dp_ctrl_stat | SSTICKYORUN | SSTICKYERR, NULL);
scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
jtag_execute_queue();
+ DEBUG("swjdp: status 0x%x", ctrlstat);
+
/* Can we find out the reason for the error ?? */
ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
ahbap_read_system_atomic_u32(swjdp, NVIC_SHCSR, &nvic_shcsr);
ahbap_read_system_atomic_u32(swjdp, NVIC_CFSR, &nvic_cfsr);
ahbap_read_system_atomic_u32(swjdp, NVIC_BFAR, &nvic_bfar);
- //DEBUG("dcb_dhcsr %x, nvic_shcsr %x, nvic_cfsr %x, nvic_bfar %x",dcb_dhcsr,nvic_shcsr,nvic_cfsr,nvic_bfar);
- ERROR("dcb_dhcsr %x, nvic_shcsr %x, nvic_cfsr %x, nvic_bfar %x",dcb_dhcsr,nvic_shcsr,nvic_cfsr,nvic_bfar);
+ ERROR("dcb_dhcsr 0x%x, nvic_shcsr 0x%x, nvic_cfsr 0x%x, nvic_bfar 0x%x", dcb_dhcsr, nvic_shcsr, nvic_cfsr, nvic_bfar);
}
jtag_execute_queue();
return ERROR_JTAG_DEVICE_ERROR;
}
return ERROR_OK;
-
}
/***************************************************************************
buf_set_u32(out_value_buf, 0, 32, value);
return scan_inout_check(swjdp, SWJDP_IR_DPACC, reg_addr, DPAP_WRITE, out_value_buf, NULL);
-
}
int swjdp_read_dpacc(swjdp_common_t *swjdp, u32 *value, u8 reg_addr)
{
-
scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, reg_addr, DPAP_READ, 0, value);
return ERROR_OK;
int swjdp_bankselect_apacc(swjdp_common_t *swjdp,u32 reg_addr)
{
u32 select;
- select = (reg_addr&0xFF0000F0);
+ select = (reg_addr & 0xFF0000F0);
- if ( select != swjdp->dp_select_value )
+ if (select != swjdp->dp_select_value)
{
swjdp_write_dpacc(swjdp, select, DP_SELECT);
swjdp->dp_select_value = select;
int ahbap_setup_accessport(swjdp_common_t *swjdp, u32 csw, u32 tar)
{
-
csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
- if ( csw != swjdp->ap_csw_value )
+ if (csw != swjdp->ap_csw_value)
{
- //DEBUG("swjdp : Set CSW %x",csw);
+ //DEBUG("swjdp : Set CSW %x",csw);
ahbap_write_reg_u32(swjdp, AHBAP_CSW, csw );
swjdp->ap_csw_value = csw;
}
- if ( tar != swjdp->ap_tar_value )
+ if (tar != swjdp->ap_tar_value)
{
- //DEBUG("swjdp : Set TAR %x",tar);
+ //DEBUG("swjdp : Set TAR %x",tar);
ahbap_write_reg_u32(swjdp, AHBAP_TAR, tar );
swjdp->ap_tar_value = tar;
}
*****************************************************************************/
int ahbap_read_system_u32(swjdp_common_t *swjdp, u32 address, u32 *value)
{
-
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
- ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address&0xFFFFFFF0);
- ahbap_read_reg_u32(swjdp, AHBAP_BD0|address&0xC, value );
+ ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address & 0xFFFFFFF0);
+ ahbap_read_reg_u32(swjdp, AHBAP_BD0 | (address & 0xC), value );
return ERROR_OK;
}
*****************************************************************************/
int ahbap_write_system_u32(swjdp_common_t *swjdp, u32 address, u32 value)
{
-
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
- ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address&0xFFFFFFF0);
- ahbap_write_reg_u32(swjdp, AHBAP_BD0|address&0xC, value );
+ ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address & 0xFFFFFFF0);
+ ahbap_write_reg_u32(swjdp, AHBAP_BD0 | (address & 0xC), value );
return ERROR_OK;
}
int ahbap_write_system_atomic_u32(swjdp_common_t *swjdp, u32 address, u32 value)
{
-
ahbap_write_system_u32(swjdp, address, value);
return swjdp_transaction_endcheck(swjdp);
int ahbap_write_buf(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address)
{
u32 outvalue;
- int wcount, blocksize, writecount, errorcount=0, retval=ERROR_OK;
+ int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK;
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
- while ( (address&0x3)&&(count>0) )
+ while ((address & 0x3) && (count > 0))
{
ahbap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
- outvalue = (*buffer++)<<8*(address&0x3) ;
+ outvalue = (*buffer++) << 8 * (address & 0x3);
ahbap_write_reg_u32(swjdp, AHBAP_DRW, outvalue );
swjdp_transaction_endcheck(swjdp);
count--;
address++;
}
- wcount = count>>2;
- count = count-4*wcount;
- while (wcount>0)
+ wcount = count >> 2;
+ count = count - 4 * wcount;
+ while (wcount > 0)
{
/* Adjust to read within 4K block boundaries */
- blocksize = (0x1000-(0xFFF&address))>>2;
- if (wcount<blocksize)
+ blocksize = (0x1000 - (0xFFF & address)) >> 2;
+ if (wcount < blocksize)
blocksize = wcount;
ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
for (writecount=0; writecount<blocksize; writecount++)
{
- ahbap_write_reg(swjdp, AHBAP_DRW, buffer+4*writecount );
+ ahbap_write_reg(swjdp, AHBAP_DRW, buffer + 4 * writecount );
}
- if (swjdp_transaction_endcheck(swjdp)==ERROR_OK)
+ if (swjdp_transaction_endcheck(swjdp) == ERROR_OK)
{
- wcount = wcount-blocksize;
- address = address+4*blocksize;
- buffer = buffer + 4*blocksize;
+ wcount = wcount - blocksize;
+ address = address + 4 * blocksize;
+ buffer = buffer + 4 * blocksize;
}
else
{
errorcount++;
}
- if (errorcount>1)
+ if (errorcount > 1)
{
WARNING("Block read error address %x, count %x", address, count);
return ERROR_JTAG_DEVICE_ERROR;
}
}
-
- while (count>0)
+
+ while (count > 0)
{
ahbap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
- outvalue = (*buffer++)<<8*(address&0x3) ;
+ outvalue = (*buffer++) << 8 * (address & 0x3);
ahbap_write_reg_u32(swjdp, AHBAP_DRW, outvalue );
retval = swjdp_transaction_endcheck(swjdp);
count--;
return retval;
}
+int ahbap_write_buf_u16(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address)
+{
+ u32 outvalue;
+ int retval = ERROR_OK;
+
+ swjdp->trans_mode = TRANS_MODE_COMPOSITE;
+
+ while (count > 0)
+ {
+ ahbap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
+ outvalue = *((u16*)buffer) << 8 * (address & 0x3);
+ ahbap_write_reg_u32(swjdp, AHBAP_DRW, outvalue );
+ retval = swjdp_transaction_endcheck(swjdp);
+ count -= 2;
+ address += 2;
+ buffer += 2;
+ }
+
+ return retval;
+}
+
/*****************************************************************************
* *
* ahbap_read_buf(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address) *
int ahbap_read_buf(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address)
{
u32 invalue;
- int wcount, blocksize, readcount, errorcount=0, retval=ERROR_OK;
+ int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
- while ( (address&0x3)&&(count>0) )
+ while ((address & 0x3) && (count > 0))
{
ahbap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
- ahbap_read_reg_u32(swjdp, AHBAP_DRW, &invalue );
+ ahbap_read_reg_u32(swjdp, AHBAP_DRW, &invalue);
swjdp_transaction_endcheck(swjdp);
- *buffer++ = (invalue>>8*(address&0x3))&0xFF;
+ *buffer++ = (invalue >> 8 * (address & 0x3)) & 0xFF;
count--;
address++;
}
- wcount = count>>2;
- count = count-4*wcount;
- while (wcount>0)
+ wcount = count >> 2;
+ count = count - 4 * wcount;
+ while (wcount > 0)
{
/* Adjust to read within 4K block boundaries */
- blocksize = (0x1000-(0xFFF&address))>>2;
- if (wcount<blocksize)
+ blocksize = (0x1000 - (0xFFF & address)) >> 2;
+ if (wcount < blocksize)
blocksize = wcount;
ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
/* Scan out first read */
swjdp_scan(swjdp->jtag_info, SWJDP_IR_APACC, AHBAP_DRW, DPAP_READ, 0, NULL, NULL);
- for (readcount=0; readcount<blocksize-1; readcount++)
+ for (readcount = 0; readcount < blocksize - 1; readcount++)
{
/* Scan out read instruction and scan in previous value */
- swjdp_scan(swjdp->jtag_info, SWJDP_IR_APACC, AHBAP_DRW, DPAP_READ, 0, buffer+4*readcount, &swjdp->ack);
+ swjdp_scan(swjdp->jtag_info, SWJDP_IR_APACC, AHBAP_DRW, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack);
}
/* Scan in last value */
- swjdp_scan(swjdp->jtag_info, SWJDP_IR_DPACC, 0xC, DPAP_READ, 0, buffer+4*readcount, &swjdp->ack);
- if (swjdp_transaction_endcheck(swjdp)==ERROR_OK)
+ swjdp_scan(swjdp->jtag_info, SWJDP_IR_DPACC, 0xC, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack);
+ if (swjdp_transaction_endcheck(swjdp) == ERROR_OK)
{
- wcount = wcount-blocksize;
- address += 4*blocksize;
- buffer += 4*blocksize;
+ wcount = wcount - blocksize;
+ address += 4 * blocksize;
+ buffer += 4 * blocksize;
}
else
{
errorcount++;
}
- if (errorcount>1)
+ if (errorcount > 1)
{
WARNING("Block read error address %x, count %x", address, count);
return ERROR_JTAG_DEVICE_ERROR;
}
}
- while (count>0)
+ while (count > 0)
{
ahbap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
ahbap_read_reg_u32(swjdp, AHBAP_DRW, &invalue );
retval = swjdp_transaction_endcheck(swjdp);
- *buffer++ = (invalue>>8*(address&0x3))&0xFF;
+ *buffer++ = (invalue >> 8 * (address & 0x3)) & 0xFF;
count--;
address++;
}
return retval;
}
+int ahbap_read_buf_u16(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address)
+{
+ u32 invalue;
+ int retval = ERROR_OK;
+
+ swjdp->trans_mode = TRANS_MODE_COMPOSITE;
+
+ while (count > 0)
+ {
+ ahbap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
+ ahbap_read_reg_u32(swjdp, AHBAP_DRW, &invalue );
+ retval = swjdp_transaction_endcheck(swjdp);
+ *((u16*)buffer) = (invalue >> 8 * (address & 0x3));
+ count -= 2;
+ address += 2;
+ buffer += 2;
+ }
+
+ return retval;
+}
+
int ahbap_block_read_u32(swjdp_common_t *swjdp, u32 *buffer, int count, u32 address)
{
- int readcount, errorcount=0;
+ int readcount, errorcount = 0;
u32 blockmax, blocksize;
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
- while (count>0)
+ while (count > 0)
{
/* Adjust to read within 4K block boundaries */
- blocksize = (0x1000-(0xFFF&address))>>2;
- if (count<blocksize)
+ blocksize = (0x1000 - (0xFFF & address)) >> 2;
+ if (count < blocksize)
blocksize = count;
ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
- for (readcount=0; readcount<blocksize; readcount++)
+ for (readcount = 0; readcount < blocksize; readcount++)
{
- ahbap_read_reg_u32(swjdp, AHBAP_DRW, buffer+readcount );
+ ahbap_read_reg_u32(swjdp, AHBAP_DRW, buffer + readcount );
}
- if (swjdp_transaction_endcheck(swjdp)==ERROR_OK)
+ if (swjdp_transaction_endcheck(swjdp) == ERROR_OK)
{
- count = count-blocksize;
- address = address+4*blocksize;
+ count = count - blocksize;
+ address = address + 4 * blocksize;
buffer = buffer + blocksize;
}
else
{
errorcount++;
}
- if (errorcount>1)
+ if (errorcount > 1)
{
WARNING("Block read error address %x, count %x", address, count);
return ERROR_JTAG_DEVICE_ERROR;
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
/* ahbap_write_system_u32(swjdp, DCB_DCRSR, regnum); */
- ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR&0xFFFFFFF0);
- ahbap_write_reg_u32(swjdp, AHBAP_BD0|DCB_DCRSR&0xC, regnum );
+ ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
+ ahbap_write_reg_u32(swjdp, AHBAP_BD0 | (DCB_DCRSR & 0xC), regnum );
/* ahbap_read_system_u32(swjdp, DCB_DCRDR, value); */
- ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR&0xFFFFFFF0);
- ahbap_read_reg_u32(swjdp, AHBAP_BD0|DCB_DCRDR&0xC, value );
+ ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
+ ahbap_read_reg_u32(swjdp, AHBAP_BD0 | (DCB_DCRDR & 0xC), value );
return swjdp_transaction_endcheck(swjdp);
}
swjdp->trans_mode = TRANS_MODE_COMPOSITE;
/* ahbap_write_system_u32(swjdp, DCB_DCRDR, core_regs[i]); */
- ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR&0xFFFFFFF0);
- ahbap_write_reg_u32(swjdp, AHBAP_BD0|DCB_DCRDR&0xC, value );
+ ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
+ ahbap_write_reg_u32(swjdp, AHBAP_BD0 | (DCB_DCRDR & 0xC), value );
/* ahbap_write_system_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR ); */
- ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR&0xFFFFFFF0);
- ahbap_write_reg_u32(swjdp, AHBAP_BD0|DCB_DCRSR&0xC, regnum | DCRSR_WnR );
+ ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
+ ahbap_write_reg_u32(swjdp, AHBAP_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR );
return swjdp_transaction_endcheck(swjdp);
}
int ahbap_debugport_init(swjdp_common_t *swjdp)
{
-
-u32 idreg, romaddr, dummy;
-u32 ctrlstat;
-int cnt=0;
-DEBUG("");
+ u32 idreg, romaddr, dummy;
+ u32 ctrlstat;
+ int cnt = 0;
+
+ DEBUG(" ");
+
swjdp->ap_csw_value = -1;
swjdp->ap_tar_value = -1;
swjdp->trans_mode = TRANS_MODE_ATOMIC;
swjdp_read_dpacc(swjdp, &dummy, DP_CTRL_STAT);
swjdp_write_dpacc(swjdp, SSTICKYERR, DP_CTRL_STAT);
swjdp_read_dpacc(swjdp, &dummy, DP_CTRL_STAT);
-
- swjdp->dp_ctrl_stat = CDBGPWRUPREQ|CSYSPWRUPREQ;
+
+ swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
swjdp_write_dpacc(swjdp, swjdp->dp_ctrl_stat, DP_CTRL_STAT);
swjdp_read_dpacc(swjdp, &ctrlstat, DP_CTRL_STAT);
jtag_execute_queue();
/* Check that we have debug power domains activated */
- while (!(ctrlstat & CDBGPWRUPACK) && (cnt++<10))
+ while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10))
{
- DEBUG(" swjdp: wait CDBGPWRUPACK");
+ DEBUG("swjdp: wait CDBGPWRUPACK");
swjdp_read_dpacc(swjdp, &ctrlstat, DP_CTRL_STAT);
jtag_execute_queue();
-
usleep(10000);
}
- while (!(ctrlstat & CSYSPWRUPACK) && (cnt++<10))
+ while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10))
{
- DEBUG(" swjdp: wait CSYSPWRUPACK");
+ DEBUG("swjdp: wait CSYSPWRUPACK");
swjdp_read_dpacc(swjdp, &ctrlstat, DP_CTRL_STAT);
jtag_execute_queue();
usleep(10000);
}
-
swjdp_read_dpacc(swjdp, &dummy, DP_CTRL_STAT);
/* With debug power on we can activate OVERRUN checking */
- swjdp->dp_ctrl_stat = CDBGPWRUPREQ|CSYSPWRUPREQ|CORUNDETECT;
+ swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
swjdp_write_dpacc(swjdp, swjdp->dp_ctrl_stat , DP_CTRL_STAT);
swjdp_read_dpacc(swjdp, &dummy, DP_CTRL_STAT);
- ahbap_read_reg_u32(swjdp, 0xFC, &idreg );
- ahbap_read_reg_u32(swjdp, 0xF8, &romaddr );
+ ahbap_read_reg_u32(swjdp, 0xFC, &idreg);
+ ahbap_read_reg_u32(swjdp, 0xF8, &romaddr);
-DEBUG("AHB-AP ID Register 0x%x, Debug ROM Address 0x%x",idreg,romaddr);
+ DEBUG("AHB-AP ID Register 0x%x, Debug ROM Address 0x%x", idreg, romaddr);
return ERROR_OK;
}
#define CSYSPWRUPREQ (1<<30)
#define CSYSPWRUPACK (1<<31)
-
-
#define AHBAP_CSW 0x00
#define AHBAP_TAR 0x04
#define AHBAP_DRW 0x0C
#define AHBAP_DBGROMA 0xF8
#define AHBAP_IDR 0xFC
-
#define CSW_8BIT 0
#define CSW_16BIT 1
#define CSW_32BIT 2
#define CSW_ADDRINC_OFF 0
#define CSW_ADDRINC_SINGLE (1<<4)
#define CSW_ADDRINC_PACKED (2<<4)
-#define CSW_HPROT (1<<25)
+#define CSW_HPROT (1<<25)
#define CSW_MASTER_DEBUG (1<<29)
-#define CSW_DBGSWENABLE (1<<31)
-#define TRANS_MODE_NONE 0
+#define CSW_DBGSWENABLE (1<<31)
+/* transaction mode */
+#define TRANS_MODE_NONE 0
/* Transaction waits for previous to complete */
#define TRANS_MODE_ATOMIC 1
/* Freerunning transactions with delays and overrun checking */
#define TRANS_MODE_COMPOSITE 2
-
typedef struct swjdp_reg_s
{
int addr;
u8 trans_mode;
u8 trans_rw;
u8 ack;
- u32 * trans_value;
+ u32 *trans_value;
} swjdp_common_t;
/* Internal functions used in the module, partial transactions, use with caution */
extern int ahbap_write_system_u32(swjdp_common_t *swjdp, u32 address, u32 value);
extern int swjdp_transaction_endcheck(swjdp_common_t *swjdp);
-
/* External interface, complete atomic operations */
/* Host endian word transfer of single memory and system registers */
extern int ahbap_read_system_atomic_u32(swjdp_common_t *swjdp, u32 address, u32 *value);
extern int ahbap_read_coreregister_u32(swjdp_common_t *swjdp, u32 *value, int regnum);
extern int ahbap_write_coreregister_u32(swjdp_common_t *swjdp, u32 value, int regnum);
+extern int ahbap_read_buf(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
+extern int ahbap_read_buf_u16(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
+extern int ahbap_write_buf(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
+extern int ahbap_write_buf_u16(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
+
/* Initialisation of the debug system, power domains and registers */
extern int ahbap_debugport_init(swjdp_common_t *swjdp);
{
if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
return retval;
+ return ERROR_OK;
}
/* handle unaligned head bytes */
{
if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
return retval;
+ return ERROR_OK;
}
/* handle unaligned head bytes */