X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fnds32.c;h=8ab285999e2072e0f30736905b371b88abcde926;hp=50d6e3b9e1818cad65b5022b7b73cd821117a634;hb=677b02b475870b7d9e5d86e9bf61dc28dae5a6e4;hpb=399561eafa747e71202d00985206b65868142afb diff --git a/src/target/nds32.c b/src/target/nds32.c index 50d6e3b9e1..8ab285999e 100644 --- a/src/target/nds32.c +++ b/src/target/nds32.c @@ -86,7 +86,7 @@ static int nds32_get_core_reg(struct reg *reg) } 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; } @@ -110,7 +110,7 @@ static int nds32_get_core_reg(struct reg *reg) 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); } @@ -309,7 +309,7 @@ static int nds32_set_core_reg(struct reg *reg, uint8_t *buf) 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) && @@ -395,7 +395,7 @@ static const struct reg_arch_type nds32_reg_access_type_64 = { 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; @@ -423,7 +423,7 @@ static struct reg_cache *nds32_build_reg_cache(struct target *target, 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); @@ -1545,8 +1545,8 @@ int nds32_restore_context(struct target *target) if (reg->valid == true) { LOG_DEBUG("examining dirty reg: %s", reg->name); - LOG_DEBUG("writing register %i " - "with value 0x%8.8" PRIx32, i, buf_get_u32(reg->value, 0, 32)); + LOG_DEBUG("writing register %d with value 0x%8.8" PRIx32, + i, buf_get_u32(reg->value, 0, 32)); reg_arch_info = reg->arch_info; if (FD0 <= reg_arch_info->num && reg_arch_info->num <= FD31) @@ -1572,7 +1572,7 @@ int nds32_edm_config(struct nds32 *nds32) 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; @@ -1644,11 +1644,20 @@ int nds32_init_arch_info(struct target *target, struct nds32 *nds32) 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(); @@ -1999,7 +2008,7 @@ int nds32_login(struct nds32 *nds32) 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); } @@ -2024,7 +2033,7 @@ int nds32_login(struct nds32 *nds32) 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; } @@ -2109,7 +2118,9 @@ int nds32_poll(struct target *target) 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); @@ -2155,16 +2166,41 @@ int nds32_resume(struct target *target, int current, 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 { @@ -2183,25 +2219,21 @@ int nds32_assert_reset(struct target *target) 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; @@ -2212,7 +2244,7 @@ static int nds32_gdb_detach(struct nds32 *nds32) 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 */ @@ -2223,13 +2255,10 @@ static int nds32_gdb_detach(struct nds32 *nds32) 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; @@ -2239,7 +2268,12 @@ static int nds32_callback_event_handler(struct target *target, 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: @@ -2260,11 +2294,9 @@ int nds32_init(struct nds32 *nds32) /* 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; } @@ -2288,7 +2320,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil 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) { @@ -2298,14 +2330,14 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil switch (syscall_id) { case NDS32_SYSCALL_EXIT: - fileio_info->identifier = (char *)malloc(5); + fileio_info->identifier = malloc(5); sprintf(fileio_info->identifier, "exit"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); break; case NDS32_SYSCALL_OPEN: { uint8_t filename[256]; - fileio_info->identifier = (char *)malloc(5); + fileio_info->identifier = malloc(5); sprintf(fileio_info->identifier, "open"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); /* reserve fileio_info->param_2 for length of path */ @@ -2318,26 +2350,26 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil } break; case NDS32_SYSCALL_CLOSE: - fileio_info->identifier = (char *)malloc(6); + fileio_info->identifier = malloc(6); sprintf(fileio_info->identifier, "close"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); break; case NDS32_SYSCALL_READ: - fileio_info->identifier = (char *)malloc(5); + fileio_info->identifier = malloc(5); sprintf(fileio_info->identifier, "read"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); nds32_get_mapped_reg(nds32, R2, &(fileio_info->param_3)); break; case NDS32_SYSCALL_WRITE: - fileio_info->identifier = (char *)malloc(6); + fileio_info->identifier = malloc(6); sprintf(fileio_info->identifier, "write"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); nds32_get_mapped_reg(nds32, R2, &(fileio_info->param_3)); break; case NDS32_SYSCALL_LSEEK: - fileio_info->identifier = (char *)malloc(6); + fileio_info->identifier = malloc(6); sprintf(fileio_info->identifier, "lseek"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); @@ -2346,7 +2378,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil case NDS32_SYSCALL_UNLINK: { uint8_t filename[256]; - fileio_info->identifier = (char *)malloc(7); + fileio_info->identifier = malloc(7); sprintf(fileio_info->identifier, "unlink"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); /* reserve fileio_info->param_2 for length of path */ @@ -2359,7 +2391,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil case NDS32_SYSCALL_RENAME: { uint8_t filename[256]; - fileio_info->identifier = (char *)malloc(7); + fileio_info->identifier = malloc(7); sprintf(fileio_info->identifier, "rename"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); /* reserve fileio_info->param_2 for length of old path */ @@ -2376,7 +2408,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil } break; case NDS32_SYSCALL_FSTAT: - fileio_info->identifier = (char *)malloc(6); + fileio_info->identifier = malloc(6); sprintf(fileio_info->identifier, "fstat"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); @@ -2384,7 +2416,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil case NDS32_SYSCALL_STAT: { uint8_t filename[256]; - fileio_info->identifier = (char *)malloc(5); + fileio_info->identifier = malloc(5); sprintf(fileio_info->identifier, "stat"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); /* reserve fileio_info->param_2 for length of old path */ @@ -2396,20 +2428,20 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil } break; case NDS32_SYSCALL_GETTIMEOFDAY: - fileio_info->identifier = (char *)malloc(13); + fileio_info->identifier = malloc(13); sprintf(fileio_info->identifier, "gettimeofday"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); break; case NDS32_SYSCALL_ISATTY: - fileio_info->identifier = (char *)malloc(7); + fileio_info->identifier = malloc(7); sprintf(fileio_info->identifier, "isatty"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); break; case NDS32_SYSCALL_SYSTEM: { uint8_t command[256]; - fileio_info->identifier = (char *)malloc(7); + fileio_info->identifier = malloc(7); sprintf(fileio_info->identifier, "system"); nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); /* reserve fileio_info->param_2 for length of old path */ @@ -2420,12 +2452,12 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil } break; case NDS32_SYSCALL_ERRNO: - fileio_info->identifier = (char *)malloc(6); + fileio_info->identifier = malloc(6); sprintf(fileio_info->identifier, "errno"); nds32_set_mapped_reg(nds32, R0, nds32->virtual_hosting_errno); break; default: - fileio_info->identifier = (char *)malloc(8); + fileio_info->identifier = malloc(8); sprintf(fileio_info->identifier, "unknown"); break; } @@ -2435,7 +2467,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c) { - LOG_DEBUG("syscall return code: 0x%x, errno: 0x%x, ctrl_c: %s", + LOG_DEBUG("syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s", retcode, fileio_errno, ctrl_c ? "true" : "false"); struct nds32 *nds32 = target_to_nds32(target); @@ -2449,6 +2481,25 @@ int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, b 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) {