* 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. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
uint32_t disable_bit;
uint32_t busy_bits;
uint32_t register_base;
- struct working_area *write_algorithm;
};
struct str7x_mem_layout {
STR7X_BUSY = 11
};
-static struct str7x_mem_layout mem_layout_str7bank0[] = {
+static const struct str7x_mem_layout mem_layout_str7bank0[] = {
{0x00000000, 0x02000, 0x01},
{0x00002000, 0x02000, 0x02},
{0x00004000, 0x02000, 0x04},
{0x00030000, 0x10000, 0x80}
};
-static struct str7x_mem_layout mem_layout_str7bank1[] = {
+static const struct str7x_mem_layout mem_layout_str7bank1[] = {
{0x00000000, 0x02000, 0x10000},
{0x00002000, 0x02000, 0x20000}
};
struct str7x_flash_bank *str7x_info = bank->driver_priv;
int i;
- int num_sectors;
+ unsigned int num_sectors;
int b0_sectors = 0, b1_sectors = 0;
switch (bank->size) {
str7x_build_block_list(bank);
- str7x_info->write_algorithm = NULL;
-
return ERROR_OK;
}
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
- int i;
uint32_t flash_flags;
if (bank->target->state != TARGET_HALTED) {
if (retval != ERROR_OK)
return retval;
- for (i = 0; i < bank->num_sectors; i++) {
+ for (unsigned int i = 0; i < bank->num_sectors; i++) {
if (flash_flags & str7x_info->sector_bits[i])
bank->sectors[i].is_protected = 0;
else
return ERROR_OK;
}
-static int str7x_erase(struct flash_bank *bank, int first, int last)
+static int str7x_erase(struct flash_bank *bank, unsigned int first,
+ unsigned int last)
{
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
- int i;
uint32_t cmd;
uint32_t sectors = 0;
int err;
return ERROR_TARGET_NOT_HALTED;
}
- for (i = first; i <= last; i++)
+ for (unsigned int i = first; i <= last; i++)
sectors |= str7x_info->sector_bits[i];
LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
if (err != ERROR_OK)
return err;
- for (i = first; i <= last; i++)
+ for (unsigned int i = first; i <= last; i++)
bank->sectors[i].is_erased = 1;
return ERROR_OK;
}
-static int str7x_protect(struct flash_bank *bank, int set, int first, int last)
+static int str7x_protect(struct flash_bank *bank, int set, unsigned int first,
+ unsigned int last)
{
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
- int i;
uint32_t cmd;
uint32_t protect_blocks;
protect_blocks = 0xFFFFFFFF;
if (set) {
- for (i = first; i <= last; i++)
+ for (unsigned int i = first; i <= last; i++)
protect_blocks &= ~(str7x_info->sector_bits[i]);
}
return ERROR_OK;
}
-static int str7x_write_block(struct flash_bank *bank, uint8_t *buffer,
+static int str7x_write_block(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t buffer_size = 32768;
+ struct working_area *write_algorithm;
struct working_area *source;
uint32_t address = bank->base + offset;
struct reg_param reg_params[6];
struct arm_algorithm arm_algo;
int retval = ERROR_OK;
- /* see contib/loaders/flash/str7x.s for src */
+ /* see contrib/loaders/flash/str7x.s for src */
static const uint32_t str7x_flash_write_code[] = {
/* write: */
/* flash write code */
if (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),
- &str7x_info->write_algorithm) != ERROR_OK) {
+ &write_algorithm) != ERROR_OK) {
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
- target_write_buffer(target, str7x_info->write_algorithm->address,
- sizeof(str7x_flash_write_code),
- (uint8_t *)str7x_flash_write_code);
+ uint8_t code[sizeof(str7x_flash_write_code)];
+ target_buffer_set_u32_array(target, code, ARRAY_SIZE(str7x_flash_write_code),
+ str7x_flash_write_code);
+ target_write_buffer(target, write_algorithm->address, sizeof(code), code);
/* memory buffer */
while (target_alloc_working_area_try(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
+ /* we already allocated the writing code, but failed to get a
* buffer, free the algorithm */
- if (str7x_info->write_algorithm)
- target_free_working_area(target, str7x_info->write_algorithm);
+ target_free_working_area(target, write_algorithm);
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
- str7x_info->write_algorithm->address,
- str7x_info->write_algorithm->address + (sizeof(str7x_flash_write_code) - 4),
+ write_algorithm->address,
+ write_algorithm->address + (sizeof(str7x_flash_write_code) - 4),
10000, &arm_algo);
if (retval != ERROR_OK)
break;
}
target_free_working_area(target, source);
- target_free_working_area(target, str7x_info->write_algorithm);
+ target_free_working_area(target, write_algorithm);
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
return retval;
}
-static int str7x_write(struct flash_bank *bank, uint8_t *buffer,
+static int str7x_write(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
struct target *target = bank->target;
uint32_t cmd;
int retval;
uint32_t check_address = offset;
- int i;
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
- for (i = 0; i < bank->num_sectors; i++) {
+ for (unsigned int i = 0; i < bank->num_sectors; i++) {
uint32_t sec_start = bank->sectors[i].offset;
uint32_t sec_end = sec_start + bank->sectors[i].size;
}
#endif
-static int get_str7x_info(struct flash_bank *bank, char *buf, int buf_size)
+static int get_str7x_info(struct flash_bank *bank, struct command_invocation *cmd)
{
- snprintf(buf, buf_size, "str7x flash driver info");
- /* STR7x flash doesn't support sector protection interrogation.
- * FLASH_NVWPAR acts as a write only register; its read value
- * doesn't reflect the actual protection state of the sectors.
+ /* Setting the write protection on a sector is a permanent change but it
+ * can be disabled temporarily. FLASH_NVWPAR reflects the permanent
+ * protection state of the sectors, not the temporary.
*/
- LOG_WARNING("STR7x flash lock information might not be correct "
- "due to hardware limitations.");
+ command_print_sameline(cmd, "STR7x flash protection info is only valid after a power cycle, "
+ "clearing the protection is only temporary and may not be reflected in the current "
+ "info returned.");
return ERROR_OK;
}
struct str7x_flash_bank *str7x_info = NULL;
uint32_t flash_cmd;
- uint16_t ProtectionLevel = 0;
- uint16_t ProtectionRegs;
+ uint16_t protection_level = 0;
+ uint16_t protection_regs;
if (CMD_ARGC < 1)
return ERROR_COMMAND_SYNTAX_ERROR;
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), ®);
if (!(reg & str7x_info->disable_bit))
- ProtectionLevel = 1;
+ protection_level = 1;
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), ®);
- ProtectionRegs = ~(reg >> 16);
+ protection_regs = ~(reg >> 16);
- while (((ProtectionRegs) != 0) && (ProtectionLevel < 16)) {
- ProtectionRegs >>= 1;
- ProtectionLevel++;
+ while (((protection_regs) != 0) && (protection_level < 16)) {
+ protection_regs >>= 1;
+ protection_level++;
}
- if (ProtectionLevel == 0) {
+ if (protection_level == 0) {
flash_cmd = FLASH_SPR;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),
- ~(1 << (15 + ProtectionLevel)));
+ ~(1 << (15 + protection_level)));
flash_cmd = FLASH_SPR | FLASH_WMS;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
}
COMMAND_REGISTRATION_DONE
};
-struct flash_driver str7x_flash = {
+const struct flash_driver str7x_flash = {
.name = "str7x",
.commands = str7x_command_handlers,
.flash_bank_command = str7x_flash_bank_command,
.erase_check = default_flash_blank_check,
.protect_check = str7x_protect_check,
.info = get_str7x_info,
+ .free_driver_priv = default_flash_free_driver_priv,
};