kinetis: macro organization and clearer function naming

Signed-off-by: Rafael Silva <perigoso@riseup.net>
This commit is contained in:
Rafael Silva 2022-07-02 03:11:55 +01:00 committed by Piotr Esden-Tempski
parent ba1f102469
commit 0c18fcefe3
1 changed files with 110 additions and 103 deletions

View File

@ -39,36 +39,56 @@
#include "target_internal.h" #include "target_internal.h"
#include "adiv5.h" #include "adiv5.h"
#define KINETIS_MDM_IDR_K22F 0x1c0000
#define KINETIS_MDM_IDR_KZ03 0x1c0020
#define MDM_STATUS ADIV5_AP_REG(0x00)
#define MDM_CONTROL ADIV5_AP_REG(0x04)
#define MDM_STATUS_MASS_ERASE_ACK (1 << 0)
#define MDM_STATUS_FLASH_READY (1 << 1)
#define MDM_STATUS_MASS_ERASE_ENABLED (1 << 5)
#define MDM_STATUS_BACK_KEY_ENABLED (1 << 6)
#define MDM_CONTROL_MASS_ERASE (1 << 0)
#define MDM_CONTROL_SYS_RESET (1 << 3)
#define SIM_SDID 0x40048024 #define SIM_SDID 0x40048024
#define SIM_FCFG1 0x4004804C #define SIM_FCFG1 0x4004804C
#define FTFA_BASE 0x40020000 #define FLASH_SECURITY_BYTE_ADDRESS 0x40C
#define FTFA_FSTAT (FTFA_BASE + 0x00) #define FLASH_SECURITY_BYTE_UNSECURED 0xFE
#define FTFA_FCNFG (FTFA_BASE + 0x01)
#define FTFA_FSEC (FTFA_BASE + 0x02)
#define FTFA_FOPT (FTFA_BASE + 0x03)
#define FTFA_FCCOB_0 (FTFA_BASE + 0x04)
#define FTFA_FCCOB_1 (FTFA_BASE + 0x08)
#define FTFA_FCCOB_2 (FTFA_BASE + 0x0C)
#define FTFA_FSTAT_CCIF (1 << 7) #define FTFx_BASE 0x40020000
#define FTFA_FSTAT_RDCOLERR (1 << 6) #define FTFx_FSTAT (FTFx_BASE + 0x00)
#define FTFA_FSTAT_ACCERR (1 << 5) #define FTFx_FCNFG (FTFx_BASE + 0x01)
#define FTFA_FSTAT_FPVIOL (1 << 4) #define FTFx_FSEC (FTFx_BASE + 0x02)
#define FTFA_FSTAT_MGSTAT0 (1 << 0) #define FTFx_FOPT (FTFx_BASE + 0x03)
#define FTFx_FCCOB0 (FTFx_BASE + 0x04)
#define FTFx_FCCOB4 (FTFx_BASE + 0x08)
#define FTFx_FCCOB8 (FTFx_BASE + 0x0C)
#define FTFA_CMD_CHECK_ERASE 0x01 #define FTFx_FSTAT_CCIF (1 << 7)
#define FTFA_CMD_PROGRAM_CHECK 0x02 #define FTFx_FSTAT_RDCOLERR (1 << 6)
#define FTFA_CMD_READ_RESOURCE 0x03 #define FTFx_FSTAT_ACCERR (1 << 5)
#define FTFA_CMD_PROGRAM_LONGWORD 0x06 #define FTFx_FSTAT_FPVIOL (1 << 4)
#define FTFx_FSTAT_MGSTAT0 (1 << 0)
#define FTFx_FSEC_KEYEN_MSK (0b11 << 6)
#define FTFx_FSEC_KEYEN (0b10 << 6)
#define FTFx_CMD_CHECK_ERASE 0x01
#define FTFx_CMD_PROGRAM_CHECK 0x02
#define FTFx_CMD_READ_RESOURCE 0x03
#define FTFx_CMD_PROGRAM_LONGWORD 0x06
/* Part of the FTFE module for K64 */ /* Part of the FTFE module for K64 */
#define FTFE_CMD_PROGRAM_PHRASE 0x07 #define FTFx_CMD_PROGRAM_PHRASE 0x07
#define FTFA_CMD_ERASE_SECTOR 0x09 #define FTFx_CMD_ERASE_SECTOR 0x09
#define FTFA_CMD_CHECK_ERASE_ALL 0x40 #define FTFx_CMD_CHECK_ERASE_ALL 0x40
#define FTFA_CMD_READ_ONCE 0x41 #define FTFx_CMD_READ_ONCE 0x41
#define FTFA_CMD_PROGRAM_ONCE 0x43 #define FTFx_CMD_PROGRAM_ONCE 0x43
#define FTFA_CMD_ERASE_ALL 0x44 #define FTFx_CMD_ERASE_ALL 0x44
#define FTFA_CMD_BACKDOOR_ACCESS 0x45 #define FTFx_CMD_BACKDOOR_ACCESS 0x45
#define KL_WRITE_LEN 4 #define KL_WRITE_LEN 4
/* 8 byte phrases need to be written to the k64 flash */ /* 8 byte phrases need to be written to the k64 flash */
@ -78,7 +98,8 @@ static bool kinetis_cmd_unsafe(target *t, int argc, char **argv);
const struct command_s kinetis_cmd_list[] = { const struct command_s kinetis_cmd_list[] = {
{"unsafe", (cmd_handler)kinetis_cmd_unsafe, "Allow programming security byte (enable|disable)"}, {"unsafe", (cmd_handler)kinetis_cmd_unsafe, "Allow programming security byte (enable|disable)"},
{NULL, NULL, NULL}}; {NULL, NULL, NULL},
};
static bool kinetis_cmd_unsafe(target *t, int argc, char **argv) static bool kinetis_cmd_unsafe(target *t, int argc, char **argv)
{ {
@ -90,16 +111,16 @@ static bool kinetis_cmd_unsafe(target *t, int argc, char **argv)
return true; return true;
} }
static int kl_gen_flash_erase(struct target_flash *f, target_addr addr, size_t len); static int kinetis_flash_cmd_erase(struct target_flash *f, target_addr addr, size_t len);
static int kl_gen_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len); static int kinetis_flash_cmd_write(struct target_flash *f, target_addr dest, const void *src, size_t len);
static int kl_gen_flash_done(struct target_flash *f); static int kinetis_flash_done(struct target_flash *f);
struct kinetis_flash { struct kinetis_flash {
struct target_flash f; struct target_flash f;
uint8_t write_len; uint8_t write_len;
}; };
static void kl_gen_add_flash( static void kinetis_add_flash(
target *const t, const uint32_t addr, const size_t length, const size_t erasesize, const size_t write_len) target *const t, const uint32_t addr, const size_t length, const size_t erasesize, const size_t write_len)
{ {
struct kinetis_flash *kf = calloc(1, sizeof(*kf)); struct kinetis_flash *kf = calloc(1, sizeof(*kf));
@ -114,9 +135,9 @@ static void kl_gen_add_flash(
f->start = addr; f->start = addr;
f->length = length; f->length = length;
f->blocksize = erasesize; f->blocksize = erasesize;
f->erase = kl_gen_flash_erase; f->erase = kinetis_flash_cmd_erase;
f->write = kl_gen_flash_write; f->write = kinetis_flash_cmd_write;
f->done = kl_gen_flash_done; f->done = kinetis_flash_done;
f->erased = 0xff; f->erased = 0xff;
kf->write_len = write_len; kf->write_len = write_len;
target_add_flash(t, f); target_add_flash(t, f);
@ -129,8 +150,8 @@ static void kl_s32k14_setup(
target_add_ram(t, sram_l, 0x20000000 - sram_l); target_add_ram(t, sram_l, 0x20000000 - sram_l);
target_add_ram(t, 0x20000000, sram_h); target_add_ram(t, 0x20000000, sram_h);
kl_gen_add_flash(t, 0x00000000, flash_size, 0x1000, K64_WRITE_LEN); /* P-Flash, 4 KB Sectors */ kinetis_add_flash(t, 0x00000000, flash_size, 0x1000, K64_WRITE_LEN); /* P-Flash, 4 KB Sectors */
kl_gen_add_flash(t, 0x10000000, flexmem_size, 0x1000, K64_WRITE_LEN); /* FlexNVM, 4 KB Sectors */ kinetis_add_flash(t, 0x10000000, flexmem_size, 0x1000, K64_WRITE_LEN); /* FlexNVM, 4 KB Sectors */
} }
bool kinetis_probe(target *const t) bool kinetis_probe(target *const t)
@ -167,22 +188,22 @@ bool kinetis_probe(target *const t)
switch ((fcfg1 >> 24) & 0x0f) { switch ((fcfg1 >> 24) & 0x0f) {
case 0x03: /* 32 KB */ case 0x03: /* 32 KB */
t->driver = "KL16Z32Vxxx"; t->driver = "KL16Z32Vxxx";
kl_gen_add_flash(t, 0x00000000, 0x08000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x08000, 0x400, KL_WRITE_LEN);
break; break;
case 0x05: /* 64 KB */ case 0x05: /* 64 KB */
t->driver = "KL16Z64Vxxx"; t->driver = "KL16Z64Vxxx";
kl_gen_add_flash(t, 0x00000000, 0x10000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x10000, 0x400, KL_WRITE_LEN);
break; break;
case 0x07: /* 128 KB */ case 0x07: /* 128 KB */
t->driver = "KL16Z128Vxxx"; t->driver = "KL16Z128Vxxx";
kl_gen_add_flash(t, 0x00000000, 0x20000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x20000, 0x400, KL_WRITE_LEN);
break; break;
case 0x09: /* 256 KB */ case 0x09: /* 256 KB */
t->driver = "KL16Z256Vxxx"; t->driver = "KL16Z256Vxxx";
kl_gen_add_flash(t, 0x00000000, 0x40000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x40000, 0x400, KL_WRITE_LEN);
break; break;
default: default:
return false; return false;
@ -195,13 +216,13 @@ bool kinetis_probe(target *const t)
t->driver = "KL25"; t->driver = "KL25";
target_add_ram(t, 0x1ffff000, 0x1000); target_add_ram(t, 0x1ffff000, 0x1000);
target_add_ram(t, 0x20000000, 0x3000); target_add_ram(t, 0x20000000, 0x3000);
kl_gen_add_flash(t, 0x00000000, 0x20000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x20000, 0x400, KL_WRITE_LEN);
break; break;
case 0x231: case 0x231:
t->driver = "KL27x128"; // MKL27 >=128kb t->driver = "KL27x128"; // MKL27 >=128kb
target_add_ram(t, 0x1fffe000, 0x2000); target_add_ram(t, 0x1fffe000, 0x2000);
target_add_ram(t, 0x20000000, 0x6000); target_add_ram(t, 0x20000000, 0x6000);
kl_gen_add_flash(t, 0x00000000, 0x40000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x40000, 0x400, KL_WRITE_LEN);
break; break;
case 0x271: case 0x271:
switch ((sdid >> 16) & 0x0f) { switch ((sdid >> 16) & 0x0f) {
@ -209,13 +230,13 @@ bool kinetis_probe(target *const t)
t->driver = "KL27x32"; t->driver = "KL27x32";
target_add_ram(t, 0x1ffff800, 0x0800); target_add_ram(t, 0x1ffff800, 0x0800);
target_add_ram(t, 0x20000000, 0x1800); target_add_ram(t, 0x20000000, 0x1800);
kl_gen_add_flash(t, 0x00000000, 0x8000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x8000, 0x400, KL_WRITE_LEN);
break; break;
case 5: case 5:
t->driver = "KL27x64"; t->driver = "KL27x64";
target_add_ram(t, 0x1ffff000, 0x1000); target_add_ram(t, 0x1ffff000, 0x1000);
target_add_ram(t, 0x20000000, 0x3000); target_add_ram(t, 0x20000000, 0x3000);
kl_gen_add_flash(t, 0x00000000, 0x10000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x10000, 0x400, KL_WRITE_LEN);
break; break;
default: default:
return false; return false;
@ -227,19 +248,19 @@ bool kinetis_probe(target *const t)
t->driver = "KL02x32"; t->driver = "KL02x32";
target_add_ram(t, 0x1FFFFC00, 0x400); target_add_ram(t, 0x1FFFFC00, 0x400);
target_add_ram(t, 0x20000000, 0xc00); target_add_ram(t, 0x20000000, 0xc00);
kl_gen_add_flash(t, 0x00000000, 0x7FFF, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x7FFF, 0x400, KL_WRITE_LEN);
break; break;
case 2: case 2:
t->driver = "KL02x16"; t->driver = "KL02x16";
target_add_ram(t, 0x1FFFFE00, 0x200); target_add_ram(t, 0x1FFFFE00, 0x200);
target_add_ram(t, 0x20000000, 0x600); target_add_ram(t, 0x20000000, 0x600);
kl_gen_add_flash(t, 0x00000000, 0x3FFF, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x3FFF, 0x400, KL_WRITE_LEN);
break; break;
case 1: case 1:
t->driver = "KL02x8"; t->driver = "KL02x8";
target_add_ram(t, 0x1FFFFF00, 0x100); target_add_ram(t, 0x1FFFFF00, 0x100);
target_add_ram(t, 0x20000000, 0x300); target_add_ram(t, 0x20000000, 0x300);
kl_gen_add_flash(t, 0x00000000, 0x1FFF, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0x00000000, 0x1FFF, 0x400, KL_WRITE_LEN);
break; break;
default: default:
return false; return false;
@ -249,14 +270,14 @@ bool kinetis_probe(target *const t)
t->driver = "KL03"; t->driver = "KL03";
target_add_ram(t, 0x1ffffe00, 0x200); target_add_ram(t, 0x1ffffe00, 0x200);
target_add_ram(t, 0x20000000, 0x600); target_add_ram(t, 0x20000000, 0x600);
kl_gen_add_flash(t, 0, 0x8000, 0x400, KL_WRITE_LEN); kinetis_add_flash(t, 0, 0x8000, 0x400, KL_WRITE_LEN);
break; break;
case 0x220: /* K22F family */ case 0x220: /* K22F family */
t->driver = "K22F"; t->driver = "K22F";
target_add_ram(t, 0x1c000000, 0x4000000); target_add_ram(t, 0x1c000000, 0x4000000);
target_add_ram(t, 0x20000000, 0x100000); target_add_ram(t, 0x20000000, 0x100000);
kl_gen_add_flash(t, 0, 0x40000, 0x800, KL_WRITE_LEN); kinetis_add_flash(t, 0, 0x40000, 0x800, KL_WRITE_LEN);
kl_gen_add_flash(t, 0x40000, 0x40000, 0x800, KL_WRITE_LEN); kinetis_add_flash(t, 0x40000, 0x40000, 0x800, KL_WRITE_LEN);
break; break;
case 0x620: /* K64F family. */ case 0x620: /* K64F family. */
/* This should be 0x640, but according to the errata sheet /* This should be 0x640, but according to the errata sheet
@ -266,8 +287,8 @@ bool kinetis_probe(target *const t)
t->driver = "K64"; t->driver = "K64";
target_add_ram(t, 0x1FFF0000, 0x10000); target_add_ram(t, 0x1FFF0000, 0x10000);
target_add_ram(t, 0x20000000, 0x30000); target_add_ram(t, 0x20000000, 0x30000);
kl_gen_add_flash(t, 0, 0x80000, 0x1000, K64_WRITE_LEN); kinetis_add_flash(t, 0, 0x80000, 0x1000, K64_WRITE_LEN);
kl_gen_add_flash(t, 0x80000, 0x80000, 0x1000, K64_WRITE_LEN); kinetis_add_flash(t, 0x80000, 0x80000, 0x1000, K64_WRITE_LEN);
break; break;
case 0x000: /* Older K-series */ case 0x000: /* Older K-series */
switch (sdid & 0xff0) { switch (sdid & 0xff0) {
@ -282,24 +303,24 @@ bool kinetis_probe(target *const t)
/* K12 Sub-Family Reference Manual, K12P80M50SF4RM, Rev. 4, February 2013 */ /* K12 Sub-Family Reference Manual, K12P80M50SF4RM, Rev. 4, February 2013 */
case 0x7: case 0x7:
t->driver = "MK12DX128Vxx5"; t->driver = "MK12DX128Vxx5";
target_add_ram(t, 0x1fffc000, 0x00004000); /* SRAM_L, 16 KB */ target_add_ram(t, 0x1fffc000, 0x00004000); /* SRAM_L, 16 KB */
target_add_ram(t, 0x20000000, 0x00004000); /* SRAM_H, 16 KB */ target_add_ram(t, 0x20000000, 0x00004000); /* SRAM_H, 16 KB */
kl_gen_add_flash(t, 0x00000000, 0x00020000, 0x800, KL_WRITE_LEN); /* P-Flash, 128 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x00000000, 0x00020000, 0x800, KL_WRITE_LEN); /* P-Flash, 128 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00010000, 0x800, KL_WRITE_LEN); /* FlexNVM, 64 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x10000000, 0x00010000, 0x800, KL_WRITE_LEN); /* FlexNVM, 64 KB, 2 KB Sectors */
break; break;
case 0x9: case 0x9:
t->driver = "MK12DX256Vxx5"; t->driver = "MK12DX256Vxx5";
target_add_ram(t, 0x1fffc000, 0x00004000); /* SRAM_L, 16 KB */ target_add_ram(t, 0x1fffc000, 0x00004000); /* SRAM_L, 16 KB */
target_add_ram(t, 0x20000000, 0x00004000); /* SRAM_H, 16 KB */ target_add_ram(t, 0x20000000, 0x00004000); /* SRAM_H, 16 KB */
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, KL_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x00000000, 0x00040000, 0x800, KL_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00010000, 0x800, KL_WRITE_LEN); /* FlexNVM, 64 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x10000000, 0x00010000, 0x800, KL_WRITE_LEN); /* FlexNVM, 64 KB, 2 KB Sectors */
break; break;
case 0xb: case 0xb:
t->driver = "MK12DN512Vxx5"; t->driver = "MK12DN512Vxx5";
target_add_ram(t, 0x1fff8000, 0x00008000); /* SRAM_L, 32 KB */ target_add_ram(t, 0x1fff8000, 0x00008000); /* SRAM_L, 32 KB */
target_add_ram(t, 0x20000000, 0x00008000); /* SRAM_H, 32 KB */ target_add_ram(t, 0x20000000, 0x00008000); /* SRAM_H, 32 KB */
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, KL_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x00000000, 0x00040000, 0x800, KL_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x00040000, 0x00040000, 0x800, KL_WRITE_LEN); /* FlexNVM, 256 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x00040000, 0x00040000, 0x800, KL_WRITE_LEN); /* FlexNVM, 256 KB, 2 KB Sectors */
break; break;
default: default:
return false; return false;
@ -329,10 +350,10 @@ bool kinetis_probe(target *const t)
break; break;
case 0x118: /* S32K118 */ case 0x118: /* S32K118 */
t->driver = "S32K118"; t->driver = "S32K118";
target_add_ram(t, 0x1ffffc00, 0x00000400); /* SRAM_L, 1 KB */ target_add_ram(t, 0x1ffffc00, 0x00000400); /* SRAM_L, 1 KB */
target_add_ram(t, 0x20000000, 0x00005800); /* SRAM_H, 22 KB */ target_add_ram(t, 0x20000000, 0x00005800); /* SRAM_H, 22 KB */
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, K64_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x00000000, 0x00040000, 0x800, K64_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00008000, 0x800, K64_WRITE_LEN); /* FlexNVM, 32 KB, 2 KB Sectors */ kinetis_add_flash(t, 0x10000000, 0x00008000, 0x800, K64_WRITE_LEN); /* FlexNVM, 32 KB, 2 KB Sectors */
break; break;
/* gen1 s32k14x */ /* gen1 s32k14x */
case 0x142: /* S32K142 */ case 0x142: /* S32K142 */
@ -373,46 +394,46 @@ bool kinetis_probe(target *const t)
return true; return true;
} }
static bool kl_gen_command(target *t, uint8_t cmd, uint32_t addr, const uint32_t *data, int n_items) static bool kinetis_fccob_cmd(target *t, uint8_t cmd, uint32_t addr, const uint32_t *data, int n_items)
{ {
uint8_t fstat; uint8_t fstat;
/* clear errors unconditionally, so we can start a new operation */ /* clear errors unconditionally, so we can start a new operation */
target_mem_write8(t, FTFA_FSTAT, (FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL)); target_mem_write8(t, FTFx_FSTAT, (FTFx_FSTAT_ACCERR | FTFx_FSTAT_FPVIOL));
/* Wait for CCIF to be high */ /* Wait for CCIF to be high */
do { do {
fstat = target_mem_read8(t, FTFA_FSTAT); fstat = target_mem_read8(t, FTFx_FSTAT);
} while (!(fstat & FTFA_FSTAT_CCIF)); } while (!(fstat & FTFx_FSTAT_CCIF));
/* Write command to FCCOB */ /* Write command to FCCOB */
addr &= 0xffffff; addr &= 0xffffff;
addr |= (uint32_t)cmd << 24; addr |= (uint32_t)cmd << 24;
target_mem_write32(t, FTFA_FCCOB_0, addr); target_mem_write32(t, FTFx_FCCOB0, addr);
if (data) { if (data) {
target_mem_write32(t, FTFA_FCCOB_1, data[0]); target_mem_write32(t, FTFx_FCCOB4, data[0]);
if (n_items > 1) if (n_items > 1)
target_mem_write32(t, FTFA_FCCOB_2, data[1]); target_mem_write32(t, FTFx_FCCOB8, data[1]);
} }
/* Enable execution by clearing CCIF */ /* Enable execution by clearing CCIF */
target_mem_write8(t, FTFA_FSTAT, FTFA_FSTAT_CCIF); target_mem_write8(t, FTFx_FSTAT, FTFx_FSTAT_CCIF);
/* Wait for execution to complete */ /* Wait for execution to complete */
do { do {
fstat = target_mem_read8(t, FTFA_FSTAT); fstat = target_mem_read8(t, FTFx_FSTAT);
/* Check ACCERR and FPVIOL are zero in FSTAT */ /* Check ACCERR and FPVIOL are zero in FSTAT */
if (fstat & (FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL)) if (fstat & (FTFx_FSTAT_ACCERR | FTFx_FSTAT_FPVIOL))
return false; return false;
} while (!(fstat & FTFA_FSTAT_CCIF)); } while (!(fstat & FTFx_FSTAT_CCIF));
return true; return true;
} }
static int kl_gen_flash_erase(struct target_flash *const f, target_addr addr, size_t len) static int kinetis_flash_cmd_erase(struct target_flash *const f, target_addr addr, size_t len)
{ {
while (len) { while (len) {
if (kl_gen_command(f->t, FTFA_CMD_ERASE_SECTOR, addr, NULL, 0)) { if (kinetis_fccob_cmd(f->t, FTFx_CMD_ERASE_SECTOR, addr, NULL, 0)) {
/* Different targets have different flash erase sizes */ /* Different targets have different flash erase sizes */
if (len > f->blocksize) if (len > f->blocksize)
len -= f->blocksize; len -= f->blocksize;
@ -426,10 +447,7 @@ static int kl_gen_flash_erase(struct target_flash *const f, target_addr addr, si
return 0; return 0;
} }
#define FLASH_SECURITY_BYTE_ADDRESS 0x40C static int kinetis_flash_cmd_write(struct target_flash *f, target_addr dest, const void *src, size_t len)
#define FLASH_SECURITY_BYTE_UNSECURED 0xFE
static int kl_gen_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len)
{ {
struct kinetis_flash *const kf = (struct kinetis_flash *)f; struct kinetis_flash *const kf = (struct kinetis_flash *)f;
@ -441,12 +459,12 @@ static int kl_gen_flash_write(struct target_flash *f, target_addr dest, const vo
/* Determine write command based on the alignment. */ /* Determine write command based on the alignment. */
uint8_t write_cmd; uint8_t write_cmd;
if (kf->write_len == K64_WRITE_LEN) if (kf->write_len == K64_WRITE_LEN)
write_cmd = FTFE_CMD_PROGRAM_PHRASE; write_cmd = FTFx_CMD_PROGRAM_PHRASE;
else else
write_cmd = FTFA_CMD_PROGRAM_LONGWORD; write_cmd = FTFx_CMD_PROGRAM_LONGWORD;
while (len) { while (len) {
if (kl_gen_command(f->t, write_cmd, dest, src, 1)) { if (kinetis_fccob_cmd(f->t, write_cmd, dest, src, 1)) {
if (len > kf->write_len) if (len > kf->write_len)
len -= kf->write_len; len -= kf->write_len;
else else
@ -459,7 +477,7 @@ static int kl_gen_flash_write(struct target_flash *f, target_addr dest, const vo
return 0; return 0;
} }
static int kl_gen_flash_done(struct target_flash *const f) static int kinetis_flash_done(struct target_flash *const f)
{ {
struct kinetis_flash *const kf = (struct kinetis_flash *)f; struct kinetis_flash *const kf = (struct kinetis_flash *)f;
@ -477,12 +495,12 @@ static int kl_gen_flash_done(struct target_flash *const f)
vals[0] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS - 4); vals[0] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS - 4);
vals[1] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS); vals[1] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS);
vals[1] = (vals[1] & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED; vals[1] = (vals[1] & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED;
kl_gen_command(f->t, FTFE_CMD_PROGRAM_PHRASE, FLASH_SECURITY_BYTE_ADDRESS - 4, vals, 2); kinetis_fccob_cmd(f->t, FTFx_CMD_PROGRAM_PHRASE, FLASH_SECURITY_BYTE_ADDRESS - 4, vals, 2);
} else { } else {
uint32_t vals[1]; uint32_t vals[1];
vals[0] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS); vals[0] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS);
vals[0] = (vals[0] & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED; vals[0] = (vals[0] & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED;
kl_gen_command(f->t, FTFA_CMD_PROGRAM_LONGWORD, FLASH_SECURITY_BYTE_ADDRESS, vals, 1); kinetis_fccob_cmd(f->t, FTFx_CMD_PROGRAM_LONGWORD, FLASH_SECURITY_BYTE_ADDRESS, vals, 1);
} }
return 0; return 0;
@ -496,15 +514,14 @@ static int kl_gen_flash_done(struct target_flash *const f)
* device. This provides a fake target to allow a monitor command interface * device. This provides a fake target to allow a monitor command interface
*/ */
#define KINETIS_MDM_IDR_K22F 0x1c0000
#define KINETIS_MDM_IDR_KZ03 0x1c0020
static bool kinetis_mdm_cmd_erase_mass(target *t, int argc, const char **argv); static bool kinetis_mdm_cmd_erase_mass(target *t, int argc, const char **argv);
static bool kinetis_mdm_cmd_ke04_mode(target *t, int argc, const char **argv); static bool kinetis_mdm_cmd_ke04_mode(target *t, int argc, const char **argv);
const struct command_s kinetis_mdm_cmd_list[] = { const struct command_s kinetis_mdm_cmd_list[] = {
{"erase_mass", (cmd_handler)kinetis_mdm_cmd_erase_mass, "Erase entire flash memory"}, {"erase_mass", (cmd_handler)kinetis_mdm_cmd_erase_mass, "Erase entire flash memory"},
{"ke04_mode", (cmd_handler)kinetis_mdm_cmd_ke04_mode, "Allow erase for KE04"}, {NULL, NULL, NULL}}; {"ke04_mode", (cmd_handler)kinetis_mdm_cmd_ke04_mode, "Allow erase for KE04"},
{NULL, NULL, NULL},
};
enum target_halt_reason mdm_halt_poll(target *t, const target_addr *const watch) enum target_halt_reason mdm_halt_poll(target *t, const target_addr *const watch)
{ {
@ -537,16 +554,6 @@ void kinetis_mdm_probe(ADIv5_AP_t *ap)
target_add_commands(t, kinetis_mdm_cmd_list, t->driver); target_add_commands(t, kinetis_mdm_cmd_list, t->driver);
} }
#define MDM_STATUS ADIV5_AP_REG(0x00)
#define MDM_CONTROL ADIV5_AP_REG(0x04)
#define MDM_STATUS_MASS_ERASE_ACK (1 << 0)
#define MDM_STATUS_FLASH_READY (1 << 1)
#define MDM_STATUS_MASS_ERASE_ENABLED (1 << 5)
#define MDM_CONTROL_MASS_ERASE (1 << 0)
#define MDM_CONTROL_SYS_RESET (1 << 3)
/* This is needed as a separate command, as there's no way to * /* This is needed as a separate command, as there's no way to *
* tell a KE04 from other kinetis in kinetis_mdm_probe() */ * tell a KE04 from other kinetis in kinetis_mdm_probe() */
static bool kinetis_mdm_cmd_ke04_mode(target *t, int argc, const char **argv) static bool kinetis_mdm_cmd_ke04_mode(target *t, int argc, const char **argv)