diff options
-rw-r--r-- | src/flash/avrf.c | 108 | ||||
-rw-r--r-- | src/flash/lpc288x.c | 94 | ||||
-rw-r--r-- | src/flash/ocl.c | 10 | ||||
-rw-r--r-- | src/flash/stellaris.c | 206 | ||||
-rw-r--r-- | src/flash/stm32x.c | 420 | ||||
-rw-r--r-- | src/flash/str9x.c | 168 | ||||
-rw-r--r-- | src/flash/str9xpec.c | 77 |
7 files changed, 505 insertions, 578 deletions
diff --git a/src/flash/avrf.c b/src/flash/avrf.c index 307e54e..301ce26 100644 --- a/src/flash/avrf.c +++ b/src/flash/avrf.c @@ -50,7 +50,7 @@ #define AVR_JTAG_REG_ProgrammingCommand_Len 15 #define AVR_JTAG_REG_FlashDataByte_Len 16 -avrf_type_t avft_chips_info[] = +avrf_type_t avft_chips_info[] = { // name, chip_id, flash_page_size, flash_page_num, eeprom_page_size, eeprom_page_num {"atmega128", 0x9702, 256, 512, 8, 512}, @@ -102,7 +102,7 @@ static int avr_jtag_reset(avr_common_t *avr, u32 reset) { avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_AVR_RESET); avr_jtag_senddat(avr->jtag_info.tap, NULL, reset ,AVR_JTAG_REG_Reset_Len); - + return ERROR_OK; } @@ -110,17 +110,17 @@ static int avr_jtag_read_jtagid(avr_common_t *avr, u32 *id) { avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_IDCODE); avr_jtag_senddat(avr->jtag_info.tap, id, 0, AVR_JTAG_REG_JTAGID_Len); - + return ERROR_OK; } static int avr_jtagprg_enterprogmode(avr_common_t *avr) { avr_jtag_reset(avr, 1); - + avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0xA370, AVR_JTAG_REG_ProgrammingEnable_Len); - + return ERROR_OK; } @@ -134,20 +134,20 @@ static int avr_jtagprg_leaveprogmode(avr_common_t *avr) avr_jtag_senddat(avr->jtag_info.tap, NULL, 0, AVR_JTAG_REG_ProgrammingEnable_Len); avr_jtag_reset(avr, 0); - + return ERROR_OK; } static int avr_jtagprg_chiperase(avr_common_t *avr) { u32 poll_value; - + avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2380, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3180, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); - + do{ poll_value = 0; avr_jtag_senddat(avr->jtag_info.tap, &poll_value, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); @@ -157,25 +157,25 @@ static int avr_jtagprg_chiperase(avr_common_t *avr) } LOG_DEBUG("poll_value = 0x%04X", poll_value); }while(!(poll_value & 0x0200)); - + return ERROR_OK; } static int avr_jtagprg_writeflashpage(avr_common_t *avr, u8 *page_buf, u32 buf_size, u32 addr, u32 page_size) { u32 i, poll_value; - + avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_ProgrammingCommand_Len); - + // load addr high byte avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0700 | ((addr >> 9) & 0xFF), AVR_JTAG_REG_ProgrammingCommand_Len); - + // load addr low byte avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0300 | ((addr >> 1) & 0xFF), AVR_JTAG_REG_ProgrammingCommand_Len); - + avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_PAGELOAD); - + for (i = 0; i < page_size; i++) { if (i < buf_size) @@ -187,14 +187,14 @@ static int avr_jtagprg_writeflashpage(avr_common_t *avr, u8 *page_buf, u32 buf_s avr_jtag_senddat(avr->jtag_info.tap, NULL, 0xFF, 8); } } - + avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - + avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3500, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); - + do{ poll_value = 0; avr_jtag_senddat(avr->jtag_info.tap, &poll_value, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); @@ -204,7 +204,7 @@ static int avr_jtagprg_writeflashpage(avr_common_t *avr, u8 *page_buf, u32 buf_s } LOG_DEBUG("poll_value = 0x%04X", poll_value); }while(!(poll_value & 0x0200)); - + return ERROR_OK; } @@ -212,28 +212,28 @@ static int avr_jtagprg_writeflashpage(avr_common_t *avr, u8 *page_buf, u32 buf_s static int avrf_register_commands(struct command_context_s *cmd_ctx) { command_t *avr_cmd = register_command(cmd_ctx, NULL, "avr", NULL, COMMAND_ANY, "avr flash specific commands"); - + register_command(cmd_ctx, avr_cmd, "mass_erase", avrf_handle_mass_erase_command, COMMAND_EXEC, "mass erase device"); - + return ERROR_OK; } static int avrf_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { avrf_flash_bank_t *avrf_info; - + if (argc < 6) { LOG_WARNING("incomplete flash_bank avr configuration"); return ERROR_FLASH_BANK_INVALID; } - + avrf_info = malloc(sizeof(avrf_flash_bank_t)); bank->driver_priv = avrf_info; - + avrf_info->probed = 0; - + return ERROR_OK; } @@ -254,28 +254,28 @@ static int avrf_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou target_t *target = bank->target; avr_common_t *avr = target->arch_info; u32 cur_size, cur_buffer_size, page_size; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + page_size = bank->sectors[0].size; if ((offset % page_size) != 0) { LOG_WARNING("offset 0x%x breaks required %d-byte alignment", offset, page_size); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } - + LOG_DEBUG("offset is 0x%08X", offset); LOG_DEBUG("count is %d", count); - + if (ERROR_OK != avr_jtagprg_enterprogmode(avr)) { return ERROR_FAIL; } - + cur_size = 0; while(count > 0) { @@ -290,10 +290,10 @@ static int avrf_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou avr_jtagprg_writeflashpage(avr, buffer + cur_size, cur_buffer_size, offset + cur_size, page_size); count -= cur_buffer_size; cur_size += cur_buffer_size; - + keep_alive(); } - + return avr_jtagprg_leaveprogmode(avr); } @@ -308,7 +308,7 @@ static int avrf_probe(struct flash_bank_s *bank) avrf_type_t *avr_info = NULL; int i; u32 device_id; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -316,19 +316,19 @@ static int avrf_probe(struct flash_bank_s *bank) } avrf_info->probed = 0; - + avr_jtag_read_jtagid(avr, &device_id); if (ERROR_OK != mcu_execute_queue()) { return ERROR_FAIL; } - + LOG_INFO( "device id = 0x%08x", device_id ); if (EXTRACT_MFG(device_id) != 0x1F) { LOG_ERROR("0x%X is invalid Manufacturer for avr, 0x%X is expected", EXTRACT_MFG(device_id), 0x1F); } - + for (i = 0; i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])); i++) { if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) @@ -338,7 +338,7 @@ static int avrf_probe(struct flash_bank_s *bank) break; } } - + if (avr_info != NULL) { // chip found @@ -346,7 +346,7 @@ static int avrf_probe(struct flash_bank_s *bank) bank->size = (avr_info->flash_page_size * avr_info->flash_page_num); bank->num_sectors = avr_info->flash_page_num; bank->sectors = malloc(sizeof(flash_sector_t) * avr_info->flash_page_num); - + for (i = 0; i < avr_info->flash_page_num; i++) { bank->sectors[i].offset = i * avr_info->flash_page_size; @@ -354,7 +354,7 @@ static int avrf_probe(struct flash_bank_s *bank) bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - + avrf_info->probed = 1; return ERROR_OK; } @@ -362,7 +362,7 @@ static int avrf_probe(struct flash_bank_s *bank) { // chip not supported LOG_ERROR("0x%X is not support for avr", EXTRACT_PART(device_id)); - + avrf_info->probed = 1; return ERROR_FAIL; } @@ -389,36 +389,36 @@ static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size) avrf_type_t *avr_info = NULL; int i; u32 device_id; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + avr_jtag_read_jtagid(avr, &device_id); if (ERROR_OK != mcu_execute_queue()) { return ERROR_FAIL; } - + LOG_INFO( "device id = 0x%08x", device_id ); if (EXTRACT_MFG(device_id) != 0x1F) { LOG_ERROR("0x%X is invalid Manufacturer for avr, 0x%X is expected", EXTRACT_MFG(device_id), 0x1F); } - + for (i = 0; i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])); i++) { if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) { avr_info = &avft_chips_info[i]; LOG_INFO("target device is %s", avr_info->name); - + break; } } - + if (avr_info != NULL) { // chip found @@ -437,20 +437,20 @@ static int avrf_mass_erase(struct flash_bank_s *bank) { target_t *target = bank->target; avr_common_t *avr = target->arch_info; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if ((ERROR_OK != avr_jtagprg_enterprogmode(avr)) || (ERROR_OK != avr_jtagprg_chiperase(avr)) || (ERROR_OK != avr_jtagprg_leaveprogmode(avr))) { return ERROR_FAIL; } - + return ERROR_OK; } @@ -458,20 +458,20 @@ static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, cha { flash_bank_t *bank; int i; - + if (argc < 1) { command_print(cmd_ctx, "avr mass_erase <bank>"); - return ERROR_OK; + 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; } - + if (avrf_mass_erase(bank) == ERROR_OK) { /* set all sectors as erased */ @@ -479,14 +479,14 @@ static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, cha { bank->sectors[i].is_erased = 1; } - + command_print(cmd_ctx, "avr mass erase complete"); } else { command_print(cmd_ctx, "avr mass erase failed"); } - + LOG_DEBUG("%s", __FUNCTION__); return ERROR_OK; } diff --git a/src/flash/lpc288x.c b/src/flash/lpc288x.c index 29b7b81..152432e 100644 --- a/src/flash/lpc288x.c +++ b/src/flash/lpc288x.c @@ -128,7 +128,7 @@ static u32 lpc288x_wait_status_busy(flash_bank_t *bank, int timeout) timeout--; target_read_u32(target, F_STAT, &status); }while (((status & FS_DONE) == 0) && timeout); - + if(timeout == 0) { LOG_DEBUG("Timedout!"); @@ -143,31 +143,31 @@ static int lpc288x_read_part_info(struct flash_bank_s *bank) lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv; target_t *target = bank->target; u32 cidr; - + int i = 0; u32 offset; - + if (lpc288x_info->cidr == 0x0102100A) return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */ - + /* Read and parse chip identification register */ target_read_u32(target, DBGU_CIDR, &cidr); - + if (cidr != 0x0102100A) { LOG_WARNING("Cannot identify target as an LPC288X (%08X)",cidr); return ERROR_FLASH_OPERATION_FAILED; } - + lpc288x_info->cidr = cidr; lpc288x_info->sector_size_break = 0x000F0000; lpc288x_info->target_name = "LPC288x"; - + /* setup the sector info... */ offset = bank->base; bank->num_sectors = 23; bank->sectors = malloc(sizeof(flash_sector_t) * 23); - + for (i = 0; i < 15; i++) { bank->sectors[i].offset = offset; @@ -184,7 +184,7 @@ static int lpc288x_read_part_info(struct flash_bank_s *bank) bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - + return ERROR_OK; } @@ -197,20 +197,20 @@ static int lpc288x_protect_check(struct flash_bank_s *bank) static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { lpc288x_flash_bank_t *lpc288x_info; - + if (argc < 6) { LOG_WARNING("incomplete flash_bank LPC288x configuration"); return ERROR_FLASH_BANK_INVALID; } - + lpc288x_info = malloc(sizeof(lpc288x_flash_bank_t)); bank->driver_priv = lpc288x_info; - + /* part wasn't probed for info yet */ lpc288x_info->cidr = 0; lpc288x_info->cclk = strtoul(args[6], NULL, 0); - + return ERROR_OK; } @@ -230,9 +230,9 @@ static void lpc288x_set_flash_clk(struct flash_bank_s *bank) /* AHB tcyc (in ns) 83 ns * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512 - * = 9412 (9500) (AN10548 9375) + * = 9412 (9500) (AN10548 9375) * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512 - * = 23 (75) (AN10548 72 - is this wrong?) + * = 23 (75) (AN10548 72 - is this wrong?) * TODO: Sort out timing calcs ;) */ static void lpc288x_load_timer(int erase, struct target_s *target) { @@ -253,7 +253,7 @@ static u32 lpc288x_system_ready(struct flash_bank_s *bank) { return ERROR_FLASH_BANK_NOT_PROBED; } - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -270,7 +270,7 @@ static int lpc288x_erase_check(struct flash_bank_s *bank) LOG_INFO("Processor not halted/not probed"); return status; } - + return ERROR_OK; } @@ -279,33 +279,33 @@ static int lpc288x_erase(struct flash_bank_s *bank, int first, int last) u32 status; int sector; target_t *target = bank->target; - + status = lpc288x_system_ready(bank); /* probed? halted? */ if (status != ERROR_OK) { return status; } - + if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { LOG_INFO("Bad sector range"); return ERROR_FLASH_SECTOR_INVALID; } - + /* Configure the flash controller timing */ lpc288x_set_flash_clk(bank); - + for (sector = first; sector <= last; sector++) { if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK) { return ERROR_FLASH_OPERATION_FAILED; } - + lpc288x_load_timer(LOAD_TIMER_ERASE,target); - + target_write_u32(target, bank->sectors[sector].offset, 0x00); - + target_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_CS); } if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK) @@ -323,17 +323,17 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 u32 bytes_remaining = count; u32 first_sector, last_sector, sector, page; int i; - + /* probed? halted? */ status = lpc288x_system_ready(bank); if (status != ERROR_OK) { return status; } - + /* Initialise search indices */ first_sector = last_sector = 0xffffffff; - + /* validate the write range... */ for (i = 0; i < bank->num_sectors; i++) { @@ -356,21 +356,21 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 last_sector = i; } } - + /* Range check... */ if (first_sector == 0xffffffff || last_sector == 0xffffffff) { LOG_INFO("Range check failed %x %x", offset, count); return ERROR_FLASH_DST_OUT_OF_BANK; } - + /* Configure the flash controller timing */ lpc288x_set_flash_clk(bank); - + /* initialise the offsets */ source_offset = 0; dest_offset = 0; - + for (sector = first_sector; sector <= last_sector; sector++) { for (page = 0; page < bank->sectors[sector].size / FLASH_PAGE_SIZE; page++) @@ -391,16 +391,16 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count = FLASH_PAGE_SIZE; memcpy(page_buffer, &buffer[source_offset], count); } - + /* Wait for flash to become ready */ if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK) { return ERROR_FLASH_OPERATION_FAILED; } - + /* fill flash data latches with 1's */ target_write_u32(target, F_CTRL, FC_CS | FC_SET_DATA | FC_WEN | FC_FUNC); - + target_write_u32(target, F_CTRL, FC_CS | FC_WEN | FC_FUNC); /*would be better to use the clean target_write_buffer() interface but * it seems not to be a LOT slower.... @@ -421,13 +421,13 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 dest_offset += FLASH_PAGE_SIZE; source_offset += count; bytes_remaining -= count; - + lpc288x_load_timer(LOAD_TIMER_WRITE, target); - + target_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_FUNC | FC_CS); } } - + return ERROR_OK; } @@ -436,18 +436,18 @@ static int lpc288x_probe(struct flash_bank_s *bank) /* we only deal with LPC2888 so flash config is fixed */ lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv; int retval; - + if (lpc288x_info->cidr != 0) { return ERROR_OK; /* already probed */ } - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + retval = lpc288x_read_part_info(bank); if (retval != ERROR_OK) return retval; @@ -465,22 +465,22 @@ static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int la int lockregion, status; u32 value; target_t *target = bank->target; - + /* probed? halted? */ - status = lpc288x_system_ready(bank); + status = lpc288x_system_ready(bank); if (status != ERROR_OK) { return status; } - + if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { return ERROR_FLASH_SECTOR_INVALID; } - + /* Configure the flash controller timing */ - lpc288x_set_flash_clk(bank); - + lpc288x_set_flash_clk(bank); + for (lockregion = first; lockregion <= last; lockregion++) { if (set) @@ -496,6 +496,6 @@ static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int la target_write_u32(target, bank->sectors[lockregion].offset, value); target_write_u32(target, F_CTRL, FC_LOAD_REQ | FC_PROTECT | FC_WEN | FC_FUNC | FC_CS); } - + return ERROR_OK; } diff --git a/src/flash/ocl.c b/src/flash/ocl.c index e2099a1..b9028b1 100644 --- a/src/flash/ocl.c +++ b/src/flash/ocl.c @@ -108,13 +108,13 @@ static int ocl_erase(struct flash_bank_s *bank, int first, int last) /* check preconditions */ if (bank->num_sectors == 0) return ERROR_FLASH_BANK_NOT_PROBED; - + if (bank->target->state != TARGET_RUNNING) { LOG_ERROR("target has to be running to communicate with the loader"); return ERROR_TARGET_NOT_RUNNING; } - + if ((first == 0) && (last == bank->num_sectors - 1)) { dcc_buffer[0] = OCL_ERASE_ALL; @@ -168,7 +168,7 @@ static int ocl_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 coun int byteofs; int runlen; u32 chksum; - + int i; /* check preconditions */ @@ -227,7 +227,7 @@ static int ocl_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 coun chksum ^= *(dcc_bufptr++); *(dcc_bufptr++) = chksum; - + /* send the data */ if ((retval = embeddedice_send(ocl->jtag_info, dcc_buffer, dcc_bufptr-dcc_buffer)) != ERROR_OK) { @@ -292,7 +292,7 @@ static int ocl_probe(struct flash_bank_s *bank) /* receive response */ if ((retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK)) return retval; - + if (dcc_buffer[0] != OCL_CMD_DONE) { LOG_ERROR("loader response to OCL_PROBE 0x%08X", dcc_buffer[0]); diff --git a/src/flash/stellaris.c b/src/flash/stellaris.c index 001b017..9772790 100644 --- a/src/flash/stellaris.c +++ b/src/flash/stellaris.c @@ -241,30 +241,30 @@ static char * StellarisClassname[5] = static int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { stellaris_flash_bank_t *stellaris_info; - + if (argc < 6) { LOG_WARNING("incomplete flash_bank stellaris configuration"); return ERROR_FLASH_BANK_INVALID; } - + stellaris_info = calloc(sizeof(stellaris_flash_bank_t), 1); bank->base = 0x0; bank->driver_priv = stellaris_info; - + stellaris_info->target_name = "Unknown target"; - + /* part wasn't probed for info yet */ stellaris_info->did1 = 0; - - /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */ + + /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */ return ERROR_OK; } static int stellaris_register_commands(struct command_context_s *cmd_ctx) { command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stellaris", NULL, COMMAND_ANY, "stellaris flash specific commands"); - + register_command(cmd_ctx, stm32x_cmd, "mass_erase", stellaris_handle_mass_erase_command, COMMAND_EXEC, "mass erase device"); return ERROR_OK; } @@ -273,7 +273,7 @@ static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size) { int printed, device_class; stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - + stellaris_read_part_info(bank); if (stellaris_info->did1 == 0) @@ -283,7 +283,7 @@ static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size) buf_size -= printed; return ERROR_FLASH_OPERATION_FAILED; } - + if (DID0_VER(stellaris_info->did0) > 0) { device_class = (stellaris_info->did0>>16) & 0xFF; @@ -291,14 +291,14 @@ static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size) else { device_class = 0; - } + } printed = snprintf(buf, buf_size, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n", device_class, StellarisClassname[device_class], stellaris_info->target_name, 'A' + ((stellaris_info->did0>>8) & 0xFF), (stellaris_info->did0) & 0xFF); buf += printed; buf_size -= printed; - printed = snprintf(buf, buf_size, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n", + printed = snprintf(buf, buf_size, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n", stellaris_info->did1, stellaris_info->did1, "ARMV7M", (1+((stellaris_info->dc0>>16) & 0xFFFF))/4, (1+(stellaris_info->dc0 & 0xFFFF))*2); buf += printed; buf_size -= printed; @@ -324,14 +324,14 @@ static u32 stellaris_get_flash_status(flash_bank_t *bank) { target_t *target = bank->target; u32 fmc; - + target_read_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, &fmc); - + return fmc; } /** Read clock configuration and set stellaris_info->usec_clocks*/ - + static void stellaris_read_clock_info(flash_bank_t *bank) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; @@ -344,7 +344,7 @@ static void stellaris_read_clock_info(flash_bank_t *bank) target_read_u32(target, SCB_BASE|PLLCFG, &pllcfg); LOG_DEBUG("Stellaris PLLCFG %x", pllcfg); stellaris_info->rcc = rcc; - + sysdiv = (rcc>>23) & 0xF; usesysdiv = (rcc>>22) & 0x1; bypass = (rcc>>11) & 0x1; @@ -370,15 +370,15 @@ static void stellaris_read_clock_info(flash_bank_t *bank) mainfreq = 0; break; } - + if (!bypass) mainfreq = 200000000; /* PLL out frec */ - + if (usesysdiv) stellaris_info->mck_freq = mainfreq/(1+sysdiv); else stellaris_info->mck_freq = mainfreq; - + /* Forget old flash timing */ stellaris_set_flash_mode(bank, 0); } @@ -390,7 +390,7 @@ static void stellaris_set_flash_mode(flash_bank_t *bank,int mode) target_t *target = bank->target; u32 usecrl = (stellaris_info->mck_freq/1000000ul-1); - LOG_DEBUG("usecrl = %i",usecrl); + LOG_DEBUG("usecrl = %i",usecrl); target_write_u32(target, SCB_BASE|USECRL, usecrl); } @@ -398,33 +398,33 @@ static void stellaris_set_flash_mode(flash_bank_t *bank,int mode) static u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout) { u32 status; - + /* Stellaris waits for cmdbit to clear */ while (((status = stellaris_get_flash_status(bank)) & waitbits) && (timeout-- > 0)) { LOG_DEBUG("status: 0x%x", status); alive_sleep(1); } - + /* Flash errors are reflected in the FLASH_CRIS register */ return status; } /* Send one command to the flash controller */ -static int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) +static int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) { u32 fmc; target_t *target = bank->target; - fmc = FMC_WRKEY | cmd; + fmc = FMC_WRKEY | cmd; target_write_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, fmc); LOG_DEBUG("Flash command: 0x%x", fmc); - if (stellaris_wait_status_busy(bank, cmd, 100)) + if (stellaris_wait_status_busy(bank, cmd, 100)) { return ERROR_FLASH_OPERATION_FAILED; - } + } return ERROR_OK; } @@ -437,7 +437,7 @@ static int stellaris_read_part_info(struct flash_bank_s *bank) target_t *target = bank->target; u32 did0, did1, ver, fam, status; int i; - + /* Read and parse chip identification register */ target_read_u32(target, SCB_BASE|DID0, &did0); target_read_u32(target, SCB_BASE|DID1, &did1); @@ -470,9 +470,9 @@ static int stellaris_read_part_info(struct flash_bank_s *bank) if (StellarisParts[i].partno == ((did1 >> 16) & 0xFF)) break; } - + stellaris_info->target_name = StellarisParts[i].partname; - + stellaris_info->did0 = did0; stellaris_info->did1 = did1; @@ -496,9 +496,9 @@ static int stellaris_read_part_info(struct flash_bank_s *bank) /* Read main and master clock freqency register */ stellaris_read_clock_info(bank); - + status = stellaris_get_flash_status(bank); - + return ERROR_OK; } @@ -509,7 +509,7 @@ static int stellaris_read_part_info(struct flash_bank_s *bank) static int stellaris_protect_check(struct flash_bank_s *bank) { u32 status; - + stellaris_flash_bank_t *stellaris_info = bank->driver_priv; if (bank->target->state != TARGET_HALTED) @@ -528,10 +528,10 @@ static int stellaris_protect_check(struct flash_bank_s *bank) LOG_WARNING("Cannot identify target as an AT91SAM"); return ERROR_FLASH_OPERATION_FAILED; } - + status = stellaris_get_flash_status(bank); stellaris_info->lockbits = status >> 16; - + return ERROR_OK; } @@ -541,7 +541,7 @@ static int stellaris_erase(struct flash_bank_s *bank, int first, int last) u32 flash_fmc, flash_cris; stellaris_flash_bank_t *stellaris_info = bank->driver_priv; target_t *target = bank->target; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -557,26 +557,26 @@ static int stellaris_erase(struct flash_bank_s *bank, int first, int last) { LOG_WARNING("Cannot identify target as Stellaris"); return ERROR_FLASH_OPERATION_FAILED; - } - + } + if ((first < 0) || (last < first) || (last >= (int)stellaris_info->num_pages)) { return ERROR_FLASH_SECTOR_INVALID; } - + if ((first == 0) && (last == ((int)stellaris_info->num_pages-1))) { return stellaris_mass_erase(bank); } - + /* Configure the flash controller timing */ - stellaris_read_clock_info(bank); + stellaris_read_clock_info(bank); stellaris_set_flash_mode(bank,0); /* Clear and disable flash programming interrupts */ target_write_u32(target, FLASH_CIM, 0); target_write_u32(target, FLASH_MISC, PMISC|AMISC); - + for (banknr = first; banknr <= last; banknr++) { /* Address is first word in page */ @@ -598,7 +598,7 @@ static int stellaris_erase(struct flash_bank_s *bank, int first, int last) target_write_u32(target, FLASH_CRIS, 0); return ERROR_FLASH_OPERATION_FAILED; } - + bank->sectors[banknr].is_erased = 1; } @@ -609,21 +609,21 @@ static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int { u32 fmppe, flash_fmc, flash_cris; int lockregion; - + stellaris_flash_bank_t *stellaris_info = bank->driver_priv; target_t *target = bank->target; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if ((first < 0) || (last < first) || (last >= stellaris_info->num_lockbits)) { return ERROR_FLASH_SECTOR_INVALID; } - + if (stellaris_info->did1 == 0) { stellaris_read_part_info(bank); @@ -634,7 +634,7 @@ static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int LOG_WARNING("Cannot identify target as an Stellaris MCU"); return ERROR_FLASH_OPERATION_FAILED; } - + /* Configure the flash controller timing */ stellaris_read_clock_info(bank); stellaris_set_flash_mode(bank, 0); @@ -643,15 +643,15 @@ static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int for (lockregion = first; lockregion <= last; lockregion++) { if (set) - fmppe &= ~(1<<lockregion); + fmppe &= ~(1<<lockregion); else - fmppe |= (1<<lockregion); + fmppe |= (1<<lockregion); } /* Clear and disable flash programming interrupts */ target_write_u32(target, FLASH_CIM, 0); target_write_u32(target, FLASH_MISC, PMISC|AMISC); - + LOG_DEBUG("fmppe 0x%x",fmppe); target_write_u32(target, SCB_BASE|FMPPE, fmppe); /* Commit FMPPE */ @@ -675,21 +675,21 @@ static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int target_write_u32(target, FLASH_CRIS, 0); return ERROR_FLASH_OPERATION_FAILED; } - + target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits); - + return ERROR_OK; } -static u8 stellaris_write_code[] = +static u8 stellaris_write_code[] = { -/* - Call with : +/* + Call with : r0 = buffer address r1 = destination address - r2 = bytecount (in) - endaddr (work) - - Used registers: + r2 = bytecount (in) - endaddr (work) + + Used registers: r3 = pFLASH_CTRL_BASE r4 = FLASHWRITECMD r5 = #1 @@ -731,7 +731,7 @@ static int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offs reg_param_t reg_params[3]; armv7m_algorithm_t armv7m_info; int retval = ERROR_OK; - + LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)", bank, buffer, offset, wcount); @@ -748,32 +748,32 @@ static int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offs while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) { LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)", - target, buffer_size, source); + target, buffer_size, source); buffer_size /= 2; if (buffer_size <= 256) { /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */ if (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; } }; - + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.core_mode = ARMV7M_MODE_ANY; - + 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); - + while (wcount > 0) { u32 thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount; - + target_write_buffer(target, source->address, thisrun_count * 4, 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, 4*thisrun_count); @@ -785,19 +785,19 @@ static int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offs retval = ERROR_FLASH_OPERATION_FAILED; break; } - + buffer += thisrun_count * 4; address += thisrun_count * 4; wcount -= thisrun_count; } - + target_free_working_area(target, write_algorithm); target_free_working_area(target, source); - + destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); - + return retval; } @@ -811,7 +811,7 @@ static int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u3 u32 bytes_remaining = (count & 0x00000003); u32 bytes_written = 0; int retval; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -831,26 +831,26 @@ static int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u3 LOG_WARNING("Cannot identify target as a Stellaris processor"); return ERROR_FLASH_OPERATION_FAILED; } - + if (offset & 0x3) { LOG_WARNING("offset size must be word aligned"); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } - + if (offset + count > bank->size) return ERROR_FLASH_DST_OUT_OF_BANK; - /* Configure the flash controller timing */ - stellaris_read_clock_info(bank); + /* Configure the flash controller timing */ + stellaris_read_clock_info(bank); stellaris_set_flash_mode(bank, 0); - + /* Clear and disable flash programming interrupts */ target_write_u32(target, FLASH_CIM, 0); target_write_u32(target, FLASH_MISC, PMISC|AMISC); /* multiple words to be programmed? */ - if (words_remaining > 0) + if (words_remaining > 0) { /* try using a block write */ if ((retval = stellaris_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK) @@ -858,14 +858,14 @@ static int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u3 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ + * we use normal (slow) single dword accesses */ LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); } else if (retval == ERROR_FLASH_OPERATION_FAILED) { /* if an error occured, we examine the reason, and quit */ target_read_u32(target, FLASH_CRIS, &flash_cris); - + LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris); return ERROR_FLASH_OPERATION_FAILED; } @@ -877,12 +877,12 @@ static int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u3 words_remaining = 0; } } - + while (words_remaining > 0) { if (!(address & 0xff)) LOG_DEBUG("0x%x", address); - + /* Program one word */ target_write_u32(target, FLASH_FMA, address); target_write_buffer(target, FLASH_FMD, 4, buffer); @@ -893,27 +893,27 @@ static int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u3 { target_read_u32(target, FLASH_FMC, &flash_fmc); } while (flash_fmc & FMC_WRITE); - + buffer += 4; address += 4; words_remaining--; } - + if (bytes_remaining) { u8 last_word[4] = {0xff, 0xff, 0xff, 0xff}; int i = 0; - + while(bytes_remaining > 0) { - last_word[i++] = *(buffer + bytes_written); + last_word[i++] = *(buffer + bytes_written); bytes_remaining--; bytes_written++; } - + if (!(address & 0xff)) LOG_DEBUG("0x%x", address); - + /* Program one word */ target_write_u32(target, FLASH_FMA, address); target_write_buffer(target, FLASH_FMD, 4, last_word); @@ -925,7 +925,7 @@ static int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u3 target_read_u32(target, FLASH_FMC, &flash_fmc); } while (flash_fmc & FMC_WRITE); } - + /* Check access violations */ target_read_u32(target, FLASH_CRIS, &flash_cris); if (flash_cris & (AMASK)) @@ -941,7 +941,7 @@ static int stellaris_probe(struct flash_bank_s *bank) /* we can't probe on an stellaris * if this is an stellaris, it has the configured flash */ - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -965,35 +965,35 @@ static int stellaris_mass_erase(struct flash_bank_s *bank) target_t *target = NULL; stellaris_flash_bank_t *stellaris_info = NULL; u32 flash_fmc; - + stellaris_info = bank->driver_priv; target = bank->target; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if (stellaris_info->did1 == 0) { stellaris_read_part_info(bank); } - + if (stellaris_info->did1 == 0) { LOG_WARNING("Cannot identify target as Stellaris"); return ERROR_FLASH_OPERATION_FAILED; } - + /* Configure the flash controller timing */ - stellaris_read_clock_info(bank); + stellaris_read_clock_info(bank); stellaris_set_flash_mode(bank, 0); /* Clear and disable flash programming interrupts */ target_write_u32(target, FLASH_CIM, 0); target_write_u32(target, FLASH_MISC, PMISC|AMISC); - + target_write_u32(target, FLASH_FMA, 0); target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE); /* Wait until erase complete */ @@ -1002,7 +1002,7 @@ static int stellaris_mass_erase(struct flash_bank_s *bank) target_read_u32(target, FLASH_FMC, &flash_fmc); } while (flash_fmc & FMC_MERASE); - + /* if device has > 128k, then second erase cycle is needed * this is only valid for older devices, but will not hurt */ if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000) @@ -1016,7 +1016,7 @@ static int stellaris_mass_erase(struct flash_bank_s *bank) } while (flash_fmc & FMC_MERASE); } - + return ERROR_OK; } @@ -1024,20 +1024,20 @@ static int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx { flash_bank_t *bank; int i; - + if (argc < 1) { command_print(cmd_ctx, "stellaris mass_erase <bank>"); - return ERROR_OK; + 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; } - + if (stellaris_mass_erase(bank) == ERROR_OK) { /* set all sectors as erased */ @@ -1045,13 +1045,13 @@ static int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx { bank->sectors[i].is_erased = 1; } - + command_print(cmd_ctx, "stellaris mass erase complete"); } else { command_print(cmd_ctx, "stellaris mass erase failed"); } - + return ERROR_OK; } diff --git a/src/flash/stm32x.c b/src/flash/stm32x.c index 1f3460b..b0d6976 100644 --- a/src/flash/stm32x.c +++ b/src/flash/stm32x.c @@ -65,7 +65,7 @@ flash_driver_t stm32x_flash = static 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, @@ -84,19 +84,19 @@ static int stm32x_register_commands(struct command_context_s *cmd_ctx) static 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) { LOG_WARNING("incomplete flash_bank stm32x configuration"); return ERROR_FLASH_BANK_INVALID; } - + stm32x_info = malloc(sizeof(stm32x_flash_bank_t)); bank->driver_priv = stm32x_info; - + stm32x_info->write_algorithm = NULL; stm32x_info->probed = 0; - + return ERROR_OK; } @@ -104,9 +104,9 @@ static u32 stm32x_get_flash_status(flash_bank_t *bank) { target_t *target = bank->target; u32 status; - + target_read_u32(target, STM32_FLASH_SR, &status); - + return status; } @@ -114,7 +114,7 @@ static u32 stm32x_wait_status_busy(flash_bank_t *bank, int timeout) { target_t *target = bank->target; u32 status; - + /* wait for busy to clear */ while (((status = stm32x_get_flash_status(bank)) & FLASH_BSY) && (timeout-- > 0)) { @@ -124,7 +124,7 @@ static u32 stm32x_wait_status_busy(flash_bank_t *bank, int timeout) /* Clear but report errors */ if (status & (FLASH_WRPRTERR|FLASH_PGERR)) { - target_write_u32(target, STM32_FLASH_SR, FLASH_WRPRTERR|FLASH_PGERR); + target_write_u32(target, STM32_FLASH_SR, FLASH_WRPRTERR|FLASH_PGERR); } return status; } @@ -134,26 +134,26 @@ static int stm32x_read_options(struct flash_bank_s *bank) u32 optiondata; stm32x_flash_bank_t *stm32x_info = NULL; target_t *target = bank->target; - + stm32x_info = bank->driver_priv; - + /* read current option bytes */ target_read_u32(target, STM32_FLASH_OBR, &optiondata); - + stm32x_info->option_bytes.user_options = (u16)0xFFF8|((optiondata >> 2) & 0x07); stm32x_info->option_bytes.RDP = (optiondata & (1 << OPT_READOUT)) ? 0xFFFF : 0x5AA5; - + if (optiondata & (1 << OPT_READOUT)) LOG_INFO("Device Security Bit Set"); - + /* each bit refers to a 4bank protection */ target_read_u32(target, STM32_FLASH_WRPR, &optiondata); - + stm32x_info->option_bytes.protection[0] = (u16)optiondata; stm32x_info->option_bytes.protection[1] = (u16)(optiondata >> 8); stm32x_info->option_bytes.protection[2] = (u16)(optiondata >> 16); stm32x_info->option_bytes.protection[3] = (u16)(optiondata >> 24); - + return ERROR_OK; } @@ -162,35 +162,35 @@ static int stm32x_erase_options(struct flash_bank_s *bank) stm32x_flash_bank_t *stm32x_info = NULL; target_t *target = bank->target; u32 status; - + stm32x_info = bank->driver_priv; - + /* read current options */ stm32x_read_options(bank); - + /* 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; - + /* clear readout protection and complementary option bytes * this will also force a device unlock if set */ stm32x_info->option_bytes.RDP = 0x5AA5; - + return ERROR_OK; } @@ -199,82 +199,82 @@ static int stm32x_write_options(struct flash_bank_s *bank) stm32x_flash_bank_t *stm32x_info = NULL; target_t *target = bank->target; u32 status; - + stm32x_info = bank->driver_priv; - + /* 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 user option byte */ target_write_u16(target, STM32_OB_USER, stm32x_info->option_bytes.user_options); - + 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; - + /* write protection byte 1 */ target_write_u16(target, STM32_OB_WRP0, stm32x_info->option_bytes.protection[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; - + /* write protection byte 2 */ target_write_u16(target, STM32_OB_WRP1, stm32x_info->option_bytes.protection[1]); - + 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; - + /* write protection byte 3 */ target_write_u16(target, STM32_OB_WRP2, stm32x_info->option_bytes.protection[2]); - + 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; - + /* write protection byte 4 */ target_write_u16(target, STM32_OB_WRP3, stm32x_info->option_bytes.protection[3]); - + 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; - + /* write readout protection bit */ target_write_u16(target, STM32_OB_RDP, stm32x_info->option_bytes.RDP); - + 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; } @@ -282,70 +282,70 @@ static int stm32x_protect_check(struct flash_bank_s *bank) { target_t *target = bank->target; stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - + u32 protection; int i, s; int num_bits; int set; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - - /* medium density - each bit refers to a 4bank protection + + /* medium density - each bit refers to a 4bank protection * high density - each bit refers to a 2bank protection */ target_read_u32(target, STM32_FLASH_WRPR, &protection); - + /* medium density - each protection bit is for 4 * 1K pages * high density - each protection bit is for 2 * 2K pages */ num_bits = (bank->num_sectors / stm32x_info->ppage_size); - + if (stm32x_info->ppage_size == 2) { /* high density flash */ - + set = 1; - + if (protection & (1 << 31)) set = 0; - - /* bit 31 controls sector 62 - 255 protection */ + + /* bit 31 controls sector 62 - 255 protection */ for (s = 62; s < bank->num_sectors; s++) { bank->sectors[s].is_protected = set; } - + if (bank->num_sectors > 61) num_bits = 31; - + for (i = 0; i < num_bits; i++) { set = 1; - + if (protection & (1 << i)) set = 0; - + for (s = 0; s < stm32x_info->ppage_size; s++) bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set; } } else - { + { /* medium density flash */ for (i = 0; i < num_bits; i++) { set = 1; - + if( protection & (1 << i)) set = 0; - + for (s = 0; s < stm32x_info->ppage_size; s++) bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set; } } - + return ERROR_OK; } @@ -354,30 +354,30 @@ static int stm32x_erase(struct flash_bank_s *bank, int first, int last) target_t *target = bank->target; int i; u32 status; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if ((first == 0) && (last == (bank->num_sectors - 1))) { return stm32x_mass_erase(bank); } - + /* unlock flash registers */ target_write_u32(target, STM32_FLASH_KEYR, KEY1); target_write_u32(target, STM32_FLASH_KEYR, KEY2); - + 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 ) @@ -386,7 +386,7 @@ static int stm32x_erase(struct flash_bank_s *bank, int first, int last) } target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); - + return ERROR_OK; } @@ -398,34 +398,34 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las int i, reg, bit; int status; u32 protection; - + stm32x_info = bank->driver_priv; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if ((first && (first % stm32x_info->ppage_size)) || ((last + 1) && (last + 1) % stm32x_info->ppage_size)) { LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", stm32x_info->ppage_size); return ERROR_FLASH_SECTOR_INVALID; } - - /* medium density - each bit refers to a 4bank protection + + /* medium density - each bit refers to a 4bank protection * high density - each bit refers to a 2bank protection */ target_read_u32(target, STM32_FLASH_WRPR, &protection); - + prot_reg[0] = (u16)protection; prot_reg[1] = (u16)(protection >> 8); prot_reg[2] = (u16)(protection >> 16); prot_reg[3] = (u16)(protection >> 24); - + if (stm32x_info->ppage_size == 2) { /* high density flash */ - + /* bit 7 controls sector 62 - 255 protection */ if (last > 61) { @@ -434,17 +434,17 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las else prot_reg[3] |= (1 << 7); } - + if (first > 61) first = 62; if (last > 61) last = 61; - + for (i = first; i <= last; i++) { reg = (i / stm32x_info->ppage_size) / 8; bit = (i / stm32x_info->ppage_size) - (reg * 8); - + if( set ) prot_reg[reg] &= ~(1 << bit); else @@ -458,22 +458,22 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las { reg = (i / stm32x_info->ppage_size) / 8; bit = (i / stm32x_info->ppage_size) - (reg * 8); - + if( set ) prot_reg[reg] &= ~(1 << bit); else prot_reg[reg] |= (1 << bit); } } - + if ((status = stm32x_erase_options(bank)) != ERROR_OK) return status; - + stm32x_info->option_bytes.protection[0] = prot_reg[0]; stm32x_info->option_bytes.protection[1] = prot_reg[1]; stm32x_info->option_bytes.protection[2] = prot_reg[2]; stm32x_info->option_bytes.protection[3] = prot_reg[3]; - + return stm32x_write_options(bank); } @@ -487,7 +487,7 @@ static int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, reg_param_t reg_params[4]; armv7m_algorithm_t armv7m_info; int retval = ERROR_OK; - + u8 stm32x_flash_write_code[] = { /* write: */ 0xDF, 0xF8, 0x24, 0x40, /* ldr r4, STM32_FLASH_CR */ @@ -509,14 +509,14 @@ static int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, 0x10, 0x20, 0x02, 0x40, /* STM32_FLASH_CR: .word 0x40022010 */ 0x0C, 0x20, 0x02, 0x40 /* STM32_FLASH_SR: .word 0x4002200C */ }; - + /* flash write code */ if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code), &stm32x_info->write_algorithm) != ERROR_OK) { LOG_WARNING("no working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; }; - + if ((retval=target_write_buffer(target, stm32x_info->write_algorithm->address, sizeof(stm32x_flash_write_code), stm32x_flash_write_code))!=ERROR_OK) return retval; @@ -529,31 +529,31 @@ static int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, /* 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); - + LOG_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; - + 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); - + while (count > 0) { u32 thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count; - + if ((retval = target_write_buffer(target, source->address, thisrun_count * 2, buffer))!=ERROR_OK) break; - + 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_run_algorithm(target, 0, NULL, 4, reg_params, stm32x_info->write_algorithm->address, \ stm32x_info->write_algorithm->address + (sizeof(stm32x_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK) { @@ -561,38 +561,38 @@ static int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, retval = ERROR_FLASH_OPERATION_FAILED; break; } - + if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_PGERR) { LOG_ERROR("flash memory not erased before writing"); /* Clear but report errors */ - target_write_u32(target, STM32_FLASH_SR, FLASH_PGERR); + target_write_u32(target, STM32_FLASH_SR, FLASH_PGERR); retval = ERROR_FLASH_OPERATION_FAILED; break; } - + if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_WRPRTERR) { LOG_ERROR("flash memory write protected"); /* Clear but report errors */ - target_write_u32(target, STM32_FLASH_SR, FLASH_WRPRTERR); + target_write_u32(target, STM32_FLASH_SR, FLASH_WRPRTERR); retval = ERROR_FLASH_OPERATION_FAILED; break; } - + buffer += thisrun_count * 2; address += thisrun_count * 2; count -= thisrun_count; } - + target_free_working_area(target, source); target_free_working_area(target, stm32x_info->write_algorithm); - + destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); - + return retval; } @@ -605,7 +605,7 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c u32 bytes_written = 0; u8 status; int retval; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -617,13 +617,13 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c LOG_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) + if (words_remaining > 0) { /* try using a block write */ if ((retval = stm32x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK) @@ -631,7 +631,7 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ + * we use normal (slow) single dword accesses */ LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); } else if (retval == ERROR_FLASH_OPERATION_FAILED) @@ -655,9 +655,9 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c target_write_u32(target, STM32_FLASH_CR, FLASH_PG); target_write_u16(target, address, value); - + status = stm32x_wait_status_busy(bank, 5); - + if( status & FLASH_WRPRTERR ) { LOG_ERROR("flash memory not erased before writing"); @@ -673,7 +673,7 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c words_remaining--; address += 2; } - + if (bytes_remaining) { u16 value = 0xffff; @@ -681,9 +681,9 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c target_write_u32(target, STM32_FLASH_CR, FLASH_PG); target_write_u16(target, address, value); - + status = stm32x_wait_status_busy(bank, 5); - + if( status & FLASH_WRPRTERR ) { LOG_ERROR("flash memory not erased before writing"); @@ -695,9 +695,9 @@ static int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 c return ERROR_FLASH_OPERATION_FAILED; } } - + target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); - + return ERROR_OK; } @@ -709,7 +709,7 @@ static int stm32x_probe(struct flash_bank_s *bank) u16 num_pages; u32 device_id; int page_size; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -717,25 +717,25 @@ static int stm32x_probe(struct flash_bank_s *bank) } stm32x_info->probed = 0; - + /* read stm32 device id register */ target_read_u32(target, 0xE0042000, &device_id); LOG_INFO( "device id = 0x%08x", device_id ); - + /* get flash size from target */ if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK) { /* failed reading flash size, default to max target family */ num_pages = 0xffff; } - + if ((device_id & 0x7ff) == 0x410) { /* medium density - we have 1k pages * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; - + /* check for early silicon */ if (num_pages == 0xffff) { @@ -750,7 +750,7 @@ static int stm32x_probe(struct flash_bank_s *bank) * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; - + /* check for early silicon */ if (num_pages == 0xffff) { @@ -765,7 +765,7 @@ static int stm32x_probe(struct flash_bank_s *bank) * 2 pages for a protection area */ page_size = 2048; stm32x_info->ppage_size = 2; - + /* check for early silicon */ if (num_pages == 0xffff) { @@ -780,7 +780,7 @@ static int stm32x_probe(struct flash_bank_s *bank) * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; - + /* check for early silicon */ if (num_pages == 0xffff) { @@ -794,17 +794,17 @@ static int stm32x_probe(struct flash_bank_s *bank) LOG_WARNING( "Cannot identify target as a STM32 family." ); return ERROR_FLASH_OPERATION_FAILED; } - + LOG_INFO( "flash size = %dkbytes", num_pages ); - + /* calculate numbers of pages */ num_pages /= (page_size / 1024); - + bank->base = 0x08000000; bank->size = (num_pages * page_size); bank->num_sectors = num_pages; bank->sectors = malloc(sizeof(flash_sector_t) * num_pages); - + for (i = 0; i < num_pages; i++) { bank->sectors[i].offset = i * page_size; @@ -812,9 +812,9 @@ static int stm32x_probe(struct flash_bank_s *bank) bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - + stm32x_info->probed = 1; - + return ERROR_OK; } @@ -838,34 +838,34 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) target_t *target = bank->target; u32 device_id; int printed; - + /* read stm32 device id register */ target_read_u32(target, 0xE0042000, &device_id); - + if ((device_id & 0x7ff) == 0x410) { printed = snprintf(buf, buf_size, "stm32x (Medium Density) - Rev: "); buf += printed; buf_size -= printed; - + switch(device_id >> 16) { case 0x0000: snprintf(buf, buf_size, "A"); break; - + case 0x2000: snprintf(buf, buf_size, "B"); break; - + case 0x2001: snprintf(buf, buf_size, "Z"); break; - + case 0x2003: snprintf(buf, buf_size, "Y"); break; - + default: snprintf(buf, buf_size, "unknown"); break; @@ -876,13 +876,13 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) printed = snprintf(buf, buf_size, "stm32x (Low Density) - Rev: "); buf += printed; buf_size -= printed; - + switch(device_id >> 16) { case 0x1000: snprintf(buf, buf_size, "A"); break; - + default: snprintf(buf, buf_size, "unknown"); break; @@ -893,17 +893,17 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) printed = snprintf(buf, buf_size, "stm32x (High Density) - Rev: "); buf += printed; buf_size -= printed; - + switch(device_id >> 16) { case 0x1000: snprintf(buf, buf_size, "A"); break; - + case 0x1001: snprintf(buf, buf_size, "Z"); break; - + default: snprintf(buf, buf_size, "unknown"); break; @@ -914,7 +914,7 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) printed = snprintf(buf, buf_size, "stm32x (Connectivity) - Rev: "); buf += printed; buf_size -= printed; - + switch(device_id >> 16) { case 0x1000: @@ -931,7 +931,7 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) snprintf(buf, buf_size, "Cannot identify target as a stm32x\n"); return ERROR_FLASH_OPERATION_FAILED; } - + return ERROR_OK; } @@ -940,47 +940,47 @@ static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *c flash_bank_t *bank; target_t *target = NULL; stm32x_flash_bank_t *stm32x_info = NULL; - + if (argc < 1) { command_print(cmd_ctx, "stm32x lock <bank>"); - return ERROR_OK; + 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 = bank->target; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if (stm32x_erase_options(bank) != ERROR_OK) { command_print(cmd_ctx, "stm32x failed to erase options"); return ERROR_OK; } - - /* set readout protection */ + + /* set readout protection */ stm32x_info->option_bytes.RDP = 0; - + if (stm32x_write_options(bank) != ERROR_OK) { command_print(cmd_ctx, "stm32x failed to lock device"); return ERROR_OK; } - + command_print(cmd_ctx, "stm32x locked"); - + return ERROR_OK; } @@ -989,44 +989,44 @@ static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char flash_bank_t *bank; target_t *target = NULL; stm32x_flash_bank_t *stm32x_info = NULL; - + if (argc < 1) { command_print(cmd_ctx, "stm32x unlock <bank>"); - return ERROR_OK; + 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 = bank->target; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if (stm32x_erase_options(bank) != ERROR_OK) { command_print(cmd_ctx, "stm32x failed to unlock device"); return ERROR_OK; } - + if (stm32x_write_options(bank) != ERROR_OK) { command_print(cmd_ctx, "stm32x failed to lock device"); return ERROR_OK; } - + command_print(cmd_ctx, "stm32x unlocked"); - + return ERROR_OK; } @@ -1036,56 +1036,56 @@ static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, 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; + 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 = bank->target; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + 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; } @@ -1095,30 +1095,30 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx target_t *target = NULL; stm32x_flash_bank_t *stm32x_info = NULL; u16 optionbyte = 0xF8; - + if (argc < 4) { command_print(cmd_ctx, "stm32x options_write <bank> <SWWDG|HWWDG> <RSTSTNDBY|NORSTSTNDBY> <RSTSTOP|NORSTSTOP>"); 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 = bank->target; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + if (strcmp(args[1], "SWWDG") == 0) { optionbyte |= (1<<0); @@ -1127,7 +1127,7 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx { optionbyte &= ~(1<<0); } - + if (strcmp(args[2], "NORSTSTNDBY") == 0) { optionbyte |= (1<<1); @@ -1136,7 +1136,7 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx { optionbyte &= ~(1<<1); } - + if (strcmp(args[3], "NORSTSTOP") == 0) { optionbyte |= (1<<2); @@ -1145,23 +1145,23 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx { optionbyte &= ~(1<<2); } - + if (stm32x_erase_options(bank) != ERROR_OK) { command_print(cmd_ctx, "stm32x failed to erase options"); return ERROR_OK; } - + stm32x_info->option_bytes.user_options = optionbyte; - + if (stm32x_write_options(bank) != ERROR_OK) { command_print(cmd_ctx, "stm32x failed to write options"); return ERROR_OK; } - + command_print(cmd_ctx, "stm32x write options complete"); - + return ERROR_OK; } @@ -1169,37 +1169,37 @@ static int stm32x_mass_erase(struct flash_bank_s *bank) { target_t *target = bank->target; u32 status; - + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not 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); - + target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); - + if( status & FLASH_WRPRTERR ) { LOG_ERROR("stm32x device protected"); return ERROR_OK; } - + if( status & FLASH_PGERR ) { LOG_ERROR("stm32x device programming failed"); return ERROR_OK; } - + return ERROR_OK; } @@ -1207,20 +1207,20 @@ static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, c { flash_bank_t *bank; int i; - + if (argc < 1) { command_print(cmd_ctx, "stm32x mass_erase <bank>"); - return ERROR_OK; + 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; } - + if (stm32x_mass_erase(bank) == ERROR_OK) { /* set all sectors as erased */ @@ -1228,13 +1228,13 @@ static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, c { bank->sectors[i].is_erased = 1; } - + command_print(cmd_ctx, "stm32x mass erase complete"); } else { command_print(cmd_ctx, "stm32x mass erase failed"); } - + return ERROR_OK; } diff --git a/src/flash/str9x.c b/src/flash/str9x.c index 3566bf9..b949065 100644 --- a/src/flash/str9x.c +++ b/src/flash/str9x.c @@ -63,26 +63,26 @@ flash_driver_t str9x_flash = static int str9x_register_commands(struct command_context_s *cmd_ctx) { command_t *str9x_cmd = register_command(cmd_ctx, NULL, "str9x", NULL, COMMAND_ANY, NULL); - + register_command(cmd_ctx, str9x_cmd, "flash_config", str9x_handle_flash_config_command, COMMAND_EXEC, "configure str9 flash controller"); - + return ERROR_OK; } static int str9x_build_block_list(struct flash_bank_s *bank) { str9x_flash_bank_t *str9x_info = bank->driver_priv; - + int i; int num_sectors; int b0_sectors = 0, b1_sectors = 0; u32 offset = 0; - + /* set if we have large flash str9 */ str9x_info->variant = 0; str9x_info->bank1 = 0; - + switch (bank->size) { case (256 * 1024): @@ -116,15 +116,15 @@ static int str9x_build_block_list(struct flash_bank_s *bank) LOG_ERROR("BUG: unknown bank->size encountered"); exit(-1); } - + num_sectors = b0_sectors + b1_sectors; - + bank->num_sectors = num_sectors; bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors); str9x_info->sector_bits = malloc(sizeof(u32) * num_sectors); - + num_sectors = 0; - + for (i = 0; i < b0_sectors; i++) { bank->sectors[num_sectors].offset = offset; @@ -147,7 +147,7 @@ static int str9x_build_block_list(struct flash_bank_s *bank) else str9x_info->sector_bits[num_sectors++] = (1<<(i+8)); } - + return ERROR_OK; } @@ -157,20 +157,20 @@ static int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { str9x_flash_bank_t *str9x_info; - + if (argc < 6) { LOG_WARNING("incomplete flash_bank str9x configuration"); return ERROR_FLASH_BANK_INVALID; } - + str9x_info = malloc(sizeof(str9x_flash_bank_t)); bank->driver_priv = str9x_info; - + str9x_build_block_list(bank); - + str9x_info->write_algorithm = NULL; - + return ERROR_OK; } @@ -179,7 +179,7 @@ static int str9x_protect_check(struct flash_bank_s *bank) int retval; str9x_flash_bank_t *str9x_info = bank->driver_priv; target_t *target = bank->target; - + int i; u32 adr; u32 status = 0; @@ -192,7 +192,7 @@ static int str9x_protect_check(struct flash_bank_s *bank) } /* read level one protection */ - + if (str9x_info->variant) { if (str9x_info->bank1) @@ -234,13 +234,13 @@ static int str9x_protect_check(struct flash_bank_s *bank) } status = hstatus; } - + /* read array command */ if ((retval=target_write_u16(target, adr, 0xFF))!=ERROR_OK) { return retval; } - + for (i = 0; i < bank->num_sectors; i++) { if (status & str9x_info->sector_bits[i]) @@ -248,7 +248,7 @@ static int str9x_protect_check(struct flash_bank_s *bank) else bank->sectors[i].is_protected = 0; } - + return ERROR_OK; } @@ -259,7 +259,7 @@ static int str9x_erase(struct flash_bank_s *bank, int first, int last) u32 adr; u8 status; u8 erase_cmd; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -277,12 +277,12 @@ static int str9x_erase(struct flash_bank_s *bank, int first, int last) /* Erase sector command */ erase_cmd = 0x20; } - + for (i = first; i <= last; i++) { int retval; adr = bank->base + bank->sectors[i].offset; - + /* erase sectors */ if ((retval=target_write_u16(target, adr, erase_cmd))!=ERROR_OK) { @@ -292,14 +292,14 @@ static int str9x_erase(struct flash_bank_s *bank, int first, int last) { return retval; } - + /* get status */ if ((retval=target_write_u16(target, adr, 0x70))!=ERROR_OK) { return retval; } - int timeout; + int timeout; for (timeout=0; timeout<1000; timeout++) { if ((retval=target_read_u8(target, adr, &status))!=ERROR_OK) { @@ -314,30 +314,30 @@ static int str9x_erase(struct flash_bank_s *bank, int first, int last) LOG_ERROR("erase timed out"); return ERROR_FAIL; } - + /* clear status, also clear read array */ if ((retval=target_write_u16(target, adr, 0x50))!=ERROR_OK) { return retval; } - + /* read array command */ if ((retval=target_write_u16(target, adr, 0xFF))!=ERROR_OK) { return retval; } - + if( status & 0x22 ) { LOG_ERROR("error erasing flash bank, status: 0x%x", status); return ERROR_FLASH_OPERATION_FAILED; } - + /* If we ran erase bank command, we are finished */ if (erase_cmd == 0x80) break; } - + for (i = first; i <= last; i++) bank->sectors[i].is_erased = 1; @@ -351,35 +351,35 @@ static int str9x_protect(struct flash_bank_s *bank, int i; u32 adr; u8 status; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + for (i = first; i <= last; i++) { /* Level One Protection */ - + adr = bank->base + bank->sectors[i].offset; - + target_write_u16(target, adr, 0x60); if( set ) target_write_u16(target, adr, 0x01); else target_write_u16(target, adr, 0xD0); - + /* query status */ target_read_u8(target, adr, &status); - + /* clear status, also clear read array */ target_write_u16(target, adr, 0x50); - + /* read array command */ target_write_u16(target, adr, 0xFF); } - + return ERROR_OK; } @@ -394,7 +394,7 @@ static int str9x_write_block(struct flash_bank_s *bank, reg_param_t reg_params[4]; armv4_5_algorithm_t armv4_5_info; int retval = ERROR_OK; - + u32 str9x_flash_write_code[] = { /* write: */ 0xe3c14003, /* bic r4, r1, #3 */ @@ -419,14 +419,14 @@ static int str9x_write_block(struct flash_bank_s *bank, /* exit: */ 0xeafffffe, /* b exit */ }; - + /* flash write code */ if (target_alloc_working_area(target, 4 * 19, &str9x_info->write_algorithm) != ERROR_OK) { LOG_WARNING("no working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; }; - + target_write_buffer(target, str9x_info->write_algorithm->address, 19 * 4, (u8*)str9x_flash_write_code); /* memory buffer */ @@ -438,27 +438,27 @@ static int str9x_write_block(struct flash_bank_s *bank, /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */ if (str9x_info->write_algorithm) target_free_working_area(target, str9x_info->write_algorithm); - + LOG_WARNING("no large enough working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } } - + armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC; armv4_5_info.core_mode = ARMV4_5_MODE_SVC; armv4_5_info.core_state = ARMV4_5_STATE_ARM; - + 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); - + 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); @@ -469,26 +469,26 @@ static int str9x_write_block(struct flash_bank_s *bank, retval = ERROR_FLASH_OPERATION_FAILED; break; } - + if (buf_get_u32(reg_params[3].value, 0, 32) != 0x80) { retval = ERROR_FLASH_OPERATION_FAILED; break; } - + buffer += thisrun_count * 2; address += thisrun_count * 2; count -= thisrun_count; } - + target_free_working_area(target, source); target_free_working_area(target, str9x_info->write_algorithm); - + destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); - + return retval; } @@ -505,7 +505,7 @@ static int str9x_write(struct flash_bank_s *bank, u32 check_address = offset; u32 bank_adr; int i; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -517,12 +517,12 @@ static int str9x_write(struct flash_bank_s *bank, LOG_WARNING("offset 0x%x breaks required 2-byte alignment", offset); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } - + for (i = 0; i < bank->num_sectors; i++) { u32 sec_start = bank->sectors[i].offset; u32 sec_end = sec_start + bank->sectors[i].size; - + /* check if destination falls within the current sector */ if ((check_address >= sec_start) && (check_address < sec_end)) { @@ -533,12 +533,12 @@ static int str9x_write(struct flash_bank_s *bank, check_address = sec_end; } } - + if (check_address != offset + count) return ERROR_FLASH_DST_OUT_OF_BANK; - + /* multiple half words (2-byte) to be programmed? */ - if (words_remaining > 0) + if (words_remaining > 0) { /* try using a block write */ if ((retval = str9x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK) @@ -546,7 +546,7 @@ static int str9x_write(struct flash_bank_s *bank, if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ + * we use normal (slow) single dword accesses */ LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); } else if (retval == ERROR_FLASH_OPERATION_FAILED) @@ -566,17 +566,17 @@ static int str9x_write(struct flash_bank_s *bank, while (words_remaining > 0) { bank_adr = address & ~0x03; - + /* write data command */ target_write_u16(target, bank_adr, 0x40); target_write_memory(target, address, 2, 1, buffer + bytes_written); - + /* get status command */ target_write_u16(target, bank_adr, 0x70); - + int timeout; for (timeout=0; timeout<1000; timeout++) - { + { target_read_u8(target, bank_adr, &status); if( status & 0x80 ) break; @@ -587,11 +587,11 @@ static int str9x_write(struct flash_bank_s *bank, LOG_ERROR("write timed out"); return ERROR_FAIL; } - + /* clear status reg and read array */ target_write_u16(target, bank_adr, 0x50); target_write_u16(target, bank_adr, 0xFF); - + if (status & 0x10) return ERROR_FLASH_OPERATION_FAILED; else if (status & 0x02) @@ -601,31 +601,31 @@ static int str9x_write(struct flash_bank_s *bank, 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); + last_halfword[i++] = *(buffer + bytes_written); bytes_remaining--; bytes_written++; } - + bank_adr = address & ~0x03; - - /* write data comamnd */ + + /* write data command */ target_write_u16(target, bank_adr, 0x40); target_write_memory(target, address, 2, 1, last_halfword); - + /* query status command */ target_write_u16(target, bank_adr, 0x70); - + int timeout; for (timeout=0; timeout<1000; timeout++) - { + { target_read_u8(target, bank_adr, &status); if( status & 0x80 ) break; @@ -636,17 +636,17 @@ static int str9x_write(struct flash_bank_s *bank, LOG_ERROR("write timed out"); return ERROR_FAIL; } - + /* clear status reg and read array */ target_write_u16(target, bank_adr, 0x50); target_write_u16(target, bank_adr, 0xFF); - + if (status & 0x10) return ERROR_FLASH_OPERATION_FAILED; else if (status & 0x02) return ERROR_FLASH_OPERATION_FAILED; } - + return ERROR_OK; } @@ -675,29 +675,29 @@ static int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, str9x_flash_bank_t *str9x_info; flash_bank_t *bank; target_t *target = NULL; - + if (argc < 5) { return ERROR_COMMAND_SYNTAX_ERROR; } - + 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; } - + str9x_info = bank->driver_priv; - + target = bank->target; - + if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - + /* config flash controller */ target_write_u32(target, FLASH_BBSR, strtoul(args[1], NULL, 0)); target_write_u32(target, FLASH_NBBSR, strtoul(args[2], NULL, 0)); @@ -706,7 +706,7 @@ static int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, /* set bit 18 instruction TCM order as per flash programming manual */ arm966e_write_cp15(target, 62, 0x40000); - + /* enable flash bank 1 */ target_write_u32(target, FLASH_CR, 0x18); return ERROR_OK; diff --git a/src/flash/str9xpec.c b/src/flash/str9xpec.c index 5e9f438..1ea8176 100644 --- a/src/flash/str9xpec.c +++ b/src/flash/str9xpec.c @@ -113,12 +113,7 @@ int str9xpec_set_instr(jtag_tap_t *tap, u32 new_instr, tap_state_t end_state) field.num_bits = tap->ir_length; field.out_value = calloc(CEIL(field.num_bits, 8), 1); buf_set_u32(field.out_value, 0, field.num_bits, new_instr); - field.in_value = NULL; - - - - jtag_add_ir_scan(1, &field, end_state); @@ -139,12 +134,8 @@ static u8 str9xpec_isc_status(jtag_tap_t *tap) field.tap = tap; field.num_bits = 8; field.out_value = NULL; - field.in_value = &status; - - - - + jtag_add_dr_scan(1, &field, TAP_IDLE); jtag_execute_queue(); @@ -231,12 +222,8 @@ static int str9xpec_read_config(struct flash_bank_s *bank) field.tap = tap; field.num_bits = 64; field.out_value = NULL; - field.in_value = str9xpec_info->options; - - - - + jtag_add_dr_scan(1, &field, TAP_IDLE); jtag_execute_queue(); @@ -383,12 +370,7 @@ static int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last) field.tap = tap; field.num_bits = 64; field.out_value = buffer; - field.in_value = NULL; - - - - jtag_add_dr_scan(1, &field, TAP_IDLE); jtag_add_sleep(40000); @@ -397,12 +379,7 @@ static int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last) field.tap = tap; field.num_bits = 64; field.out_value = NULL; - field.in_value = buffer; - - - - jtag_add_dr_scan(1, &field, TAP_IRPAUSE); jtag_execute_queue(); @@ -499,12 +476,7 @@ static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last) field.tap = tap; field.num_bits = 64; field.out_value = buffer; - field.in_value = NULL; - - - - jtag_add_dr_scan(1, &field, TAP_IDLE); jtag_execute_queue(); @@ -565,12 +537,7 @@ static int str9xpec_lock_device(struct flash_bank_s *bank) field.tap = tap; field.num_bits = 8; field.out_value = NULL; - field.in_value = &status; - - - - jtag_add_dr_scan(1, &field, TAP_INVALID); jtag_execute_queue(); @@ -651,12 +618,7 @@ static int str9xpec_set_address(struct flash_bank_s *bank, u8 sector) field.tap = tap; field.num_bits = 8; field.out_value = §or; - field.in_value = NULL; - - - - jtag_add_dr_scan(1, &field, TAP_INVALID); @@ -740,12 +702,7 @@ static int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 field.tap = tap; field.num_bits = 64; field.out_value = (buffer + bytes_written); - field.in_value = NULL; - - - - jtag_add_dr_scan(1, &field, TAP_IDLE); @@ -758,12 +715,7 @@ static int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 field.tap = tap; field.num_bits = 8; field.out_value = NULL; - field.in_value = scanbuf; - - - - jtag_add_dr_scan(1, &field, TAP_INVALID); jtag_execute_queue(); @@ -800,12 +752,7 @@ static int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 field.tap = tap; field.num_bits = 64; field.out_value = last_dword; - field.in_value = NULL; - - - - jtag_add_dr_scan(1, &field, TAP_IDLE); @@ -818,12 +765,7 @@ static int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 field.tap = tap; field.num_bits = 8; field.out_value = NULL; - field.in_value = scanbuf; - - - - jtag_add_dr_scan(1, &field, TAP_INVALID); jtag_execute_queue(); @@ -882,12 +824,7 @@ static int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, ch field.tap = tap; field.num_bits = 32; field.out_value = NULL; - field.in_value = buffer; - - - - jtag_add_dr_scan(1, &field, TAP_IDLE); jtag_execute_queue(); @@ -1007,12 +944,7 @@ static int str9xpec_write_options(struct flash_bank_s *bank) field.tap = tap; field.num_bits = 64; field.out_value = str9xpec_info->options; - field.in_value = NULL; - - - - jtag_add_dr_scan(1, &field, TAP_IDLE); @@ -1025,12 +957,7 @@ static int str9xpec_write_options(struct flash_bank_s *bank) field.tap = tap; field.num_bits = 8; field.out_value = NULL; - field.in_value = &status; - - - - jtag_add_dr_scan(1, &field, TAP_INVALID); jtag_execute_queue(); |