]> git.sur5r.net Git - openocd/blobdiff - src/target/armv8.c
Rework/update ARM semihosting
[openocd] / src / target / armv8.c
index b88f37d6bd02a033c325f387eca48b1d77a05d1c..20f2b671c6da98af7271133fb4005646d9321830 100644 (file)
@@ -1,6 +1,9 @@
 /***************************************************************************
  *   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     *
@@ -36,6 +39,7 @@
 #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",
@@ -1046,7 +1050,7 @@ int armv8_aarch64_state(struct target *target)
                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->is_active ? ", semihosting" : "");
 
        return ERROR_OK;
 }
@@ -1547,15 +1551,14 @@ struct reg_cache *armv8_build_reg_cache(struct target *target)
                } 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;
@@ -1608,14 +1611,45 @@ struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
        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)