Skip to content

Commit

Permalink
adiv5: Encode APnDP into register definition.
Browse files Browse the repository at this point in the history
Clean up magic numbers in adiv5 calls.
Removed old adiv5_dp_write_ap and adiv5_dp_read_ap.
  • Loading branch information
gsmcmullin committed Mar 15, 2015
1 parent 6f5b187 commit 2e785e5
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 133 deletions.
90 changes: 32 additions & 58 deletions src/adiv5.c
Expand Up @@ -160,23 +160,6 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
adiv5_dp_unref(dp);
}

void adiv5_dp_write_ap(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
{
adiv5_dp_low_access(dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE, addr, value);
}

uint32_t adiv5_dp_read_ap(ADIv5_DP_t *dp, uint8_t addr)
{
uint32_t ret;

adiv5_dp_low_access(dp, ADIV5_LOW_AP, ADIV5_LOW_READ, addr, 0);
ret = adiv5_dp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);

return ret;
}


static int
ap_check_error(struct target_s *target)
{
Expand All @@ -194,26 +177,24 @@ ap_mem_read_words(struct target_s *target, uint32_t *dest, uint32_t src, int len

adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_WORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_READ,
ADIV5_AP_DRW, 0);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
while(--len) {
*dest++ = adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
*dest++ = adiv5_dp_low_access(ap->dp,
ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
src += 4;
/* Check for 10 bit address overflow */
if ((src ^ osrc) & 0xfffffc00) {
osrc = src;
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_WRITE, ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
}

}
*dest++ = adiv5_dp_low_access(ap->dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
*dest++ = adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);

return 0;
}
Expand All @@ -229,26 +210,24 @@ ap_mem_read_halfwords(struct target_s *target, uint16_t *dest, uint32_t src, int

adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_HALFWORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_READ,
ADIV5_AP_DRW, 0);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
while(--len) {
tmp = adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_READ,
tmp = adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ,
ADIV5_AP_DRW, 0);
*dest++ = (tmp >> ((src & 0x2) << 3) & 0xFFFF);

src += 2;
/* Check for 10 bit address overflow */
if ((src ^ osrc) & 0xfffffc00) {
osrc = src;
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_WRITE, ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
}
}
tmp = adiv5_dp_low_access(ap->dp, 0, 1, ADIV5_DP_RDBUFF, 0);
tmp = adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_DP_RDBUFF, 0);
*dest++ = (tmp >> ((src & 0x2) << 3) & 0xFFFF);

return 0;
Expand All @@ -263,25 +242,23 @@ ap_mem_read_bytes(struct target_s *target, uint8_t *dest, uint32_t src, int len)

adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_BYTE | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_READ,
ADIV5_AP_DRW, 0);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
while(--len) {
tmp = adiv5_dp_low_access(ap->dp, 1, 1, ADIV5_AP_DRW, 0);
tmp = adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
*dest++ = (tmp >> ((src & 0x3) << 3) & 0xFF);

src++;
/* Check for 10 bit address overflow */
if ((src ^ osrc) & 0xfffffc00) {
osrc = src;
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_WRITE, ADIV5_AP_TAR, src);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
}
}
tmp = adiv5_dp_low_access(ap->dp, 0, 1, ADIV5_DP_RDBUFF, 0);
tmp = adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_DP_RDBUFF, 0);
*dest++ = (tmp >> ((src++ & 0x3) << 3) & 0xFF);

return 0;
Expand All @@ -298,16 +275,15 @@ ap_mem_write_words(struct target_s *target, uint32_t dest, const uint32_t *src,

adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_WORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, dest);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, dest);
while(len--) {
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DRW, *src++);
dest += 4;
/* Check for 10 bit address overflow */
if ((dest ^ odest) & 0xfffffc00) {
odest = dest;
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_WRITE, ADIV5_AP_TAR, dest);
}
}
Expand All @@ -325,17 +301,16 @@ ap_mem_write_halfwords(struct target_s *target, uint32_t dest, const uint16_t *s

adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_HALFWORD | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, dest);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, dest);
while(len--) {
uint32_t tmp = (uint32_t)*src++ << ((dest & 2) << 3);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DRW, tmp);
dest += 2;
/* Check for 10 bit address overflow */
if ((dest ^ odest) & 0xfffffc00) {
odest = dest;
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_WRITE, ADIV5_AP_TAR, dest);
}
}
Expand All @@ -350,17 +325,16 @@ ap_mem_write_bytes(struct target_s *target, uint32_t dest, const uint8_t *src, i

adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw |
ADIV5_AP_CSW_SIZE_BYTE | ADIV5_AP_CSW_ADDRINC_SINGLE);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, dest);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, dest);
while(len--) {
uint32_t tmp = (uint32_t)*src++ << ((dest++ & 3) << 3);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DRW, tmp);

/* Check for 10 bit address overflow */
if ((dest ^ odest) & 0xfffffc00) {
odest = dest;
adiv5_dp_low_access(ap->dp, ADIV5_LOW_AP,
adiv5_dp_low_access(ap->dp,
ADIV5_LOW_WRITE, ADIV5_AP_TAR, dest);
}
}
Expand Down Expand Up @@ -429,19 +403,19 @@ void adiv5_ap_mem_write_byte(ADIv5_AP_t *ap, uint32_t addr, uint8_t value)
adiv5_ap_write(ap, ADIV5_AP_DRW, v);
}

void adiv5_ap_write(ADIv5_AP_t *ap, uint8_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,
((uint32_t)ap->apsel << 24)|(addr & 0xF0));
adiv5_dp_write_ap(ap->dp, addr, value);
adiv5_dp_write(ap->dp, addr, value);
}

uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint8_t addr)
uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr)
{
uint32_t ret;
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,
((uint32_t)ap->apsel << 24)|(addr & 0xF0));
ret = adiv5_dp_read_ap(ap->dp, addr);
ret = adiv5_dp_read(ap->dp, addr);
return ret;
}

31 changes: 16 additions & 15 deletions src/adiv5_jtagdp.c
Expand Up @@ -36,13 +36,13 @@
#define IR_DPACC 0xA
#define IR_APACC 0xB

static void adiv5_jtagdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value);
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint8_t addr);
static void adiv5_jtagdp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value);
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr);

static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);

static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value);
static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value);


void adiv5_jtag_dp_handler(jtag_dev_t *dev)
Expand All @@ -60,35 +60,36 @@ void adiv5_jtag_dp_handler(jtag_dev_t *dev)
adiv5_dp_init(dp);
}

static void adiv5_jtagdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
static void adiv5_jtagdp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value)
{
adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_WRITE, addr, value);
adiv5_jtagdp_low_access(dp, ADIV5_LOW_WRITE, addr, value);
}

static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint8_t addr)
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr)
{
adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ, addr, 0);
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
}

static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp)
{
adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_CTRLSTAT, 0);
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_WRITE,
adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ, ADIV5_DP_CTRLSTAT, 0);
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_WRITE,
ADIV5_DP_CTRLSTAT, 0xF0000032) & 0x32;
}

static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value)
static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value)
{
bool APnDP = addr & ADIV5_APnDP;
addr &= 0xff;
uint64_t request, response;
uint8_t ack;

request = ((uint64_t)value << 3) | ((addr >> 1) & 0x06) | (RnW?1:0);

jtag_dev_write_ir(dp->dev, APnDP?IR_APACC:IR_DPACC);
jtag_dev_write_ir(dp->dev, APnDP ? IR_APACC : IR_DPACC);

int tries = 1000;
do {
Expand Down
28 changes: 18 additions & 10 deletions src/adiv5_swdp.c
Expand Up @@ -33,13 +33,13 @@
#define SWDP_ACK_WAIT 0x02
#define SWDP_ACK_FAULT 0x04

static void adiv5_swdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value);
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint8_t addr);
static void adiv5_swdp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value);
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint16_t addr);

static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp);

static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value);
static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value);


int adiv5_swdp_scan(void)
Expand Down Expand Up @@ -78,14 +78,20 @@ int adiv5_swdp_scan(void)
return target_list?1:0;
}

static void adiv5_swdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
static void adiv5_swdp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value)
{
adiv5_swdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_WRITE, addr, value);
adiv5_swdp_low_access(dp, ADIV5_LOW_WRITE, addr, value);
}

static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint8_t addr)
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint16_t addr)
{
return adiv5_swdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ, addr, 0);
if (addr & ADIV5_APnDP) {
adiv5_dp_low_access(dp, ADIV5_LOW_READ, addr, 0);
return adiv5_dp_low_access(dp, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
} else {
return adiv5_swdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
}
}

static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp)
Expand All @@ -111,9 +117,11 @@ static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp)
return err;
}

static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value)
static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value)
{
bool APnDP = addr & ADIV5_APnDP;
addr &= 0xff;
uint8_t request = 0x81;
uint32_t response;
uint8_t ack;
Expand Down
35 changes: 21 additions & 14 deletions src/cortexm.c
Expand Up @@ -359,20 +359,23 @@ cortexm_regs_read(struct target_s *target, void *data)

/* Map the banked data registers (0x10-0x1c) to the
* debug registers DHCSR, DCRSR, DCRDR and DEMCR respectively */
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_TAR, CORTEXM_DHCSR);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, CORTEXM_DHCSR);

/* Walk the regnum_cortex_m array, reading the registers it
* calls out. */
adiv5_ap_write(ap, ADIV5_AP_DB(1), regnum_cortex_m[0]); /* Required to switch banks */
*regs++ = adiv5_dp_read_ap(ap->dp, ADIV5_AP_DB(2));
*regs++ = adiv5_dp_read(ap->dp, ADIV5_AP_DB(2));
for(i = 1; i < sizeof(regnum_cortex_m) / 4; i++) {
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(1), regnum_cortex_m[i]);
*regs++ = adiv5_dp_read_ap(ap->dp, ADIV5_AP_DB(2));
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_DB(1),
regnum_cortex_m[i]);
*regs++ = adiv5_dp_read(ap->dp, ADIV5_AP_DB(2));
}
if (target->target_options & TOPT_FLAVOUR_V7MF)
for(i = 0; i < sizeof(regnum_cortex_mf) / 4; i++) {
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(1), regnum_cortex_mf[i]);
*regs++ = adiv5_dp_read_ap(ap->dp, ADIV5_AP_DB(2));
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DB(1),
regnum_cortex_mf[i]);
*regs++ = adiv5_dp_read(ap->dp, ADIV5_AP_DB(2));
}

return 0;
Expand All @@ -391,22 +394,26 @@ cortexm_regs_write(struct target_s *target, const void *data)

/* Map the banked data registers (0x10-0x1c) to the
* debug registers DHCSR, DCRSR, DCRDR and DEMCR respectively */
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_TAR, CORTEXM_DHCSR);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_TAR, CORTEXM_DHCSR);

/* Walk the regnum_cortex_m array, writing the registers it
* calls out. */
adiv5_ap_write(ap, ADIV5_AP_DB(2), *regs++); /* Required to switch banks */
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(1), 0x10000 | regnum_cortex_m[0]);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_DB(1),
0x10000 | regnum_cortex_m[0]);
for(i = 1; i < sizeof(regnum_cortex_m) / 4; i++) {
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(2), *regs++);
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(1),
0x10000 | regnum_cortex_m[i]);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DB(2), *regs++);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_DB(1),
0x10000 | regnum_cortex_m[i]);
}
if (target->target_options & TOPT_FLAVOUR_V7MF)
for(i = 0; i < sizeof(regnum_cortex_mf) / 4; i++) {
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(2), *regs++);
adiv5_dp_low_access(ap->dp, 1, 0, ADIV5_AP_DB(1),
0x10000 | regnum_cortex_mf[i]);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DB(2), *regs++);
adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE,
ADIV5_AP_DB(1),
0x10000 | regnum_cortex_mf[i]);
}

return 0;
Expand Down

0 comments on commit 2e785e5

Please sign in to comment.