Commit 16f364a5 authored by Tomas Vanek's avatar Tomas Vanek Committed by Freddie Chopin
Browse files

flash Kinetis: add KV5x family



Real time control MCU has a Cortex-M7 and numerous changes in flash layout.
Introduced a new ID of MDM-AP.

While on it a LOG_DEBUG format error fixed.

Change-Id: I1018660ce0c3dd63ac5e2563408fabff3c3daef7
Signed-off-by: default avatarTomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/3900


Tested-by: jenkins
Reviewed-by: default avatarJoakim Nohlgård <joakim.nohlgard@eistec.se>
Reviewed-by: default avatarFreddie Chopin <freddie.chopin@gmail.com>
parent 97d29663
...@@ -209,6 +209,7 @@ ...@@ -209,6 +209,7 @@
#define KINETIS_SDID_FAMILYID_K2X 0x20000000 #define KINETIS_SDID_FAMILYID_K2X 0x20000000
#define KINETIS_SDID_FAMILYID_K3X 0x30000000 #define KINETIS_SDID_FAMILYID_K3X 0x30000000
#define KINETIS_SDID_FAMILYID_K4X 0x40000000 #define KINETIS_SDID_FAMILYID_K4X 0x40000000
#define KINETIS_SDID_FAMILYID_K5X 0x50000000
#define KINETIS_SDID_FAMILYID_K6X 0x60000000 #define KINETIS_SDID_FAMILYID_K6X 0x60000000
#define KINETIS_SDID_FAMILYID_K7X 0x70000000 #define KINETIS_SDID_FAMILYID_K7X 0x70000000
#define KINETIS_SDID_FAMILYID_K8X 0x80000000 #define KINETIS_SDID_FAMILYID_K8X 0x80000000
...@@ -228,10 +229,6 @@ struct kinetis_flash_bank { ...@@ -228,10 +229,6 @@ struct kinetis_flash_bank {
/* same as bank->base for pflash, differs for FlexNVM */ /* same as bank->base for pflash, differs for FlexNVM */
uint32_t protection_block; /* number of first protection block in this bank */ uint32_t protection_block; /* number of first protection block in this bank */
uint32_t sim_sdid;
uint32_t sim_fcfg1;
uint32_t sim_fcfg2;
enum { enum {
FC_AUTO = 0, FC_AUTO = 0,
FC_PFLASH, FC_PFLASH,
...@@ -247,7 +244,15 @@ struct kinetis_flash_bank { ...@@ -247,7 +244,15 @@ struct kinetis_flash_bank {
FS_INVALIDATE_CACHE_L = 0x10, /* using MCM->PLACR */ FS_INVALIDATE_CACHE_L = 0x10, /* using MCM->PLACR */
FS_INVALIDATE_CACHE_MSCM = 0x20, FS_INVALIDATE_CACHE_MSCM = 0x20,
FS_NO_CMD_BLOCKSTAT = 0x40, FS_NO_CMD_BLOCKSTAT = 0x40,
FS_WIDTH_256BIT = 0x80,
} flash_support; } flash_support;
/* device parameters - should be same for all probed banks of one device */
uint32_t sim_sdid;
uint32_t sim_fcfg1;
uint32_t sim_fcfg2;
uint32_t progr_accel_ram;
}; };
#define MDM_AP 1 #define MDM_AP 1
...@@ -605,6 +610,7 @@ deassert_reset_and_exit: ...@@ -605,6 +610,7 @@ deassert_reset_and_exit:
static const uint32_t kinetis_known_mdm_ids[] = { static const uint32_t kinetis_known_mdm_ids[] = {
0x001C0000, /* Kinetis-K Series */ 0x001C0000, /* Kinetis-K Series */
0x001C0020, /* Kinetis-L/M/V/E Series */ 0x001C0020, /* Kinetis-L/M/V/E Series */
0x001C0030, /* Kinetis with a Cortex-M7, in time of writing KV58 */
}; };
/* /*
...@@ -1251,7 +1257,7 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last) ...@@ -1251,7 +1257,7 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last)
bank->sectors[i].is_erased = 1; bank->sectors[i].is_erased = 1;
if (bank->base == 0 if (kinfo->prog_base == 0
&& bank->sectors[i].offset <= FCF_ADDRESS && bank->sectors[i].offset <= FCF_ADDRESS
&& bank->sectors[i].offset + bank->sectors[i].size > FCF_ADDRESS + FCF_SIZE) { && bank->sectors[i].offset + bank->sectors[i].size > FCF_ADDRESS + FCF_SIZE) {
if (allow_fcf_writes) { if (allow_fcf_writes) {
...@@ -1346,13 +1352,13 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer ...@@ -1346,13 +1352,13 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer
memset(buffer_aligned, 0xff, size_aligned); memset(buffer_aligned, 0xff, size_aligned);
memcpy(buffer_aligned + align_begin, buffer, size); memcpy(buffer_aligned + align_begin, buffer, size);
result = target_write_memory(bank->target, FLEXRAM, result = target_write_memory(bank->target, kinfo->progr_accel_ram,
4, size_aligned / 4, buffer_aligned); 4, size_aligned / 4, buffer_aligned);
LOG_DEBUG("section @ %08" PRIx32 " aligned begin %" PRIu32 ", end %" PRIu32, LOG_DEBUG("section @ %08" PRIx32 " aligned begin %" PRIu32 ", end %" PRIu32,
bank->base + offset, align_begin, align_end); bank->base + offset, align_begin, align_end);
} else } else
result = target_write_memory(bank->target, FLEXRAM, result = target_write_memory(bank->target, kinfo->progr_accel_ram,
4, size_aligned / 4, buffer); 4, size_aligned / 4, buffer);
LOG_DEBUG("write section @ %08" PRIx32 " with length %" PRIu32 " bytes", LOG_DEBUG("write section @ %08" PRIx32 " with length %" PRIu32 " bytes",
...@@ -1374,8 +1380,16 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer ...@@ -1374,8 +1380,16 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer
break; break;
} }
if (ftfx_fstat & 0x01) if (ftfx_fstat & 0x01) {
LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset); LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset);
if (kinfo->prog_base == 0 && offset == FCF_ADDRESS + FCF_SIZE
&& (kinfo->flash_support & FS_WIDTH_256BIT)) {
LOG_ERROR("Flash write immediately after the end of Flash Config Field shows error");
LOG_ERROR("because the flash memory is 256 bits wide (data were written correctly).");
LOG_ERROR("Either change the linker script to add a gap of 16 bytes after FCF");
LOG_ERROR("or set 'kinetis fcf_source write'");
}
}
buffer += size; buffer += size;
offset += size; offset += size;
...@@ -1405,7 +1419,7 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer, ...@@ -1405,7 +1419,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 @ %08" PRIx32, bank->base + offset);
if (fallback == 0) { if (fallback == 0) {
/* program section command */ /* program section command */
...@@ -1488,6 +1502,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer, ...@@ -1488,6 +1502,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
int result; int result;
bool set_fcf = false; bool set_fcf = false;
int sect = 0; int sect = 0;
struct kinetis_flash_bank *kinfo = bank->driver_priv;
result = kinetis_check_run_mode(bank->target); result = kinetis_check_run_mode(bank->target);
if (result != ERROR_OK) if (result != ERROR_OK)
...@@ -1498,7 +1513,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer, ...@@ -1498,7 +1513,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
if (result != ERROR_OK) if (result != ERROR_OK)
return result; return result;
if (bank->base == 0 && !allow_fcf_writes) { if (kinfo->prog_base == 0 && !allow_fcf_writes) {
if (bank->sectors[1].offset <= FCF_ADDRESS) if (bank->sectors[1].offset <= FCF_ADDRESS)
sect = 1; /* 1kb sector, FCF in 2nd sector */ sect = 1; /* 1kb sector, FCF in 2nd sector */
...@@ -1520,7 +1535,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer, ...@@ -1520,7 +1535,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
return result; return result;
} }
result = target_read_memory(bank->target, FCF_ADDRESS, 4, FCF_SIZE / 4, fcf_current); result = target_read_memory(bank->target, bank->base + FCF_ADDRESS, 4, FCF_SIZE / 4, fcf_current);
if (result == ERROR_OK && memcmp(fcf_current, fcf_buffer, FCF_SIZE) == 0) if (result == ERROR_OK && memcmp(fcf_current, fcf_buffer, FCF_SIZE) == 0)
set_fcf = false; set_fcf = false;
...@@ -1555,10 +1570,12 @@ static int kinetis_probe(struct flash_bank *bank) ...@@ -1555,10 +1570,12 @@ static int kinetis_probe(struct flash_bank *bank)
uint32_t nvm_size = 0, pf_size = 0, df_size = 0, ee_size = 0; uint32_t nvm_size = 0, pf_size = 0, df_size = 0, ee_size = 0;
unsigned num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0, first_nvm_bank = 0, unsigned num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0, first_nvm_bank = 0,
pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0; pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0;
unsigned maxaddr_shift = 13;
struct target *target = bank->target; struct target *target = bank->target;
struct kinetis_flash_bank *kinfo = bank->driver_priv; struct kinetis_flash_bank *kinfo = bank->driver_priv;
kinfo->probed = false; kinfo->probed = false;
kinfo->progr_accel_ram = FLEXRAM;
result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid); result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
if (result != ERROR_OK) if (result != ERROR_OK)
...@@ -1771,6 +1788,19 @@ static int kinetis_probe(struct flash_bank *bank) ...@@ -1771,6 +1788,19 @@ static int kinetis_probe(struct flash_bank *bank)
kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K; kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break; break;
case KINETIS_SDID_FAMILYID_K5X | KINETIS_SDID_SUBFAMID_KX6:
case KINETIS_SDID_FAMILYID_K5X | KINETIS_SDID_SUBFAMID_KX8:
/* KV5x: FTFE, 8kB sectors */
pflash_sector_size_bytes = 8<<10;
maxaddr_shift = 14;
kinfo->max_flash_prog_size = 1<<10;
num_blocks = 1;
kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_WIDTH_256BIT;
bank->base = 0x10000000;
kinfo->prog_base = 0;
kinfo->progr_accel_ram = 0x18000000;
break;
default: default:
LOG_ERROR("Unsupported KV FAMILYID SUBFAMID"); LOG_ERROR("Unsupported KV FAMILYID SUBFAMID");
} }
...@@ -1931,9 +1961,9 @@ static int kinetis_probe(struct flash_bank *bank) ...@@ -1931,9 +1961,9 @@ static int kinetis_probe(struct flash_bank *bank)
* Checking fcfg2_maxaddr0 later in this routine is pointless then * Checking fcfg2_maxaddr0 later in this routine is pointless then
*/ */
if (fcfg2_pflsh) if (fcfg2_pflsh)
pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks; pf_size = ((uint32_t)fcfg2_maxaddr0 << maxaddr_shift) * num_blocks;
else else
pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks / 2; pf_size = ((uint32_t)fcfg2_maxaddr0 << maxaddr_shift) * num_blocks / 2;
if (pf_size != 2048<<10) if (pf_size != 2048<<10)
LOG_WARNING("SIM_FCFG1 PFSIZE = 0xf: please check if pflash is %u KB", pf_size>>10); LOG_WARNING("SIM_FCFG1 PFSIZE = 0xf: please check if pflash is %u KB", pf_size>>10);
...@@ -1959,8 +1989,10 @@ static int kinetis_probe(struct flash_bank *bank) ...@@ -1959,8 +1989,10 @@ static int kinetis_probe(struct flash_bank *bank)
/* pflash, banks start at address zero */ /* pflash, banks start at address zero */
kinfo->flash_class = FC_PFLASH; kinfo->flash_class = FC_PFLASH;
bank->size = (pf_size / num_pflash_blocks); bank->size = (pf_size / num_pflash_blocks);
bank->base = 0x00000000 + bank->size * bank->bank_number; if (bank->base == 0) {
kinfo->prog_base = bank->base; bank->base = 0x00000000 + bank->size * bank->bank_number;
kinfo->prog_base = bank->base;
}
kinfo->sector_size = pflash_sector_size_bytes; kinfo->sector_size = pflash_sector_size_bytes;
/* pflash is divided into 32 protection areas for /* pflash is divided into 32 protection areas for
* parts with more than 32K of PFlash. For parts with * parts with more than 32K of PFlash. For parts with
...@@ -2013,16 +2045,16 @@ static int kinetis_probe(struct flash_bank *bank) ...@@ -2013,16 +2045,16 @@ static int kinetis_probe(struct flash_bank *bank)
return ERROR_FLASH_BANK_INVALID; return ERROR_FLASH_BANK_INVALID;
} }
if (bank->bank_number == 0 && ((uint32_t)fcfg2_maxaddr0 << 13) != bank->size) if (bank->bank_number == 0 && ((uint32_t)fcfg2_maxaddr0 << maxaddr_shift) != bank->size)
LOG_WARNING("MAXADDR0 0x%02" PRIx8 " check failed," LOG_WARNING("MAXADDR0 0x%02" PRIx8 " check failed,"
" please report to OpenOCD mailing list", fcfg2_maxaddr0); " please report to OpenOCD mailing list", fcfg2_maxaddr0);
if (fcfg2_pflsh) { if (fcfg2_pflsh) {
if (bank->bank_number == 1 && ((uint32_t)fcfg2_maxaddr1 << 13) != bank->size) if (bank->bank_number == 1 && ((uint32_t)fcfg2_maxaddr1 << maxaddr_shift) != bank->size)
LOG_WARNING("MAXADDR1 0x%02" PRIx8 " check failed," LOG_WARNING("MAXADDR1 0x%02" PRIx8 " check failed,"
" please report to OpenOCD mailing list", fcfg2_maxaddr1); " please report to OpenOCD mailing list", fcfg2_maxaddr1);
} else { } else {
if ((unsigned)bank->bank_number == first_nvm_bank if ((unsigned)bank->bank_number == first_nvm_bank
&& ((uint32_t)fcfg2_maxaddr1 << 13) != df_size) && ((uint32_t)fcfg2_maxaddr1 << maxaddr_shift) != df_size)
LOG_WARNING("FlexNVM MAXADDR1 0x%02" PRIx8 " check failed," LOG_WARNING("FlexNVM MAXADDR1 0x%02" PRIx8 " check failed,"
" please report to OpenOCD mailing list", fcfg2_maxaddr1); " please report to OpenOCD mailing list", fcfg2_maxaddr1);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment