+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
LOG_DEBUG("-");
- if (target->state != TARGET_HALTED)
+ if (target->state != TARGET_HALTED) {
+ LOG_TARGET_ERROR(target, "not halted");
return ERROR_TARGET_NOT_HALTED;
+ }
int retval = esirisc_jtag_flush_caches(jtag_info);
if (retval != ERROR_OK) {
LOG_DEBUG("-");
for (int bp_index = 0; breakpoints_p < breakpoints_e; ++breakpoints_p, ++bp_index)
- if (*breakpoints_p == NULL)
+ if (!*breakpoints_p)
return bp_index;
return -1;
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = bp_index + 1;
+ breakpoint_hw_set(breakpoint, bp_index);
esirisc->breakpoints_p[bp_index] = breakpoint;
/* specify instruction breakpoint address */
LOG_DEBUG("-");
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
esirisc_add_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
{
struct esirisc_common *esirisc = target_to_esirisc(target);
struct esirisc_jtag *jtag_info = &esirisc->jtag_info;
- int bp_index = breakpoint->set - 1;
+ unsigned int bp_index = breakpoint->number;
uint32_t ibc;
int retval;
}
esirisc->breakpoints_p[bp_index] = NULL;
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
LOG_DEBUG("-");
for (int wp_index = 0; watchpoints_p < watchpoints_e; ++watchpoints_p, ++wp_index)
- if (*watchpoints_p == NULL)
+ if (!*watchpoints_p)
return wp_index;
return -1;
return ERROR_FAIL;
}
- watchpoint->set = wp_index + 1;
+ watchpoint_set(watchpoint, wp_index);
esirisc->watchpoints_p[wp_index] = watchpoint;
/* specify data breakpoint address */
LOG_DEBUG("-");
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
esirisc_add_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
{
struct esirisc_common *esirisc = target_to_esirisc(target);
struct esirisc_jtag *jtag_info = &esirisc->jtag_info;
- int wp_index = watchpoint->set - 1;
+ unsigned int wp_index = watchpoint->number;
uint32_t dbc;
int retval;
}
esirisc->watchpoints_p[wp_index] = NULL;
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
LOG_DEBUG("-");
- if (target->state != TARGET_HALTED)
+ if (target->state != TARGET_HALTED) {
+ LOG_TARGET_ERROR(target, "not halted");
return ERROR_TARGET_NOT_HALTED;
+ }
if (!debug_execution) {
target_free_all_working_areas(target);
return ERROR_OK;
}
-static const char *esirisc_get_gdb_arch(struct target *target)
+static const char *esirisc_get_gdb_arch(const struct target *target)
{
struct esirisc_common *esirisc = target_to_esirisc(target);
* requires additional configuration to properly interact with these
* targets in GDB (also see: `esirisc cache_arch`).
*/
- if (esirisc->gdb_arch == NULL && target_was_examined(target))
+ if (!esirisc->gdb_arch && target_was_examined(target))
esirisc->gdb_arch = alloc_printf("esirisc:%d_bit_%d_reg_%s",
esirisc->num_bits, esirisc->num_regs, esirisc_cache_arch_name(esirisc));
*reg_list_size = ESIRISC_NUM_REGS;
*reg_list = calloc(*reg_list_size, sizeof(struct reg *));
- if (*reg_list == NULL)
+ if (!*reg_list)
return ERROR_FAIL;
if (reg_class == REG_CLASS_ALL)
return cache;
}
+static void esirisc_free_reg_cache(struct target *target)
+{
+ struct esirisc_common *esirisc = target_to_esirisc(target);
+ struct reg_cache *cache = esirisc->reg_cache;
+ struct reg *reg_list = cache->reg_list;
+
+ for (int i = 0; i < esirisc->num_regs; ++i) {
+ struct reg *reg = reg_list + esirisc_regs[i].number;
+
+ free(reg->arch_info);
+ free(reg->value);
+ free(reg->reg_data_type);
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(esirisc_csrs); ++i) {
+ struct reg *reg = reg_list + esirisc_csrs[i].number;
+
+ free(reg->arch_info);
+ free(reg->value);
+ free(reg->reg_data_type);
+ }
+
+ free(reg_list);
+ free(cache);
+}
+
static int esirisc_identify(struct target *target)
{
struct esirisc_common *esirisc = target_to_esirisc(target);
return ERROR_OK;
}
+static void esirisc_deinit_target(struct target *target)
+{
+ struct esirisc_common *esirisc = target_to_esirisc(target);
+
+ if (!target_was_examined(target))
+ return;
+
+ esirisc_free_reg_cache(target);
+
+ free(esirisc->gdb_arch);
+ free(esirisc);
+}
+
static int esirisc_examine(struct target *target)
{
struct esirisc_common *esirisc = target_to_esirisc(target);
.target_create = esirisc_target_create,
.init_target = esirisc_init_target,
+ .deinit_target = esirisc_deinit_target,
.examine = esirisc_examine,
};