ipdbg: fix double free of virtual-ir data
[openocd.git] / src / target / riscv / riscv.c
index 367506dde8675496868c9cf3472813af2362782b..9cd4922d20d7f0974d1d72410f7bfb663111eb70 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <assert.h>
 #include <stdlib.h>
@@ -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;
@@ -449,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)
@@ -489,14 +490,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 +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);
@@ -859,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);
@@ -903,7 +906,7 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       breakpoint->set = true;
+       breakpoint->is_set = true;
        return ERROR_OK;
 }
 
@@ -939,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) {
@@ -963,7 +966,7 @@ int riscv_remove_breakpoint(struct target *target,
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       breakpoint->set = false;
+       breakpoint->is_set = false;
 
        return ERROR_OK;
 }
@@ -990,7 +993,7 @@ int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
        int result = add_trigger(target, &trigger);
        if (result != ERROR_OK)
                return result;
-       watchpoint->set = true;
+       watchpoint->is_set = true;
 
        return ERROR_OK;
 }
@@ -1006,7 +1009,7 @@ int riscv_remove_watchpoint(struct target *target,
        int result = remove_trigger(target, &trigger);
        if (result != ERROR_OK)
                return result;
-       watchpoint->set = false;
+       watchpoint->is_set = false;
 
        return ERROR_OK;
 }
@@ -1017,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;
 
@@ -1160,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);
 
@@ -1180,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);
 
@@ -1198,9 +1201,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 +1245,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 +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);
 
@@ -1338,9 +1341,9 @@ static int disable_triggers(struct target *target, riscv_reg_t *state)
                struct watchpoint *watchpoint = target->watchpoints;
                int i = 0;
                while (watchpoint) {
-                       LOG_DEBUG("watchpoint %d: set=%d", i, watchpoint->set);
-                       state[i] = watchpoint->set;
-                       if (watchpoint->set) {
+                       LOG_DEBUG("watchpoint %d: set=%d", i, watchpoint->is_set);
+                       state[i] = watchpoint->is_set;
+                       if (watchpoint->is_set) {
                                if (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)
                                        return ERROR_FAIL;
                        }
@@ -1434,7 +1437,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 +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,
@@ -1483,7 +1486,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)
@@ -1604,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) {
@@ -1740,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:
@@ -1826,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);
 
@@ -1836,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;
        }
 
@@ -2048,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,
@@ -2103,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:
@@ -2129,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);
 
@@ -2183,13 +2187,12 @@ 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;
                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:
@@ -2199,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);
@@ -2209,17 +2211,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 +2282,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 {
@@ -2363,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);
@@ -2456,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)
@@ -2662,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)
@@ -2740,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;
@@ -2943,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,
@@ -3016,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,
@@ -3114,9 +3033,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,11 +3116,14 @@ 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->registers_initialized = false;
        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,18 +3222,15 @@ 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)
 {
-       RISCV_INFO(r);
-
        LOG_DEBUG("[%d]", target->coreid);
        register_cache_invalidate(target->reg_cache);
        for (size_t i = 0; i < target->reg_cache->num_regs; ++i) {
                struct reg *reg = &target->reg_cache->reg_list[i];
                reg->valid = false;
        }
-
-       r->registers_initialized = true;
 }
 
 int riscv_current_hartid(const struct target *target)
@@ -3453,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)
@@ -3931,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" };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)