/***************************************************************************
* Copyright (C) 2015 by David Ung *
* *
+ * Copyright (C) 2018 by Liviu Ionescu *
+ * <ilg@livius.net> *
+ * *
* 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 *
#include "armv8_opcodes.h"
#include "target.h"
#include "target_type.h"
+#include "semihosting_common.h"
static const char * const armv8_state_strings[] = {
"AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
"Secure", "Not Secure"
};
+ if (target->state != TARGET_HALTED) {
+ LOG_WARNING("target %s not halted", target_name(target));
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
retval = dpm->prepare(dpm);
if (retval != ERROR_OK)
return retval;
return ERROR_OK;
}
+static int armv8_setup_semihosting(struct target *target, int enable)
+{
+ struct arm *arm = target_to_arm(target);
+
+ if (arm->core_state != ARM_STATE_AARCH64) {
+ LOG_ERROR("semihosting only supported in AArch64 state\n");
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
{
struct arm *arm = &armv8->arm;
arm->arch_info = armv8;
target->arch_info = &armv8->arm;
+ arm->setup_semihosting = armv8_setup_semihosting;
/* target is useful in all function arm v4 5 compatible */
armv8->arm.target = target;
armv8->arm.common_magic = ARM_COMMON_MAGIC;
armv8_mode_name(arm->core_mode),
buf_get_u32(arm->cpsr->value, 0, 32),
buf_get_u64(arm->pc->value, 0, 64),
- arm->is_semihosting ? ", semihosting" : "");
+ (target->semihosting && target->semihosting->is_active) ? ", semihosting" : "");
return ERROR_OK;
}
struct reg *reg64;
int retval;
+ if (target->state != TARGET_HALTED)
+ return ERROR_TARGET_NOT_HALTED;
+
/* get the corresponding Aarch64 register */
reg64 = cache->reg_list + armv8_reg->num;
if (reg64->valid) {
struct reg *reg64 = cache->reg_list + armv8_reg->num;
uint32_t value = buf_get_u32(buf, 0, 32);
+ if (target->state != TARGET_HALTED)
+ return ERROR_TARGET_NOT_HALTED;
+
if (reg64 == arm->cpsr) {
armv8_set_cpsr(arm, value);
} else {
} else
LOG_ERROR("unable to allocate feature list");
- if (armv8_regs[i].data_type == NULL) {
- reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
- if (reg_list[i].reg_data_type)
+ reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
+ if (reg_list[i].reg_data_type) {
+ if (armv8_regs[i].data_type == NULL)
reg_list[i].reg_data_type->type = armv8_regs[i].type;
else
- LOG_ERROR("unable to allocate reg type list");
+ *reg_list[i].reg_data_type = *armv8_regs[i].data_type;
} else
- reg_list[i].reg_data_type = armv8_regs[i].data_type;
-
+ LOG_ERROR("unable to allocate reg type list");
}
arm->cpsr = reg_list + ARMV8_xPSR;
return r;
}
+static void armv8_free_cache(struct reg_cache *cache, bool regs32)
+{
+ struct reg *reg;
+ unsigned int i;
+
+ if (!cache)
+ return;
+
+ for (i = 0; i < cache->num_regs; i++) {
+ reg = &cache->reg_list[i];
+
+ free(reg->feature);
+ free(reg->reg_data_type);
+ }
+
+ if (!regs32)
+ free(cache->reg_list[0].arch_info);
+ free(cache->reg_list);
+ free(cache);
+}
+
+void armv8_free_reg_cache(struct target *target)
+{
+ struct armv8_common *armv8 = target_to_armv8(target);
+ struct arm *arm = &armv8->arm;
+ struct reg_cache *cache = NULL, *cache32 = NULL;
+
+ cache = arm->core_cache;
+ if (cache != NULL)
+ cache32 = cache->next;
+ armv8_free_cache(cache32, true);
+ armv8_free_cache(cache, false);
+ arm->core_cache = NULL;
+}
+
const struct command_registration armv8_command_handlers[] = {
- {
- .chain = dap_command_handlers,
- },
COMMAND_REGISTRATION_DONE
};
-
int armv8_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size,
enum target_register_class reg_class)