ARM: only use one set of dummy FPA registers
authorDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 18 Nov 2009 07:50:17 +0000 (23:50 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 18 Nov 2009 07:50:17 +0000 (23:50 -0800)
All ARM cores need to provide obsolete FPA registers in their
GDB register dumps.  (Even though cores with floating point
support now generally use some version of VFP...)

Clean up that support a bit by sharing the same dummy registers,
and removing the duplicate copies.  Eventually we shouldn't need
to export those dummies.

(This makes the ARMv7-M support include the armv4_5 header, and
cleans up related #includes, but doesn't yet use anything from
there except those dummies.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/flash/lpc2000.c
src/target/arm11.c
src/target/armv4_5.c
src/target/armv4_5.h
src/target/armv7a.c
src/target/armv7m.c
src/target/armv7m.h
src/target/cortex_m3.c
src/target/cortex_m3.h

index 191eb4b..5442e71 100644 (file)
@@ -26,7 +26,6 @@
 #endif
 
 #include "lpc2000.h"
-#include "armv4_5.h"
 #include "armv7m.h"
 #include "binarybuffer.h"
 #include "algorithm.h"
index 65e0780..5e73275 100644 (file)
@@ -246,36 +246,6 @@ enum arm11_regcache_ids
 
 #define ARM11_GDB_REGISTER_COUNT       26
 
-/* FIXME these are *identical* to the ARMv4_5 dummies ...  except
- * for their names, and being static vs global, and having different
- * addresses.  Ditto ARMv7a and ARMv7m dummies.
- */
-
-static uint8_t arm11_gdb_dummy_fp_value[12];
-
-static struct reg arm11_gdb_dummy_fp_reg =
-{
-       .name = "GDB dummy floating-point register",
-       .value = arm11_gdb_dummy_fp_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 96,
-       .arch_info = NULL,
-};
-
-static uint8_t arm11_gdb_dummy_fps_value[4];
-
-static struct reg arm11_gdb_dummy_fps_reg =
-{
-       .name = "GDB dummy floating-point status register",
-       .value = arm11_gdb_dummy_fps_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 32,
-       .arch_info = NULL,
-};
-
-
 static int arm11_on_enter_debug_state(struct arm11_common *arm11);
 static int arm11_step(struct target *target, int current,
                uint32_t address, int handle_breakpoints);
@@ -1265,12 +1235,10 @@ static int arm11_get_gdb_reg_list(struct target *target,
        *reg_list_size  = ARM11_GDB_REGISTER_COUNT;
        *reg_list               = malloc(sizeof(struct reg*) * ARM11_GDB_REGISTER_COUNT);
 
+       /* nine unused legacy FPA registers are expected by GDB */
        for (size_t i = 16; i < 24; i++)
-       {
-               (*reg_list)[i] = &arm11_gdb_dummy_fp_reg;
-       }
-
-       (*reg_list)[24] = &arm11_gdb_dummy_fps_reg;
+               (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
+       (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
 
        for (size_t i = 0; i < ARM11_REGCACHE_COUNT; i++)
        {
@@ -1954,9 +1922,6 @@ static int arm11_build_reg_cache(struct target *target)
        NEW(struct reg,                         reg_list,                       ARM11_REGCACHE_COUNT);
        NEW(struct arm11_reg_state,     arm11_reg_states,       ARM11_REGCACHE_COUNT);
 
-       register_init_dummy(&arm11_gdb_dummy_fp_reg);
-       register_init_dummy(&arm11_gdb_dummy_fps_reg);
-
        arm11->reg_list = reg_list;
 
        /* Build the process context cache */
index 6f8d14c..aba4431 100644 (file)
@@ -189,30 +189,44 @@ int armv4_5_core_reg_map[7][17] =
        }
 };
 
-uint8_t armv4_5_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const uint8_t arm_gdb_dummy_fp_value[12];
 
-struct reg armv4_5_gdb_dummy_fp_reg =
+/**
+ * Dummy FPA registers are required to support GDB on ARM.
+ * Register packets require eight obsolete FPA register values.
+ * Modern ARM cores use Vector Floating Point (VFP), if they
+ * have any floating point support.  VFP is not FPA-compatible.
+ */
+struct reg arm_gdb_dummy_fp_reg =
 {
-       .name = "GDB dummy floating-point register",
-       .value = armv4_5_gdb_dummy_fp_value,
-       .dirty = 0,
+       .name = "GDB dummy FPA register",
+       .value = (uint8_t *) arm_gdb_dummy_fp_value,
        .valid = 1,
        .size = 96,
-       .arch_info = NULL,
 };
 
-uint8_t armv4_5_gdb_dummy_fps_value[] = {0, 0, 0, 0};
+static const uint8_t arm_gdb_dummy_fps_value[4];
 
-struct reg armv4_5_gdb_dummy_fps_reg =
+/**
+ * Dummy FPA status registers are required to support GDB on ARM.
+ * Register packets require an obsolete FPA status register.
+ */
+struct reg arm_gdb_dummy_fps_reg =
 {
-       .name = "GDB dummy floating-point status register",
-       .value = armv4_5_gdb_dummy_fps_value,
-       .dirty = 0,
+       .name = "GDB dummy FPA status register",
+       .value = (uint8_t *) arm_gdb_dummy_fps_value,
        .valid = 1,
        .size = 32,
-       .arch_info = NULL,
 };
 
+static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
+
+static void arm_gdb_dummy_init(void)
+{
+       register_init_dummy(&arm_gdb_dummy_fp_reg);
+       register_init_dummy(&arm_gdb_dummy_fps_reg);
+}
+
 int armv4_5_get_core_reg(struct reg *reg)
 {
        int retval;
@@ -313,9 +327,6 @@ struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *arm
        cache->reg_list = reg_list;
        cache->num_regs = num_regs;
 
-       register_init_dummy(&armv4_5_gdb_dummy_fp_reg);
-       register_init_dummy(&armv4_5_gdb_dummy_fps_reg);
-
        for (i = 0; i < 37; i++)
        {
                arch_info[i] = armv4_5_core_reg_list_arch_info[i];
@@ -550,10 +561,10 @@ int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
 
        for (i = 16; i < 24; i++)
        {
-               (*reg_list)[i] = &armv4_5_gdb_dummy_fp_reg;
+               (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
        }
 
-       (*reg_list)[24] = &armv4_5_gdb_dummy_fps_reg;
+       (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
        (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
 
        return ERROR_OK;
index 5fef094..d126f96 100644 (file)
@@ -158,6 +158,8 @@ int arm_checksum_memory(struct target *target,
 int arm_blank_check_memory(struct target *target,
                uint32_t address, uint32_t count, uint32_t *blank);
 
+extern struct reg arm_gdb_dummy_fp_reg;
+extern struct reg arm_gdb_dummy_fps_reg;
 
 /* ARM mode instructions
  */
index 8f90dd3..1518674 100644 (file)
@@ -144,21 +144,6 @@ int armv7a_core_reg_map[8][17] =
        }
 };
 
-/* FIXME this dummy is IDENTICAL to the armv4_5, arm11, and armv7m
- * ones... except for naming/scoping
- */
-uint8_t armv7a_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-struct reg armv7a_gdb_dummy_fp_reg =
-{
-       .name = "GDB dummy floating-point register",
-       .value = armv7a_gdb_dummy_fp_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 96,
-       .arch_info = NULL,
-};
-
 void armv7a_show_fault_registers(struct target *target)
 {
        uint32_t dfsr, ifsr, dfar, ifar;
index 862261d..56fbb05 100644 (file)
@@ -35,7 +35,6 @@
 #endif
 
 #include "breakpoints.h"
-#include "target.h"
 #include "armv7m.h"
 #include "algorithm.h"
 #include "register.h"
@@ -59,33 +58,6 @@ static char *armv7m_exception_strings[] =
        "DebugMonitor", "RESERVED", "PendSV", "SysTick"
 };
 
-/* FIXME these dummies are IDENTICAL to the armv4_5, arm11, and armv7a
- * ones... except for naming/scoping
- */
-static uint8_t armv7m_gdb_dummy_fp_value[12];
-
-static struct reg armv7m_gdb_dummy_fp_reg =
-{
-       .name = "GDB dummy floating-point register",
-       .value = armv7m_gdb_dummy_fp_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 96,
-       .arch_info = NULL,
-};
-
-static uint8_t armv7m_gdb_dummy_fps_value[4];
-
-static struct reg armv7m_gdb_dummy_fps_reg =
-{
-       .name = "GDB dummy floating-point status register",
-       .value = armv7m_gdb_dummy_fps_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 32,
-       .arch_info = NULL,
-};
-
 #ifdef ARMV7_GDB_HACKS
 uint8_t armv7m_gdb_dummy_cpsr_value[] = {0, 0, 0, 0};
 
@@ -316,11 +288,8 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
        }
 
        for (i = 16; i < 24; i++)
-       {
-               (*reg_list)[i] = &armv7m_gdb_dummy_fp_reg;
-       }
-
-       (*reg_list)[24] = &armv7m_gdb_dummy_fps_reg;
+               (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
+       (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
 
 #ifdef ARMV7_GDB_HACKS
        /* use dummy cpsr reg otherwise gdb may try and set the thumb bit */
@@ -553,11 +522,9 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
        struct armv7m_core_reg *arch_info = calloc(num_regs, sizeof(struct armv7m_core_reg));
        int i;
 
-       register_init_dummy(&armv7m_gdb_dummy_fps_reg);
 #ifdef ARMV7_GDB_HACKS
        register_init_dummy(&armv7m_gdb_dummy_cpsr_reg);
 #endif
-       register_init_dummy(&armv7m_gdb_dummy_fp_reg);
 
        /* Build the process context cache */
        cache->name = "arm v7m registers";
index dba9a3b..9dd4ddb 100644 (file)
@@ -27,6 +27,7 @@
 #define ARMV7M_COMMON_H
 
 #include "arm_adi_v5.h"
+#include "armv4_5.h"
 
 /* define for enabling armv7 gdb workarounds */
 #if 1
index c9938c9..42f8ee0 100644 (file)
@@ -334,6 +334,9 @@ static int cortex_m3_debug_entry(struct target *target)
        xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
 
 #ifdef ARMV7_GDB_HACKS
+       /* FIXME this breaks on scan chains with more than one Cortex-M3.
+        * Instead, each CM3 should have its own dummy value...
+        */
        /* copy real xpsr reg for gdb, setting thumb bit */
        buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR);
        buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1);
index 759c2bc..7ce8901 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef CORTEX_M3_H
 #define CORTEX_M3_H
 
-#include "target.h"
 #include "armv7m.h"