}
if (reg->valid) {
- LOG_DEBUG("reading register(cached) %i(%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);
return ERROR_OK;
}
mapped_regnum, &(reg_arch_info->value));
}
- LOG_DEBUG("reading register %i(%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);
}
if (nds32_reg_exception(mapped_regnum, value))
return ERROR_OK;
- LOG_DEBUG("writing register %i(%s) with value 0x%8.8" PRIx32,
+ LOG_DEBUG("writing register %" PRIi32 "(%s) with value 0x%8.8" PRIx32,
reg_arch_info->num, reg->name, value);
if ((nds32->fpu_enable == false) &&
static struct reg_cache *nds32_build_reg_cache(struct target *target,
struct nds32 *nds32)
{
- struct reg_cache *cache = malloc(sizeof(struct reg_cache));
+ struct reg_cache *cache = calloc(sizeof(struct reg_cache), 1);
struct reg *reg_list = calloc(TOTAL_REG_NUM, sizeof(struct reg));
struct nds32_reg *reg_arch_info = calloc(TOTAL_REG_NUM, sizeof(struct nds32_reg));
int i;
reg_list[i].size = nds32_reg_size(i);
reg_list[i].arch_info = ®_arch_info[i];
- reg_list[i].reg_data_type = malloc(sizeof(struct reg_data_type));
+ 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) {
reg_list[i].value = &(reg_arch_info[i].value_64);
aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
nds32->edm.version = (edm_cfg >> 16) & 0xFFFF;
- LOG_INFO("EDM version 0x%04" PRIx32, nds32->edm.version);
+ LOG_INFO("EDM version 0x%04x", nds32->edm.version);
nds32->edm.breakpoint_num = (edm_cfg & 0x7) + 1;
nds32->reset_halt_as_examine = false;
nds32->keep_target_edm_ctl = false;
nds32->word_access_mem = false;
- nds32->virtual_hosting = false;
+ nds32->virtual_hosting = true;
nds32->hit_syscall = false;
nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED;
nds32->virtual_hosting_errno = 0;
nds32->virtual_hosting_ctrl_c = false;
+ nds32->attached = false;
+
+ nds32->syscall_break.asid = 0;
+ nds32->syscall_break.length = 4;
+ nds32->syscall_break.set = 0;
+ nds32->syscall_break.orig_instr = NULL;
+ nds32->syscall_break.next = NULL;
+ nds32->syscall_break.unique_id = 0x515CAll + target->target_number;
+ nds32->syscall_break.linked_BRP = 0;
nds32_reg_init();
&instruction))
return ERROR_FAIL;
- target->debug_reason = DBG_REASON_BREAKPOINT;
+ /* hit 'break 0x7FFF' */
+ if ((instruction.info.opc_6 == 0x32) &&
+ (instruction.info.sub_opc == 0xA) &&
+ (instruction.info.imm == 0x7FFF)) {
+ target->debug_reason = DBG_REASON_EXIT;
+ } else
+ target->debug_reason = DBG_REASON_BREAKPOINT;
}
break;
case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE:
code_str[copy_length] = '\0';
code = strtoul(code_str, NULL, 16);
- sprintf(command_str, "write_misc gen_port0 0x%x;", code);
+ sprintf(command_str, "write_misc gen_port0 0x%" PRIx32 ";", code);
strcat(command_sequence, command_str);
}
else
return ERROR_FAIL;
- sprintf(command_str, "write_misc %s 0x%x;", reg_name, code);
+ sprintf(command_str, "write_misc %s 0x%" PRIx32 ";", reg_name, code);
if (ERROR_OK != aice_program_edm(aice, command_str))
return ERROR_FAIL;
}
int nds32_resume(struct target *target, int current,
uint32_t address, int handle_breakpoints, int debug_execution)
{
- LOG_DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d",
+ LOG_DEBUG("current %d address %08" PRIx32 " handle_breakpoints %d debug_execution %d",
current, address, handle_breakpoints, debug_execution);
struct nds32 *nds32 = target_to_nds32(target);
return ERROR_OK;
}
-int nds32_assert_reset(struct target *target)
+static int nds32_soft_reset_halt(struct target *target)
{
+ /* TODO: test it */
struct nds32 *nds32 = target_to_nds32(target);
struct aice_port_s *aice = target_to_aice(target);
- jtag_poll_set_enabled(true);
+ aice_assert_srst(aice, AICE_SRST);
+
+ /* halt core and set pc to 0x0 */
+ int retval = target_halt(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* start fetching from IVB */
+ uint32_t value_ir3;
+ nds32_get_mapped_reg(nds32, IR3, &value_ir3);
+ nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000);
+
+ return ERROR_OK;
+}
+
+int nds32_assert_reset(struct target *target)
+{
+ struct nds32 *nds32 = target_to_nds32(target);
+ struct aice_port_s *aice = target_to_aice(target);
+ struct nds32_cpu_version *cpu_version = &(nds32->cpu_version);
if (target->reset_halt) {
- if (nds32->soft_reset_halt)
- target->type->soft_reset_halt(target);
+ if ((nds32->soft_reset_halt)
+ || (nds32->edm.version < 0x51)
+ || ((nds32->edm.version == 0x51)
+ && (cpu_version->revision == 0x1C)
+ && (cpu_version->cpu_id_family == 0xC)
+ && (cpu_version->cpu_id_version == 0x0)))
+ nds32_soft_reset_halt(target);
else
aice_assert_srst(aice, AICE_RESET_HOLD);
} else {
return ERROR_OK;
}
-static uint32_t nds32_backup_edm_ctl;
-static bool gdb_attached;
-
static int nds32_gdb_attach(struct nds32 *nds32)
{
- LOG_DEBUG("nds32_gdb_attach");
+ LOG_DEBUG("nds32_gdb_attach, target coreid: %" PRId32, nds32->target->coreid);
- if (gdb_attached == false) {
+ if (nds32->attached == false) {
if (nds32->keep_target_edm_ctl) {
/* backup target EDM_CTL */
struct aice_port_s *aice = target_to_aice(nds32->target);
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &nds32_backup_edm_ctl);
+ aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &nds32->backup_edm_ctl);
}
target_halt(nds32->target);
- target_poll(nds32->target);
- gdb_attached = true;
+ nds32->attached = true;
}
return ERROR_OK;
LOG_DEBUG("nds32_gdb_detach");
bool backup_virtual_hosting_setting;
- if (gdb_attached) {
+ if (nds32->attached) {
backup_virtual_hosting_setting = nds32->virtual_hosting;
/* turn off virtual hosting before resume as gdb-detach */
if (nds32->keep_target_edm_ctl) {
/* restore target EDM_CTL */
struct aice_port_s *aice = target_to_aice(nds32->target);
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, nds32_backup_edm_ctl);
+ aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, nds32->backup_edm_ctl);
}
- /* turn off polling */
- jtag_poll_set_enabled(false);
-
- gdb_attached = false;
+ nds32->attached = false;
}
return ERROR_OK;
enum target_event event, void *priv)
{
int retval = ERROR_OK;
- struct nds32 *nds32 = priv;
+ int target_number = *(int *)priv;
+
+ if (target_number != target->target_number)
+ return ERROR_OK;
+
+ struct nds32 *nds32 = target_to_nds32(target);
switch (event) {
case TARGET_EVENT_GDB_ATTACH:
/* Initialize anything we can set up without talking to the target */
nds32->memory.access_channel = NDS_MEMORY_ACC_CPU;
- /* turn off polling by default */
- jtag_poll_set_enabled(false);
-
/* register event callback */
- target_register_event_callback(nds32_callback_event_handler, nds32);
+ target_register_event_callback(nds32_callback_event_handler,
+ &(nds32->target->target_number));
return ERROR_OK;
}
syscall_id = (value_ir6 >> 16) & 0x7FFF;
nds32->active_syscall_id = syscall_id;
- LOG_DEBUG("hit syscall ID: 0x%x", syscall_id);
+ LOG_DEBUG("hit syscall ID: 0x%" PRIx32, syscall_id);
/* free previous identifier storage */
if (NULL != fileio_info->identifier) {
return ERROR_OK;
}
+int nds32_profiling(struct target *target, uint32_t *samples,
+ uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
+{
+ /* sample $PC every 10 milliseconds */
+ uint32_t iteration = seconds * 100;
+ struct aice_port_s *aice = target_to_aice(target);
+ struct nds32 *nds32 = target_to_nds32(target);
+
+ if (max_num_samples < iteration)
+ iteration = max_num_samples;
+
+ int pc_regnum = nds32->register_map(nds32, PC);
+ aice_profiling(aice, 10, iteration, pc_regnum, samples, num_samples);
+
+ register_cache_invalidate(nds32->core_cache);
+
+ return ERROR_OK;
+}
+
int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address,
uint32_t size, const uint8_t *buffer)
{