X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fkinetis.c;h=1d63352823e91961c4ee9a03efe96bb18cac336c;hp=2c2d062acd530507528061909bede1ebeaa17172;hb=bb1c7ae4ae23a507175e751c705ad543ea2e9953;hpb=e3f3b77729a07e8c0fa036c8ec1e021773142892 diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index 2c2d062acd..1d63352823 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -393,7 +393,7 @@ static bool fcf_fopt_configured; static bool create_banks; -struct flash_driver kinetis_flash; +const struct flash_driver kinetis_flash; static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count); static int kinetis_probe_chip(struct kinetis_chip *k_chip); @@ -915,13 +915,29 @@ FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command) } +static void kinetis_free_driver_priv(struct flash_bank *bank) +{ + struct kinetis_flash_bank *k_bank = bank->driver_priv; + if (k_bank == NULL) + return; + + struct kinetis_chip *k_chip = k_bank->k_chip; + if (k_chip == NULL) + return; + + k_chip->num_banks--; + if (k_chip->num_banks == 0) + free(k_chip); +} + + static int kinetis_create_missing_banks(struct kinetis_chip *k_chip) { unsigned bank_idx; unsigned num_blocks; struct kinetis_flash_bank *k_bank; struct flash_bank *bank; - char base_name[80], name[80], num[4]; + char base_name[69], name[80], num[4]; char *class, *p; num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks; @@ -932,19 +948,21 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip) bank = k_chip->banks[0].bank; if (bank && bank->name) { - strncpy(base_name, bank->name, sizeof(base_name)); + strncpy(base_name, bank->name, sizeof(base_name) - 1); + base_name[sizeof(base_name) - 1] = '\0'; p = strstr(base_name, ".pflash"); if (p) { *p = '\0'; if (k_chip->num_pflash_blocks > 1) { /* rename first bank if numbering is needed */ snprintf(name, sizeof(name), "%s.pflash0", base_name); - free((void *)bank->name); + free(bank->name); bank->name = strdup(name); } } } else { - strncpy(base_name, target_name(k_chip->target), sizeof(base_name)); + strncpy(base_name, target_name(k_chip->target), sizeof(base_name) - 1); + base_name[sizeof(base_name) - 1] = '\0'; p = strstr(base_name, ".cpu"); if (p) *p = '\0'; @@ -1017,7 +1035,7 @@ static int kinetis_disable_wdog_algo(struct target *target, size_t code_size, co armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.core_mode = ARM_MODE_THREAD; - init_reg_param(®_params[0], "r0", 32, PARAM_IN); + init_reg_param(®_params[0], "r0", 32, PARAM_OUT); buf_set_u32(reg_params[0].value, 0, 32, wdog_base); retval = target_run_algorithm(target, 0, NULL, 1, reg_params, @@ -1425,6 +1443,8 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf) kinetis_auto_probe(bank_iter); + assert(bank_iter->prot_blocks); + if (k_bank->flash_class == FC_PFLASH) { for (i = 0; i < bank_iter->num_prot_blocks; i++) { if (bank_iter->prot_blocks[i].is_protected == 1) @@ -1737,13 +1757,15 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer result = target_write_memory(bank->target, k_chip->progr_accel_ram, 4, size_aligned / 4, buffer_aligned); - LOG_DEBUG("section @ %08" PRIx32 " aligned begin %" PRIu32 ", end %" PRIu32, + LOG_DEBUG("section @ " TARGET_ADDR_FMT " aligned begin %" PRIu32 + ", end %" PRIu32, bank->base + offset, align_begin, align_end); } else result = target_write_memory(bank->target, k_chip->progr_accel_ram, 4, size_aligned / 4, buffer); - LOG_DEBUG("write section @ %08" PRIx32 " with length %" PRIu32 " bytes", + LOG_DEBUG("write section @ " TARGET_ADDR_FMT " with length %" PRIu32 + " bytes", bank->base + offset, size); if (result != ERROR_OK) { @@ -1758,12 +1780,14 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer 0, 0, 0, 0, &ftfx_fstat); if (result != ERROR_OK) { - LOG_ERROR("Error writing section at %08" PRIx32, bank->base + offset); + LOG_ERROR("Error writing section at " TARGET_ADDR_FMT, + bank->base + offset); break; } if (ftfx_fstat & 0x01) { - LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset); + LOG_ERROR("Flash write error at " TARGET_ADDR_FMT, + bank->base + offset); if (k_bank->prog_base == 0 && offset == FCF_ADDRESS + FCF_SIZE && (k_chip->flash_support & FS_WIDTH_256BIT)) { LOG_ERROR("Flash write immediately after the end of Flash Config Field shows error"); @@ -1802,7 +1826,7 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer, } } - LOG_DEBUG("flash write @ %08" PRIx32, bank->base + offset); + LOG_DEBUG("flash write @ " TARGET_ADDR_FMT, bank->base + offset); if (fallback == 0) { /* program section command */ @@ -1855,12 +1879,14 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer, 0, 0, 0, 0, &ftfx_fstat); if (result != ERROR_OK) { - LOG_ERROR("Error writing longword at %08" PRIx32, bank->base + offset); + LOG_ERROR("Error writing longword at " TARGET_ADDR_FMT, + bank->base + offset); break; } if (ftfx_fstat & 0x01) - LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset); + LOG_ERROR("Flash write error at " TARGET_ADDR_FMT, + bank->base + offset); buffer += 4; offset += 4; @@ -1996,7 +2022,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) unsigned cpu_mhz = 120; unsigned idx; bool use_nvm_marking = false; - char flash_marking[11], nvm_marking[2]; + char flash_marking[12], nvm_marking[2]; char name[40]; k_chip->probed = false; @@ -2187,6 +2213,17 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) cpu_mhz = 180; break; + case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX7: + /* K27FN2M0 */ + case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX8: + /* K28FN2M0 */ + k_chip->pflash_sector_size = 4<<10; + k_chip->max_flash_prog_size = 1<<10; + num_blocks = 4; + k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_ECC; + cpu_mhz = 150; + break; + case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX0: case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX1: case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX2: @@ -2589,7 +2626,10 @@ static int kinetis_probe(struct flash_bank *bank) unsigned num_blocks, first_nvm_bank; uint32_t size_k; struct kinetis_flash_bank *k_bank = bank->driver_priv; - struct kinetis_chip *k_chip = k_bank->k_chip; + struct kinetis_chip *k_chip; + + assert(k_bank); + k_chip = k_bank->k_chip; k_bank->probed = false; @@ -2740,7 +2780,7 @@ static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size) uint32_t size_k = bank->size / 1024; snprintf(buf, buf_size, - "%s %s: %" PRIu32 "k %s bank %s at 0x%08" PRIx32, + "%s %s: %" PRIu32 "k %s bank %s at " TARGET_ADDR_FMT, bank->driver->name, k_chip->name, size_k, bank_class_names[k_bank->flash_class], bank->name, bank->base); @@ -2860,7 +2900,7 @@ COMMAND_HANDLER(kinetis_nvm_partition) flex_nvm_partition_code = (uint8_t)((sim_fcfg1 >> 8) & 0x0f); switch (flex_nvm_partition_code) { case 0: - command_print(CMD_CTX, "No EEPROM backup, data flash only"); + command_print(CMD, "No EEPROM backup, data flash only"); break; case 1: case 2: @@ -2868,10 +2908,10 @@ COMMAND_HANDLER(kinetis_nvm_partition) case 4: case 5: case 6: - command_print(CMD_CTX, "EEPROM backup %d KB", 4 << flex_nvm_partition_code); + command_print(CMD, "EEPROM backup %d KB", 4 << flex_nvm_partition_code); break; case 8: - command_print(CMD_CTX, "No data flash, EEPROM backup only"); + command_print(CMD, "No data flash, EEPROM backup only"); break; case 0x9: case 0xA: @@ -2879,13 +2919,13 @@ COMMAND_HANDLER(kinetis_nvm_partition) case 0xC: case 0xD: case 0xE: - command_print(CMD_CTX, "data flash %d KB", 4 << (flex_nvm_partition_code & 7)); + command_print(CMD, "data flash %d KB", 4 << (flex_nvm_partition_code & 7)); break; case 0xf: - command_print(CMD_CTX, "No EEPROM backup, data flash only (DEPART not set)"); + command_print(CMD, "No EEPROM backup, data flash only (DEPART not set)"); break; default: - command_print(CMD_CTX, "Unsupported EEPROM backup size code 0x%02" PRIx8, flex_nvm_partition_code); + command_print(CMD, "Unsupported EEPROM backup size code 0x%02" PRIx8, flex_nvm_partition_code); } return ERROR_OK; @@ -2951,7 +2991,7 @@ COMMAND_HANDLER(kinetis_nvm_partition) if (result != ERROR_OK) return result; - command_print(CMD_CTX, "FlexNVM partition set. Please reset MCU."); + command_print(CMD, "FlexNVM partition set. Please reset MCU."); if (k_chip) { first_nvm_bank = k_chip->num_pflash_blocks; @@ -2961,7 +3001,7 @@ COMMAND_HANDLER(kinetis_nvm_partition) k_chip->probed = false; } - command_print(CMD_CTX, "FlexNVM banks will be re-probed to set new data flash size."); + command_print(CMD, "FlexNVM banks will be re-probed to set new data flash size."); return ERROR_OK; } @@ -2980,12 +3020,12 @@ COMMAND_HANDLER(kinetis_fcf_source_handler) } if (allow_fcf_writes) { - command_print(CMD_CTX, "Arbitrary Flash Configuration Field writes enabled."); - command_print(CMD_CTX, "Protection info writes to FCF disabled."); + command_print(CMD, "Arbitrary Flash Configuration Field writes enabled."); + command_print(CMD, "Protection info writes to FCF disabled."); LOG_WARNING("BEWARE: incorrect flash configuration may permanently lock the device."); } else { - command_print(CMD_CTX, "Protection info writes to Flash Configuration Field enabled."); - command_print(CMD_CTX, "Arbitrary FCF writes disabled. Mode safe from unwanted locking of the device."); + command_print(CMD, "Protection info writes to Flash Configuration Field enabled."); + command_print(CMD, "Arbitrary FCF writes disabled. Mode safe from unwanted locking of the device."); } return ERROR_OK; @@ -3000,7 +3040,7 @@ COMMAND_HANDLER(kinetis_fopt_handler) fcf_fopt = (uint8_t)strtoul(CMD_ARGV[0], NULL, 0); fcf_fopt_configured = true; } else { - command_print(CMD_CTX, "FCF_FOPT 0x%02" PRIx8, fcf_fopt); + command_print(CMD, "FCF_FOPT 0x%02" PRIx8, fcf_fopt); } return ERROR_OK; @@ -3039,7 +3079,8 @@ static const struct command_registration kinetis_security_command_handlers[] = { .usage = "", .handler = kinetis_mdm_mass_erase, }, - { .name = "reset", + { + .name = "reset", .mode = COMMAND_EXEC, .help = "Issue a reset via the MDM-AP", .usage = "", @@ -3091,6 +3132,7 @@ static const struct command_registration kinetis_exec_command_handlers[] = { .mode = COMMAND_CONFIG, .help = "Driver creates additional banks if device with two/four flash blocks is probed", .handler = kinetis_create_banks_handler, + .usage = "", }, COMMAND_REGISTRATION_DONE }; @@ -3108,7 +3150,7 @@ static const struct command_registration kinetis_command_handler[] = { -struct flash_driver kinetis_flash = { +const struct flash_driver kinetis_flash = { .name = "kinetis", .commands = kinetis_command_handler, .flash_bank_command = kinetis_flash_bank_command, @@ -3121,4 +3163,5 @@ struct flash_driver kinetis_flash = { .erase_check = kinetis_blank_check, .protect_check = kinetis_protect_check, .info = kinetis_info, + .free_driver_priv = kinetis_free_driver_priv, };