nds32: Use the correct method to access registers
The registers are represented as bit arrays intended to be accessed using the buf_set_* and buf_get_* functions. Storing the register values in integers enables accessing them directly, which gives different results depending on host byte order. Convert the register store to use a byte array instead and fix all the byte order bugs uncovered by that. Also merge the 32 and 64 bit register fields. Only one of them is used at a time and after the change to byte arrays their types are also the same. Change-Id: I456869a1737f4b4f5e8ecbfc1c63c49a75d21619 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: http://openocd.zylin.com/2475 Tested-by: jenkins Reviewed-by: Hsiangkai Wang <hsiangkai@gmail.com> Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
parent
fd43be0726
commit
0ecb0396d4
|
@ -86,32 +86,32 @@ static int nds32_get_core_reg(struct reg *reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg->valid) {
|
if (reg->valid) {
|
||||||
|
uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32);
|
||||||
LOG_DEBUG("reading register(cached) %" PRIi32 "(%s), value: 0x%8.8" PRIx32,
|
LOG_DEBUG("reading register(cached) %" PRIi32 "(%s), value: 0x%8.8" PRIx32,
|
||||||
reg_arch_info->num, reg->name, reg_arch_info->value);
|
reg_arch_info->num, reg->name, val);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num);
|
int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num);
|
||||||
|
|
||||||
if (reg_arch_info->enable == false) {
|
if (reg_arch_info->enable == false) {
|
||||||
reg_arch_info->value = NDS32_REGISTER_DISABLE;
|
buf_set_u32(reg_arch_info->value, 0, 32, NDS32_REGISTER_DISABLE);
|
||||||
retval = ERROR_FAIL;
|
retval = ERROR_FAIL;
|
||||||
} else {
|
} else {
|
||||||
if ((nds32->fpu_enable == false) &&
|
uint32_t val = 0;
|
||||||
(NDS32_REG_TYPE_FPU == nds32_reg_type(mapped_regnum))) {
|
if ((nds32->fpu_enable == false)
|
||||||
reg_arch_info->value = 0;
|
&& (NDS32_REG_TYPE_FPU == nds32_reg_type(mapped_regnum))) {
|
||||||
retval = ERROR_OK;
|
retval = ERROR_OK;
|
||||||
} else if ((nds32->audio_enable == false) &&
|
} else if ((nds32->audio_enable == false)
|
||||||
(NDS32_REG_TYPE_AUMR == nds32_reg_type(mapped_regnum))) {
|
&& (NDS32_REG_TYPE_AUMR == nds32_reg_type(mapped_regnum))) {
|
||||||
reg_arch_info->value = 0;
|
|
||||||
retval = ERROR_OK;
|
retval = ERROR_OK;
|
||||||
} else {
|
} else {
|
||||||
retval = aice_read_register(aice,
|
retval = aice_read_register(aice, mapped_regnum, &val);
|
||||||
mapped_regnum, &(reg_arch_info->value));
|
|
||||||
}
|
}
|
||||||
|
buf_set_u32(reg_arch_info->value, 0, 32, val);
|
||||||
|
|
||||||
LOG_DEBUG("reading register %" PRIi32 "(%s), value: 0x%8.8" PRIx32,
|
LOG_DEBUG("reading register %" PRIi32 "(%s), value: 0x%8.8" PRIx32,
|
||||||
reg_arch_info->num, reg->name, reg_arch_info->value);
|
reg_arch_info->num, reg->name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval == ERROR_OK) {
|
if (retval == ERROR_OK) {
|
||||||
|
@ -139,17 +139,17 @@ static int nds32_get_core_reg_64(struct reg *reg)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
||||||
if (reg_arch_info->enable == false) {
|
if (reg_arch_info->enable == false) {
|
||||||
reg_arch_info->value_64 = NDS32_REGISTER_DISABLE;
|
buf_set_u64(reg_arch_info->value, 0, 64, NDS32_REGISTER_DISABLE);
|
||||||
retval = ERROR_FAIL;
|
retval = ERROR_FAIL;
|
||||||
} else {
|
} else {
|
||||||
if ((nds32->fpu_enable == false) &&
|
uint64_t val = 0;
|
||||||
((FD0 <= reg_arch_info->num) && (reg_arch_info->num <= FD31))) {
|
if ((nds32->fpu_enable == false)
|
||||||
reg_arch_info->value_64 = 0;
|
&& ((FD0 <= reg_arch_info->num) && (reg_arch_info->num <= FD31))) {
|
||||||
retval = ERROR_OK;
|
retval = ERROR_OK;
|
||||||
} else {
|
} else {
|
||||||
retval = aice_read_reg_64(aice, reg_arch_info->num,
|
retval = aice_read_reg_64(aice, reg_arch_info->num, &val);
|
||||||
&(reg_arch_info->value_64));
|
|
||||||
}
|
}
|
||||||
|
buf_set_u64(reg_arch_info->value, 0, 64, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval == ERROR_OK) {
|
if (retval == ERROR_OK) {
|
||||||
|
@ -322,11 +322,13 @@ static int nds32_set_core_reg(struct reg *reg, uint8_t *buf)
|
||||||
buf_set_u32(reg->value, 0, 32, 0);
|
buf_set_u32(reg->value, 0, 32, 0);
|
||||||
} else {
|
} else {
|
||||||
buf_set_u32(reg->value, 0, 32, value);
|
buf_set_u32(reg->value, 0, 32, value);
|
||||||
aice_write_register(aice, mapped_regnum, reg_arch_info->value);
|
uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32);
|
||||||
|
aice_write_register(aice, mapped_regnum, val);
|
||||||
|
|
||||||
/* After set value to registers, read the value from target
|
/* After set value to registers, read the value from target
|
||||||
* to avoid W1C inconsistency. */
|
* to avoid W1C inconsistency. */
|
||||||
aice_read_register(aice, mapped_regnum, &(reg_arch_info->value));
|
aice_read_register(aice, mapped_regnum, &val);
|
||||||
|
buf_set_u32(reg_arch_info->value, 0, 32, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg->valid = true;
|
reg->valid = true;
|
||||||
|
@ -426,14 +428,14 @@ static struct reg_cache *nds32_build_reg_cache(struct target *target,
|
||||||
reg_list[i].reg_data_type = calloc(sizeof(struct reg_data_type), 1);
|
reg_list[i].reg_data_type = calloc(sizeof(struct reg_data_type), 1);
|
||||||
|
|
||||||
if (FD0 <= reg_arch_info[i].num && reg_arch_info[i].num <= FD31) {
|
if (FD0 <= reg_arch_info[i].num && reg_arch_info[i].num <= FD31) {
|
||||||
reg_list[i].value = &(reg_arch_info[i].value_64);
|
reg_list[i].value = reg_arch_info[i].value;
|
||||||
reg_list[i].type = &nds32_reg_access_type_64;
|
reg_list[i].type = &nds32_reg_access_type_64;
|
||||||
|
|
||||||
reg_list[i].reg_data_type->type = REG_TYPE_IEEE_DOUBLE;
|
reg_list[i].reg_data_type->type = REG_TYPE_IEEE_DOUBLE;
|
||||||
reg_list[i].reg_data_type->id = "ieee_double";
|
reg_list[i].reg_data_type->id = "ieee_double";
|
||||||
reg_list[i].group = "float";
|
reg_list[i].group = "float";
|
||||||
} else {
|
} else {
|
||||||
reg_list[i].value = &(reg_arch_info[i].value);
|
reg_list[i].value = reg_arch_info[i].value;
|
||||||
reg_list[i].type = &nds32_reg_access_type;
|
reg_list[i].type = &nds32_reg_access_type;
|
||||||
reg_list[i].group = "general";
|
reg_list[i].group = "general";
|
||||||
|
|
||||||
|
@ -1549,10 +1551,14 @@ int nds32_restore_context(struct target *target)
|
||||||
i, buf_get_u32(reg->value, 0, 32));
|
i, buf_get_u32(reg->value, 0, 32));
|
||||||
|
|
||||||
reg_arch_info = reg->arch_info;
|
reg_arch_info = reg->arch_info;
|
||||||
if (FD0 <= reg_arch_info->num && reg_arch_info->num <= FD31)
|
if (FD0 <= reg_arch_info->num && reg_arch_info->num <= FD31) {
|
||||||
aice_write_reg_64(aice, reg_arch_info->num, reg_arch_info->value_64);
|
uint64_t val = buf_get_u64(reg_arch_info->value, 0, 64);
|
||||||
else
|
aice_write_reg_64(aice, reg_arch_info->num, val);
|
||||||
aice_write_register(aice, reg_arch_info->num, reg_arch_info->value);
|
} else {
|
||||||
|
uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32);
|
||||||
|
aice_write_register(aice, reg_arch_info->num, val);
|
||||||
|
}
|
||||||
|
|
||||||
reg->valid = true;
|
reg->valid = true;
|
||||||
reg->dirty = false;
|
reg->dirty = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,8 +362,7 @@ struct nds32 {
|
||||||
|
|
||||||
struct nds32_reg {
|
struct nds32_reg {
|
||||||
int32_t num;
|
int32_t num;
|
||||||
uint32_t value;
|
uint8_t value[8];
|
||||||
uint64_t value_64;
|
|
||||||
struct target *target;
|
struct target *target;
|
||||||
struct nds32 *nds32;
|
struct nds32 *nds32;
|
||||||
bool enable;
|
bool enable;
|
||||||
|
|
Loading…
Reference in New Issue