Add functions into types.h, target.c, target.h to operate 64bits data. Prepare for 64bits mips target. Change-Id: I668a8a5ac12ba754ae310fa6e92cfc91af850b1c Signed-off-by: Dongxue Zhang <elta.era@gmail.com> Reviewed-on: http://openocd.zylin.com/1700 Tested-by: jenkins Reviewed-by: Mathias Küster <kesmtp@freenet.de> Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>tags/v0.8.0-rc1
@@ -110,6 +110,17 @@ typedef bool _Bool; | |||
* Again, note that the "buf" pointer in memory is probably unaligned. | |||
*/ | |||
static inline uint64_t le_to_h_u64(const uint8_t *buf) | |||
{ | |||
return (uint64_t)((uint64_t)buf[0] | | |||
(uint64_t)buf[1] << 8 | | |||
(uint64_t)buf[2] << 16 | | |||
(uint64_t)buf[3] << 24 | | |||
(uint64_t)buf[4] << 32 | | |||
(uint64_t)buf[5] << 40 | | |||
(uint64_t)buf[6] << 48 | | |||
(uint64_t)buf[7] << 56); | |||
} | |||
static inline uint32_t le_to_h_u32(const uint8_t* buf) | |||
{ | |||
@@ -126,6 +137,18 @@ static inline uint16_t le_to_h_u16(const uint8_t* buf) | |||
return (uint16_t)(buf[0] | buf[1] << 8); | |||
} | |||
static inline uint64_t be_to_h_u64(const uint8_t *buf) | |||
{ | |||
return (uint64_t)((uint64_t)buf[7] | | |||
(uint64_t)buf[6] << 8 | | |||
(uint64_t)buf[5] << 16 | | |||
(uint64_t)buf[4] << 24 | | |||
(uint64_t)buf[3] << 32 | | |||
(uint64_t)buf[2] << 40 | | |||
(uint64_t)buf[1] << 48 | | |||
(uint64_t)buf[0] << 56); | |||
} | |||
static inline uint32_t be_to_h_u32(const uint8_t* buf) | |||
{ | |||
return (uint32_t)(buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24); | |||
@@ -141,6 +164,30 @@ static inline uint16_t be_to_h_u16(const uint8_t* buf) | |||
return (uint16_t)(buf[1] | buf[0] << 8); | |||
} | |||
static inline void h_u64_to_le(uint8_t *buf, int64_t val) | |||
{ | |||
buf[7] = (uint8_t) (val >> 56); | |||
buf[6] = (uint8_t) (val >> 48); | |||
buf[5] = (uint8_t) (val >> 40); | |||
buf[4] = (uint8_t) (val >> 32); | |||
buf[3] = (uint8_t) (val >> 24); | |||
buf[2] = (uint8_t) (val >> 16); | |||
buf[1] = (uint8_t) (val >> 8); | |||
buf[0] = (uint8_t) (val >> 0); | |||
} | |||
static inline void h_u64_to_be(uint8_t *buf, int64_t val) | |||
{ | |||
buf[0] = (uint8_t) (val >> 56); | |||
buf[1] = (uint8_t) (val >> 48); | |||
buf[2] = (uint8_t) (val >> 40); | |||
buf[3] = (uint8_t) (val >> 32); | |||
buf[4] = (uint8_t) (val >> 24); | |||
buf[5] = (uint8_t) (val >> 16); | |||
buf[6] = (uint8_t) (val >> 8); | |||
buf[7] = (uint8_t) (val >> 0); | |||
} | |||
static inline void h_u32_to_le(uint8_t* buf, int val) | |||
{ | |||
buf[3] = (uint8_t) (val >> 24); | |||
@@ -294,6 +294,15 @@ static int new_target_number(void) | |||
return x + 1; | |||
} | |||
/* read a uint64_t from a buffer in target memory endianness */ | |||
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer) | |||
{ | |||
if (target->endianness == TARGET_LITTLE_ENDIAN) | |||
return le_to_h_u64(buffer); | |||
else | |||
return be_to_h_u64(buffer); | |||
} | |||
/* read a uint32_t from a buffer in target memory endianness */ | |||
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer) | |||
{ | |||
@@ -327,6 +336,15 @@ static uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer | |||
return *buffer & 0x0ff; | |||
} | |||
/* write a uint64_t to a buffer in target memory endianness */ | |||
void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value) | |||
{ | |||
if (target->endianness == TARGET_LITTLE_ENDIAN) | |||
h_u64_to_le(buffer, value); | |||
else | |||
h_u64_to_be(buffer, value); | |||
} | |||
/* write a uint32_t to a buffer in target memory endianness */ | |||
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value) | |||
{ | |||
@@ -360,6 +378,14 @@ static void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t | |||
*buffer = value; | |||
} | |||
/* write a uint64_t array to a buffer in target memory endianness */ | |||
void target_buffer_get_u64_array(struct target *target, const uint8_t *buffer, uint32_t count, uint64_t *dstbuf) | |||
{ | |||
uint32_t i; | |||
for (i = 0; i < count; i++) | |||
dstbuf[i] = target_buffer_get_u64(target, &buffer[i * 8]); | |||
} | |||
/* write a uint32_t array to a buffer in target memory endianness */ | |||
void target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf) | |||
{ | |||
@@ -376,6 +402,14 @@ void target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, u | |||
dstbuf[i] = target_buffer_get_u16(target, &buffer[i * 2]); | |||
} | |||
/* write a uint64_t array to a buffer in target memory endianness */ | |||
void target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_t count, const uint64_t *srcbuf) | |||
{ | |||
uint32_t i; | |||
for (i = 0; i < count; i++) | |||
target_buffer_set_u64(target, &buffer[i * 8], srcbuf[i]); | |||
} | |||
/* write a uint32_t array to a buffer in target memory endianness */ | |||
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf) | |||
{ | |||
@@ -1983,6 +2017,30 @@ int target_blank_check_memory(struct target *target, uint32_t address, uint32_t | |||
return retval; | |||
} | |||
int target_read_u64(struct target *target, uint64_t address, uint64_t *value) | |||
{ | |||
uint8_t value_buf[8]; | |||
if (!target_was_examined(target)) { | |||
LOG_ERROR("Target not examined yet"); | |||
return ERROR_FAIL; | |||
} | |||
int retval = target_read_memory(target, address, 8, 1, value_buf); | |||
if (retval == ERROR_OK) { | |||
*value = target_buffer_get_u64(target, value_buf); | |||
LOG_DEBUG("address: 0x%" PRIx64 ", value: 0x%16.16" PRIx64 "", | |||
address, | |||
*value); | |||
} else { | |||
*value = 0x0; | |||
LOG_DEBUG("address: 0x%" PRIx64 " failed", | |||
address); | |||
} | |||
return retval; | |||
} | |||
int target_read_u32(struct target *target, uint32_t address, uint32_t *value) | |||
{ | |||
uint8_t value_buf[4]; | |||
@@ -2053,6 +2111,27 @@ int target_read_u8(struct target *target, uint32_t address, uint8_t *value) | |||
return retval; | |||
} | |||
int target_write_u64(struct target *target, uint64_t address, uint64_t value) | |||
{ | |||
int retval; | |||
uint8_t value_buf[8]; | |||
if (!target_was_examined(target)) { | |||
LOG_ERROR("Target not examined yet"); | |||
return ERROR_FAIL; | |||
} | |||
LOG_DEBUG("address: 0x%" PRIx64 ", value: 0x%16.16" PRIx64 "", | |||
address, | |||
value); | |||
target_buffer_set_u64(target, value_buf, value); | |||
retval = target_write_memory(target, address, 8, 1, value_buf); | |||
if (retval != ERROR_OK) | |||
LOG_DEBUG("failed: %i", retval); | |||
return retval; | |||
} | |||
int target_write_u32(struct target *target, uint32_t address, uint32_t value) | |||
{ | |||
int retval; | |||
@@ -593,21 +593,27 @@ uint32_t target_get_working_area_avail(struct target *target); | |||
extern struct target *all_targets; | |||
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer); | |||
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer); | |||
uint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer); | |||
uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer); | |||
void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value); | |||
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value); | |||
void target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value); | |||
void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value); | |||
void target_buffer_get_u64_array(struct target *target, const uint8_t *buffer, uint32_t count, uint64_t *dstbuf); | |||
void target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf); | |||
void target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf); | |||
void target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_t count, const uint64_t *srcbuf); | |||
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf); | |||
void target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, const uint16_t *srcbuf); | |||
int target_read_u64(struct target *target, uint64_t address, uint64_t *value); | |||
int target_read_u32(struct target *target, uint32_t address, uint32_t *value); | |||
int target_read_u16(struct target *target, uint32_t address, uint16_t *value); | |||
int target_read_u8(struct target *target, uint32_t address, uint8_t *value); | |||
int target_write_u64(struct target *target, uint64_t address, uint64_t value); | |||
int target_write_u32(struct target *target, uint32_t address, uint32_t value); | |||
int target_write_u16(struct target *target, uint32_t address, uint16_t value); | |||
int target_write_u8(struct target *target, uint32_t address, uint8_t value); | |||