We don't need to swap the endianness in the target generic code. This swap is necessary because of the adv_debug_if debug unit. This patch moves this specific piece of code from or1k.c to or1k_du_adv.c. Change-Id: I3acea092fe6edfa79b4a87861b5f01204f071bf0 Signed-off-by: Franck Jullien <franck.jullien@gmail.com> Reviewed-on: http://openocd.zylin.com/1663 Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>tags/v0.9.0-rc1
@@ -950,12 +950,13 @@ static int or1k_add_breakpoint(struct target *target, | |||
memcpy(breakpoint->orig_instr, &data, breakpoint->length); | |||
/* Sub in the OR1K trap instruction */ | |||
uint32_t or1k_trap_insn = OR1K_TRAP_INSTR; | |||
uint8_t or1k_trap_insn[4]; | |||
target_buffer_set_u32(target, or1k_trap_insn, OR1K_TRAP_INSTR); | |||
retval = du_core->or1k_jtag_write_memory(&or1k->jtag, | |||
breakpoint->address, | |||
4, | |||
1, | |||
(uint8_t *)&or1k_trap_insn); | |||
or1k_trap_insn); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("Error while writing OR1K_TRAP_INSTR at 0x%08" PRIx32, | |||
@@ -1050,38 +1051,7 @@ static int or1k_read_memory(struct target *target, uint32_t address, | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
} | |||
/* or1k_read_memory with size 4/2 returns uint32_t/uint16_t in host */ | |||
/* endianness, but byte array should represent target endianness */ | |||
void *t = NULL; | |||
if (size > 1) { | |||
t = malloc(count * size * sizeof(uint8_t)); | |||
if (t == NULL) { | |||
LOG_ERROR("Out of memory"); | |||
return ERROR_FAIL; | |||
} | |||
} else | |||
t = buffer; | |||
int retval = du_core->or1k_jtag_read_memory(&or1k->jtag, address, | |||
size, count, t); | |||
if (retval == ERROR_OK) { | |||
switch (size) { | |||
case 4: | |||
target_buffer_set_u32_array(target, buffer, count, t); | |||
break; | |||
case 2: | |||
target_buffer_set_u16_array(target, buffer, count, t); | |||
break; | |||
} | |||
} | |||
if ((size > 1) && (t != NULL)) | |||
free(t); | |||
return ERROR_OK; | |||
return du_core->or1k_jtag_read_memory(&or1k->jtag, address, size, count, buffer); | |||
} | |||
static int or1k_write_memory(struct target *target, uint32_t address, | |||
@@ -1108,37 +1078,7 @@ static int or1k_write_memory(struct target *target, uint32_t address, | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
} | |||
/* or1k_write_memory with size 4/2 requires uint32_t/uint16_t in host */ | |||
/* endianness, but byte array represents target endianness */ | |||
void *t = NULL; | |||
if (size > 1) { | |||
t = malloc(count * size * sizeof(uint8_t)); | |||
if (t == NULL) { | |||
LOG_ERROR("Out of memory"); | |||
return ERROR_FAIL; | |||
} | |||
switch (size) { | |||
case 4: | |||
target_buffer_get_u32_array(target, buffer, count, (uint32_t *)t); | |||
break; | |||
case 2: | |||
target_buffer_get_u16_array(target, buffer, count, (uint16_t *)t); | |||
break; | |||
} | |||
buffer = t; | |||
} | |||
int retval = du_core->or1k_jtag_write_memory(&or1k->jtag, address, size, count, buffer); | |||
if (t != NULL) | |||
free(t); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
return ERROR_OK; | |||
return du_core->or1k_jtag_write_memory(&or1k->jtag, address, size, count, buffer); | |||
} | |||
static int or1k_init_target(struct command_context *cmd_ctx, | |||
@@ -1161,6 +1101,7 @@ static int or1k_init_target(struct command_context *cmd_ctx, | |||
or1k->jtag.tap = target->tap; | |||
or1k->jtag.or1k_jtag_inited = 0; | |||
or1k->jtag.or1k_jtag_module_selected = -1; | |||
or1k->jtag.target = target; | |||
or1k_build_reg_cache(target); | |||
@@ -94,6 +94,7 @@ struct or1k_jtag { | |||
uint8_t *current_reg_idx; | |||
struct or1k_tap_ip *tap_ip; | |||
struct or1k_du *du_core; | |||
struct target *target; | |||
}; | |||
struct or1k_common { | |||
@@ -846,7 +846,7 @@ static int or1k_adv_jtag_read_memory(struct or1k_jtag *jtag_info, | |||
int block_count_left = count; | |||
uint32_t block_count_address = addr; | |||
uint8_t *block_count_buffer = (uint8_t *)buffer; | |||
uint8_t *block_count_buffer = buffer; | |||
while (block_count_left) { | |||
@@ -863,6 +863,23 @@ static int or1k_adv_jtag_read_memory(struct or1k_jtag *jtag_info, | |||
block_count_buffer += size * MAX_BURST_SIZE; | |||
} | |||
/* The adv_debug_if always return words and half words in | |||
* little-endian order no matter what the target endian is. | |||
* So if the target endian is big, change the order. | |||
*/ | |||
struct target *target = jtag_info->target; | |||
if ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) { | |||
switch (size) { | |||
case 4: | |||
buf_bswap32(buffer, buffer, size * count); | |||
break; | |||
case 2: | |||
buf_bswap16(buffer, buffer, size * count); | |||
break; | |||
} | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -882,6 +899,31 @@ static int or1k_adv_jtag_write_memory(struct or1k_jtag *jtag_info, | |||
if (retval != ERROR_OK) | |||
return retval; | |||
/* The adv_debug_if wants words and half words in little-endian | |||
* order no matter what the target endian is. So if the target | |||
* endian is big, change the order. | |||
*/ | |||
void *t = NULL; | |||
struct target *target = jtag_info->target; | |||
if ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) { | |||
t = malloc(count * size * sizeof(uint8_t)); | |||
if (t == NULL) { | |||
LOG_ERROR("Out of memory"); | |||
return ERROR_FAIL; | |||
} | |||
switch (size) { | |||
case 4: | |||
buf_bswap32(t, buffer, size * count); | |||
break; | |||
case 2: | |||
buf_bswap16(t, buffer, size * count); | |||
break; | |||
} | |||
buffer = t; | |||
} | |||
int block_count_left = count; | |||
uint32_t block_count_address = addr; | |||
uint8_t *block_count_buffer = (uint8_t *)buffer; | |||
@@ -894,14 +936,20 @@ static int or1k_adv_jtag_write_memory(struct or1k_jtag *jtag_info, | |||
retval = adbg_wb_burst_write(jtag_info, block_count_buffer, | |||
size, blocks_this_round, | |||
block_count_address); | |||
if (retval != ERROR_OK) | |||
if (retval != ERROR_OK) { | |||
if (t != NULL) | |||
free(t); | |||
return retval; | |||
} | |||
block_count_left -= blocks_this_round; | |||
block_count_address += size * MAX_BURST_SIZE; | |||
block_count_buffer += size * MAX_BURST_SIZE; | |||
} | |||
if (t != NULL) | |||
free(t); | |||
return ERROR_OK; | |||
} | |||