Browse Source

Replace adiv5_ap_mem* functions with inline wrappers to target mem*.

pull/84/merge
Gareth McMullin 10 years ago
parent
commit
2bf54f9a72
  1. 60
      src/adiv5.c
  2. 100
      src/cortexm.c
  3. 6
      src/crc32.c
  4. 7
      src/include/adiv5.h
  5. 38
      src/include/target.h
  6. 15
      src/kinetis.c
  7. 2
      src/lmi.c
  8. 2
      src/lpc11xx.c
  9. 4
      src/lpc43xx.c
  10. 60
      src/nrf51.c
  11. 49
      src/sam3x.c
  12. 134
      src/samd.c
  13. 73
      src/stm32f1.c
  14. 56
      src/stm32f4.c
  15. 138
      src/stm32l0.c
  16. 40
      src/stm32l1.c

60
src/adiv5.c

@ -273,66 +273,6 @@ ap_mem_write(struct target_s *target, uint32_t dest, const void *src, size_t len
}
}
uint32_t adiv5_ap_mem_read(ADIv5_AP_t *ap, uint32_t addr)
{
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_WORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
return adiv5_ap_read(ap, ADIV5_AP_DRW);
}
void adiv5_ap_mem_write(ADIv5_AP_t *ap, uint32_t addr, uint32_t value)
{
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_WORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
adiv5_ap_write(ap, ADIV5_AP_DRW, value);
}
uint16_t adiv5_ap_mem_read_halfword(ADIv5_AP_t *ap, uint32_t addr)
{
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_HALFWORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
uint32_t v = adiv5_ap_read(ap, ADIV5_AP_DRW);
if (addr & 2)
return v >> 16;
else
return v & 0xFFFF;
}
void adiv5_ap_mem_write_halfword(ADIv5_AP_t *ap, uint32_t addr, uint16_t value)
{
uint32_t v = value;
if (addr & 2)
v <<= 16;
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_HALFWORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
adiv5_ap_write(ap, ADIV5_AP_DRW, v);
}
uint8_t adiv5_ap_mem_read_byte(ADIv5_AP_t *ap, uint32_t addr)
{
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_BYTE | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
uint32_t v = adiv5_ap_read(ap, ADIV5_AP_DRW);
return v >> ((addr & 3) * 8);
}
void adiv5_ap_mem_write_byte(ADIv5_AP_t *ap, uint32_t addr, uint8_t value)
{
uint32_t v = value << ((addr & 3) * 8);
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_BYTE | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
adiv5_ap_write(ap, ADIV5_AP_DRW, v);
}
void adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
{
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,

100
src/cortexm.c

@ -228,16 +228,16 @@ cortexm_probe(struct target_s *target)
target_add_commands(target, cortexm_cmd_list, cortexm_driver_str);
/* Probe for FP extension */
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint32_t cpacr = adiv5_ap_mem_read(ap, CORTEXM_CPACR);
uint32_t cpacr = target_mem_read32(target, CORTEXM_CPACR);
cpacr |= 0x00F00000; /* CP10 = 0b11, CP11 = 0b11 */
adiv5_ap_mem_write(ap, CORTEXM_CPACR, cpacr);
if (adiv5_ap_mem_read(ap, CORTEXM_CPACR) == cpacr) {
target_mem_write32(target, CORTEXM_CPACR, cpacr);
if (target_mem_read32(target, CORTEXM_CPACR) == cpacr) {
target->target_options |= TOPT_FLAVOUR_V7MF;
target->regs_size += sizeof(regnum_cortex_mf);
target->tdesc = tdesc_cortex_mf;
}
ADIv5_AP_t *ap = adiv5_target_ap(target);
struct cortexm_priv *priv = calloc(1, sizeof(*priv));
ap->priv = priv;
ap->priv_free = free;
@ -284,35 +284,35 @@ bool cortexm_attach(struct target_s *target)
return false;
/* Request halt on reset */
adiv5_ap_mem_write(ap, CORTEXM_DEMCR, priv->demcr);
target_mem_write32(target, CORTEXM_DEMCR, priv->demcr);
/* Reset DFSR flags */
adiv5_ap_mem_write(ap, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
target_mem_write32(target, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
/* size the break/watchpoint units */
priv->hw_breakpoint_max = CORTEXM_MAX_BREAKPOINTS;
r = adiv5_ap_mem_read(ap, CORTEXM_FPB_CTRL);
r = target_mem_read32(target, CORTEXM_FPB_CTRL);
if (((r >> 4) & 0xf) < priv->hw_breakpoint_max) /* only look at NUM_COMP1 */
priv->hw_breakpoint_max = (r >> 4) & 0xf;
priv->hw_watchpoint_max = CORTEXM_MAX_WATCHPOINTS;
r = adiv5_ap_mem_read(ap, CORTEXM_DWT_CTRL);
r = target_mem_read32(target, CORTEXM_DWT_CTRL);
if ((r >> 28) > priv->hw_watchpoint_max)
priv->hw_watchpoint_max = r >> 28;
/* Clear any stale breakpoints */
for(i = 0; i < priv->hw_breakpoint_max; i++) {
adiv5_ap_mem_write(ap, CORTEXM_FPB_COMP(i), 0);
target_mem_write32(target, CORTEXM_FPB_COMP(i), 0);
priv->hw_breakpoint[i] = 0;
}
/* Clear any stale watchpoints */
for(i = 0; i < priv->hw_watchpoint_max; i++) {
adiv5_ap_mem_write(ap, CORTEXM_DWT_FUNC(i), 0);
target_mem_write32(target, CORTEXM_DWT_FUNC(i), 0);
priv->hw_watchpoint[i].type = 0;
}
/* Flash Patch Control Register: set ENABLE */
adiv5_ap_mem_write(ap, CORTEXM_FPB_CTRL,
target_mem_write32(target, CORTEXM_FPB_CTRL,
CORTEXM_FPB_CTRL_KEY | CORTEXM_FPB_CTRL_ENABLE);
target->set_hw_bp = cortexm_set_hw_bp;
target->clear_hw_bp = cortexm_clear_hw_bp;
@ -336,14 +336,14 @@ void cortexm_detach(struct target_s *target)
/* Clear any stale breakpoints */
for(i = 0; i < priv->hw_breakpoint_max; i++)
adiv5_ap_mem_write(ap, CORTEXM_FPB_COMP(i), 0);
target_mem_write32(target, CORTEXM_FPB_COMP(i), 0);
/* Clear any stale watchpoints */
for(i = 0; i < priv->hw_watchpoint_max; i++)
adiv5_ap_mem_write(ap, CORTEXM_DWT_FUNC(i), 0);
target_mem_write32(target, CORTEXM_DWT_FUNC(i), 0);
/* Disable debug */
adiv5_ap_mem_write(ap, CORTEXM_DHCSR, CORTEXM_DHCSR_DBGKEY);
target_mem_write32(target, CORTEXM_DHCSR, CORTEXM_DHCSR_DBGKEY);
}
static int
@ -422,10 +422,8 @@ cortexm_regs_write(struct target_s *target, const void *data)
static uint32_t
cortexm_pc_read(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
adiv5_ap_mem_write(ap, CORTEXM_DCRSR, 0x0F);
return adiv5_ap_mem_read(ap, CORTEXM_DCRDR);
target_mem_write32(target, CORTEXM_DCRSR, 0x0F);
return target_mem_read32(target, CORTEXM_DCRDR);
return 0;
}
@ -433,10 +431,8 @@ cortexm_pc_read(struct target_s *target)
static int
cortexm_pc_write(struct target_s *target, const uint32_t val)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
adiv5_ap_mem_write(ap, CORTEXM_DCRDR, val);
adiv5_ap_mem_write(ap, CORTEXM_DCRSR, CORTEXM_DCRSR_REGWnR | 0x0F);
target_mem_write32(target, CORTEXM_DCRDR, val);
target_mem_write32(target, CORTEXM_DCRSR, CORTEXM_DCRSR_REGWnR | 0x0F);
return 0;
}
@ -446,26 +442,24 @@ cortexm_pc_write(struct target_s *target, const uint32_t val)
static void
cortexm_reset(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
jtagtap_srst(true);
jtagtap_srst(false);
/* Read DHCSR here to clear S_RESET_ST bit before reset */
adiv5_ap_mem_read(ap, CORTEXM_DHCSR);
target_mem_read32(target, CORTEXM_DHCSR);
/* Request system reset from NVIC: SRST doesn't work correctly */
/* This could be VECTRESET: 0x05FA0001 (reset only core)
* or SYSRESETREQ: 0x05FA0004 (system reset)
*/
adiv5_ap_mem_write(ap, CORTEXM_AIRCR,
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
target_mem_write32(target, CORTEXM_AIRCR,
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
/* Poll for release from reset */
while(adiv5_ap_mem_read(ap, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
while (target_mem_read32(target, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
/* Reset DFSR flags */
adiv5_ap_mem_write(ap, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
target_mem_write32(target, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
}
static void
@ -474,8 +468,9 @@ cortexm_halt_request(struct target_s *target)
ADIv5_AP_t *ap = adiv5_target_ap(target);
ap->dp->allow_timeout = false;
adiv5_ap_mem_write(ap, CORTEXM_DHCSR,
CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_HALT | CORTEXM_DHCSR_C_DEBUGEN);
target_mem_write32(target, CORTEXM_DHCSR,
CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_HALT |
CORTEXM_DHCSR_C_DEBUGEN);
}
static int
@ -483,14 +478,14 @@ cortexm_halt_wait(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
struct cortexm_priv *priv = ap->priv;
if (!(adiv5_ap_mem_read(ap, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_HALT))
if (!(target_mem_read32(target, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_HALT))
return 0;
ap->dp->allow_timeout = false;
/* We've halted. Let's find out why. */
uint32_t dfsr = adiv5_ap_mem_read(ap, CORTEXM_DFSR);
adiv5_ap_mem_write(ap, CORTEXM_DFSR, dfsr); /* write back to reset */
uint32_t dfsr = target_mem_read32(target, CORTEXM_DFSR);
target_mem_write32(target, CORTEXM_DFSR, dfsr); /* write back to reset */
if ((dfsr & CORTEXM_DFSR_VCATCH) && cortexm_fault_unwind(target))
return SIGSEGV;
@ -502,7 +497,7 @@ cortexm_halt_wait(struct target_s *target)
* call. */
uint32_t pc = cortexm_pc_read(target);
uint16_t bkpt_instr;
target_mem_read(target, &bkpt_instr, pc, 2);
bkpt_instr = target_mem_read16(target, pc);
if (bkpt_instr == 0xBEAB) {
int n = cortexm_hostio_request(target);
if (n > 0) {
@ -535,27 +530,26 @@ void cortexm_halt_resume(struct target_s *target, bool step)
/* Disable interrupts while single stepping... */
if(step != priv->stepping) {
adiv5_ap_mem_write(ap, CORTEXM_DHCSR, dhcsr | CORTEXM_DHCSR_C_HALT);
target_mem_write32(target, CORTEXM_DHCSR, dhcsr | CORTEXM_DHCSR_C_HALT);
priv->stepping = step;
}
if (priv->on_bkpt) {
uint32_t pc = cortexm_pc_read(target);
if ((adiv5_ap_mem_read_halfword(ap, pc) & 0xFF00) == 0xBE00)
if ((target_mem_read16(target, pc) & 0xFF00) == 0xBE00)
cortexm_pc_write(target, pc + 2);
}
adiv5_ap_mem_write(ap, CORTEXM_DHCSR, dhcsr);
target_mem_write32(target, CORTEXM_DHCSR, dhcsr);
ap->dp->allow_timeout = true;
}
static int cortexm_fault_unwind(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint32_t hfsr = adiv5_ap_mem_read(ap, CORTEXM_HFSR);
uint32_t cfsr = adiv5_ap_mem_read(ap, CORTEXM_CFSR);
adiv5_ap_mem_write(ap, CORTEXM_HFSR, hfsr);/* write back to reset */
adiv5_ap_mem_write(ap, CORTEXM_CFSR, cfsr);/* write back to reset */
uint32_t hfsr = target_mem_read32(target, CORTEXM_HFSR);
uint32_t cfsr = target_mem_read32(target, CORTEXM_CFSR);
target_mem_write32(target, CORTEXM_HFSR, hfsr);/* write back to reset */
target_mem_write32(target, CORTEXM_CFSR, cfsr);/* write back to reset */
/* We check for FORCED in the HardFault Status Register or
* for a configurable fault to avoid catching core resets */
if((hfsr & CORTEXM_HFSR_FORCED) || cfsr) {
@ -598,7 +592,7 @@ static int cortexm_fault_unwind(struct target_s *target)
/* Reset exception state to allow resuming from restored
* state.
*/
adiv5_ap_mem_write(ap, CORTEXM_AIRCR,
target_mem_write32(target, CORTEXM_AIRCR,
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_VECTCLRACTIVE);
/* Write pre-exception registers back to core */
@ -630,7 +624,7 @@ cortexm_set_hw_bp(struct target_s *target, uint32_t addr)
priv->hw_breakpoint[i] = addr | 1;
adiv5_ap_mem_write(ap, CORTEXM_FPB_COMP(i), val);
target_mem_write32(target, CORTEXM_FPB_COMP(i), val);
return 0;
}
@ -649,7 +643,7 @@ cortexm_clear_hw_bp(struct target_s *target, uint32_t addr)
priv->hw_breakpoint[i] = 0;
adiv5_ap_mem_write(ap, CORTEXM_FPB_COMP(i), 0);
target_mem_write32(target, CORTEXM_FPB_COMP(i), 0);
return 0;
}
@ -683,7 +677,7 @@ cortexm_set_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_t
for(i = 0; i < priv->hw_watchpoint_max; i++)
if((priv->hw_watchpoint[i].type == 0) &&
((adiv5_ap_mem_read(ap, CORTEXM_DWT_FUNC(i)) & 0xF) == 0))
((target_mem_read32(target, CORTEXM_DWT_FUNC(i)) & 0xF) == 0))
break;
if(i == priv->hw_watchpoint_max) return -2;
@ -692,9 +686,9 @@ cortexm_set_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_t
priv->hw_watchpoint[i].addr = addr;
priv->hw_watchpoint[i].size = len;
adiv5_ap_mem_write(ap, CORTEXM_DWT_COMP(i), addr);
adiv5_ap_mem_write(ap, CORTEXM_DWT_MASK(i), len);
adiv5_ap_mem_write(ap, CORTEXM_DWT_FUNC(i), type |
target_mem_write32(target, CORTEXM_DWT_COMP(i), addr);
target_mem_write32(target, CORTEXM_DWT_MASK(i), len);
target_mem_write32(target, CORTEXM_DWT_FUNC(i), type |
((target->target_options & TOPT_FLAVOUR_V6M) ? 0: CORTEXM_DWT_FUNC_DATAVSIZE_WORD));
return 0;
@ -732,7 +726,7 @@ cortexm_clear_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_
priv->hw_watchpoint[i].type = 0;
adiv5_ap_mem_write(ap, CORTEXM_DWT_FUNC(i), 0);
target_mem_write32(target, CORTEXM_DWT_FUNC(i), 0);
return 0;
}
@ -747,7 +741,7 @@ cortexm_check_hw_wp(struct target_s *target, uint32_t *addr)
for(i = 0; i < priv->hw_watchpoint_max; i++)
/* if SET and MATCHED then break */
if(priv->hw_watchpoint[i].type &&
(adiv5_ap_mem_read(ap, CORTEXM_DWT_FUNC(i)) &
(target_mem_read32(target, CORTEXM_DWT_FUNC(i)) &
CORTEXM_DWT_FUNC_MATCHED))
break;
@ -781,7 +775,7 @@ static bool cortexm_vector_catch(target *t, int argc, char *argv[])
else
priv->demcr &= ~tmp;
adiv5_ap_mem_write(ap, CORTEXM_DEMCR, priv->demcr);
target_mem_write32(t, CORTEXM_DEMCR, priv->demcr);
}
gdb_out("Catching vectors: ");

6
src/crc32.c

@ -100,7 +100,7 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
uint8_t byte;
while (len--) {
target_mem_read(target, &byte, base, 1);
byte = target_mem_read8(target, base);
crc = crc32_calc(crc, byte);
base++;
@ -118,7 +118,7 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
CRC_CR |= CRC_CR_RESET;
while (len > 3) {
target_mem_read(target, &data, base, 4);
data = target_mem_read32(target, base);
CRC_DR = __builtin_bswap32(data);
base += 4;
@ -128,7 +128,7 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
crc = CRC_DR;
while (len--) {
target_mem_read(target, &data, base++, 1);
data = target_mem_read8(target, base++);
crc ^= data << 24;
for (i = 0; i < 8; i++) {

7
src/include/adiv5.h

@ -166,13 +166,6 @@ void adiv5_ap_ref(ADIv5_AP_t *ap);
void adiv5_dp_unref(ADIv5_DP_t *dp);
void adiv5_ap_unref(ADIv5_AP_t *ap);
uint32_t adiv5_ap_mem_read(ADIv5_AP_t *ap, uint32_t addr);
void adiv5_ap_mem_write(ADIv5_AP_t *ap, uint32_t addr, uint32_t value);
uint16_t adiv5_ap_mem_read_halfword(ADIv5_AP_t *ap, uint32_t addr);
void adiv5_ap_mem_write_halfword(ADIv5_AP_t *ap, uint32_t addr, uint16_t value);
uint8_t adiv5_ap_mem_read_byte(ADIv5_AP_t *ap, uint32_t addr);
void adiv5_ap_mem_write_byte(ADIv5_AP_t *ap, uint32_t addr, uint8_t value);
void adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value);
uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr);

38
src/include/target.h

@ -111,7 +111,6 @@ target *target_attach(target *t, target_destroy_callback destroy_cb);
#define target_hostio_reply(target, recode, errcode) \
(target)->hostio_reply((target), (retcode), (errcode))
struct target_s {
/* Notify controlling debugger if target is lost */
target_destroy_callback destroy_callback;
@ -187,6 +186,43 @@ target *target_new(unsigned size);
void target_list_free(void);
void target_add_commands(target *t, const struct command_s *cmds, const char *name);
static inline uint32_t target_mem_read32(target *t, uint32_t addr)
{
uint32_t ret;
target_mem_read(t, &ret, addr, sizeof(ret));
return ret;
}
static inline void target_mem_write32(target *t, uint32_t addr, uint32_t value)
{
target_mem_write(t, addr, &value, sizeof(value));
}
static inline uint16_t target_mem_read16(target *t, uint32_t addr)
{
uint16_t ret;
target_mem_read(t, &ret, addr, sizeof(ret));
return ret;
}
static inline void target_mem_write16(target *t, uint32_t addr, uint16_t value)
{
target_mem_write(t, addr, &value, sizeof(value));
}
static inline uint8_t target_mem_read8(target *t, uint32_t addr)
{
uint8_t ret;
target_mem_read(t, &ret, addr, sizeof(ret));
return ret;
}
static inline void target_mem_write8(target *t, uint32_t addr, uint8_t value)
{
target_mem_write(t, addr, &value, sizeof(value));
}
/* Probe for various targets.
* Actual functions implemented in their respective drivers.
*/

15
src/kinetis.c

@ -72,7 +72,7 @@ static const char kl25_xml_memory_map[] = "<?xml version=\"1.0\"?>"
bool kinetis_probe(struct target_s *t)
{
uint32_t sdid = adiv5_ap_mem_read(adiv5_target_ap(t), SIM_SDID);
uint32_t sdid = target_mem_read32(t, SIM_SDID);
switch (sdid >> 20) {
case 0x251:
t->driver = "KL25";
@ -87,12 +87,11 @@ bool kinetis_probe(struct target_s *t)
static bool
kl25_command(struct target_s *t, uint8_t cmd, uint32_t addr, const uint8_t data[8])
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint8_t fstat;
/* Wait for CCIF to be high */
do {
fstat = adiv5_ap_mem_read_byte(ap, FTFA_FSTAT);
fstat = target_mem_read8(t, FTFA_FSTAT);
/* Check ACCERR and FPVIOL are zero in FSTAT */
if (fstat & (FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL))
return false;
@ -101,18 +100,18 @@ kl25_command(struct target_s *t, uint8_t cmd, uint32_t addr, const uint8_t data[
/* Write command to FCCOB */
addr &= 0xffffff;
addr |= (uint32_t)cmd << 24;
adiv5_ap_mem_write(ap, FTFA_FCCOB(0), addr);
target_mem_write32(t, FTFA_FCCOB(0), addr);
if (data) {
adiv5_ap_mem_write(ap, FTFA_FCCOB(4), *(uint32_t*)&data[0]);
adiv5_ap_mem_write(ap, FTFA_FCCOB(8), *(uint32_t*)&data[4]);
target_mem_write32(t, FTFA_FCCOB(4), *(uint32_t*)&data[0]);
target_mem_write32(t, FTFA_FCCOB(8), *(uint32_t*)&data[4]);
}
/* Enable execution by clearing CCIF */
adiv5_ap_mem_write_byte(ap, FTFA_FSTAT, FTFA_FSTAT_CCIF);
target_mem_write8(t, FTFA_FSTAT, FTFA_FSTAT_CCIF);
/* Wait for execution to complete */
do {
fstat = adiv5_ap_mem_read_byte(ap, FTFA_FSTAT);
fstat = target_mem_read8(t, FTFA_FSTAT);
/* Check ACCERR and FPVIOL are zero in FSTAT */
if (fstat & (FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL))
return false;

2
src/lmi.c

@ -100,7 +100,7 @@ static const uint16_t lmi_flash_write_stub[] = {
bool lmi_probe(struct target_s *target)
{
uint32_t did1 = adiv5_ap_mem_read(adiv5_target_ap(target), 0x400FE004);
uint32_t did1 = target_mem_read32(target, 0x400FE004);
switch (did1 >> 16) {
case 0x1049: /* LM3S3748 */
target->driver = lmi_driver_str;

2
src/lpc11xx.c

@ -108,7 +108,7 @@ lpc11xx_probe(struct target_s *target)
uint32_t idcode;
/* read the device ID register */
idcode = adiv5_ap_mem_read(adiv5_target_ap(target), 0x400483F4);
idcode = target_mem_read32(target, 0x400483F4);
switch (idcode) {

4
src/lpc43xx.c

@ -170,8 +170,8 @@ bool lpc43xx_probe(struct target_s *target)
{
uint32_t chipid, cpuid;
chipid = adiv5_ap_mem_read(adiv5_target_ap(target), LPC43XX_CHIPID);
cpuid = adiv5_ap_mem_read(adiv5_target_ap(target), ARM_CPUID);
chipid = target_mem_read32(target, LPC43XX_CHIPID);
cpuid = target_mem_read32(target, ARM_CPUID);
switch(chipid) {
case 0x4906002B: /* Parts with on-chip flash */

60
src/nrf51.c

@ -136,9 +136,7 @@ static const uint16_t nrf51_flash_write_stub[] = {
bool nrf51_probe(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
target->idcode = adiv5_ap_mem_read(ap, NRF51_FICR_CONFIGID) & 0xFFFF;
target->idcode = target_mem_read32(target, NRF51_FICR_CONFIGID) & 0xFFFF;
switch (target->idcode) {
case 0x001D:
@ -165,32 +163,29 @@ bool nrf51_probe(struct target_s *target)
static int nrf51_flash_erase(struct target_s *target, uint32_t addr, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
addr &= ~(NRF51_PAGE_SIZE - 1);
len &= ~(NRF51_PAGE_SIZE - 1);
/* Enable erase */
adiv5_ap_mem_write(ap, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN);
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN);
/* Poll for NVMC_READY */
while(adiv5_ap_mem_read(ap, NRF51_NVMC_READY) == 0)
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
if(target_check_error(target))
return -1;
while (len) {
if (addr == NRF51_UICR) { // Special Case
/* Write to the ERASE_UICR register to erase */
adiv5_ap_mem_write(ap, NRF51_NVMC_ERASEUICR, 0x1);
target_mem_write32(target, NRF51_NVMC_ERASEUICR, 0x1);
} else { // Standard Flash Page
/* Write address of first word in page to erase it */
adiv5_ap_mem_write(ap, NRF51_NVMC_ERASEPAGE, addr);
target_mem_write32(target, NRF51_NVMC_ERASEPAGE, addr);
}
/* Poll for NVMC_READY */
while(adiv5_ap_mem_read(ap, NRF51_NVMC_READY) == 0)
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
if(target_check_error(target))
return -1;
@ -199,10 +194,10 @@ static int nrf51_flash_erase(struct target_s *target, uint32_t addr, size_t len)
}
/* Return to read-only */
adiv5_ap_mem_write(ap, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
/* Poll for NVMC_READY */
while(adiv5_ap_mem_read(ap, NRF51_NVMC_READY) == 0)
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
if(target_check_error(target))
return -1;
@ -212,7 +207,6 @@ static int nrf51_flash_erase(struct target_s *target, uint32_t addr, size_t len)
static int nrf51_flash_write(struct target_s *target, uint32_t dest,
const uint8_t *src, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint32_t offset = dest % 4;
uint32_t words = (offset + len + 3) / 4;
uint32_t data[2 + words];
@ -225,10 +219,10 @@ static int nrf51_flash_write(struct target_s *target, uint32_t dest,
memcpy((uint8_t *)&data[2] + offset, src, len);
/* Enable write */
adiv5_ap_mem_write(ap, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_WEN);
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_WEN);
/* Poll for NVMC_READY */
while(adiv5_ap_mem_read(ap, NRF51_NVMC_READY) == 0)
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
if(target_check_error(target))
return -1;
@ -244,30 +238,28 @@ static int nrf51_flash_write(struct target_s *target, uint32_t dest,
while(!target_halt_wait(target));
/* Return to read-only */
adiv5_ap_mem_write(ap, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
return 0;
}
static bool nrf51_cmd_erase_all(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
gdb_out("erase..\n");
/* Enable erase */
adiv5_ap_mem_write(ap, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN);
target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN);
/* Poll for NVMC_READY */
while(adiv5_ap_mem_read(ap, NRF51_NVMC_READY) == 0)
while (target_mem_read32(t, NRF51_NVMC_READY) == 0)
if(target_check_error(t))
return false;
/* Erase all */
adiv5_ap_mem_write(ap, NRF51_NVMC_ERASEALL, 1);
target_mem_write32(t, NRF51_NVMC_ERASEALL, 1);
/* Poll for NVMC_READY */
while(adiv5_ap_mem_read(ap, NRF51_NVMC_READY) == 0)
while (target_mem_read32(t, NRF51_NVMC_READY) == 0)
if(target_check_error(t))
return false;
@ -276,28 +268,22 @@ static bool nrf51_cmd_erase_all(target *t)
static bool nrf51_cmd_read_hwid(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t hwid = adiv5_ap_mem_read(ap, NRF51_FICR_CONFIGID) & 0xFFFF;
uint32_t hwid = target_mem_read32(t, NRF51_FICR_CONFIGID) & 0xFFFF;
gdb_outf("Hardware ID: 0x%04X\n", hwid);
return true;
}
static bool nrf51_cmd_read_fwid(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t fwid = (adiv5_ap_mem_read(ap, NRF51_FICR_CONFIGID) >> 16) & 0xFFFF;
uint32_t fwid = (target_mem_read32(t, NRF51_FICR_CONFIGID) >> 16) & 0xFFFF;
gdb_outf("Firmware ID: 0x%04X\n", fwid);
return true;
}
static bool nrf51_cmd_read_deviceid(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t deviceid_low = adiv5_ap_mem_read(ap, NRF51_FICR_DEVICEID_LOW);
uint32_t deviceid_high = adiv5_ap_mem_read(ap, NRF51_FICR_DEVICEID_HIGH);
uint32_t deviceid_low = target_mem_read32(t, NRF51_FICR_DEVICEID_LOW);
uint32_t deviceid_high = target_mem_read32(t, NRF51_FICR_DEVICEID_HIGH);
gdb_outf("Device ID: 0x%08X%08X\n", deviceid_high, deviceid_low);
@ -305,11 +291,9 @@ static bool nrf51_cmd_read_deviceid(target *t)
}
static bool nrf51_cmd_read_deviceaddr(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t addr_type = adiv5_ap_mem_read(ap, NRF51_FICR_DEVICEADDRTYPE);
uint32_t addr_low = adiv5_ap_mem_read(ap, NRF51_FICR_DEVICEADDR_LOW);
uint32_t addr_high = adiv5_ap_mem_read(ap, NRF51_FICR_DEVICEADDR_HIGH) & 0xFFFF;
uint32_t addr_type = target_mem_read32(t, NRF51_FICR_DEVICEADDRTYPE);
uint32_t addr_low = target_mem_read32(t, NRF51_FICR_DEVICEADDR_LOW);
uint32_t addr_high = target_mem_read32(t, NRF51_FICR_DEVICEADDR_HIGH) & 0xFFFF;
if ((addr_type & 1) == 0) {
gdb_outf("Publicly Listed Address: 0x%04X%08X\n", addr_high, addr_low);

49
src/sam3x.c

@ -148,9 +148,7 @@ static const char sam4s_xml_memory_map[] = "<?xml version=\"1.0\"?>"
bool sam3x_probe(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
target->idcode = adiv5_ap_mem_read(ap, SAM3X_CHIPID_CIDR);
target->idcode = target_mem_read32(target, SAM3X_CHIPID_CIDR);
/* FIXME: Check for all variants with similar flash interface */
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
@ -165,7 +163,7 @@ bool sam3x_probe(struct target_s *target)
return true;
}
target->idcode = adiv5_ap_mem_read(ap, SAM3N_CHIPID_CIDR);
target->idcode = target_mem_read32(target, SAM3N_CHIPID_CIDR);
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM3NxA | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3NxB | CHIPID_CIDR_EPROC_CM3:
@ -177,21 +175,21 @@ bool sam3x_probe(struct target_s *target)
target_add_commands(target, sam3x_cmd_list, "SAM3N");
return true;
}
target->idcode = adiv5_ap_mem_read(ap, SAM3S_CHIPID_CIDR);
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM3SxA | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3SxB | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3SxC | CHIPID_CIDR_EPROC_CM3:
target->driver = "Atmel SAM3S";
target->xml_mem_map = sam3n_xml_memory_map;
target->flash_erase = sam3x_flash_erase;
target->flash_write = sam3x_flash_write;
target_add_commands(target, sam3x_cmd_list, "SAM3S");
return true;
}
target->idcode = adiv5_ap_mem_read(ap, SAM4S_CHIPID_CIDR);
target->idcode = target_mem_read32(target, SAM3S_CHIPID_CIDR);
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM3SxA | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3SxB | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3SxC | CHIPID_CIDR_EPROC_CM3:
target->driver = "Atmel SAM3S";
target->xml_mem_map = sam3n_xml_memory_map;
target->flash_erase = sam3x_flash_erase;
target->flash_write = sam3x_flash_write;
target_add_commands(target, sam3x_cmd_list, "SAM3S");
return true;
}
target->idcode = target_mem_read32(target, SAM4S_CHIPID_CIDR);
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM4SxA | CHIPID_CIDR_EPROC_CM4:
case CHIPID_CIDR_ARCH_SAM4SxB | CHIPID_CIDR_EPROC_CM4:
@ -210,18 +208,16 @@ bool sam3x_probe(struct target_s *target)
static int
sam3x_flash_cmd(struct target_s *target, uint32_t base, uint8_t cmd, uint16_t arg)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
DEBUG("%s: base = 0x%08x cmd = 0x%02X, arg = 0x%06X\n",
__func__, base, cmd, arg);
adiv5_ap_mem_write(ap, EEFC_FCR(base),
EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8));
target_mem_write32(target, EEFC_FCR(base),
EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8));
while(!(adiv5_ap_mem_read(ap, EEFC_FSR(base)) & EEFC_FSR_FRDY))
while (!(target_mem_read32(target, EEFC_FSR(base)) & EEFC_FSR_FRDY))
if(target_check_error(target))
return -1;
uint32_t sr = adiv5_ap_mem_read(ap, EEFC_FSR(base));
uint32_t sr = target_mem_read32(target, EEFC_FSR(base));
return sr & EEFC_FSR_ERROR;
}
@ -394,11 +390,10 @@ static int sam3x_flash_write(struct target_s *target, uint32_t dest,
static bool sam3x_cmd_gpnvm_get(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t base = sam3x_flash_base(t, 0, NULL);
sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_GGPB, 0);
gdb_outf("GPNVM: 0x%08X\n", adiv5_ap_mem_read(ap, EEFC_FRR(base)));
gdb_outf("GPNVM: 0x%08X\n", target_mem_read32(t, EEFC_FRR(base)));
return true;
}

134
src/samd.c

@ -167,13 +167,12 @@ static const char samd_xml_memory_map[] = "<?xml version=\"1.0\"?>"
*/
uint64_t samd_read_pid(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint64_t pid = 0;
uint8_t i, j;
/* Five PID registers to read LSB first */
for (i = 0, j = 0; i < 5; i++, j += 8)
pid |= (adiv5_ap_mem_read(ap, SAMD_DSU_PID(i)) & 0xFF) << j;
pid |= (target_mem_read32(target, SAMD_DSU_PID(i)) & 0xFF) << j;
return pid;
}
@ -182,13 +181,12 @@ uint64_t samd_read_pid(struct target_s *target)
*/
uint32_t samd_read_cid(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint64_t cid = 0;
uint8_t i, j;
/* Four CID registers to read LSB first */
for (i = 0, j = 0; i < 4; i++, j += 8)
cid |= (adiv5_ap_mem_read(ap, SAMD_DSU_CID(i)) & 0xFF) << j;
cid |= (target_mem_read32(target, SAMD_DSU_CID(i)) & 0xFF) << j;
return cid;
}
@ -200,8 +198,6 @@ uint32_t samd_read_cid(struct target_s *target)
static void
samd_reset(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
/**
* SRST is not asserted here as it appears to reset the adiv5
* logic, meaning that subsequent adiv5_* calls PLATFORM_FATAL_ERROR.
@ -219,28 +215,28 @@ samd_reset(struct target_s *target)
*/
/* Read DHCSR here to clear S_RESET_ST bit before reset */
adiv5_ap_mem_read(ap, CORTEXM_DHCSR);
target_mem_read32(target, CORTEXM_DHCSR);
/* Request system reset from NVIC: SRST doesn't work correctly */
/* This could be VECTRESET: 0x05FA0001 (reset only core)
* or SYSRESETREQ: 0x05FA0004 (system reset)
*/
adiv5_ap_mem_write(ap, CORTEXM_AIRCR,
target_mem_write32(target, CORTEXM_AIRCR,
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
/* Exit extended reset */
if (adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT) &
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
SAMD_STATUSA_CRSTEXT) {
/* Write bit to clear from extended reset */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT,
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
SAMD_STATUSA_CRSTEXT);
}
/* Poll for release from reset */
while(adiv5_ap_mem_read(ap, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
while (target_mem_read32(target, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
/* Reset DFSR flags */
adiv5_ap_mem_write(ap, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
target_mem_write32(target, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
/* Clear any target errors */
target_check_error(target);
@ -255,16 +251,15 @@ samd_reset(struct target_s *target)
static void
samd20_revB_detach(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
cortexm_detach(target);
/* ---- Additional ---- */
/* Exit extended reset */
if (adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT) &
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
SAMD_STATUSA_CRSTEXT) {
/* Write bit to clear from extended reset */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT,
SAMD_STATUSA_CRSTEXT);
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
SAMD_STATUSA_CRSTEXT);
}
}
@ -277,16 +272,15 @@ samd20_revB_detach(struct target_s *target)
static void
samd20_revB_halt_resume(struct target_s *target, bool step)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
cortexm_halt_resume(target, step);
/* ---- Additional ---- */
/* Exit extended reset */
if (adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT) &
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
SAMD_STATUSA_CRSTEXT) {
/* Write bit to clear from extended reset */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT,
SAMD_STATUSA_CRSTEXT);
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
SAMD_STATUSA_CRSTEXT);
}
}
@ -376,7 +370,6 @@ struct samd_descr samd_parse_device_id(uint32_t did)
char variant_string[40];
bool samd_probe(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint32_t cid = samd_read_cid(target);
uint32_t pid = samd_read_pid(target);
@ -385,12 +378,13 @@ bool samd_probe(struct target_s *target)
(pid & SAMD_PID_MASK) == SAMD_PID_CONST_VALUE) {
/* Read the Device ID */
uint32_t did = adiv5_ap_mem_read(ap, SAMD_DSU_DID);
uint32_t did = target_mem_read32(target, SAMD_DSU_DID);
/* If the Device ID matches */
if ((did & SAMD_DID_MASK) == SAMD_DID_CONST_VALUE) {
uint32_t ctrlstat = adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT);
uint32_t ctrlstat = target_mem_read32(target,
SAMD_DSU_CTRLSTAT);
struct samd_descr samd = samd_parse_device_id(did);
/* Protected? */
@ -442,11 +436,11 @@ bool samd_probe(struct target_s *target)
if (!connect_assert_srst) {
/* We'll have to release the target from
* extended reset to make attach possible */
if (adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT) &
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
SAMD_STATUSA_CRSTEXT) {
/* Write bit to clear from extended reset */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT,
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
SAMD_STATUSA_CRSTEXT);
}
}
@ -463,17 +457,15 @@ bool samd_probe(struct target_s *target)
*/
static void samd_lock_current_address(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
/* Issue the unlock command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_LOCK);
target_mem_write32(target, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_LOCK);
}
static void samd_unlock_current_address(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
/* Issue the unlock command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_UNLOCK);
target_mem_write32(target, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_UNLOCK);
}
/**
@ -481,23 +473,22 @@ static void samd_unlock_current_address(struct target_s *target)
*/
static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
addr &= ~(SAMD_ROW_SIZE - 1);
len &= ~(SAMD_ROW_SIZE - 1);
while (len) {
/* Write address of first word in row to erase it */
/* Must be shifted right for 16-bit address, see Datasheet §20.8.8 Address */
adiv5_ap_mem_write(ap, SAMD_NVMC_ADDRESS, addr >> 1);
target_mem_write32(target, SAMD_NVMC_ADDRESS, addr >> 1);
/* Unlock */
samd_unlock_current_address(target);
/* Issue the erase command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_ERASEROW);
target_mem_write32(target, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_ERASEROW);
/* Poll for NVM Ready */
while ((adiv5_ap_mem_read(ap, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
if(target_check_error(target))
return -1;
@ -518,7 +509,6 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
const uint8_t *src, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
/* Find the size of our 32-bit data buffer */
uint32_t offset = dest % 4;
uint32_t words = (offset + len + 3) / 4;
@ -560,11 +550,11 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
samd_unlock_current_address(target);
/* Issue the write page command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA,
target_mem_write32(target, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE);
} else {
/* Write first word to set address */
adiv5_ap_mem_write(ap, addr, data[i]); addr += 4; i++;
target_mem_write32(target, addr, data[i]); addr += 4; i++;
/* Unlock */
samd_unlock_current_address(target);
@ -583,7 +573,7 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
}
/* Poll for NVM Ready */
while ((adiv5_ap_mem_read(ap, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
if(target_check_error(target))
return -1;
@ -599,18 +589,16 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
*/
static bool samd_cmd_erase_all(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
/* Clear the DSU status bits */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT,
target_mem_write32(t, SAMD_DSU_CTRLSTAT,
(SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL));
/* Erase all */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT, SAMD_CTRL_CHIP_ERASE);
target_mem_write32(t, SAMD_DSU_CTRLSTAT, SAMD_CTRL_CHIP_ERASE);
/* Poll for DSU Ready */
uint32_t status;
while (((status = adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT)) &
while (((status = target_mem_read32(t, SAMD_DSU_CTRLSTAT)) &
(SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL)) == 0)
if(target_check_error(t))
return false;
@ -641,20 +629,19 @@ static bool samd_cmd_erase_all(target *t)
*/
static bool samd_set_flashlock(target *t, uint16_t value)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t high = adiv5_ap_mem_read(ap, SAMD_NVM_USER_ROW_HIGH);
uint32_t low = adiv5_ap_mem_read(ap, SAMD_NVM_USER_ROW_LOW);
uint32_t high = target_mem_read32(t, SAMD_NVM_USER_ROW_HIGH);
uint32_t low = target_mem_read32(t, SAMD_NVM_USER_ROW_LOW);
/* Write address of a word in the row to erase it */
/* Must be shifted right for 16-bit address, see Datasheet §20.8.8 Address */
adiv5_ap_mem_write(ap, SAMD_NVMC_ADDRESS, SAMD_NVM_USER_ROW_LOW >> 1);
target_mem_write32(t, SAMD_NVMC_ADDRESS, SAMD_NVM_USER_ROW_LOW >> 1);
/* Issue the erase command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_ERASEAUXROW);
target_mem_write32(t, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_ERASEAUXROW);
/* Poll for NVM Ready */
while ((adiv5_ap_mem_read(ap, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
if(target_check_error(t))
return -1;
@ -662,12 +649,12 @@ static bool samd_set_flashlock(target *t, uint16_t value)
high = (high & 0x0000FFFF) | ((value << 16) & 0xFFFF0000);
/* Write back */
adiv5_ap_mem_write(ap, SAMD_NVM_USER_ROW_LOW, low);
adiv5_ap_mem_write(ap, SAMD_NVM_USER_ROW_HIGH, high);
target_mem_write32(t, SAMD_NVM_USER_ROW_LOW, low);
target_mem_write32(t, SAMD_NVM_USER_ROW_HIGH, high);
/* Issue the page write command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEAUXPAGE);
target_mem_write32(t, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEAUXPAGE);
return true;
}
@ -681,11 +668,9 @@ static bool samd_cmd_unlock_flash(target *t)
}
static bool samd_cmd_read_userrow(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
gdb_outf("User Row: 0x%08x%08x\n",
adiv5_ap_mem_read(ap, SAMD_NVM_USER_ROW_HIGH),
adiv5_ap_mem_read(ap, SAMD_NVM_USER_ROW_LOW));
target_mem_read32(t, SAMD_NVM_USER_ROW_HIGH),
target_mem_read32(t, SAMD_NVM_USER_ROW_LOW));
return true;
}
@ -694,12 +679,10 @@ static bool samd_cmd_read_userrow(target *t)
*/
static bool samd_cmd_serial(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
gdb_outf("Serial Number: 0x");
for (uint32_t i = 0; i < 4; i++) {
gdb_outf("%08x", adiv5_ap_mem_read(ap, SAMD_NVM_SERIAL(i)));
gdb_outf("%08x", target_mem_read32(t, SAMD_NVM_SERIAL(i)));
}
gdb_outf("\n");
@ -711,10 +694,8 @@ static bool samd_cmd_serial(target *t)
*/
static uint32_t samd_flash_size(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
/* Read the Device ID */
uint32_t did = adiv5_ap_mem_read(ap, SAMD_DSU_DID);
uint32_t did = target_mem_read32(t, SAMD_DSU_DID);
/* Mask off the device select bits */
uint8_t devsel = did & SAMD_DID_DEVSEL_MASK;
@ -727,21 +708,19 @@ static uint32_t samd_flash_size(target *t)
*/
static bool samd_cmd_mbist(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
/* Write the memory parameters to the DSU */
adiv5_ap_mem_write(ap, SAMD_DSU_ADDRESS, 0);
adiv5_ap_mem_write(ap, SAMD_DSU_LENGTH, samd_flash_size(t));
target_mem_write32(t, SAMD_DSU_ADDRESS, 0);
target_mem_write32(t, SAMD_DSU_LENGTH, samd_flash_size(t));
/* Clear the fail bit */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT, SAMD_STATUSA_FAIL);
target_mem_write32(t, SAMD_DSU_CTRLSTAT, SAMD_STATUSA_FAIL);
/* Write the MBIST command */
adiv5_ap_mem_write(ap, SAMD_DSU_CTRLSTAT, SAMD_CTRL_MBIST);
target_mem_write32(t, SAMD_DSU_CTRLSTAT, SAMD_CTRL_MBIST);
/* Poll for DSU Ready */
uint32_t status;
while (((status = adiv5_ap_mem_read(ap, SAMD_DSU_CTRLSTAT)) &
while (((status = target_mem_read32(t, SAMD_DSU_CTRLSTAT)) &
(SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL)) == 0)
if(target_check_error(t))
return false;
@ -755,7 +734,7 @@ static bool samd_cmd_mbist(target *t)
/* Test the fail bit in Status A */
if (status & SAMD_STATUSA_FAIL) {
gdb_outf("MBIST Fail @ 0x%08x\n",
adiv5_ap_mem_read(ap, SAMD_DSU_ADDRESS));
target_mem_read32(t, SAMD_DSU_ADDRESS));
} else {
gdb_outf("MBIST Passed!\n");
}
@ -767,13 +746,12 @@ static bool samd_cmd_mbist(target *t)
*/
static bool samd_cmd_ssb(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
/* Issue the ssb command */
adiv5_ap_mem_write(ap, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_SSB);
target_mem_write32(t, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_SSB);
/* Poll for NVM Ready */
while ((adiv5_ap_mem_read(ap, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
if(target_check_error(t))
return -1;

73
src/stm32f1.c

@ -158,8 +158,7 @@ static const uint16_t stm32f1_flash_write_stub[] = {
bool stm32f1_probe(struct target_s *target)
{
target->idcode = adiv5_ap_mem_read(adiv5_target_ap(target), DBGMCU_IDCODE) & 0xfff;
target->idcode = target_mem_read32(target, DBGMCU_IDCODE) & 0xfff;
switch(target->idcode) {
case 0x410: /* Medium density */
case 0x412: /* Low denisty */
@ -189,7 +188,7 @@ bool stm32f1_probe(struct target_s *target)
return true;
}
target->idcode = adiv5_ap_mem_read(adiv5_target_ap(target), DBGMCU_IDCODE_F0) & 0xfff;
target->idcode = target_mem_read32(target, DBGMCU_IDCODE_F0) & 0xfff;
switch(target->idcode) {
case 0x444: /* STM32F03 RM0091 Rev.7 */
case 0x445: /* STM32F04 RM0091 Rev.7 */
@ -223,33 +222,32 @@ bool stm32f1_probe(struct target_s *target)
return false;
}
static void stm32f1_flash_unlock(ADIv5_AP_t *ap)
static void stm32f1_flash_unlock(target *t)
{
adiv5_ap_mem_write(ap, FLASH_KEYR, KEY1);
adiv5_ap_mem_write(ap, FLASH_KEYR, KEY2);
target_mem_write32(t, FLASH_KEYR, KEY1);
target_mem_write32(t, FLASH_KEYR, KEY2);
}
static int stm32f1_flash_erase(struct target_s *target, uint32_t addr,
size_t len, uint32_t pagesize)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint16_t sr;
addr &= ~(pagesize - 1);
len = (len + pagesize - 1) & ~(pagesize - 1);
stm32f1_flash_unlock(ap);
stm32f1_flash_unlock(target);
while(len) {
/* Flash page erase instruction */
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_PER);
target_mem_write32(target, FLASH_CR, FLASH_CR_PER);
/* write address to FMA */
adiv5_ap_mem_write(ap, FLASH_AR, addr);
target_mem_write32(target, FLASH_AR, addr);
/* Flash page erase start instruction */
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER);
target_mem_write32(target, FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while (target_mem_read32(target, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(target))
return -1;
@ -258,7 +256,7 @@ static int stm32f1_flash_erase(struct target_s *target, uint32_t addr,
}
/* Check for error */
sr = adiv5_ap_mem_read(ap, FLASH_SR);
sr = target_mem_read32(target, FLASH_SR);
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP))
return -1;
@ -278,7 +276,6 @@ static int stm32md_flash_erase(struct target_s *target, uint32_t addr, size_t le
static int stm32f1_flash_write(struct target_s *target, uint32_t dest,
const uint8_t *src, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint32_t offset = dest % 4;
uint32_t words = (offset + len + 3) / 4;
if (words > 256)
@ -304,7 +301,7 @@ static int stm32f1_flash_write(struct target_s *target, uint32_t dest,
while(!target_halt_wait(target));
/* Check for error */
if (adiv5_ap_mem_read(ap, FLASH_SR) & SR_ERROR_MASK)
if (target_mem_read32(target, FLASH_SR) & SR_ERROR_MASK)
return -1;
return 0;
@ -312,21 +309,19 @@ static int stm32f1_flash_write(struct target_s *target, uint32_t dest,
static bool stm32f1_cmd_erase_mass(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
stm32f1_flash_unlock(ap);
stm32f1_flash_unlock(t);
/* Flash mass erase start instruction */
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_MER);
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER);
target_mem_write32(t, FLASH_CR, FLASH_CR_MER);
target_mem_write32(t, FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
return false;
/* Check for error */
uint16_t sr = adiv5_ap_mem_read(ap, FLASH_SR);
uint16_t sr = target_mem_read32(t, FLASH_SR);
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP))
return false;
@ -335,14 +330,12 @@ static bool stm32f1_cmd_erase_mass(target *t)
static bool stm32f1_option_erase(target *t)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
/* Erase option bytes instruction */
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_OPTER | FLASH_CR_OPTWRE);
adiv5_ap_mem_write(ap, FLASH_CR,
FLASH_CR_STRT | FLASH_CR_OPTER | FLASH_CR_OPTWRE);
target_mem_write32(t, FLASH_CR, FLASH_CR_OPTER | FLASH_CR_OPTWRE);
target_mem_write32(t, FLASH_CR,
FLASH_CR_STRT | FLASH_CR_OPTER | FLASH_CR_OPTWRE);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
return false;
return true;
@ -350,15 +343,13 @@ static bool stm32f1_option_erase(target *t)
static bool stm32f1_option_write_erased(target *t, uint32_t addr, uint16_t value)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
if (value == 0xffff)
return true;
/* Erase option bytes instruction */
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_OPTPG | FLASH_CR_OPTWRE);
adiv5_ap_mem_write_halfword(ap, addr, value);
target_mem_write32(t, FLASH_CR, FLASH_CR_OPTPG | FLASH_CR_OPTWRE);
target_mem_write16(t, addr, value);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
return false;
return true;
@ -366,7 +357,6 @@ static bool stm32f1_option_write_erased(target *t, uint32_t addr, uint16_t value
static bool stm32f1_option_write(target *t, uint32_t addr, uint16_t value)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint16_t opt_val[8];
int i, index;
@ -375,7 +365,7 @@ static bool stm32f1_option_write(target *t, uint32_t addr, uint16_t value)
return false;
/* Retrieve old values */
for (i = 0; i < 16; i = i +4) {
uint32_t val = adiv5_ap_mem_read(ap, FLASH_OBP_RDP + i);
uint32_t val = target_mem_read32(t, FLASH_OBP_RDP + i);
opt_val[i/2] = val & 0xffff;
opt_val[i/2 +1] = val >> 16;
}
@ -398,7 +388,6 @@ static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
{
uint32_t addr, val;
uint32_t flash_obp_rdp_key;
ADIv5_AP_t *ap = adiv5_target_ap(t);
uint32_t rdprt;
switch(t->idcode) {
@ -409,10 +398,10 @@ static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
break;
default: flash_obp_rdp_key = FLASH_OBP_RDP_KEY;
}
rdprt = (adiv5_ap_mem_read(ap, FLASH_OBR) & FLASH_OBR_RDPRT);
stm32f1_flash_unlock(ap);
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY1);
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY2);
rdprt = target_mem_read32(t, FLASH_OBR) & FLASH_OBR_RDPRT;
stm32f1_flash_unlock(t);
target_mem_write32(t, FLASH_OPTKEYR, KEY1);
target_mem_write32(t, FLASH_OPTKEYR, KEY2);
if ((argc == 2) && !strcmp(argv[1], "erase")) {
stm32f1_option_erase(t);
@ -432,7 +421,7 @@ static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
if (0 && flash_obp_rdp_key == FLASH_OBP_RDP_KEY_F3) {
/* Reload option bytes on F0 and F3*/
val = adiv5_ap_mem_read(ap, FLASH_CR);
val = target_mem_read32(t, FLASH_CR);
val |= FLASH_CR_OBL_LAUNCH;
stm32f1_option_write(t, FLASH_CR, val);
val &= ~FLASH_CR_OBL_LAUNCH;
@ -441,7 +430,7 @@ static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
for (int i = 0; i < 0xf; i += 4) {
addr = 0x1ffff800 + i;
val = adiv5_ap_mem_read(ap, addr);
val = target_mem_read32(t, addr);
gdb_outf("0x%08X: 0x%04X\n", addr, val & 0xFFFF);
gdb_outf("0x%08X: 0x%04X\n", addr + 2, val >> 16);
}

56
src/stm32f4.c

@ -162,7 +162,7 @@ bool stm32f4_probe(struct target_s *target)
{
uint32_t idcode;
idcode = adiv5_ap_mem_read(adiv5_target_ap(target), DBGMCU_IDCODE);
idcode = target_mem_read32(target, DBGMCU_IDCODE);
switch(idcode & 0xFFF) {
case 0x411: /* Documented to be 0x413! This is what I read... */
case 0x413: /* F407VGT6 */
@ -180,25 +180,24 @@ bool stm32f4_probe(struct target_s *target)
return false;
}
static void stm32f4_flash_unlock(ADIv5_AP_t *ap)
static void stm32f4_flash_unlock(target *t)
{
if (adiv5_ap_mem_read(ap, FLASH_CR) & FLASH_CR_LOCK) {
if (target_mem_read32(t, FLASH_CR) & FLASH_CR_LOCK) {
/* Enable FPEC controller access */
adiv5_ap_mem_write(ap, FLASH_KEYR, KEY1);
adiv5_ap_mem_write(ap, FLASH_KEYR, KEY2);
target_mem_write32(t, FLASH_KEYR, KEY1);
target_mem_write32(t, FLASH_KEYR, KEY2);
}
}
static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint16_t sr;
uint32_t cr;
uint32_t pagesize;
addr &= 0x07FFC000;
stm32f4_flash_unlock(ap);
stm32f4_flash_unlock(target);
while(len) {
if (addr < 0x10000) { /* Sector 0..3 */
@ -215,12 +214,12 @@ static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t le
}
cr |= FLASH_CR_EOPIE | FLASH_CR_ERRIE | FLASH_CR_SER;
/* Flash page erase instruction */
adiv5_ap_mem_write(ap, FLASH_CR, cr);
target_mem_write32(target, FLASH_CR, cr);
/* write address to FMA */
adiv5_ap_mem_write(ap, FLASH_CR, cr | FLASH_CR_STRT);
target_mem_write32(target, FLASH_CR, cr | FLASH_CR_STRT);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while(target_mem_read32(target, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(target))
return -1;
@ -229,7 +228,7 @@ static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t le
}
/* Check for error */
sr = adiv5_ap_mem_read(ap, FLASH_SR);
sr = target_mem_read32(target, FLASH_SR);
if(sr & SR_ERROR_MASK)
return -1;
@ -239,7 +238,6 @@ static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t le
static int stm32f4_flash_write(struct target_s *target, uint32_t dest,
const uint8_t *src, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint32_t offset = dest % 4;
uint32_t words = (offset + len + 3) / 4;
uint32_t data[2 + words];
@ -264,7 +262,7 @@ static int stm32f4_flash_write(struct target_s *target, uint32_t dest,
while(!target_halt_wait(target));
/* Check for error */
sr = adiv5_ap_mem_read(ap, FLASH_SR);
sr = target_mem_read32(target, FLASH_SR);
if(sr & SR_ERROR_MASK)
return -1;
@ -276,17 +274,15 @@ static bool stm32f4_cmd_erase_mass(target *t)
const char spinner[] = "|/-\\";
int spinindex = 0;
ADIv5_AP_t *ap = adiv5_target_ap(t);
gdb_out("Erasing flash... This may take a few seconds. ");
stm32f4_flash_unlock(ap);
stm32f4_flash_unlock(t);
/* Flash mass erase start instruction */
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_MER);
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER);
target_mem_write32(t, FLASH_CR, FLASH_CR_MER);
target_mem_write32(t, FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY) {
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY) {
gdb_outf("\b%c", spinner[spinindex++ % 4]);
if(target_check_error(t)) {
gdb_out("\n");
@ -296,7 +292,7 @@ static bool stm32f4_cmd_erase_mass(target *t)
gdb_out("\n");
/* Check for error */
uint16_t sr = adiv5_ap_mem_read(ap, FLASH_SR);
uint16_t sr = target_mem_read32(t, FLASH_SR);
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP))
return false;
@ -305,23 +301,21 @@ static bool stm32f4_cmd_erase_mass(target *t)
static bool stm32f4_option_write(target *t, uint32_t value)
{
ADIv5_AP_t *ap = adiv5_target_ap(t);
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, OPTKEY1);
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, OPTKEY2);
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY1);
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY2);
value &= ~FLASH_OPTCR_RESERVED;
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
return -1;
/* WRITE option bytes instruction */
adiv5_ap_mem_write(ap, FLASH_OPTCR, value);
adiv5_ap_mem_write(ap, FLASH_OPTCR, value | FLASH_OPTCR_OPTSTRT);
target_mem_write32(t, FLASH_OPTCR, value);
target_mem_write32(t, FLASH_OPTCR, value | FLASH_OPTCR_OPTSTRT);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, FLASH_SR) & FLASH_SR_BSY)
while(target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
return false;
adiv5_ap_mem_write(ap, FLASH_OPTCR, value | FLASH_OPTCR_OPTLOCK);
target_mem_write32(t, FLASH_OPTCR, value | FLASH_OPTCR_OPTLOCK);
return true;
}
@ -329,8 +323,6 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
{
uint32_t addr, val;
ADIv5_AP_t *ap = adiv5_target_ap(t);
if ((argc == 2) && !strcmp(argv[1], "erase")) {
stm32f4_option_write(t, 0x0fffaaed);
}
@ -344,7 +336,7 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
for (int i = 0; i < 0xf; i += 8) {
addr = 0x1fffC000 + i;
val = adiv5_ap_mem_read(ap, addr);
val = target_mem_read32(t, addr);
gdb_outf("0x%08X: 0x%04X\n", addr, val & 0xFFFF);
}
return true;

138
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
@ -288,7 +288,7 @@ bool stm32l0_probe(struct target_s* target)
#if defined(CONFIG_STM32L1)
idcode = adiv5_ap_mem_read(adiv5_target_ap(target),
idcode = target_mem_read32(target,
STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff;
switch (idcode) {
case 0x416: /* CAT. 1 device */
@ -306,7 +306,7 @@ bool stm32l0_probe(struct target_s* target)
}
#endif
idcode = adiv5_ap_mem_read(adiv5_target_ap(target),
idcode = target_mem_read32(target,
STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff;
switch (idcode) {
default:
@ -327,42 +327,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);
}
@ -400,8 +400,7 @@ static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
while (!target_halt_wait(target))
;
{
ADIv5_AP_t* ap = adiv5_target_ap(target);
if (adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm))
if (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_ERR_M)
return -1;
}
@ -477,8 +476,7 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
while (!target_halt_wait(target))
;
if (adiv5_ap_mem_read(adiv5_target_ap(target),
STM32Lx_NVM_SR(nvm))
if (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_ERR_M)
return -1;
}
@ -557,7 +555,6 @@ static int stm32lx_nvm_write(struct target_s* target,
static int stm32lx_nvm_prog_erase(struct target_s* target,
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);
@ -565,15 +562,15 @@ static int stm32lx_nvm_prog_erase(struct target_s* target,
len += (addr & 3);
addr &= ~3;
if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
return -1;
/* Flash page erase instruction */
adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_PROG);
{
uint32_t pecr = adiv5_ap_mem_read(ap, STM32Lx_NVM_PECR(nvm));
uint32_t pecr = target_mem_read32(target, STM32Lx_NVM_PECR(nvm));
if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
!= (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
return -1;
@ -581,22 +578,22 @@ static int stm32lx_nvm_prog_erase(struct target_s* target,
/* 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(target, 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(target, addr, 0);
len -= page_size;
addr += page_size;
}
/* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm);
stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */
while (1) {
uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
if (target_check_error(target))
return -1;
if (sr & STM32Lx_NVM_SR_BSY)
@ -618,7 +615,6 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
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);
@ -629,7 +625,7 @@ 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(target, nvm))
return -1;
const size_t half_page_size = stm32lx_nvm_prog_page_size(target)/2;
@ -639,7 +635,7 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
/* 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(target, STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_BSY)
if (target_check_error(target)) {
return -1;
@ -649,7 +645,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(target, STM32Lx_NVM_PECR(nvm),
is_stm32l1
? 0
: STM32Lx_NVM_PECR_PROG);
@ -666,7 +662,7 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
}
// Or we are writing a half-page(s)
else {
adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_PROG
| STM32Lx_NVM_PECR_FPRG);
@ -679,11 +675,11 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
}
/* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm);
stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */
while (1) {
uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
if (target_check_error(target)) {
return -1;
}
@ -706,7 +702,6 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
static int stm32lx_nvm_data_erase(struct target_s* target,
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);
@ -714,15 +709,15 @@ static int stm32lx_nvm_data_erase(struct target_s* target,
len += (addr & 3);
addr &= ~3;
if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
return -1;
/* Flash data erase instruction */
adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA);
{
uint32_t pecr = adiv5_ap_mem_read(ap, STM32Lx_NVM_PECR(nvm));
uint32_t pecr = target_mem_read32(target, STM32Lx_NVM_PECR(nvm));
if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
!= (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
return -1;
@ -730,18 +725,18 @@ static int stm32lx_nvm_data_erase(struct target_s* target,
while (len > 0) {
/* Write first word of page to 0 */
adiv5_ap_mem_write(ap, addr, 0);
target_mem_write32(target, addr, 0);
len -= page_size;
addr += page_size;
}
/* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm);
stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */
while (1) {
uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
if (target_check_error(target))
return -1;
if (sr & STM32Lx_NVM_SR_BSY)
@ -764,22 +759,21 @@ static int stm32lx_nvm_data_write(struct target_s* target,
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;
if (!stm32lx_nvm_prog_data_unlock(ap, nvm))
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
return -1;
adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm),
target_mem_write32(target, 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(target, destination, v);
destination += 4;
if (target_check_error(target))
@ -787,11 +781,11 @@ static int stm32lx_nvm_data_write(struct target_s* target,
}
/* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm);
stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */
while (1) {
uint32_t sr = adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm));
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
if (target_check_error(target))
return -1;
if (sr & STM32Lx_NVM_SR_BSY)
@ -813,16 +807,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);
@ -839,29 +832,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);
@ -888,11 +880,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;
}
@ -900,7 +891,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)) {
@ -934,7 +925,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))
@ -942,7 +933,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)
@ -964,7 +955,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)
@ -997,17 +988,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;
}
@ -1061,6 +1051,6 @@ usage:
+ stm32lx_nvm_eeprom_size(t));
done:
stm32lx_nvm_lock(ap, nvm);
stm32lx_nvm_lock(t, nvm);
return true;
}

40
src/stm32l1.c

@ -87,7 +87,7 @@ bool stm32l1_probe(struct target_s *target)
{
uint32_t idcode;
idcode = adiv5_ap_mem_read(adiv5_target_ap(target), STM32L1_DBGMCU_IDCODE);
idcode = target_mem_read32(target, STM32L1_DBGMCU_IDCODE);
switch(idcode & 0xFFF) {
case 0x416: /* CAT. 1 device */
case 0x429: /* CAT. 2 device */
@ -105,45 +105,44 @@ bool stm32l1_probe(struct target_s *target)
return false;
}
static void stm32l1_flash_unlock(ADIv5_AP_t *ap)
static void stm32l1_flash_unlock(target *t)
{
adiv5_ap_mem_write(ap, STM32L1_FLASH_PEKEYR, STM32L1_PEKEY1);
adiv5_ap_mem_write(ap, STM32L1_FLASH_PEKEYR, STM32L1_PEKEY2);
adiv5_ap_mem_write(ap, STM32L1_FLASH_PRGKEYR, STM32L1_PRGKEY1);
adiv5_ap_mem_write(ap, STM32L1_FLASH_PRGKEYR, STM32L1_PRGKEY2);
target_mem_write32(t, STM32L1_FLASH_PEKEYR, STM32L1_PEKEY1);
target_mem_write32(t, STM32L1_FLASH_PEKEYR, STM32L1_PEKEY2);
target_mem_write32(t, STM32L1_FLASH_PRGKEYR, STM32L1_PRGKEY1);
target_mem_write32(t, STM32L1_FLASH_PRGKEYR, STM32L1_PRGKEY2);
}
static int stm32l1_flash_erase(struct target_s *target, uint32_t addr, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint16_t sr;
addr &= ~255;
len &= ~255;
stm32l1_flash_unlock(ap);
stm32l1_flash_unlock(target);
/* Flash page erase instruction */
adiv5_ap_mem_write(ap, STM32L1_FLASH_PECR, STM32L1_FLASH_PECR_ERASE | STM32L1_FLASH_PECR_PROG);
target_mem_write32(target, STM32L1_FLASH_PECR, STM32L1_FLASH_PECR_ERASE | STM32L1_FLASH_PECR_PROG);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, STM32L1_FLASH_SR) & STM32L1_FLASH_SR_BSY)
while(target_mem_read32(target, STM32L1_FLASH_SR) & STM32L1_FLASH_SR_BSY)
if(target_check_error(target))
return -1;
while(len) {
/* Write first word of page to 0 */
adiv5_ap_mem_write(ap, addr, 0);
target_mem_write32(target, addr, 0);
len -= 256;
addr += 256;
}
/* Disable programming mode */
adiv5_ap_mem_write(ap, STM32L1_FLASH_PECR, 0);
target_mem_write32(target, STM32L1_FLASH_PECR, 0);
/* Check for error */
sr = adiv5_ap_mem_read(ap, STM32L1_FLASH_SR);
sr = target_mem_read32(target, STM32L1_FLASH_SR);
if ((sr & STM32L1_FLASH_SR_ERROR_MASK) || !(sr & STM32L1_FLASH_SR_EOP))
return -1;
@ -153,7 +152,6 @@ static int stm32l1_flash_erase(struct target_s *target, uint32_t addr, size_t le
static int stm32l1_flash_write(struct target_s *target, uint32_t dest,
const uint8_t *src, size_t len)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
uint16_t sr;
/* Handle non word-aligned start */
@ -164,7 +162,7 @@ static int stm32l1_flash_write(struct target_s *target, uint32_t dest,
wlen = len;
memcpy((uint8_t *)&data + (dest & 3), src, wlen);
adiv5_ap_mem_write(ap, dest & ~3, data);
target_mem_write32(target, dest & ~3, data);
src += wlen;
dest += wlen;
len -= wlen;
@ -185,10 +183,10 @@ static int stm32l1_flash_write(struct target_s *target, uint32_t dest,
/* Write half-pages */
if(len > 128) {
/* Enable half page mode */
adiv5_ap_mem_write(ap, STM32L1_FLASH_PECR, STM32L1_FLASH_PECR_FPRG | STM32L1_FLASH_PECR_PROG);
target_mem_write32(target, STM32L1_FLASH_PECR, STM32L1_FLASH_PECR_FPRG | STM32L1_FLASH_PECR_PROG);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, STM32L1_FLASH_SR) & STM32L1_FLASH_SR_BSY)
while(target_mem_read32(target, STM32L1_FLASH_SR) & STM32L1_FLASH_SR_BSY)
if(target_check_error(target))
return -1;
@ -198,10 +196,10 @@ static int stm32l1_flash_write(struct target_s *target, uint32_t dest,
len -= len & ~127;
/* Disable half page mode */
adiv5_ap_mem_write(ap, STM32L1_FLASH_PECR, 0);
target_mem_write32(target, STM32L1_FLASH_PECR, 0);
/* Read FLASH_SR to poll for BSY bit */
while(adiv5_ap_mem_read(ap, STM32L1_FLASH_SR) & STM32L1_FLASH_SR_BSY)
while(target_mem_read32(target, STM32L1_FLASH_SR) & STM32L1_FLASH_SR_BSY)
if(target_check_error(target))
return -1;
}
@ -219,11 +217,11 @@ static int stm32l1_flash_write(struct target_s *target, uint32_t dest,
uint32_t data = 0;
memcpy((uint8_t *)&data, src, len);
adiv5_ap_mem_write(ap, dest, data);
target_mem_write32(target, dest, data);
}
/* Check for error */
sr = adiv5_ap_mem_read(ap, STM32L1_FLASH_SR);
sr = target_mem_read32(target, STM32L1_FLASH_SR);
if ((sr & STM32L1_FLASH_SR_ERROR_MASK) || !(sr & STM32L1_FLASH_SR_EOP))
return -1;

Loading…
Cancel
Save