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

This commit is contained in:
Gareth McMullin 2015-03-15 16:02:09 -07:00
parent ee3af96a73
commit 2bf54f9a72
16 changed files with 335 additions and 447 deletions

View File

@ -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) void adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
{ {
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT, adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,

View File

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

View File

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

View File

@ -166,13 +166,6 @@ void adiv5_ap_ref(ADIv5_AP_t *ap);
void adiv5_dp_unref(ADIv5_DP_t *dp); void adiv5_dp_unref(ADIv5_DP_t *dp);
void adiv5_ap_unref(ADIv5_AP_t *ap); 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); 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); uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr);

View File

@ -111,7 +111,6 @@ target *target_attach(target *t, target_destroy_callback destroy_cb);
#define target_hostio_reply(target, recode, errcode) \ #define target_hostio_reply(target, recode, errcode) \
(target)->hostio_reply((target), (retcode), (errcode)) (target)->hostio_reply((target), (retcode), (errcode))
struct target_s { struct target_s {
/* Notify controlling debugger if target is lost */ /* Notify controlling debugger if target is lost */
target_destroy_callback destroy_callback; target_destroy_callback destroy_callback;
@ -187,6 +186,43 @@ target *target_new(unsigned size);
void target_list_free(void); void target_list_free(void);
void target_add_commands(target *t, const struct command_s *cmds, const char *name); void target_add_commands(target *t, const struct command_s *cmds, const char *name);
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. /* Probe for various targets.
* Actual functions implemented in their respective drivers. * Actual functions implemented in their respective drivers.
*/ */

View File

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

View File

@ -100,7 +100,7 @@ static const uint16_t lmi_flash_write_stub[] = {
bool lmi_probe(struct target_s *target) 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) { switch (did1 >> 16) {
case 0x1049: /* LM3S3748 */ case 0x1049: /* LM3S3748 */
target->driver = lmi_driver_str; target->driver = lmi_driver_str;

View File

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

View File

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

View File

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

View File

@ -148,9 +148,7 @@ static const char sam4s_xml_memory_map[] = "<?xml version=\"1.0\"?>"
bool sam3x_probe(struct target_s *target) bool sam3x_probe(struct target_s *target)
{ {
ADIv5_AP_t *ap = adiv5_target_ap(target); target->idcode = target_mem_read32(target, SAM3X_CHIPID_CIDR);
target->idcode = adiv5_ap_mem_read(ap, SAM3X_CHIPID_CIDR);
/* FIXME: Check for all variants with similar flash interface */ /* FIXME: Check for all variants with similar flash interface */
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
@ -165,7 +163,7 @@ bool sam3x_probe(struct target_s *target)
return true; 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)) { switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM3NxA | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3NxA | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3NxB | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3NxB | CHIPID_CIDR_EPROC_CM3:
@ -178,20 +176,20 @@ bool sam3x_probe(struct target_s *target)
return true; return true;
} }
target->idcode = adiv5_ap_mem_read(ap, SAM3S_CHIPID_CIDR); target->idcode = target_mem_read32(target, SAM3S_CHIPID_CIDR);
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM3SxA | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3SxA | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3SxB | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3SxB | CHIPID_CIDR_EPROC_CM3:
case CHIPID_CIDR_ARCH_SAM3SxC | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3SxC | CHIPID_CIDR_EPROC_CM3:
target->driver = "Atmel SAM3S"; target->driver = "Atmel SAM3S";
target->xml_mem_map = sam3n_xml_memory_map; target->xml_mem_map = sam3n_xml_memory_map;
target->flash_erase = sam3x_flash_erase; target->flash_erase = sam3x_flash_erase;
target->flash_write = sam3x_flash_write; target->flash_write = sam3x_flash_write;
target_add_commands(target, sam3x_cmd_list, "SAM3S"); target_add_commands(target, sam3x_cmd_list, "SAM3S");
return true; return true;
} }
target->idcode = adiv5_ap_mem_read(ap, SAM4S_CHIPID_CIDR); target->idcode = target_mem_read32(target, SAM4S_CHIPID_CIDR);
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
case CHIPID_CIDR_ARCH_SAM4SxA | CHIPID_CIDR_EPROC_CM4: case CHIPID_CIDR_ARCH_SAM4SxA | CHIPID_CIDR_EPROC_CM4:
case CHIPID_CIDR_ARCH_SAM4SxB | 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 static int
sam3x_flash_cmd(struct target_s *target, uint32_t base, uint8_t cmd, uint16_t arg) 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", DEBUG("%s: base = 0x%08x cmd = 0x%02X, arg = 0x%06X\n",
__func__, base, cmd, arg); __func__, base, cmd, arg);
adiv5_ap_mem_write(ap, EEFC_FCR(base), target_mem_write32(target, EEFC_FCR(base),
EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8)); 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)) if(target_check_error(target))
return -1; 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; 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) 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); uint32_t base = sam3x_flash_base(t, 0, NULL);
sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_GGPB, 0); 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; return true;
} }

View File

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

View File

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

View File

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

View File

@ -72,13 +72,13 @@
to regain control of the target after the option byte reload. to regain control of the target after the option byte reload.
stm32l0_option_write(t, 0x1ff80000, 0xffff0000); 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); 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; uint32_t sr;
do { do {
sr = adiv5_ap_mem_read(ap, STM32L0_NVM_SR); sr = target_mem_read32(target, STM32L0_NVM_SR);
} while (sr & STM32L0_NVM_SR_BSY); } while (sr & STM32L0_NVM_SR_BSY);
o Errors. We probably should clear SR errors immediately after 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) #if defined(CONFIG_STM32L1)
idcode = adiv5_ap_mem_read(adiv5_target_ap(target), idcode = target_mem_read32(target,
STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff; STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff;
switch (idcode) { switch (idcode) {
case 0x416: /* CAT. 1 device */ case 0x416: /* CAT. 1 device */
@ -306,7 +306,7 @@ bool stm32l0_probe(struct target_s* target)
} }
#endif #endif
idcode = adiv5_ap_mem_read(adiv5_target_ap(target), idcode = target_mem_read32(target,
STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff; STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff;
switch (idcode) { switch (idcode) {
default: default:
@ -327,42 +327,42 @@ bool stm32l0_probe(struct target_s* target)
/** Lock the NVM control registers preventing writes or erases. */ /** 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 /** Unlock the NVM control registers for modifying program or
data flash. Returns true if the unlock succeeds. */ 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 /* Always lock first because that's the only way to know that the
unlock can succeed on the STM32L0's. */ unlock can succeed on the STM32L0's. */
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);
adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1); target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2); target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
adiv5_ap_mem_write(ap, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY1); target_mem_write32(t, 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_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); & STM32Lx_NVM_PECR_PRGLOCK);
} }
/** Unlock the NVM control registers for modifying option bytes. /** Unlock the NVM control registers for modifying option bytes.
Returns true if the unlock succeeds. */ 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 /* Always lock first because that's the only way to know that the
unlock can succeed on the STM32L0's. */ unlock can succeed on the STM32L0's. */
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);
adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1); target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
adiv5_ap_mem_write(ap, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2); target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
adiv5_ap_mem_write(ap, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY1); target_mem_write32(t, 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_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); & STM32Lx_NVM_PECR_OPTLOCK);
} }
@ -400,8 +400,7 @@ static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
while (!target_halt_wait(target)) while (!target_halt_wait(target))
; ;
{ {
ADIv5_AP_t* ap = adiv5_target_ap(target); if (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
if (adiv5_ap_mem_read(ap, STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_ERR_M) & STM32Lx_NVM_SR_ERR_M)
return -1; return -1;
} }
@ -477,8 +476,7 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
while (!target_halt_wait(target)) while (!target_halt_wait(target))
; ;
if (adiv5_ap_mem_read(adiv5_target_ap(target), if (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
STM32Lx_NVM_SR(nvm))
& STM32Lx_NVM_SR_ERR_M) & STM32Lx_NVM_SR_ERR_M)
return -1; 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, static int stm32lx_nvm_prog_erase(struct target_s* target,
uint32_t addr, size_t len) 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 size_t page_size = stm32lx_nvm_prog_page_size(target);
const uint32_t nvm = stm32lx_nvm_phys(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); len += (addr & 3);
addr &= ~3; addr &= ~3;
if (!stm32lx_nvm_prog_data_unlock(ap, nvm)) if (!stm32lx_nvm_prog_data_unlock(target, nvm))
return -1; return -1;
/* Flash page erase instruction */ /* 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); 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)) if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
!= (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE)) != (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
return -1; 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 /* Clear errors. Note that this only works when we wait for the NVM
block to complete the last operation. */ 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) { while (len > 0) {
/* Write first word of page to 0 */ /* Write first word of page to 0 */
adiv5_ap_mem_write(ap, addr, 0); target_mem_write32(target, addr, 0);
len -= page_size; len -= page_size;
addr += page_size; addr += page_size;
} }
/* Disable further programming by locking PECR */ /* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm); stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */ /* Wait for completion or an error */
while (1) { 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)) if (target_check_error(target))
return -1; return -1;
if (sr & STM32Lx_NVM_SR_BSY) 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, const uint8_t* source_8,
size_t size) size_t size)
{ {
ADIv5_AP_t* ap = adiv5_target_ap(target);
const uint32_t nvm = stm32lx_nvm_phys(target); const uint32_t nvm = stm32lx_nvm_phys(target);
const bool is_stm32l1 = stm32lx_is_stm32l1(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)) if ((destination & 3) || (size & 3))
return -1; return -1;
if (!stm32lx_nvm_prog_data_unlock(ap, nvm)) if (!stm32lx_nvm_prog_data_unlock(target, nvm))
return -1; 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(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 /* Wait for BSY to clear because we cannot write the PECR until
the previous operation completes on STM32Lxxx. */ 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) & STM32Lx_NVM_SR_BSY)
if (target_check_error(target)) { if (target_check_error(target)) {
return -1; return -1;
@ -649,7 +645,7 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
// than a half page to write // than a half page to write
if (size < half_page_size if (size < half_page_size
|| (destination & (half_page_size - 1))) { || (destination & (half_page_size - 1))) {
adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm), target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
is_stm32l1 is_stm32l1
? 0 ? 0
: STM32Lx_NVM_PECR_PROG); : 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) // Or we are writing a half-page(s)
else { 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_PROG
| STM32Lx_NVM_PECR_FPRG); | STM32Lx_NVM_PECR_FPRG);
@ -679,11 +675,11 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
} }
/* Disable further programming by locking PECR */ /* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm); stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */ /* Wait for completion or an error */
while (1) { 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)) { if (target_check_error(target)) {
return -1; 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, static int stm32lx_nvm_data_erase(struct target_s* target,
uint32_t addr, size_t len) 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 size_t page_size = stm32lx_nvm_data_page_size(target);
const uint32_t nvm = stm32lx_nvm_phys(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); len += (addr & 3);
addr &= ~3; addr &= ~3;
if (!stm32lx_nvm_prog_data_unlock(ap, nvm)) if (!stm32lx_nvm_prog_data_unlock(target, nvm))
return -1; return -1;
/* Flash data erase instruction */ /* 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); 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)) if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
!= (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA)) != (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
return -1; return -1;
@ -730,18 +725,18 @@ static int stm32lx_nvm_data_erase(struct target_s* target,
while (len > 0) { while (len > 0) {
/* Write first word of page to 0 */ /* Write first word of page to 0 */
adiv5_ap_mem_write(ap, addr, 0); target_mem_write32(target, addr, 0);
len -= page_size; len -= page_size;
addr += page_size; addr += page_size;
} }
/* Disable further programming by locking PECR */ /* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm); stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */ /* Wait for completion or an error */
while (1) { 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)) if (target_check_error(target))
return -1; return -1;
if (sr & STM32Lx_NVM_SR_BSY) 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, const uint8_t* source_8,
size_t size) size_t size)
{ {
ADIv5_AP_t* ap = adiv5_target_ap(target);
const uint32_t nvm = stm32lx_nvm_phys(target); const uint32_t nvm = stm32lx_nvm_phys(target);
const bool is_stm32l1 = stm32lx_is_stm32l1(target); const bool is_stm32l1 = stm32lx_is_stm32l1(target);
uint32_t* source = (uint32_t*) source_8; 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; 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); is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA);
while (size) { while (size) {
size -= 4; size -= 4;
uint32_t v = *source++; uint32_t v = *source++;
adiv5_ap_mem_write(ap, destination, v); target_mem_write32(target, destination, v);
destination += 4; destination += 4;
if (target_check_error(target)) 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 */ /* Disable further programming by locking PECR */
stm32lx_nvm_lock(ap, nvm); stm32lx_nvm_lock(target, nvm);
/* Wait for completion or an error */ /* Wait for completion or an error */
while (1) { 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)) if (target_check_error(target))
return -1; return -1;
if (sr & STM32Lx_NVM_SR_BSY) 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. */ The return value is true if the write succeeded. */
static bool stm32lx_option_write(target *t, uint32_t address, uint32_t value) 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); const uint32_t nvm = stm32lx_nvm_phys(t);
/* Erase and program option in one go. */ /* Erase and program option in one go. */
adiv5_ap_mem_write(ap, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_FIX); target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_FIX);
adiv5_ap_mem_write(ap, address, value); target_mem_write32(t, address, value);
uint32_t sr; uint32_t sr;
do { 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); } while (sr & STM32Lx_NVM_SR_BSY);
return !(sr & STM32Lx_NVM_SR_ERR_M); 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, static bool stm32lx_eeprom_write(target *t, uint32_t address,
size_t cb, uint32_t value) size_t cb, uint32_t value)
{ {
ADIv5_AP_t* ap = adiv5_target_ap(t);
const uint32_t nvm = stm32lx_nvm_phys(t); const uint32_t nvm = stm32lx_nvm_phys(t);
const bool is_stm32l1 = stm32lx_is_stm32l1(t); const bool is_stm32l1 = stm32lx_is_stm32l1(t);
/* Clear errors. */ /* 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. */ /* 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) (is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA)
| STM32Lx_NVM_PECR_FIX); | STM32Lx_NVM_PECR_FIX);
if (cb == 4) if (cb == 4)
adiv5_ap_mem_write(ap, address, value); target_mem_write32(t, address, value);
else if (cb == 2) else if (cb == 2)
adiv5_ap_mem_write_halfword(ap, address, value); target_mem_write16(t, address, value);
else if (cb == 1) else if (cb == 1)
adiv5_ap_mem_write_byte(ap, address, value); target_mem_write8(t, address, value);
else else
return false; return false;
uint32_t sr; uint32_t sr;
do { 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); } while (sr & STM32Lx_NVM_SR_BSY);
return !(sr & STM32Lx_NVM_SR_ERR_M); 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) 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 uint32_t nvm = stm32lx_nvm_phys(t);
const size_t opt_size = stm32lx_nvm_option_size(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"); gdb_out("unable to unlock NVM option bytes\n");
return true; return true;
} }
@ -900,7 +891,7 @@ static bool stm32lx_cmd_option(target* t, int argc, char** argv)
size_t cb = strlen(argv[1]); size_t cb = strlen(argv[1]);
if (argc == 2 && !strncasecmp(argv[1], "obl_launch", cb)) { 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); STM32Lx_NVM_PECR_OBL_LAUNCH);
} }
else if (argc == 4 && !strncasecmp(argv[1], "raw", cb)) { 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 */ /* Report the current option values */
for(unsigned i = 0; i < opt_size; i += sizeof(uint32_t)) { for(unsigned i = 0; i < opt_size; i += sizeof(uint32_t)) {
uint32_t addr = STM32Lx_NVM_OPT_PHYS + i; 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", gdb_outf("0x%08x: 0x%04x 0x%04x %s\n",
addr, val & 0xffff, (val >> 16) & 0xffff, addr, val & 0xffff, (val >> 16) & 0xffff,
((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)) { 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) uint8_t rdprot = (optr >> STM32L1_NVM_OPTR_RDPROT_S)
& STM32L1_NVM_OPTR_RDPROT_M; & STM32L1_NVM_OPTR_RDPROT_M;
if (rdprot == STM32L1_NVM_OPTR_RDPROT_0) 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); (optr & STM32L1_NVM_OPTR_nBFB2) ? 1 : 0);
} }
else { 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) uint8_t rdprot = (optr >> STM32L0_NVM_OPTR_RDPROT_S)
& STM32L0_NVM_OPTR_RDPROT_M; & STM32L0_NVM_OPTR_RDPROT_M;
if (rdprot == STM32L0_NVM_OPTR_RDPROT_0) if (rdprot == STM32L0_NVM_OPTR_RDPROT_0)
@ -997,17 +988,16 @@ usage:
STM32Lx_NVM_OPT_PHYS + opt_size - sizeof(uint32_t)); STM32Lx_NVM_OPT_PHYS + opt_size - sizeof(uint32_t));
done: done:
stm32lx_nvm_lock(ap, nvm); stm32lx_nvm_lock(t, nvm);
return true; return true;
} }
static bool stm32lx_cmd_eeprom(target* t, int argc, char** argv) 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); 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"); gdb_out("unable to unlock EEPROM\n");
return true; return true;
} }
@ -1061,6 +1051,6 @@ usage:
+ stm32lx_nvm_eeprom_size(t)); + stm32lx_nvm_eeprom_size(t));
done: done:
stm32lx_nvm_lock(ap, nvm); stm32lx_nvm_lock(t, nvm);
return true; return true;
} }

View File

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