X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Ftarget%2Friscv%2Friscv.c;h=c25efcde9a0d8cfbfe3004633dbfdc8be627de58;hb=ea9089944e509ba301f5a2ca14b30eb5d7a90f44;hp=e2d8e7098e567b1de8d0904371a604c5048a8726;hpb=7e9e5dca073d7a11c2391f57872e97372d94ad48;p=fw%2Fopenocd diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index e2d8e7098..c25efcde9 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ +// SPDX-License-Identifier: GPL-2.0-or-later #include #include @@ -109,37 +109,37 @@ typedef enum slot { #define MAX_HWBPS 16 #define DRAM_CACHE_SIZE 16 -uint8_t ir_dtmcontrol[4] = {DTMCONTROL}; +static uint8_t ir_dtmcontrol[4] = {DTMCONTROL}; struct scan_field select_dtmcontrol = { .in_value = NULL, .out_value = ir_dtmcontrol }; -uint8_t ir_dbus[4] = {DBUS}; +static uint8_t ir_dbus[4] = {DBUS}; struct scan_field select_dbus = { .in_value = NULL, .out_value = ir_dbus }; -uint8_t ir_idcode[4] = {0x1}; +static uint8_t ir_idcode[4] = {0x1}; struct scan_field select_idcode = { .in_value = NULL, .out_value = ir_idcode }; -bscan_tunnel_type_t bscan_tunnel_type; +static bscan_tunnel_type_t bscan_tunnel_type; int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */ static const uint8_t bscan_zero[4] = {0}; static const uint8_t bscan_one[4] = {1}; -uint8_t ir_user4[4]; -struct scan_field select_user4 = { +static uint8_t ir_user4[4]; +static struct scan_field select_user4 = { .in_value = NULL, .out_value = ir_user4 }; -uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */ -struct scan_field _bscan_tunnel_data_register_select_dmi[] = { +static uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */ +static struct scan_field _bscan_tunnel_data_register_select_dmi[] = { { .num_bits = 3, .out_value = bscan_zero, @@ -162,7 +162,7 @@ struct scan_field _bscan_tunnel_data_register_select_dmi[] = { } }; -struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = { +static struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = { { .num_bits = 1, .out_value = bscan_zero, @@ -184,11 +184,11 @@ struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = { .in_value = NULL, } }; -struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi; -uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi); +static struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi; +static uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi); -struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi; -uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi); +static struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi; +static uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi); struct trigger { uint64_t address; @@ -205,7 +205,7 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC; /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/ int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC; -bool riscv_enable_virt2phys = true; +static bool riscv_enable_virt2phys = true; bool riscv_ebreakm = true; bool riscv_ebreaks = true; bool riscv_ebreaku = true; @@ -217,7 +217,7 @@ static enum { RO_REVERSED } resume_order; -const virt2phys_info_t sv32 = { +static const virt2phys_info_t sv32 = { .name = "Sv32", .va_bits = 32, .level = 2, @@ -230,7 +230,7 @@ const virt2phys_info_t sv32 = { .pa_ppn_mask = {0x3ff, 0xfff}, }; -const virt2phys_info_t sv39 = { +static const virt2phys_info_t sv39 = { .name = "Sv39", .va_bits = 39, .level = 3, @@ -243,7 +243,7 @@ const virt2phys_info_t sv39 = { .pa_ppn_mask = {0x1ff, 0x1ff, 0x3ffffff}, }; -const virt2phys_info_t sv48 = { +static const virt2phys_info_t sv48 = { .name = "Sv48", .va_bits = 48, .level = 4, @@ -256,7 +256,12 @@ const virt2phys_info_t sv48 = { .pa_ppn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ffff}, }; -void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before) +static enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid); +static void riscv_info_init(struct target *target, struct riscv_info *r); +static void riscv_invalidate_register_cache(struct target *target); +static int riscv_step_rtos_hart(struct target *target); + +static void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before) { RISCV_INFO(r); uint32_t now = timeval_ms() & 0xffffffff; @@ -405,13 +410,12 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) static struct target_type *get_target_type(struct target *target) { - riscv_info_t *info = (riscv_info_t *) target->arch_info; - - if (!info) { + if (!target->arch_info) { LOG_ERROR("Target has not been initialized"); return NULL; } + RISCV_INFO(info); switch (info->dtm_version) { case 0: return &riscv011_target; @@ -426,7 +430,7 @@ static struct target_type *get_target_type(struct target *target) static int riscv_create_target(struct target *target, Jim_Interp *interp) { LOG_DEBUG("riscv_create_target()"); - target->arch_info = calloc(1, sizeof(riscv_info_t)); + target->arch_info = calloc(1, sizeof(struct riscv_info)); if (!target->arch_info) { LOG_ERROR("Failed to allocate RISC-V target structure."); return ERROR_FAIL; @@ -489,14 +493,17 @@ static void riscv_deinit_target(struct target *target) { LOG_DEBUG("riscv_deinit_target()"); - riscv_info_t *info = target->arch_info; + struct riscv_info *info = target->arch_info; struct target_type *tt = get_target_type(target); - if (tt && info->version_specific) + if (tt && info && info->version_specific) tt->deinit_target(target); riscv_free_registers(target); + if (!info) + return; + range_list_t *entry, *tmp; list_for_each_entry_safe(entry, tmp, &info->expose_csr, list) { free(entry->name); @@ -706,7 +713,6 @@ static int add_trigger(struct target *target, struct trigger *trigger) return result; int type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target))); - result = ERROR_OK; switch (type) { case 1: result = maybe_add_trigger_t1(target, trigger, tdata1); @@ -859,7 +865,7 @@ int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_ return ERROR_FAIL; } -int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint) +static int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint) { LOG_DEBUG("[%d] @0x%" TARGET_PRIxADDR, target->coreid, breakpoint->address); assert(breakpoint); @@ -939,7 +945,7 @@ static int remove_trigger(struct target *target, struct trigger *trigger) return ERROR_OK; } -int riscv_remove_breakpoint(struct target *target, +static int riscv_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) { if (breakpoint->type == BKPT_SOFT) { @@ -1017,7 +1023,7 @@ int riscv_remove_watchpoint(struct target *target, * The GDB server uses this information to tell GDB what data address has * been hit, which enables GDB to print the hit variable along with its old * and new value. */ -int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) +static int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) { struct watchpoint *wp = target->watchpoints; @@ -1160,7 +1166,7 @@ int riscv_select_current_hart(struct target *target) return riscv_set_current_hartid(target, target->coreid); } -int halt_prep(struct target *target) +static int halt_prep(struct target *target) { RISCV_INFO(r); @@ -1180,7 +1186,7 @@ int halt_prep(struct target *target) return ERROR_OK; } -int riscv_halt_go_all_harts(struct target *target) +static int riscv_halt_go_all_harts(struct target *target) { RISCV_INFO(r); @@ -1198,9 +1204,9 @@ int riscv_halt_go_all_harts(struct target *target) return ERROR_OK; } -int halt_go(struct target *target) +static int halt_go(struct target *target) { - riscv_info_t *r = riscv_info(target); + RISCV_INFO(r); int result; if (!r->is_halted) { struct target_type *tt = get_target_type(target); @@ -1242,7 +1248,7 @@ int riscv_halt(struct target *target) foreach_smp_target(tlist, target->smp_targets) { struct target *t = tlist->target; - riscv_info_t *i = riscv_info(t); + struct riscv_info *i = riscv_info(t); if (i->prepped) { if (halt_go(t) != ERROR_OK) result = ERROR_FAIL; @@ -1282,7 +1288,7 @@ static int riscv_deassert_reset(struct target *target) return tt->deassert_reset(target); } -int riscv_resume_prep_all_harts(struct target *target) +static int riscv_resume_prep_all_harts(struct target *target) { RISCV_INFO(r); @@ -1434,7 +1440,7 @@ static int resume_prep(struct target *target, int current, static int resume_go(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution) { - riscv_info_t *r = riscv_info(target); + RISCV_INFO(r); int result; if (!r->is_halted) { struct target_type *tt = get_target_type(target); @@ -1460,7 +1466,7 @@ static int resume_finish(struct target *target) * @par single_hart When true, only resume a single hart even if SMP is * configured. This is used to run algorithms on just one hart. */ -int riscv_resume( +static int riscv_resume( struct target *target, int current, target_addr_t address, @@ -1483,7 +1489,7 @@ int riscv_resume( foreach_smp_target_direction(resume_order == RO_NORMAL, tlist, target->smp_targets) { struct target *t = tlist->target; - riscv_info_t *i = riscv_info(t); + struct riscv_info *i = riscv_info(t); if (i->prepped) { if (resume_go(t, current, address, handle_breakpoints, debug_execution) != ERROR_OK) @@ -1740,7 +1746,7 @@ static int riscv_write_memory(struct target *target, target_addr_t address, return tt->write_memory(target, address, size, count, buffer); } -const char *riscv_get_gdb_arch(struct target *target) +static const char *riscv_get_gdb_arch(struct target *target) { switch (riscv_xlen(target)) { case 32: @@ -2103,7 +2109,7 @@ static enum riscv_poll_hart riscv_poll_hart(struct target *target, int hartid) return RPH_NO_CHANGE; } -int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason) +static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason) { switch (halt_reason) { case RISCV_HALT_BREAKPOINT: @@ -2129,7 +2135,7 @@ int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason) return ERROR_OK; } -int sample_memory(struct target *target) +static int sample_memory(struct target *target) { RISCV_INFO(r); @@ -2189,7 +2195,7 @@ int riscv_openocd_poll(struct target *target) struct target_list *list; foreach_smp_target(list, target->smp_targets) { struct target *t = list->target; - riscv_info_t *r = riscv_info(t); + struct riscv_info *r = riscv_info(t); enum riscv_poll_hart out = riscv_poll_hart(t, r->current_hartid); switch (out) { case RPH_NO_CHANGE: @@ -2209,17 +2215,17 @@ int riscv_openocd_poll(struct target *target) if (halt_reason == RISCV_HALT_BREAKPOINT) { int retval; switch (riscv_semihosting(t, &retval)) { - case SEMI_NONE: - case SEMI_WAITING: + case SEMIHOSTING_NONE: + case SEMIHOSTING_WAITING: /* This hart should remain halted. */ should_remain_halted++; break; - case SEMI_HANDLED: + case SEMIHOSTING_HANDLED: /* This hart should be resumed, along with any other * harts that halted due to haltgroups. */ should_resume++; break; - case SEMI_ERROR: + case SEMIHOSTING_ERROR: return retval; } } else if (halt_reason != RISCV_HALT_GROUP) { @@ -2280,15 +2286,15 @@ int riscv_openocd_poll(struct target *target) if (target->debug_reason == DBG_REASON_BREAKPOINT) { int retval; switch (riscv_semihosting(target, &retval)) { - case SEMI_NONE: - case SEMI_WAITING: + case SEMIHOSTING_NONE: + case SEMIHOSTING_WAITING: target_call_event_callbacks(target, TARGET_EVENT_HALTED); break; - case SEMI_HANDLED: + case SEMIHOSTING_HANDLED: if (riscv_resume(target, true, 0, 0, 0, false) != ERROR_OK) return ERROR_FAIL; break; - case SEMI_ERROR: + case SEMIHOSTING_ERROR: return retval; } } else { @@ -2456,7 +2462,7 @@ COMMAND_HANDLER(riscv_set_enable_virtual) return ERROR_OK; } -int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val) +static int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val) { char *args = strdup(tcl_arg); if (!args) @@ -3114,9 +3120,8 @@ static const struct command_registration riscv_exec_command_handlers[] = { * protocol, then a command like `riscv semihosting enable` will make * sense, but for now all semihosting commands are prefixed with `arm`. */ -extern const struct command_registration semihosting_common_handlers[]; -const struct command_registration riscv_command_handlers[] = { +static const struct command_registration riscv_command_handlers[] = { { .name = "riscv", .mode = COMMAND_ANY, @@ -3198,9 +3203,13 @@ struct target_type riscv_target = { /*** RISC-V Interface ***/ -void riscv_info_init(struct target *target, riscv_info_t *r) +/* Initializes the shared RISC-V structure. */ +static void riscv_info_init(struct target *target, struct riscv_info *r) { memset(r, 0, sizeof(*r)); + + r->common_magic = RISCV_COMMON_MAGIC; + r->dtm_version = 1; r->current_hartid = target->coreid; r->version_specific = NULL; @@ -3240,7 +3249,9 @@ static int riscv_resume_go_all_harts(struct target *target) return ERROR_OK; } -int riscv_step_rtos_hart(struct target *target) +/* Steps the hart that's currently selected in the RTOS, or if there is no RTOS + * then the only hart. */ +static int riscv_step_rtos_hart(struct target *target) { RISCV_INFO(r); if (riscv_select_current_hart(target) != ERROR_OK) @@ -3298,7 +3309,8 @@ int riscv_set_current_hartid(struct target *target, int hartid) return ERROR_OK; } -void riscv_invalidate_register_cache(struct target *target) +/* Invalidates the register cache. */ +static void riscv_invalidate_register_cache(struct target *target) { LOG_DEBUG("[%d]", target->coreid); register_cache_invalidate(target->reg_cache); @@ -3448,7 +3460,7 @@ bool riscv_is_halted(struct target *target) return r->is_halted(target); } -enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid) +static enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid) { RISCV_INFO(r); if (riscv_set_current_hartid(target, hartid) != ERROR_OK)