aboutsummaryrefslogtreecommitdiff
path: root/src/stm32l0.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stm32l0.c')
-rw-r--r--src/stm32l0.c374
1 files changed, 163 insertions, 211 deletions
diff --git a/src/stm32l0.c b/src/stm32l0.c
index 2e30035..8193b12 100644
--- a/src/stm32l0.c
+++ b/src/stm32l0.c
@@ -72,13 +72,13 @@
to regain control of the target after the option byte reload.
stm32l0_option_write(t, 0x1ff80000, 0xffff0000);
- adiv5_ap_mem_write(ap, STM32L0_NVM_PECR, STM32L0_NVM_PECR_OBL_LAUNCH);
+ target_mem_write32(target, STM32L0_NVM_PECR, STM32L0_NVM_PECR_OBL_LAUNCH);
stm32l0_option_write(t, 0x1ff80000, 0xff5500aa);
- adiv5_ap_mem_write(ap, STM32L0_NVM_PECR, STM32L0_NVM_PECR_OBL_LAUNCH);
+ target_mem_write32(target, STM32L0_NVM_PECR, STM32L0_NVM_PECR_OBL_LAUNCH);
uint32_t sr;
do {
- sr = adiv5_ap_mem_read(ap, STM32L0_NVM_SR);
+ sr = target_mem_read32(target, STM32L0_NVM_SR);
} while (sr & STM32L0_NVM_SR_BSY);
o Errors. We probably should clear SR errors immediately after
@@ -112,49 +112,36 @@
*/
-#define CONFIG_STM32L1 /* Include support for STM32L1 */
-
#include "general.h"
#include "adiv5.h"
#include "target.h"
#include "command.h"
#include "gdb_packet.h"
+#include "cortexm.h"
#include "stm32lx-nvm.h"
static int inhibit_stubs; /* Local option to force non-stub flash IO */
-static int stm32lx_nvm_erase(struct target_s* target,
- uint32_t addr, size_t len);
-static int stm32lx_nvm_write(struct target_s* target,
- uint32_t destination,
- const uint8_t* source,
+static int stm32lx_nvm_erase(target *t, uint32_t addr, size_t len);
+static int stm32lx_nvm_write(target *t, uint32_t dest, const uint8_t* src,
size_t size);
-static int stm32lx_nvm_prog_erase(struct target_s* target,
- uint32_t addr, size_t len);
-static int stm32lx_nvm_prog_write(struct target_s* target,
- uint32_t destination,
- const uint8_t* source,
+static int stm32lx_nvm_prog_erase(target *t, uint32_t addr, size_t len);
+static int stm32lx_nvm_prog_write(target *t, uint32_t dest, const uint8_t* src,
size_t size);
-static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
- uint32_t addr, size_t len);
-static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
- uint32_t destination,
- const uint8_t* source,
- size_t size);
+static int stm32lx_nvm_prog_erase_stubbed(target *t, uint32_t addr, size_t len);
+static int stm32lx_nvm_prog_write_stubbed(target *t, uint32_t dest,
+ const uint8_t* src, size_t size);
-static int stm32lx_nvm_data_erase(struct target_s* target,
- uint32_t addr, size_t len);
-static int stm32lx_nvm_data_write(struct target_s* target,
- uint32_t destination,
- const uint8_t* source,
- size_t size);
+static int stm32lx_nvm_data_erase(target *t, uint32_t addr, size_t len);
+static int stm32lx_nvm_data_write(target *t, uint32_t dest,
+ const uint8_t* src, size_t size);
-static bool stm32lx_cmd_option (target* t, int argc, char** argv);
-static bool stm32lx_cmd_eeprom (target* t, int argc, char** argv);
-static bool stm32lx_cmd_stubs (target* t, int argc, char** argv);
+static bool stm32lx_cmd_option(target* t, int argc, char** argv);
+static bool stm32lx_cmd_eeprom(target* t, int argc, char** argv);
+static bool stm32lx_cmd_stubs(target* t, int argc, char** argv);
static const struct command_s stm32lx_cmd_list[] = {
{ "stubs", (cmd_handler) stm32lx_cmd_stubs,
@@ -190,7 +177,6 @@ static const char stm32l0_xml_memory_map[] = "<?xml version=\"1.0\"?>"
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x2000\"/>"
"</memory-map>";
-#if defined(CONFIG_STM32L1)
static const char stm32l1_driver_str[] = "STM32L1xx";
static const char stm32l1_xml_memory_map[] = "<?xml version=\"1.0\"?>"
@@ -209,7 +195,6 @@ static const char stm32l1_xml_memory_map[] = "<?xml version=\"1.0\"?>"
/* SRAM; ranges from 4KiB to 80KiB(0x14000). */
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x14000\"/>"
"</memory-map>";
-#endif
static const uint16_t stm32l0_nvm_prog_write_stub [] = {
#include "../flashstub/stm32l05x-nvm-prog-write.stub"
@@ -219,9 +204,9 @@ static const uint16_t stm32l0_nvm_prog_erase_stub [] = {
#include "../flashstub/stm32l05x-nvm-prog-erase.stub"
};
-static uint32_t stm32lx_nvm_prog_page_size(struct target_s* target)
+static uint32_t stm32lx_nvm_prog_page_size(target *t)
{
- switch (target->idcode) {
+ switch (t->idcode) {
case 0x417: /* STM32L0xx */
return STM32L0_NVM_PROG_PAGE_SIZE;
default: /* STM32L1xx */
@@ -229,9 +214,9 @@ static uint32_t stm32lx_nvm_prog_page_size(struct target_s* target)
}
}
-static bool stm32lx_is_stm32l1(struct target_s* target)
+static bool stm32lx_is_stm32l1(target *t)
{
- switch (target->idcode) {
+ switch (t->idcode) {
case 0x417: /* STM32L0xx */
return false;
default: /* STM32L1xx */
@@ -239,9 +224,9 @@ static bool stm32lx_is_stm32l1(struct target_s* target)
}
}
-static uint32_t stm32lx_nvm_eeprom_size(struct target_s* target)
+static uint32_t stm32lx_nvm_eeprom_size(target *t)
{
- switch (target->idcode) {
+ switch (t->idcode) {
case 0x417: /* STM32L0xx */
return STM32L0_NVM_EEPROM_SIZE;
default: /* STM32L1xx */
@@ -249,9 +234,9 @@ static uint32_t stm32lx_nvm_eeprom_size(struct target_s* target)
}
}
-static uint32_t stm32lx_nvm_phys(struct target_s* target)
+static uint32_t stm32lx_nvm_phys(target *t)
{
- switch (target->idcode) {
+ switch (t->idcode) {
case 0x417: /* STM32L0xx */
return STM32L0_NVM_PHYS;
default: /* STM32L1xx */
@@ -259,9 +244,9 @@ static uint32_t stm32lx_nvm_phys(struct target_s* target)
}
}
-static uint32_t stm32lx_nvm_data_page_size(struct target_s* target)
+static uint32_t stm32lx_nvm_data_page_size(target *t)
{
- switch (target->idcode) {
+ switch (t->idcode) {
case 0x417: /* STM32L0xx */
return STM32L0_NVM_DATA_PAGE_SIZE;
default: /* STM32L1xx */
@@ -269,9 +254,9 @@ static uint32_t stm32lx_nvm_data_page_size(struct target_s* target)
}
}
-static uint32_t stm32lx_nvm_option_size(struct target_s* target)
+static uint32_t stm32lx_nvm_option_size(target *t)
{
- switch (target->idcode) {
+ switch (t->idcode) {
case 0x417: /* STM32L0xx */
return STM32L0_NVM_OPT_SIZE;
default: /* STM32L1xx */
@@ -282,43 +267,38 @@ static uint32_t stm32lx_nvm_option_size(struct target_s* target)
/** Query MCU memory for an indication as to whether or not the
currently attached target is served by this module. We detect the
STM32L0xx parts as well as the STM32L1xx's. */
-bool stm32l0_probe(struct target_s* target)
+bool stm32l0_probe(target *t)
{
uint32_t idcode;
-#if defined(CONFIG_STM32L1)
-
- idcode = adiv5_ap_mem_read(adiv5_target_ap(target),
- STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff;
+ idcode = target_mem_read32(t, STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff;
switch (idcode) {
case 0x416: /* CAT. 1 device */
case 0x429: /* CAT. 2 device */
case 0x427: /* CAT. 3 device */
case 0x436: /* CAT. 4 device */
case 0x437: /* CAT. 5 device */
- target->idcode = idcode;
- target->driver = stm32l1_driver_str;
- target->xml_mem_map = stm32l1_xml_memory_map;
- target->flash_erase = stm32lx_nvm_erase;
- target->flash_write = stm32lx_nvm_write;
- target_add_commands(target, stm32lx_cmd_list, "STM32L1x");
+ t->idcode = idcode;
+ t->driver = stm32l1_driver_str;
+ t->xml_mem_map = stm32l1_xml_memory_map;
+ t->flash_erase = stm32lx_nvm_erase;
+ t->flash_write = stm32lx_nvm_write;
+ target_add_commands(t, stm32lx_cmd_list, "STM32L1x");
return true;
}
-#endif
- idcode = adiv5_ap_mem_read(adiv5_target_ap(target),
- STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff;
+ idcode = target_mem_read32(t, STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff;
switch (idcode) {
default:
break;
case 0x417: /* STM32L0x[123] & probably others */
- target->idcode = idcode;
- target->driver = stm32l0_driver_str;
- target->xml_mem_map = stm32l0_xml_memory_map;
- target->flash_erase = stm32lx_nvm_erase;
- target->flash_write = stm32lx_nvm_write;
- target_add_commands(target, stm32lx_cmd_list, "STM32L0x");
+ t->idcode = idcode;
+ t->driver = stm32l0_driver_str;
+ t->xml_mem_map = stm32l0_xml_memory_map;
+ t->flash_erase = stm32lx_nvm_erase;
+ t->flash_write = stm32lx_nvm_write;
+ target_add_commands(t, stm32lx_cmd_list, "STM32L0x");
return true;
}
@@ -327,42 +307,42 @@ bool stm32l0_probe(struct target_s* target)
/** Lock the NVM control registers preventing writes or erases. */
-static void stm32lx_nvm_lock(ADIv5_AP_t* ap, uint32_t nvm)
+static void stm32lx_nvm_lock(target *t, uint32_t nvm)
{
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
}
/** Unlock the NVM control registers for modifying program or
data flash. Returns true if the unlock succeeds. */
-static bool stm32lx_nvm_prog_data_unlock(ADIv5_AP_t* ap, uint32_t nvm)
+static bool stm32lx_nvm_prog_data_unlock(target* t, uint32_t nvm)
{
/* Always lock first because that's the only way to know that the
unlock can succeed on the STM32L0's. */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY1);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY2);
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
+ target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
+ target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
+ target_mem_write32(t, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY1);
+ target_mem_write32(t, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY2);
- return !(adiv5_ap_mem_read(ap, STM32Lx_NVM_PECR(nvm))
+ return !(target_mem_read32(t, STM32Lx_NVM_PECR(nvm))
& STM32Lx_NVM_PECR_PRGLOCK);
}
/** Unlock the NVM control registers for modifying option bytes.
Returns true if the unlock succeeds. */
-static bool stm32lx_nvm_opt_unlock(ADIv5_AP_t* ap, uint32_t nvm)
+static bool stm32lx_nvm_opt_unlock(target *t, uint32_t nvm)
{
/* Always lock first because that's the only way to know that the
unlock can succeed on the STM32L0's. */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY1);
- adiv5_ap_mem_write(ap, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY2);
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
+ target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
+ target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
+ target_mem_write32(t, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY1);
+ target_mem_write32(t, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY2);
- return !(adiv5_ap_mem_read(ap, STM32Lx_NVM_PECR(nvm))
+ return !(target_mem_read32(t, STM32Lx_NVM_PECR(nvm))
& STM32Lx_NVM_PECR_OPTLOCK);
}
@@ -370,41 +350,34 @@ static bool stm32lx_nvm_opt_unlock(ADIv5_AP_t* ap, uint32_t nvm)
/** Erase a region of flash using a stub function. This only works
when the MCU hasn't entered a fault state(see NOTES). The flash
array is erased for all pages from addr to addr+len inclusive. */
-static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
+static int stm32lx_nvm_prog_erase_stubbed(target *t,
uint32_t addr, size_t size)
{
struct stm32lx_nvm_stub_info info;
- const uint32_t nvm = stm32lx_nvm_phys(target);
+ const uint32_t nvm = stm32lx_nvm_phys(t);
info.nvm = nvm;
- info.page_size = stm32lx_nvm_prog_page_size(target);
+ info.page_size = stm32lx_nvm_prog_page_size(t);
/* Load the stub */
- target_mem_write_words(target, STM32Lx_STUB_PHYS,
- (void*) &stm32l0_nvm_prog_erase_stub[0],
- sizeof(stm32l0_nvm_prog_erase_stub));
+ target_mem_write(t, STM32Lx_STUB_PHYS,
+ &stm32l0_nvm_prog_erase_stub[0],
+ sizeof(stm32l0_nvm_prog_erase_stub));
/* Setup parameters */
info.destination = addr;
info.size = size;
/* Copy parameters */
- target_mem_write_words(target, STM32Lx_STUB_INFO_PHYS,
- (void*) &info, sizeof(info));
+ target_mem_write(t, STM32Lx_STUB_INFO_PHYS, &info, sizeof(info));
/* Execute stub */
- target_pc_write(target, STM32Lx_STUB_PHYS);
- if (target_check_error(target))
- return -1;
- target_halt_resume(target, 0);
- while (!target_halt_wait(target))
- ;
- {
- ADIv5_AP_t* ap = adiv5_target_ap(target);
- if (adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm))
- & STM32Lx_NVM_SR_ERR_M)
- return -1;
- }
+ cortexm_run_stub(t, STM32Lx_STUB_PHYS, 0, 0, 0, 0);
+
+ if (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
+ & STM32Lx_NVM_SR_ERR_M)
+ return -1;
+
return 0;
}
@@ -414,14 +387,14 @@ static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
when the MCU hasn't entered a fault state. Once the MCU faults,
this function will not succeed because the MCU will fault before
executing a single instruction in the stub. */
-static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
+static int stm32lx_nvm_prog_write_stubbed(target *t,
uint32_t destination,
const uint8_t* source,
size_t size)
{
struct stm32lx_nvm_stub_info info;
- const uint32_t nvm = stm32lx_nvm_phys(target);
- const size_t page_size = stm32lx_nvm_prog_page_size(target);
+ const uint32_t nvm = stm32lx_nvm_phys(t);
+ const size_t page_size = stm32lx_nvm_prog_page_size(t);
/* We can only handle word aligned writes and even
word-multiple ranges. The stm32lx's cannot perform
@@ -434,9 +407,9 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
info.page_size = page_size;
/* Load the stub */
- target_mem_write_words(target, STM32Lx_STUB_PHYS,
- (void*) &stm32l0_nvm_prog_write_stub[0],
- sizeof(stm32l0_nvm_prog_write_stub));
+ target_mem_write(t, STM32Lx_STUB_PHYS,
+ &stm32l0_nvm_prog_write_stub[0],
+ sizeof(stm32l0_nvm_prog_write_stub));
while (size > 0) {
@@ -458,8 +431,7 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
info.size = cb;
/* Copy data to write to flash */
- target_mem_write_words(target, info.source, (void*) source,
- info.size);
+ target_mem_write(t, info.source, source, info.size);
/* Move pointers early */
destination += cb;
@@ -467,19 +439,13 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
size -= cb;
/* Copy parameters */
- target_mem_write_words(target, STM32Lx_STUB_INFO_PHYS,
- (void*) &info, sizeof(info));
+ target_mem_write(t, STM32Lx_STUB_INFO_PHYS,
+ &info, sizeof(info));
/* Execute stub */
- target_pc_write(target, STM32Lx_STUB_PHYS);
- if (target_check_error(target))
- return -1;
- target_halt_resume(target, 0);
- while (!target_halt_wait(target))
- ;
+ cortexm_run_stub(t, STM32Lx_STUB_PHYS, 0, 0, 0, 0);
- if (adiv5_ap_mem_read(adiv5_target_ap(target),
- STM32Lx_NVM_SR(nvm))
+ if (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_ERR_M)
return -1;
}
@@ -491,19 +457,19 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
/** Erase a region of NVM for STM32Lx. This is the lead function and
it will invoke an implementation, stubbed or not depending on the
options and the range of addresses. */
-static int stm32lx_nvm_erase(struct target_s* target, uint32_t addr, size_t size)
+static int stm32lx_nvm_erase(target *t, uint32_t addr, size_t size)
{
if (addr >= STM32Lx_NVM_EEPROM_PHYS)
- return stm32lx_nvm_data_erase(target, addr, size);
+ return stm32lx_nvm_data_erase(t, addr, size);
/* Use stub if not inhibited, the MCU is in a non-exceptonal state
and there is stub. */
volatile uint32_t regs[20];
- target_regs_read(target, &regs);
+ target_regs_read(t, &regs);
if (inhibit_stubs || (regs[16] & 0xf))
- return stm32lx_nvm_prog_erase(target, addr, size);
+ return stm32lx_nvm_prog_erase(t, addr, size);
- return stm32lx_nvm_prog_erase_stubbed(target, addr, size);
+ return stm32lx_nvm_prog_erase_stubbed(t, addr, size);
}
@@ -512,13 +478,13 @@ static int stm32lx_nvm_erase(struct target_s* target, uint32_t addr, size_t size
the options and the range of addresses. Data (EEPROM) writes
don't have to care about alignment, but the program flash does.
There is a fixup for unaligned program flash writes. */
-static int stm32lx_nvm_write(struct target_s* target,
+static int stm32lx_nvm_write(target *t,
uint32_t destination,
const uint8_t* source,
size_t size)
{
if (destination >= STM32Lx_NVM_EEPROM_PHYS)
- return stm32lx_nvm_data_write(target, destination, source,
+ return stm32lx_nvm_data_write(t, destination, source,
size);
/* Unaligned destinations. To make this feature simple to
@@ -541,12 +507,12 @@ static int stm32lx_nvm_write(struct target_s* target,
/* Skip stub if the MCU is in a questionable state, or if the
user asks us to avoid stubs. */
volatile uint32_t regs[20];
- target_regs_read(target, &regs);
+ target_regs_read(t, &regs);
if (inhibit_stubs || (regs[16] & 0xf))
- return stm32lx_nvm_prog_write(target, destination, source,
+ return stm32lx_nvm_prog_write(t, destination, source,
size);
- return stm32lx_nvm_prog_write_stubbed(target, destination, source,
+ return stm32lx_nvm_prog_write_stubbed(t, destination, source,
size);
}
@@ -555,50 +521,46 @@ static int stm32lx_nvm_write(struct target_s* target,
interface. This is slower than stubbed versions(see NOTES). The
flash array is erased for all pages from addr to addr+len
inclusive. NVM register file address chosen from target. */
-static int stm32lx_nvm_prog_erase(struct target_s* target,
- uint32_t addr, size_t len)
+static int stm32lx_nvm_prog_erase(target *t, uint32_t addr, size_t len)
{
- ADIv5_AP_t* ap = adiv5_target_ap(target);
- const size_t page_size = stm32lx_nvm_prog_page_size(target);
- const uint32_t nvm = stm32lx_nvm_phys(target);
+ const size_t page_size = stm32lx_nvm_prog_page_size(t);
+ const uint32_t nvm = stm32lx_nvm_phys(t);
/* Word align */
len += (addr & 3);
addr &= ~3;
- if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
+ if (!stm32lx_nvm_prog_data_unlock(t, nvm))
return -1;
/* Flash page erase instruction */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_PROG);
- {
- uint32_t pecr = adiv5_ap_mem_read(ap, STM32Lx_NVM_PECR(nvm));
- if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
- != (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
- return -1;
- }
+ uint32_t pecr = target_mem_read32(t, STM32Lx_NVM_PECR(nvm));
+ if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
+ != (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
+ return -1;
/* Clear errors. Note that this only works when we wait for the NVM
block to complete the last operation. */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
+ target_mem_write32(t, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
while (len > 0) {
/* Write first word of page to 0 */
- adiv5_ap_mem_write(ap, addr, 0);
+ target_mem_write32(t, addr, 0);
len -= page_size;
addr += page_size;
}
/* Disable further programming by locking PECR */
- stm32lx_nvm_lock(ap, nvm);
+ stm32lx_nvm_lock(t, nvm);
/* Wait for completion or an error */
while (1) {
- uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
- if (target_check_error(target))
+ uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
+ if (target_check_error(t))
return -1;
if (sr & STM32Lx_NVM_SR_BSY)
continue;
@@ -614,14 +576,13 @@ static int stm32lx_nvm_prog_erase(struct target_s* target,
/** Write to program flash using operations through the debug
interface. This is slower than the stubbed write(see NOTES).
NVM register file address chosen from target. */
-static int stm32lx_nvm_prog_write(struct target_s* target,
+static int stm32lx_nvm_prog_write(target *t,
uint32_t destination,
const uint8_t* source_8,
size_t size)
{
- ADIv5_AP_t* ap = adiv5_target_ap(target);
- const uint32_t nvm = stm32lx_nvm_phys(target);
- const bool is_stm32l1 = stm32lx_is_stm32l1(target);
+ const uint32_t nvm = stm32lx_nvm_phys(t);
+ const bool is_stm32l1 = stm32lx_is_stm32l1(t);
/* We can only handle word aligned writes and even
word-multiple ranges. The stm32lx's cannot perform
@@ -630,19 +591,19 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
if ((destination & 3) || (size & 3))
return -1;
- if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
+ if (!stm32lx_nvm_prog_data_unlock(t, nvm))
return -1;
- const size_t half_page_size = stm32lx_nvm_prog_page_size(target)/2;
+ const size_t half_page_size = stm32lx_nvm_prog_page_size(t)/2;
uint32_t* source = (uint32_t*) source_8;
while (size > 0) {
/* Wait for BSY to clear because we cannot write the PECR until
the previous operation completes on STM32Lxxx. */
- while (adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm))
+ while (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_BSY)
- if (target_check_error(target)) {
+ if (target_check_error(t)) {
return -1;
}
@@ -650,7 +611,7 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
// than a half page to write
if (size < half_page_size
|| (destination & (half_page_size - 1))) {
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
is_stm32l1
? 0
: STM32Lx_NVM_PECR_PROG);
@@ -661,31 +622,31 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
c = size;
size -= c;
- target_mem_write_words(target, destination, source, c);
+ target_mem_write(t, destination, source, c);
source += c/4;
destination += c;
}
// Or we are writing a half-page(s)
else {
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_PROG
| STM32Lx_NVM_PECR_FPRG);
size_t c = size & ~(half_page_size - 1);
size -= c;
- target_mem_write_words(target, destination, source, c);
+ target_mem_write(t, destination, source, c);
source += c/4;
destination += c;
}
}
/* Disable further programming by locking PECR */
- stm32lx_nvm_lock(ap, nvm);
+ stm32lx_nvm_lock(t, nvm);
/* Wait for completion or an error */
while (1) {
- uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
- if (target_check_error(target)) {
+ uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
+ if (target_check_error(t)) {
return -1;
}
if (sr & STM32Lx_NVM_SR_BSY)
@@ -704,46 +665,43 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
interface . The flash is erased for all pages from addr to
addr+len, inclusive, on a word boundary. NVM register file
address chosen from target. */
-static int stm32lx_nvm_data_erase(struct target_s* target,
+static int stm32lx_nvm_data_erase(target *t,
uint32_t addr, size_t len)
{
- ADIv5_AP_t* ap = adiv5_target_ap(target);
- const size_t page_size = stm32lx_nvm_data_page_size(target);
- const uint32_t nvm = stm32lx_nvm_phys(target);
+ const size_t page_size = stm32lx_nvm_data_page_size(t);
+ const uint32_t nvm = stm32lx_nvm_phys(t);
/* Word align */
len += (addr & 3);
addr &= ~3;
- if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
+ if (!stm32lx_nvm_prog_data_unlock(t, nvm))
return -1;
/* Flash data erase instruction */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA);
- {
- uint32_t pecr = adiv5_ap_mem_read(ap, STM32Lx_NVM_PECR(nvm));
- if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
- != (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
- return -1;
- }
+ uint32_t pecr = target_mem_read32(t, STM32Lx_NVM_PECR(nvm));
+ if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
+ != (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
+ return -1;
while (len > 0) {
/* Write first word of page to 0 */
- adiv5_ap_mem_write(ap, addr, 0);
+ target_mem_write32(t, addr, 0);
len -= page_size;
addr += page_size;
}
/* Disable further programming by locking PECR */
- stm32lx_nvm_lock(ap, nvm);
+ stm32lx_nvm_lock(t, nvm);
/* Wait for completion or an error */
while (1) {
- uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
- if (target_check_error(target))
+ uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
+ if (target_check_error(t))
return -1;
if (sr & STM32Lx_NVM_SR_BSY)
continue;
@@ -760,40 +718,38 @@ static int stm32lx_nvm_data_erase(struct target_s* target,
NVM register file address chosen from target. Unaligned
destination writes are supported (though unaligned sources are
not). */
-static int stm32lx_nvm_data_write(struct target_s* target,
+static int stm32lx_nvm_data_write(target *t,
uint32_t destination,
const uint8_t* source_8,
size_t size)
{
- ADIv5_AP_t* ap = adiv5_target_ap(target);
- const uint32_t nvm = stm32lx_nvm_phys(target);
- const bool is_stm32l1 = stm32lx_is_stm32l1(target);
- uint32_t* source = (uint32_t*) source_8;
+ const uint32_t nvm = stm32lx_nvm_phys(t);
+ const bool is_stm32l1 = stm32lx_is_stm32l1(t);
+ uint32_t* source = (uint32_t*) source_8;
- if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
+ if (!stm32lx_nvm_prog_data_unlock(t, nvm))
return -1;
-
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA);
while (size) {
size -= 4;
uint32_t v = *source++;
- adiv5_ap_mem_write(ap, destination, v);
+ target_mem_write32(t, destination, v);
destination += 4;
- if (target_check_error(target))
+ if (target_check_error(t))
return -1;
}
/* Disable further programming by locking PECR */
- stm32lx_nvm_lock(ap, nvm);
+ stm32lx_nvm_lock(t, nvm);
/* Wait for completion or an error */
while (1) {
- uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
- if (target_check_error(target))
+ uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
+ if (target_check_error(t))
return -1;
if (sr & STM32Lx_NVM_SR_BSY)
continue;
@@ -814,16 +770,15 @@ static int stm32lx_nvm_data_write(struct target_s* target,
The return value is true if the write succeeded. */
static bool stm32lx_option_write(target *t, uint32_t address, uint32_t value)
{
- ADIv5_AP_t* ap = adiv5_target_ap(t);
const uint32_t nvm = stm32lx_nvm_phys(t);
/* Erase and program option in one go. */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_FIX);
- adiv5_ap_mem_write(ap, address, value);
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_FIX);
+ target_mem_write32(t, address, value);
uint32_t sr;
do {
- sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
+ sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
} while (sr & STM32Lx_NVM_SR_BSY);
return !(sr & STM32Lx_NVM_SR_ERR_M);
@@ -840,29 +795,28 @@ static bool stm32lx_option_write(target *t, uint32_t address, uint32_t value)
static bool stm32lx_eeprom_write(target *t, uint32_t address,
size_t cb, uint32_t value)
{
- ADIv5_AP_t* ap = adiv5_target_ap(t);
const uint32_t nvm = stm32lx_nvm_phys(t);
const bool is_stm32l1 = stm32lx_is_stm32l1(t);
/* Clear errors. */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
+ target_mem_write32(t, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
/* Erase and program option in one go. */
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
(is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA)
| STM32Lx_NVM_PECR_FIX);
if (cb == 4)
- adiv5_ap_mem_write(ap, address, value);
+ target_mem_write32(t, address, value);
else if (cb == 2)
- adiv5_ap_mem_write_halfword(ap, address, value);
+ target_mem_write16(t, address, value);
else if (cb == 1)
- adiv5_ap_mem_write_byte(ap, address, value);
+ target_mem_write8(t, address, value);
else
return false;
uint32_t sr;
do {
- sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
+ sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
} while (sr & STM32Lx_NVM_SR_BSY);
return !(sr & STM32Lx_NVM_SR_ERR_M);
@@ -889,11 +843,10 @@ static bool stm32lx_cmd_stubs(target* t,
static bool stm32lx_cmd_option(target* t, int argc, char** argv)
{
- ADIv5_AP_t* ap = adiv5_target_ap(t);
const uint32_t nvm = stm32lx_nvm_phys(t);
const size_t opt_size = stm32lx_nvm_option_size(t);
- if (!stm32lx_nvm_opt_unlock(ap, nvm)) {
+ if (!stm32lx_nvm_opt_unlock(t, nvm)) {
gdb_out("unable to unlock NVM option bytes\n");
return true;
}
@@ -901,7 +854,7 @@ static bool stm32lx_cmd_option(target* t, int argc, char** argv)
size_t cb = strlen(argv[1]);
if (argc == 2 && !strncasecmp(argv[1], "obl_launch", cb)) {
- adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
+ target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_OBL_LAUNCH);
}
else if (argc == 4 && !strncasecmp(argv[1], "raw", cb)) {
@@ -935,7 +888,7 @@ static bool stm32lx_cmd_option(target* t, int argc, char** argv)
/* Report the current option values */
for(unsigned i = 0; i < opt_size; i += sizeof(uint32_t)) {
uint32_t addr = STM32Lx_NVM_OPT_PHYS + i;
- uint32_t val = adiv5_ap_mem_read(ap, addr);
+ uint32_t val = target_mem_read32(t, addr);
gdb_outf("0x%08x: 0x%04x 0x%04x %s\n",
addr, val & 0xffff, (val >> 16) & 0xffff,
((val & 0xffff) == ((~val >> 16) & 0xffff))
@@ -943,7 +896,7 @@ static bool stm32lx_cmd_option(target* t, int argc, char** argv)
}
if (stm32lx_is_stm32l1(t)) {
- uint32_t optr = adiv5_ap_mem_read(ap, STM32Lx_NVM_OPTR(nvm));
+ uint32_t optr = target_mem_read32(t, STM32Lx_NVM_OPTR(nvm));
uint8_t rdprot = (optr >> STM32L1_NVM_OPTR_RDPROT_S)
& STM32L1_NVM_OPTR_RDPROT_M;
if (rdprot == STM32L1_NVM_OPTR_RDPROT_0)
@@ -965,7 +918,7 @@ static bool stm32lx_cmd_option(target* t, int argc, char** argv)
(optr & STM32L1_NVM_OPTR_nBFB2) ? 1 : 0);
}
else {
- uint32_t optr = adiv5_ap_mem_read(ap, STM32Lx_NVM_OPTR(nvm));
+ uint32_t optr = target_mem_read32(t, STM32Lx_NVM_OPTR(nvm));
uint8_t rdprot = (optr >> STM32L0_NVM_OPTR_RDPROT_S)
& STM32L0_NVM_OPTR_RDPROT_M;
if (rdprot == STM32L0_NVM_OPTR_RDPROT_0)
@@ -998,17 +951,16 @@ usage:
STM32Lx_NVM_OPT_PHYS + opt_size - sizeof(uint32_t));
done:
- stm32lx_nvm_lock(ap, nvm);
+ stm32lx_nvm_lock(t, nvm);
return true;
}
static bool stm32lx_cmd_eeprom(target* t, int argc, char** argv)
{
- ADIv5_AP_t* ap = adiv5_target_ap(t);
const uint32_t nvm = stm32lx_nvm_phys(t);
- if (!stm32lx_nvm_prog_data_unlock(ap, nvm)) {
+ if (!stm32lx_nvm_prog_data_unlock(t, nvm)) {
gdb_out("unable to unlock EEPROM\n");
return true;
}
@@ -1062,6 +1014,6 @@ usage:
+ stm32lx_nvm_eeprom_size(t));
done:
- stm32lx_nvm_lock(ap, nvm);
+ stm32lx_nvm_lock(t, nvm);
return true;
}