Correction of #445 attach-detach problem

Memory map is now completely freed and rebuilt in the separate attach
function.
It was previoulsy split beween probe and attach and never released,
causing problems when reattaching to the same target.
This commit is contained in:
newbrain 2019-03-02 20:21:43 +01:00
parent da62cbaa3d
commit 6887628eaa
1 changed files with 152 additions and 99 deletions

View File

@ -124,6 +124,108 @@ struct stm32l4_flash {
uint32_t bank1_start; uint32_t bank1_start;
}; };
enum ID_STM32L4 {
ID_STM32L41 = 0x464u, /* RM0394, Rev.4 */
ID_STM32L43 = 0x435u, /* RM0394, Rev.4 */
ID_STM32L45 = 0x462u, /* RM0394, Rev.4 */
ID_STM32L47 = 0x415u, /* RM0351, Rev.5 */
ID_STM32L49 = 0x461u, /* RM0351, Rev.5 */
ID_STM32L4R = 0x470u, /* RM0432, Rev.5 */
ID_STM32G07 = 0x460u, /* RM0444/454, Rev.1 */
};
enum FAM_STM32L4 {
FAM_STM32L4xx = 1,
FAM_STM32L4Rx = 2,
FAM_STM32G0x = 3,
FAM_STM32WBxx = 4,
};
#define DUAL_BANK 0x80u
#define RAM_COUNT_MSK 0x07u
struct stm32l4_info {
char designator[10];
uint16_t sram1;
uint16_t sram2;
uint16_t sram3;
enum ID_STM32L4 idcode;
enum FAM_STM32L4 family;
uint8_t flags;
};
struct stm32l4_info const L4info[] = {
{
.idcode = ID_STM32L41,
.family = FAM_STM32L4xx,
.designator = "STM32L41x",
.sram1 = 32,
.sram2 = 8,
.flags = 2,
},
{
.idcode = ID_STM32L43,
.family = FAM_STM32L4xx,
.designator = "STM32L43x",
.sram1 = 48,
.sram2 = 16,
.flags = 2,
},
{
.idcode = ID_STM32L45,
.family = FAM_STM32L4xx,
.designator = "STM32L45x",
.sram1 = 128,
.sram2 = 32,
.flags = 2,
},
{
.idcode = ID_STM32L47,
.family = FAM_STM32L4xx,
.designator = "STM32L47x",
.sram1 = 96,
.sram2 = 32,
.flags = 2 | DUAL_BANK,
},
{
.idcode = ID_STM32L49,
.family = FAM_STM32L4xx,
.designator = "STM32L49x",
.sram1 = 256,
.sram2 = 64,
.flags = 2 | DUAL_BANK,
},
{
.idcode = ID_STM32L4R,
.family = FAM_STM32L4Rx,
.designator = "STM32L4Rx",
.sram1 = 192,
.sram2 = 64,
.sram3 = 384,
.flags = 3 | DUAL_BANK,
},
{
.idcode = ID_STM32G07,
.family = FAM_STM32G0x,
.designator = "STM32G07",
.sram1 = 36,
.flags = 1,
},
{
/* Terminator */
.idcode = 0,
},
};
/* Retrieve chip basic information, just add to the vector to extend */
static struct stm32l4_info const * stm32l4_get_chip_info(uint32_t idcode) {
struct stm32l4_info const *p = L4info;
while (p->idcode && (p->idcode != idcode))
p++;
return p;
}
static void stm32l4_add_flash(target *t, static void stm32l4_add_flash(target *t,
uint32_t addr, size_t length, size_t blocksize, uint32_t addr, size_t length, size_t blocksize,
uint32_t bank1_start) uint32_t bank1_start)
@ -141,61 +243,61 @@ static void stm32l4_add_flash(target *t,
target_add_flash(t, f); target_add_flash(t, f);
} }
enum ID_STM32L4 {
ID_STM32L43 = 0x435, /* RM0394, Rev.4 */
ID_STM32L45 = 0x462, /* RM0394, Rev.4 */
ID_STM32L41 = 0x464, /* RM0394, Rev.4 */
ID_STM32L47 = 0x415, /* RM0351, Rev.5 */
ID_STM32G07 = 0x460, /* RM0444/454, Rev.1 */
ID_STM32L49 = 0x461, /* RM0351, Rev.5 */
ID_STM32L4R = 0x470, /* RM0432, Rev.5 */
};
static bool stm32l4_attach(target *t) static bool stm32l4_attach(target *t)
{ {
if (!cortexm_attach(t)) if (!cortexm_attach(t))
return false; return false;
bool dual_bank = false; /* Retrive chip information, no need to check return */
uint32_t idcodereg = STM32L4_DBGMCU_IDCODE_PHYS; struct stm32l4_info const *chip = stm32l4_get_chip_info(t->idcode);
uint32_t size = 0;
uint32_t idcodereg = (chip->family == FAM_STM32G0x)
? STM32G0_DBGMCU_IDCODE_PHYS
: STM32L4_DBGMCU_IDCODE_PHYS;
switch(t->idcode) {
case ID_STM32L47:
case ID_STM32L49:
case ID_STM32L4R:
dual_bank = true;
break;
case ID_STM32G07:
idcodereg = STM32G0_DBGMCU_IDCODE_PHYS;
break;
}
/* Save DBGMCU_CR to restore it when detaching*/ /* Save DBGMCU_CR to restore it when detaching*/
uint32_t dbgmcu_cr = target_mem_read32(t, DBGMCU_CR(idcodereg)); uint32_t dbgmcu_cr = target_mem_read32(t, DBGMCU_CR(idcodereg));
t->target_storage = dbgmcu_cr; t->target_storage = dbgmcu_cr;
/* Enable debugging during all low power modes*/ /* Enable debugging during all low power modes*/
target_mem_write32(t, DBGMCU_CR(idcodereg), DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP); target_mem_write32(t, DBGMCU_CR(idcodereg), DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP);
size = (target_mem_read32(t, FLASH_SIZE_REG) & 0xffff);
if (dual_bank) { /* Free previously loaded memory map */
uint32_t options = target_mem_read32(t, FLASH_OPTR); target_mem_map_free(t);
if (t->idcode == ID_STM32L4R) {
/* rm0432 Rev. 2 does not mention 1 MB devices or explain DB1M.*/ /* Add RAM to memory map */
if (options & OR_DBANK) { if (chip->family == FAM_STM32G0x) {
stm32l4_add_flash(t, 0x08000000, 0x00100000, 0x1000, 0x08100000); target_add_ram(t, 0x20000000, chip->sram1 << 10);
stm32l4_add_flash(t, 0x08100000, 0x00100000, 0x1000, 0x08100000); } else {
} else target_add_ram(t, 0x10000000, chip->sram2 << 10);
stm32l4_add_flash(t, 0x08000000, 0x00200000, 0x2000, -1); /* All L4 beside L47 alias SRAM2 after SRAM1.*/
uint32_t ramsize = (t->idcode == ID_STM32L47)?
chip->sram1 : (chip->sram1 + chip->sram2 + chip->sram3);
target_add_ram(t, 0x20000000, ramsize << 10);
}
/* Add the flash to memory map. */
uint32_t size = target_mem_read16(t, FLASH_SIZE_REG);
uint32_t options = target_mem_read32(t, FLASH_OPTR);
if (chip->family == FAM_STM32L4Rx) {
/* rm0432 Rev. 2 does not mention 1 MB devices or explain DB1M.*/
if (options & OR_DBANK) {
stm32l4_add_flash(t, 0x08000000, 0x00100000, 0x1000, 0x08100000);
stm32l4_add_flash(t, 0x08100000, 0x00100000, 0x1000, 0x08100000);
} else
stm32l4_add_flash(t, 0x08000000, 0x00200000, 0x2000, -1);
} else if (chip->flags & DUAL_BANK) {
if (options & OR_DUALBANK) {
uint32_t banksize = size << 9;
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, 0x08000000 + banksize);
stm32l4_add_flash(t, 0x08000000 + banksize, banksize, 0x0800, 0x08000000 + banksize);
} else { } else {
if (options & OR_DUALBANK) { uint32_t banksize = size << 10;
uint32_t banksize = size << 9; stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, -1);
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, 0x08000000 + banksize);
stm32l4_add_flash(t, 0x08000000 + banksize, banksize, 0x0800, 0x08000000 + banksize);
} else {
uint32_t banksize = size << 10;
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, -1);
}
} }
} else } else
stm32l4_add_flash(t, 0x08000000, size << 10, 0x800, -1); stm32l4_add_flash(t, 0x08000000, size << 10, 0x800, -1);
@ -218,71 +320,22 @@ static void stm32l4_detach(target *t)
bool stm32l4_probe(target *t) bool stm32l4_probe(target *t)
{ {
const char* designator = NULL;
bool is_stm32g0 = false;
uint16_t sram1_size = 0;
uint16_t sram2_size = 0;
uint16_t sram3_size = 0;
uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS; uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS;
ADIv5_AP_t *ap = cortexm_ap(t); ADIv5_AP_t *ap = cortexm_ap(t);
if (ap->dp->idcode == 0x0BC11477) if (ap->dp->idcode == 0x0BC11477)
idcode_reg = STM32G0_DBGMCU_IDCODE_PHYS; idcode_reg = STM32G0_DBGMCU_IDCODE_PHYS;
uint32_t idcode = target_mem_read32(t, idcode_reg) & 0xfff; uint32_t idcode = target_mem_read32(t, idcode_reg) & 0xfff;
switch(idcode) {
case ID_STM32G07: struct stm32l4_info const *chip = stm32l4_get_chip_info(idcode);
designator = "STM32G07";
is_stm32g0 = true; if( !chip->idcode ) /* Not found */
sram1_size = 36;
break;
case ID_STM32L41:
designator = "STM32L41x";
sram1_size = 32;
sram2_size = 8;
break;
case ID_STM32L43:
designator = "STM32L43x";
sram1_size = 48;
sram2_size = 16;
break;
case ID_STM32L45:
designator = "STM32L45x";
sram1_size = 128;
sram2_size = 32;
break;
case ID_STM32L47:
designator = "STM32L47x";
sram1_size = 96;
sram2_size = 32;
break;
case ID_STM32L49:
designator = "STM32L49x";
sram1_size = 256;
sram2_size = 64;
break;
case ID_STM32L4R:
designator = "STM32L4Rx";
sram1_size = 192;
sram2_size = 64;
sram3_size = 384;
break;
default:
return false; return false;
}
t->idcode = idcode; t->idcode = idcode;
t->driver = designator; t->driver = chip->designator;
t->attach = stm32l4_attach; t->attach = stm32l4_attach;
t->detach = stm32l4_detach; t->detach = stm32l4_detach;
if (is_stm32g0) { target_add_commands(t, stm32l4_cmd_list, chip->designator);
target_add_ram(t, 0x20000000, sram1_size << 10);
} else {
target_add_ram(t, 0x10000000, sram2_size << 10);
/* All L4 beside L47 alias SRAM2 after SRAM1.*/
uint32_t ramsize = (idcode == ID_STM32L47)?
sram1_size : (sram1_size + sram2_size + sram3_size);
target_add_ram(t, 0x20000000, ramsize << 10);
}
target_add_commands(t, stm32l4_cmd_list, designator);
return true; return true;
} }
@ -413,7 +466,7 @@ static const uint8_t g0_i2offset[7] = {
static bool stm32l4_option_write( static bool stm32l4_option_write(
target *t,const uint32_t *values, int len, const uint8_t *i2offset) target *t,const uint32_t *values, int len, const uint8_t *i2offset)
{ {
tc_printf(t, "Device will loose connection. Rescan!\n"); tc_printf(t, "Device will lose connection. Rescan!\n");
stm32l4_flash_unlock(t); stm32l4_flash_unlock(t);
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY1); target_mem_write32(t, FLASH_OPTKEYR, OPTKEY1);
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY2); target_mem_write32(t, FLASH_OPTKEYR, OPTKEY2);
@ -459,7 +512,7 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
const uint8_t *i2offset = l4_i2offset; const uint8_t *i2offset = l4_i2offset;
if (t->idcode == 0x435) {/* L43x */ if (t->idcode == 0x435) {/* L43x */
len = 5; len = 5;
} else if (t->idcode == 0x460) {/* G07x */ } else if (t->idcode == ID_STM32G07) {/* G07x */
i2offset = g0_i2offset; i2offset = g0_i2offset;
len = 7; len = 7;
} else { } else {