Merge pull request #302 from gsmcmullin/always_buffer_flash
Only support buffered flash writes
This commit is contained in:
commit
455e0a74d2
|
@ -239,9 +239,7 @@ static void efm32_add_flash(target *t, target_addr addr, size_t length,
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = page_size;
|
f->blocksize = page_size;
|
||||||
f->erase = efm32_flash_erase;
|
f->erase = efm32_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = efm32_flash_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = efm32_flash_write;
|
|
||||||
f->buf_size = page_size;
|
f->buf_size = page_size;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
* KL25 Sub-family Reference Manual
|
* KL25 Sub-family Reference Manual
|
||||||
*
|
*
|
||||||
* Extended with support for KL02 family
|
* Extended with support for KL02 family
|
||||||
*
|
*
|
||||||
* Extended with support for K64 family with info from K22P64M50SF4RM:
|
* Extended with support for K64 family with info from K22P64M50SF4RM:
|
||||||
* K22 Sub-Family Reference Manual
|
* K22 Sub-Family Reference Manual
|
||||||
*
|
*
|
||||||
* Extended with support for K64 family with info from K64P144M120SF5RM:
|
* Extended with support for K64 family with info from K64P144M120SF5RM:
|
||||||
* K64 Sub-Family Reference Manual, Rev. 2,
|
* K64 Sub-Family Reference Manual, Rev. 2,
|
||||||
*/
|
*/
|
||||||
|
@ -57,9 +57,9 @@
|
||||||
#define FTFA_CMD_CHECK_ERASE 0x01
|
#define FTFA_CMD_CHECK_ERASE 0x01
|
||||||
#define FTFA_CMD_PROGRAM_CHECK 0x02
|
#define FTFA_CMD_PROGRAM_CHECK 0x02
|
||||||
#define FTFA_CMD_READ_RESOURCE 0x03
|
#define FTFA_CMD_READ_RESOURCE 0x03
|
||||||
#define FTFA_CMD_PROGRAM_LONGWORD 0x06
|
#define FTFA_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 FTFE_CMD_PROGRAM_PHRASE 0x07
|
||||||
#define FTFA_CMD_ERASE_SECTOR 0x09
|
#define FTFA_CMD_ERASE_SECTOR 0x09
|
||||||
#define FTFA_CMD_CHECK_ERASE_ALL 0x40
|
#define FTFA_CMD_CHECK_ERASE_ALL 0x40
|
||||||
#define FTFA_CMD_READ_ONCE 0x41
|
#define FTFA_CMD_READ_ONCE 0x41
|
||||||
|
@ -94,19 +94,24 @@ static int kl_gen_flash_write(struct target_flash *f,
|
||||||
target_addr dest, const void *src, size_t len);
|
target_addr dest, const void *src, size_t len);
|
||||||
static int kl_gen_flash_done(struct target_flash *f);
|
static int kl_gen_flash_done(struct target_flash *f);
|
||||||
|
|
||||||
static void kl_gen_add_flash(target *t,
|
struct kinetis_flash {
|
||||||
uint32_t addr, size_t length, size_t erasesize,
|
struct target_flash f;
|
||||||
size_t write_len)
|
uint8_t write_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void kl_gen_add_flash(target *t, uint32_t addr, size_t length,
|
||||||
|
size_t erasesize, size_t write_len)
|
||||||
{
|
{
|
||||||
struct target_flash *f = calloc(1, sizeof(*f));
|
struct kinetis_flash *kf = calloc(1, sizeof(*kf));
|
||||||
|
struct target_flash *f = &kf->f;
|
||||||
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 = kl_gen_flash_erase;
|
||||||
f->write = kl_gen_flash_write;
|
f->write = kl_gen_flash_write;
|
||||||
f->done = kl_gen_flash_done;
|
f->done = kl_gen_flash_done;
|
||||||
f->align = write_len;
|
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
|
kf->write_len = write_len;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,9 +187,9 @@ bool kinetis_probe(target *t)
|
||||||
kl_gen_add_flash(t, 0x40000, 0x40000, 0x800, KL_WRITE_LEN);
|
kl_gen_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
|
||||||
* (KINETIS_1N83J) K64 and K24's will show up with the
|
* (KINETIS_1N83J) K64 and K24's will show up with the
|
||||||
* subfamily nibble as 2
|
* subfamily nibble as 2
|
||||||
*/
|
*/
|
||||||
t->driver = "K64";
|
t->driver = "K64";
|
||||||
target_add_ram(t, 0x1FFF0000, 0x10000);
|
target_add_ram(t, 0x1FFF0000, 0x10000);
|
||||||
|
@ -241,7 +246,7 @@ static int kl_gen_flash_erase(struct target_flash *f, target_addr addr, size_t l
|
||||||
while (len) {
|
while (len) {
|
||||||
if (kl_gen_command(f->t, FTFA_CMD_ERASE_SECTOR, addr, NULL)) {
|
if (kl_gen_command(f->t, FTFA_CMD_ERASE_SECTOR, addr, NULL)) {
|
||||||
/* Different targets have different flash erase sizes */
|
/* Different targets have different flash erase sizes */
|
||||||
len -= f->blocksize;
|
len -= f->blocksize;
|
||||||
addr += f->blocksize;
|
addr += f->blocksize;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -256,6 +261,8 @@ static int kl_gen_flash_erase(struct target_flash *f, target_addr addr, size_t l
|
||||||
static int kl_gen_flash_write(struct target_flash *f,
|
static int kl_gen_flash_write(struct target_flash *f,
|
||||||
target_addr dest, const void *src, size_t len)
|
target_addr dest, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
|
struct kinetis_flash *kf = (struct kinetis_flash *)f;
|
||||||
|
|
||||||
/* Ensure we don't write something horrible over the security byte */
|
/* Ensure we don't write something horrible over the security byte */
|
||||||
if (!unsafe_enabled &&
|
if (!unsafe_enabled &&
|
||||||
(dest <= FLASH_SECURITY_BYTE_ADDRESS) &&
|
(dest <= FLASH_SECURITY_BYTE_ADDRESS) &&
|
||||||
|
@ -266,17 +273,17 @@ static int kl_gen_flash_write(struct target_flash *f,
|
||||||
|
|
||||||
/* Determine write command based on the alignment. */
|
/* Determine write command based on the alignment. */
|
||||||
uint8_t write_cmd;
|
uint8_t write_cmd;
|
||||||
if (f->align == K64_WRITE_LEN) {
|
if (kf->write_len == K64_WRITE_LEN) {
|
||||||
write_cmd = FTFE_CMD_PROGRAM_PHRASE;
|
write_cmd = FTFE_CMD_PROGRAM_PHRASE;
|
||||||
} else {
|
} else {
|
||||||
write_cmd = FTFA_CMD_PROGRAM_LONGWORD;
|
write_cmd = FTFA_CMD_PROGRAM_LONGWORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
if (kl_gen_command(f->t, write_cmd, dest, src)) {
|
if (kl_gen_command(f->t, write_cmd, dest, src)) {
|
||||||
len -= f->align;
|
len -= kf->write_len;
|
||||||
dest += f->align;
|
dest += kf->write_len;
|
||||||
src += f->align;
|
src += kf->write_len;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -286,6 +293,7 @@ static int kl_gen_flash_write(struct target_flash *f,
|
||||||
|
|
||||||
static int kl_gen_flash_done(struct target_flash *f)
|
static int kl_gen_flash_done(struct target_flash *f)
|
||||||
{
|
{
|
||||||
|
struct kinetis_flash *kf = (struct kinetis_flash *)f;
|
||||||
|
|
||||||
if (unsafe_enabled)
|
if (unsafe_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -297,18 +305,18 @@ static int kl_gen_flash_done(struct target_flash *f)
|
||||||
/* Load the security byte based on the alignment (determine 8 byte phrases
|
/* Load the security byte based on the alignment (determine 8 byte phrases
|
||||||
* vs 4 byte phrases).
|
* vs 4 byte phrases).
|
||||||
*/
|
*/
|
||||||
if (f->align == 8) {
|
if (kf->write_len == 8) {
|
||||||
uint32_t vals[2];
|
uint32_t vals[2];
|
||||||
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,
|
kl_gen_command(f->t, FTFE_CMD_PROGRAM_PHRASE,
|
||||||
FLASH_SECURITY_BYTE_ADDRESS - 4, (uint8_t*)vals);
|
FLASH_SECURITY_BYTE_ADDRESS - 4, (uint8_t*)vals);
|
||||||
} else {
|
} else {
|
||||||
uint32_t val = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS);
|
uint32_t val = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS);
|
||||||
val = (val & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED;
|
val = (val & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED;
|
||||||
kl_gen_command(f->t, FTFA_CMD_PROGRAM_LONGWORD,
|
kl_gen_command(f->t, FTFA_CMD_PROGRAM_LONGWORD,
|
||||||
FLASH_SECURITY_BYTE_ADDRESS, (uint8_t*)&val);
|
FLASH_SECURITY_BYTE_ADDRESS, (uint8_t*)&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -65,7 +65,6 @@ static void lmi_add_flash(target *t, size_t length)
|
||||||
f->blocksize = 0x400;
|
f->blocksize = 0x400;
|
||||||
f->erase = lmi_flash_erase;
|
f->erase = lmi_flash_erase;
|
||||||
f->write = lmi_flash_write;
|
f->write = lmi_flash_write;
|
||||||
f->align = 4;
|
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize)
|
||||||
struct lpc_flash *lf = lpc_add_flash(t, addr, len);
|
struct lpc_flash *lf = lpc_add_flash(t, addr, len);
|
||||||
lf->f.blocksize = erasesize;
|
lf->f.blocksize = erasesize;
|
||||||
lf->f.buf_size = IAP_PGM_CHUNKSIZE;
|
lf->f.buf_size = IAP_PGM_CHUNKSIZE;
|
||||||
lf->f.write_buf = lpc_flash_write_magic_vect;
|
lf->f.write = lpc_flash_write_magic_vect;
|
||||||
lf->iap_entry = IAP_ENTRYPOINT;
|
lf->iap_entry = IAP_ENTRYPOINT;
|
||||||
lf->iap_ram = IAP_RAM_BASE;
|
lf->iap_ram = IAP_RAM_BASE;
|
||||||
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
||||||
|
@ -122,4 +122,3 @@ lpc11xx_probe(target *t)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ void lpc15xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize)
|
||||||
struct lpc_flash *lf = lpc_add_flash(t, addr, len);
|
struct lpc_flash *lf = lpc_add_flash(t, addr, len);
|
||||||
lf->f.blocksize = erasesize;
|
lf->f.blocksize = erasesize;
|
||||||
lf->f.buf_size = IAP_PGM_CHUNKSIZE;
|
lf->f.buf_size = IAP_PGM_CHUNKSIZE;
|
||||||
lf->f.write_buf = lpc_flash_write_magic_vect;
|
lf->f.write = lpc_flash_write_magic_vect;
|
||||||
lf->iap_entry = IAP_ENTRYPOINT;
|
lf->iap_entry = IAP_ENTRYPOINT;
|
||||||
lf->iap_ram = IAP_RAM_BASE;
|
lf->iap_ram = IAP_RAM_BASE;
|
||||||
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
||||||
|
@ -77,4 +77,3 @@ lpc15xx_probe(target *t)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ void lpc17xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, u
|
||||||
lf->f.blocksize = erasesize;
|
lf->f.blocksize = erasesize;
|
||||||
lf->base_sector = base_sector;
|
lf->base_sector = base_sector;
|
||||||
lf->f.buf_size = IAP_PGM_CHUNKSIZE;
|
lf->f.buf_size = IAP_PGM_CHUNKSIZE;
|
||||||
lf->f.write_buf = lpc_flash_write_magic_vect;
|
lf->f.write = lpc_flash_write_magic_vect;
|
||||||
lf->iap_entry = IAP_ENTRYPOINT;
|
lf->iap_entry = IAP_ENTRYPOINT;
|
||||||
lf->iap_ram = IAP_RAM_BASE;
|
lf->iap_ram = IAP_RAM_BASE;
|
||||||
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
||||||
|
|
|
@ -40,9 +40,7 @@ struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length)
|
||||||
f->start = addr;
|
f->start = addr;
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->erase = lpc_flash_erase;
|
f->erase = lpc_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = lpc_flash_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = lpc_flash_write;
|
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
return lf;
|
return lf;
|
||||||
|
@ -148,4 +146,3 @@ int lpc_flash_write_magic_vect(struct target_flash *f,
|
||||||
}
|
}
|
||||||
return lpc_flash_write(f, dest, src, len);
|
return lpc_flash_write(f, dest, src, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,6 @@ static void nrf51_add_flash(target *t,
|
||||||
f->blocksize = erasesize;
|
f->blocksize = erasesize;
|
||||||
f->erase = nrf51_flash_erase;
|
f->erase = nrf51_flash_erase;
|
||||||
f->write = nrf51_flash_write;
|
f->write = nrf51_flash_write;
|
||||||
f->align = 4;
|
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
@ -112,7 +111,7 @@ bool nrf51_probe(target *t)
|
||||||
case 0x0020: /* nRF51822 (rev 1) CEAA BA */
|
case 0x0020: /* nRF51822 (rev 1) CEAA BA */
|
||||||
case 0x0024: /* nRF51422 (rev 1) QFAA C0 */
|
case 0x0024: /* nRF51422 (rev 1) QFAA C0 */
|
||||||
case 0x002A: /* nRF51822 (rev 2) QFAA FA0 */
|
case 0x002A: /* nRF51822 (rev 2) QFAA FA0 */
|
||||||
case 0x004A: /* nRF51822 (rev 3) QFAA G1 */
|
case 0x004A: /* nRF51822 (rev 3) QFAA G1 */
|
||||||
case 0x002D: /* nRF51422 (rev 2) QFAA DAA */
|
case 0x002D: /* nRF51422 (rev 2) QFAA DAA */
|
||||||
case 0x002E: /* nRF51422 (rev 2) QFAA E0 */
|
case 0x002E: /* nRF51422 (rev 2) QFAA E0 */
|
||||||
case 0x002F: /* nRF51822 (rev 1) CEAA B0 */
|
case 0x002F: /* nRF51822 (rev 1) CEAA B0 */
|
||||||
|
@ -129,7 +128,7 @@ bool nrf51_probe(target *t)
|
||||||
case 0x0079: /* nRF51822 (rev 3) CEAA E0 */
|
case 0x0079: /* nRF51822 (rev 3) CEAA E0 */
|
||||||
case 0x007A: /* nRF51422 (rev 3) CEAA C0 */
|
case 0x007A: /* nRF51422 (rev 3) CEAA C0 */
|
||||||
case 0x008F: /* nRF51822 (rev 3) QFAA H1 See https://devzone.nordicsemi.com/question/97769/can-someone-conform-the-config-id-code-for-the-nrf51822qfaah1/ */
|
case 0x008F: /* nRF51822 (rev 3) QFAA H1 See https://devzone.nordicsemi.com/question/97769/can-someone-conform-the-config-id-code-for-the-nrf51822qfaah1/ */
|
||||||
case 0x00D1: /* nRF51822 (rev 3) QFAA H2 */
|
case 0x00D1: /* nRF51822 (rev 3) QFAA H2 */
|
||||||
case 0x0114: /* nRF51802 (rev ?) QFAA A1 */
|
case 0x0114: /* nRF51802 (rev ?) QFAA A1 */
|
||||||
t->driver = "Nordic nRF51";
|
t->driver = "Nordic nRF51";
|
||||||
target_add_ram(t, 0x20000000, 0x4000);
|
target_add_ram(t, 0x20000000, 0x4000);
|
||||||
|
|
|
@ -131,9 +131,7 @@ static void sam3_add_flash(target *t,
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = SAM3_PAGE_SIZE;
|
f->blocksize = SAM3_PAGE_SIZE;
|
||||||
f->erase = sam3_flash_erase;
|
f->erase = sam3_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = sam3x_flash_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = sam3x_flash_write;
|
|
||||||
f->buf_size = SAM3_PAGE_SIZE;
|
f->buf_size = SAM3_PAGE_SIZE;
|
||||||
sf->eefc_base = eefc_base;
|
sf->eefc_base = eefc_base;
|
||||||
sf->write_cmd = EEFC_FCR_FCMD_EWP;
|
sf->write_cmd = EEFC_FCR_FCMD_EWP;
|
||||||
|
@ -149,9 +147,7 @@ static void sam4_add_flash(target *t,
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = SAM4_PAGE_SIZE * 8;
|
f->blocksize = SAM4_PAGE_SIZE * 8;
|
||||||
f->erase = sam4_flash_erase;
|
f->erase = sam4_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = sam3x_flash_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = sam3x_flash_write;
|
|
||||||
f->buf_size = SAM4_PAGE_SIZE;
|
f->buf_size = SAM4_PAGE_SIZE;
|
||||||
sf->eefc_base = eefc_base;
|
sf->eefc_base = eefc_base;
|
||||||
sf->write_cmd = EEFC_FCR_FCMD_WP;
|
sf->write_cmd = EEFC_FCR_FCMD_WP;
|
||||||
|
@ -355,4 +351,3 @@ static bool sam3x_cmd_gpnvm_set(target *t, int argc, char *argv[])
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,9 +173,7 @@ static void sam4l_add_flash(target *t, uint32_t addr, size_t length)
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = SAM4L_PAGE_SIZE;
|
f->blocksize = SAM4L_PAGE_SIZE;
|
||||||
f->erase = sam4l_flash_erase;
|
f->erase = sam4l_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = sam4l_flash_write_buf;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = sam4l_flash_write_buf;
|
|
||||||
f->buf_size = SAM4L_PAGE_SIZE;
|
f->buf_size = SAM4L_PAGE_SIZE;
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
/* add it into the target structures flash chain */
|
/* add it into the target structures flash chain */
|
||||||
|
@ -238,7 +236,7 @@ bool sam4l_probe(target *t)
|
||||||
DEBUG("\nSAM4L: RAM = 0x%x (%dK), FLASH = 0x%x (%dK)\n",
|
DEBUG("\nSAM4L: RAM = 0x%x (%dK), FLASH = 0x%x (%dK)\n",
|
||||||
(unsigned int) ram_size, (unsigned int) (ram_size / 1024),
|
(unsigned int) ram_size, (unsigned int) (ram_size / 1024),
|
||||||
(unsigned int) flash_size, (unsigned int)(flash_size / 1024));
|
(unsigned int) flash_size, (unsigned int)(flash_size / 1024));
|
||||||
|
|
||||||
/* enable SMAP if not, check for HCR and reset if set */
|
/* enable SMAP if not, check for HCR and reset if set */
|
||||||
sam4l_extended_reset(t);
|
sam4l_extended_reset(t);
|
||||||
DEBUG("\nSAM4L: SAM4L Selected.\n");
|
DEBUG("\nSAM4L: SAM4L Selected.\n");
|
||||||
|
@ -331,7 +329,7 @@ sam4l_flash_write_buf(struct target_flash *f, target_addr addr, const void *src,
|
||||||
uint32_t *src_data = (uint32_t *)src;
|
uint32_t *src_data = (uint32_t *)src;
|
||||||
uint32_t ndx;
|
uint32_t ndx;
|
||||||
uint16_t page;
|
uint16_t page;
|
||||||
|
|
||||||
DEBUG("\nSAM4L: sam4l_flash_write_buf: addr = 0x%08lx, len %d\n", (long unsigned int) addr, (int) len);
|
DEBUG("\nSAM4L: sam4l_flash_write_buf: addr = 0x%08lx, len %d\n", (long unsigned int) addr, (int) len);
|
||||||
/* This will fail with unaligned writes, the write_buf version */
|
/* This will fail with unaligned writes, the write_buf version */
|
||||||
page = addr / SAM4L_PAGE_SIZE;
|
page = addr / SAM4L_PAGE_SIZE;
|
||||||
|
|
|
@ -350,9 +350,7 @@ static void samd_add_flash(target *t, uint32_t addr, size_t length)
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = SAMD_ROW_SIZE;
|
f->blocksize = SAMD_ROW_SIZE;
|
||||||
f->erase = samd_flash_erase;
|
f->erase = samd_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = samd_flash_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = samd_flash_write;
|
|
||||||
f->buf_size = SAMD_PAGE_SIZE;
|
f->buf_size = SAMD_PAGE_SIZE;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
@ -698,4 +696,3 @@ static bool samd_cmd_ssb(target *t)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,6 @@ static void stm32f1_add_flash(target *t,
|
||||||
f->blocksize = erasesize;
|
f->blocksize = erasesize;
|
||||||
f->erase = stm32f1_flash_erase;
|
f->erase = stm32f1_flash_erase;
|
||||||
f->write = stm32f1_flash_write;
|
f->write = stm32f1_flash_write;
|
||||||
f->align = 2;
|
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,6 @@ static void stm32f4_add_flash(target *t,
|
||||||
f->blocksize = blocksize;
|
f->blocksize = blocksize;
|
||||||
f->erase = stm32f4_flash_erase;
|
f->erase = stm32f4_flash_erase;
|
||||||
f->write = stm32f4_flash_write;
|
f->write = stm32f4_flash_write;
|
||||||
f->align = 4;
|
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
sf->base_sector = base_sector;
|
sf->base_sector = base_sector;
|
||||||
sf->psize = 32;
|
sf->psize = 32;
|
||||||
|
|
|
@ -237,9 +237,7 @@ static void stm32l_add_flash(target *t,
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = erasesize;
|
f->blocksize = erasesize;
|
||||||
f->erase = stm32lx_nvm_prog_erase;
|
f->erase = stm32lx_nvm_prog_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = stm32lx_nvm_prog_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = stm32lx_nvm_prog_write;
|
|
||||||
f->buf_size = erasesize/2;
|
f->buf_size = erasesize/2;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
@ -252,7 +250,6 @@ static void stm32l_add_eeprom(target *t, uint32_t addr, size_t length)
|
||||||
f->blocksize = 4;
|
f->blocksize = 4;
|
||||||
f->erase = stm32lx_nvm_data_erase;
|
f->erase = stm32lx_nvm_data_erase;
|
||||||
f->write = stm32lx_nvm_data_write;
|
f->write = stm32lx_nvm_data_write;
|
||||||
f->align = 1;
|
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,9 +135,7 @@ static void stm32l4_add_flash(target *t,
|
||||||
f->length = length;
|
f->length = length;
|
||||||
f->blocksize = blocksize;
|
f->blocksize = blocksize;
|
||||||
f->erase = stm32l4_flash_erase;
|
f->erase = stm32l4_flash_erase;
|
||||||
f->write = target_flash_write_buffered;
|
f->write = stm32l4_flash_write;
|
||||||
f->done = target_flash_done_buffered;
|
|
||||||
f->write_buf = stm32l4_flash_write;
|
|
||||||
f->buf_size = 2048;
|
f->buf_size = 2048;
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
sf->bank1_start = bank1_start;
|
sf->bank1_start = bank1_start;
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
|
|
||||||
target *target_list = NULL;
|
target *target_list = NULL;
|
||||||
|
|
||||||
|
static int target_flash_write_buffered(struct target_flash *f,
|
||||||
|
target_addr dest, const void *src, size_t len);
|
||||||
|
static int target_flash_done_buffered(struct target_flash *f);
|
||||||
|
|
||||||
target *target_new(void)
|
target *target_new(void)
|
||||||
{
|
{
|
||||||
target *t = (void*)calloc(1, sizeof(*t));
|
target *t = (void*)calloc(1, sizeof(*t));
|
||||||
|
@ -138,6 +142,8 @@ void target_add_ram(target *t, target_addr start, uint32_t len)
|
||||||
|
|
||||||
void target_add_flash(target *t, struct target_flash *f)
|
void target_add_flash(target *t, struct target_flash *f)
|
||||||
{
|
{
|
||||||
|
if (f->buf_size == 0)
|
||||||
|
f->buf_size = MIN(f->blocksize, 0x400);
|
||||||
f->t = t;
|
f->t = t;
|
||||||
f->next = t->flash;
|
f->next = t->flash;
|
||||||
t->flash = f;
|
t->flash = f;
|
||||||
|
@ -216,15 +222,7 @@ int target_flash_write(target *t,
|
||||||
struct target_flash *f = flash_for_addr(t, dest);
|
struct target_flash *f = flash_for_addr(t, dest);
|
||||||
size_t tmptarget = MIN(dest + len, f->start + f->length);
|
size_t tmptarget = MIN(dest + len, f->start + f->length);
|
||||||
size_t tmplen = tmptarget - dest;
|
size_t tmplen = tmptarget - dest;
|
||||||
if (f->align > 1) {
|
ret |= target_flash_write_buffered(f, dest, src, tmplen);
|
||||||
uint32_t offset = dest % f->align;
|
|
||||||
uint8_t data[ALIGN(offset + tmplen, f->align)];
|
|
||||||
memset(data, f->erased, sizeof(data));
|
|
||||||
memcpy((uint8_t *)data + offset, src, tmplen);
|
|
||||||
ret |= f->write(f, dest - offset, data, sizeof(data));
|
|
||||||
} else {
|
|
||||||
ret |= f->write(f, dest, src, tmplen);
|
|
||||||
}
|
|
||||||
dest += tmplen;
|
dest += tmplen;
|
||||||
src += tmplen;
|
src += tmplen;
|
||||||
len -= tmplen;
|
len -= tmplen;
|
||||||
|
@ -235,6 +233,9 @@ int target_flash_write(target *t,
|
||||||
int target_flash_done(target *t)
|
int target_flash_done(target *t)
|
||||||
{
|
{
|
||||||
for (struct target_flash *f = t->flash; f; f = f->next) {
|
for (struct target_flash *f = t->flash; f; f = f->next) {
|
||||||
|
int tmp = target_flash_done_buffered(f);
|
||||||
|
if (tmp)
|
||||||
|
return tmp;
|
||||||
if (f->done) {
|
if (f->done) {
|
||||||
int tmp = f->done(f);
|
int tmp = f->done(f);
|
||||||
if (tmp)
|
if (tmp)
|
||||||
|
@ -260,8 +261,8 @@ int target_flash_write_buffered(struct target_flash *f,
|
||||||
if (base != f->buf_addr) {
|
if (base != f->buf_addr) {
|
||||||
if (f->buf_addr != (uint32_t)-1) {
|
if (f->buf_addr != (uint32_t)-1) {
|
||||||
/* Write sector to flash if valid */
|
/* Write sector to flash if valid */
|
||||||
ret |= f->write_buf(f, f->buf_addr,
|
ret |= f->write(f, f->buf_addr,
|
||||||
f->buf, f->buf_size);
|
f->buf, f->buf_size);
|
||||||
}
|
}
|
||||||
/* Setup buffer for a new sector */
|
/* Setup buffer for a new sector */
|
||||||
f->buf_addr = base;
|
f->buf_addr = base;
|
||||||
|
@ -282,7 +283,7 @@ int target_flash_done_buffered(struct target_flash *f)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if ((f->buf != NULL) &&(f->buf_addr != (uint32_t)-1)) {
|
if ((f->buf != NULL) &&(f->buf_addr != (uint32_t)-1)) {
|
||||||
/* Write sector to flash if valid */
|
/* Write sector to flash if valid */
|
||||||
ret = f->write_buf(f, f->buf_addr, f->buf, f->buf_size);
|
ret = f->write(f, f->buf_addr, f->buf, f->buf_size);
|
||||||
f->buf_addr = -1;
|
f->buf_addr = -1;
|
||||||
free(f->buf);
|
free(f->buf);
|
||||||
f->buf = NULL;
|
f->buf = NULL;
|
||||||
|
@ -564,4 +565,3 @@ int tc_system(target *t, target_addr cmd, size_t cmdlen)
|
||||||
}
|
}
|
||||||
return t->tc->system(t->tc, cmd, cmdlen);
|
return t->tc->system(t->tc, cmd, cmdlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,9 @@ struct target_flash {
|
||||||
flash_write_func write;
|
flash_write_func write;
|
||||||
flash_done_func done;
|
flash_done_func done;
|
||||||
target *t;
|
target *t;
|
||||||
struct target_flash *next;
|
|
||||||
int align;
|
|
||||||
uint8_t erased;
|
uint8_t erased;
|
||||||
|
|
||||||
/* For buffered flash */
|
|
||||||
size_t buf_size;
|
size_t buf_size;
|
||||||
flash_write_func write_buf;
|
struct target_flash *next;
|
||||||
target_addr buf_addr;
|
target_addr buf_addr;
|
||||||
void *buf;
|
void *buf;
|
||||||
};
|
};
|
||||||
|
@ -131,9 +127,6 @@ struct target_s {
|
||||||
void target_add_commands(target *t, const struct command_s *cmds, const char *name);
|
void target_add_commands(target *t, const struct command_s *cmds, const char *name);
|
||||||
void target_add_ram(target *t, target_addr start, uint32_t len);
|
void target_add_ram(target *t, target_addr start, uint32_t len);
|
||||||
void target_add_flash(target *t, struct target_flash *f);
|
void target_add_flash(target *t, struct target_flash *f);
|
||||||
int target_flash_write_buffered(struct target_flash *f,
|
|
||||||
target_addr dest, const void *src, size_t len);
|
|
||||||
int target_flash_done_buffered(struct target_flash *f);
|
|
||||||
|
|
||||||
/* Convenience function for MMIO access */
|
/* Convenience function for MMIO access */
|
||||||
uint32_t target_mem_read32(target *t, uint32_t addr);
|
uint32_t target_mem_read32(target *t, uint32_t addr);
|
||||||
|
@ -185,4 +178,3 @@ bool kinetis_probe(target *t);
|
||||||
bool efm32_probe(target *t);
|
bool efm32_probe(target *t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue