diff options
author | Aurelien Jacobs <aurel@gnuage.org> | 2012-05-08 20:53:18 +0200 |
---|---|---|
committer | Spencer Oliver <spen@spen-soft.co.uk> | 2012-05-14 09:30:18 +0000 |
commit | 9d31589d19b1c9c4cbde5c361c046d735c43c215 (patch) | |
tree | 103a7e8b0b96587da5198fa6325f0839b8d52373 /src/flash/nor/cfi.c | |
parent | e95f8d93f2ae92d7226be947ca5c963bf879c18e (diff) |
cfi: fix write_bank segfault with spansion flash on armv7m
cfi_spansion_write_block() passes an arm_algorithm struct to
target_run_algorithm() which in turn calls armv7m_start_algorithm()
which expect an armv7m_algorithm struct.
As armv7m_algorithm is bigger than arm_algorithm, when
armv7m_start_algorithm() writes in the struct, it overrun the buffer,
writting junk on the stack, which latter on generates a segfault.
This patch ensure we use a properly sized armv7m_algorithm struct
when the target is an armv7m.
Change-Id: I4ab67c15ae4bb72454414a81b92a4231dcdb2239
Signed-off-by: Aurelien Jacobs <aurel@gnuage.org>
Reviewed-on: http://openocd.zylin.com/623
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src/flash/nor/cfi.c')
-rw-r--r-- | src/flash/nor/cfi.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index bb6afa32..ec90d7a2 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -1634,7 +1634,9 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; struct target *target = bank->target; struct reg_param reg_params[10]; - struct arm_algorithm arm_algo; + struct arm_algorithm *arm_algo; + struct arm_algorithm armv4_5_algo; + struct armv7m_algorithm armv7m_algo; struct working_area *source; uint32_t buffer_size = 32768; uint32_t status; @@ -1814,14 +1816,15 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, return cfi_spansion_write_block_mips(bank, buffer, address, count); if (is_armv7m(target_to_armv7m(target))) { /* Cortex-M3 target */ - arm_algo.common_magic = ARMV7M_COMMON_MAGIC; - arm_algo.core_mode = ARMV7M_MODE_HANDLER; - arm_algo.core_state = ARM_STATE_ARM; + armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_algo.core_mode = ARMV7M_MODE_HANDLER; + arm_algo = (struct arm_algorithm *)&armv7m_algo; } else if (is_arm(target_to_arm(target))) { /* All other ARM CPUs have 32 bit instructions */ - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; + armv4_5_algo.common_magic = ARM_COMMON_MAGIC; + armv4_5_algo.core_mode = ARM_MODE_SVC; + armv4_5_algo.core_state = ARM_STATE_ARM; + arm_algo = &armv4_5_algo; } else { LOG_ERROR("Unknown architecture"); return ERROR_FAIL; @@ -1832,7 +1835,7 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, switch (bank->bus_width) { case 1: - if (arm_algo.common_magic != ARM_COMMON_MAGIC) { + if (arm_algo->common_magic != ARM_COMMON_MAGIC) { LOG_ERROR("Unknown ARM architecture"); return ERROR_FAIL; } @@ -1842,10 +1845,10 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, case 2: /* Check for DQ5 support */ if (cfi_info->status_poll_mask & (1 << 5)) { - if (arm_algo.common_magic == ARM_COMMON_MAGIC) {/* armv4_5 target */ + if (arm_algo->common_magic == ARM_COMMON_MAGIC) {/* armv4_5 target */ target_code_src = armv4_5_word_16_code; target_code_size = sizeof(armv4_5_word_16_code); - } else if (arm_algo.common_magic == ARMV7M_COMMON_MAGIC) { /* + } else if (arm_algo->common_magic == ARMV7M_COMMON_MAGIC) { /* *cortex-m3 *target **/ @@ -1854,7 +1857,7 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, } } else { /* No DQ5 support. Use DQ7 DATA# polling only. */ - if (arm_algo.common_magic != ARM_COMMON_MAGIC) { + if (arm_algo->common_magic != ARM_COMMON_MAGIC) { LOG_ERROR("Unknown ARM architecture"); return ERROR_FAIL; } @@ -1863,7 +1866,7 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, } break; case 4: - if (arm_algo.common_magic != ARM_COMMON_MAGIC) { + if (arm_algo->common_magic != ARM_COMMON_MAGIC) { LOG_ERROR("Unknown ARM architecture"); return ERROR_FAIL; } @@ -1954,7 +1957,7 @@ static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, retval = target_run_algorithm(target, 0, NULL, 10, reg_params, cfi_info->write_algorithm->address, cfi_info->write_algorithm->address + ((target_code_size) - 4), - 10000, &arm_algo); + 10000, arm_algo); if (retval != ERROR_OK) break; |