X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Friscv%2Friscv.c;h=9cd4922d20d7f0974d1d72410f7bfb663111eb70;hp=eccceade1919d169f4ec375af044515760fa8d7c;hb=HEAD;hpb=82e76262a13299f11d0a73418a8e76558761dccc diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index eccceade19..9cd4922d20 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; @@ -448,10 +453,7 @@ static int riscv_init_target(struct command_context *cmd_ctx, if (bscan_tunnel_ir_width != 0) { assert(target->tap->ir_length >= 6); uint32_t ir_user4_raw = 0x23 << (target->tap->ir_length - 6); - ir_user4[0] = (uint8_t)ir_user4_raw; - ir_user4[1] = (uint8_t)(ir_user4_raw >>= 8); - ir_user4[2] = (uint8_t)(ir_user4_raw >>= 8); - ir_user4[3] = (uint8_t)(ir_user4_raw >>= 8); + h_u32_to_le(ir_user4, ir_user4_raw); select_user4.num_bits = target->tap->ir_length; bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width; if (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER) @@ -708,7 +710,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); @@ -861,7 +862,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); @@ -941,7 +942,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) { @@ -1019,7 +1020,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; @@ -1162,7 +1163,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); @@ -1182,7 +1183,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); @@ -1200,7 +1201,7 @@ 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(r); int result; @@ -1284,7 +1285,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); @@ -1462,7 +1463,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, @@ -1606,6 +1607,7 @@ static int riscv_address_translate(struct target *target, LOG_DEBUG("virtual=0x%" TARGET_PRIxADDR "; mode=%s", virtual, info->name); /* verify bits xlen-1:va_bits-1 are all equal */ + assert(xlen >= info->va_bits); target_addr_t mask = ((target_addr_t)1 << (xlen - (info->va_bits - 1))) - 1; target_addr_t masked_msbs = (virtual >> (info->va_bits - 1)) & mask; if (masked_msbs != 0 && masked_msbs != mask) { @@ -1742,7 +1744,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(const struct target *target) { switch (riscv_xlen(target)) { case 32: @@ -1828,7 +1830,7 @@ static int riscv_arch_state(struct target *target) static int riscv_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, - target_addr_t exit_point, int timeout_ms, void *arch_info) + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { RISCV_INFO(info); @@ -1838,7 +1840,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, } if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); + LOG_TARGET_ERROR(target, "not halted (run target algo)"); return ERROR_TARGET_NOT_HALTED; } @@ -2050,7 +2052,7 @@ static int riscv_checksum_memory(struct target *target, buf_set_u64(reg_params[1].value, 0, xlen, count); /* 20 second timeout/megabyte */ - int timeout = 20000 * (1 + (count / (1024 * 1024))); + unsigned int timeout = 20000 * (1 + (count / (1024 * 1024))); retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, @@ -2105,7 +2107,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: @@ -2131,7 +2133,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); @@ -2185,7 +2187,6 @@ int riscv_openocd_poll(struct target *target) int halted_hart = -1; if (target->smp) { - unsigned halts_discovered = 0; unsigned should_remain_halted = 0; unsigned should_resume = 0; struct target_list *list; @@ -2201,7 +2202,6 @@ int riscv_openocd_poll(struct target *target) t->debug_reason = DBG_REASON_NOTHALTED; break; case RPH_DISCOVERED_HALTED: - halts_discovered++; t->state = TARGET_HALTED; enum riscv_halt_reason halt_reason = riscv_halt_reason(t, r->current_hartid); @@ -2365,37 +2365,6 @@ COMMAND_HANDLER(riscv_set_reset_timeout_sec) return ERROR_OK; } -COMMAND_HANDLER(riscv_set_prefer_sba) -{ - struct target *target = get_current_target(CMD_CTX); - RISCV_INFO(r); - bool prefer_sba; - LOG_WARNING("`riscv set_prefer_sba` is deprecated. Please use `riscv set_mem_access` instead."); - if (CMD_ARGC != 1) { - LOG_ERROR("Command takes exactly 1 parameter"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - COMMAND_PARSE_ON_OFF(CMD_ARGV[0], prefer_sba); - if (prefer_sba) { - /* Use system bus with highest priority */ - r->mem_access_methods[0] = RISCV_MEM_ACCESS_SYSBUS; - r->mem_access_methods[1] = RISCV_MEM_ACCESS_PROGBUF; - r->mem_access_methods[2] = RISCV_MEM_ACCESS_ABSTRACT; - } else { - /* Use progbuf with highest priority */ - r->mem_access_methods[0] = RISCV_MEM_ACCESS_PROGBUF; - r->mem_access_methods[1] = RISCV_MEM_ACCESS_SYSBUS; - r->mem_access_methods[2] = RISCV_MEM_ACCESS_ABSTRACT; - } - - /* Reset warning flags */ - r->mem_access_progbuf_warn = true; - r->mem_access_sysbus_warn = true; - r->mem_access_abstract_warn = true; - - return ERROR_OK; -} - COMMAND_HANDLER(riscv_set_mem_access) { struct target *target = get_current_target(CMD_CTX); @@ -2458,7 +2427,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) @@ -2664,27 +2633,25 @@ COMMAND_HANDLER(riscv_authdata_write) uint32_t value; unsigned int index = 0; - if (CMD_ARGC == 0) { - /* nop */ - } else if (CMD_ARGC == 1) { + if (CMD_ARGC == 0 || CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 1) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], value); - } else if (CMD_ARGC == 2) { + } else { COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], index); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - } else { - LOG_ERROR("Command takes at most 2 arguments"); - return ERROR_COMMAND_SYNTAX_ERROR; } struct target *target = get_current_target(CMD_CTX); RISCV_INFO(r); - if (r->authdata_write) { - return r->authdata_write(target, value, index); - } else { + if (!r->authdata_write) { LOG_ERROR("authdata_write is not implemented for this target."); return ERROR_FAIL; } + + return r->authdata_write(target, value, index); } COMMAND_HANDLER(riscv_dmi_read) @@ -2742,35 +2709,6 @@ COMMAND_HANDLER(riscv_dmi_write) } } -COMMAND_HANDLER(riscv_test_sba_config_reg) -{ - if (CMD_ARGC != 4) { - LOG_ERROR("Command takes exactly 4 arguments"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - struct target *target = get_current_target(CMD_CTX); - RISCV_INFO(r); - - target_addr_t legal_address; - uint32_t num_words; - target_addr_t illegal_address; - bool run_sbbusyerror_test; - - COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[0], legal_address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], num_words); - COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[2], illegal_address); - COMMAND_PARSE_ON_OFF(CMD_ARGV[3], run_sbbusyerror_test); - - if (r->test_sba_config_reg) { - return r->test_sba_config_reg(target, legal_address, num_words, - illegal_address, run_sbbusyerror_test); - } else { - LOG_ERROR("test_sba_config_reg is not implemented for this target."); - return ERROR_FAIL; - } -} - COMMAND_HANDLER(riscv_reset_delays) { int wait = 0; @@ -2945,14 +2883,6 @@ static const struct command_registration riscv_exec_command_handlers[] = { .usage = "[sec]", .help = "Set the wall-clock timeout (in seconds) after reset is deasserted" }, - { - .name = "set_prefer_sba", - .handler = riscv_set_prefer_sba, - .mode = COMMAND_ANY, - .usage = "on|off", - .help = "When on, prefer to use System Bus Access to access memory. " - "When off (default), prefer to use the Program Buffer to access memory." - }, { .name = "set_mem_access", .handler = riscv_set_mem_access, @@ -3018,19 +2948,6 @@ static const struct command_registration riscv_exec_command_handlers[] = { .usage = "address value", .help = "Perform a 32-bit DMI write of value at address." }, - { - .name = "test_sba_config_reg", - .handler = riscv_test_sba_config_reg, - .mode = COMMAND_ANY, - .usage = "legal_address num_words " - "illegal_address run_sbbusyerror_test[on/off]", - .help = "Perform a series of tests on the SBCS register. " - "Inputs are a legal, 128-byte aligned address and a number of words to " - "read/write starting at that address (i.e., address range [legal address, " - "legal_address+word_size*num_words) must be legally readable/writable), " - "an illegal, 128-byte aligned address for error flag/handling cases, " - "and whether sbbusyerror test should be run." - }, { .name = "reset_delays", .handler = riscv_reset_delays, @@ -3117,7 +3034,7 @@ static const struct command_registration riscv_exec_command_handlers[] = { * sense, but for now all semihosting commands are prefixed with `arm`. */ -const struct command_registration riscv_command_handlers[] = { +static const struct command_registration riscv_command_handlers[] = { { .name = "riscv", .mode = COMMAND_ANY, @@ -3199,9 +3116,13 @@ struct target_type riscv_target = { /*** RISC-V Interface ***/ -void riscv_info_init(struct target *target, struct riscv_info *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; @@ -3241,7 +3162,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) @@ -3299,7 +3222,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); @@ -3449,7 +3373,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) @@ -3927,7 +3851,7 @@ int riscv_init_registers(struct target *target) .type = REG_TYPE_ARCH_DEFINED, .id = "FPU_FD", .type_class = REG_TYPE_CLASS_UNION, - .reg_type_union = &single_double_union + { .reg_type_union = &single_double_union } }; static struct reg_data_type type_uint8 = { .type = REG_TYPE_UINT8, .id = "uint8" }; static struct reg_data_type type_uint16 = { .type = REG_TYPE_UINT16, .id = "uint16" };