ChangeLog:
authorUlrich Weigand <uweigand@de.ibm.com>
Fri, 31 Jul 2009 15:35:38 +0000 (15:35 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Fri, 31 Jul 2009 15:35:38 +0000 (15:35 +0000)
* spu-tdep.c: Include "infcall.h".
(spu_address_class_type_flags): New function.
(spu_address_class_type_flags_to_name): Likewise.
(spu_address_class_name_to_type_flags): Likewise.
(spu_pointer_to_address): Handle __ea pointers.
(spu_auto_flush_cache_p): New static variable.
(spu_objfile_from_frame): New function.
(flush_ea_cache, spu_attach_normal_stop): Likewise.
(show_spu_auto_flush_cache): Likewise.
(spu_gdbarch_init): Install address class handlers.
(_initialize_spu_tdep): Attach to normal_stop observer.
Install "set spu auto-flush-cache" / "show spu auto-flush-cache"
commands.

* NEWS: Mention "set/show spu auto-flush-cache" commands.

doc/ChangeLog:

* gdb.texinfo (Cell Broadband Engine SPU architecture): Document the
"set spu auto-flush-cache" and "show spu auto-flush-cache" commands.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/spu-tdep.c

index cff32f0..1ef0860 100644 (file)
@@ -1,5 +1,23 @@
 2009-07-31  Ulrich Weigand  <uweigand@de.ibm.com>
 
+       * spu-tdep.c: Include "infcall.h".
+       (spu_address_class_type_flags): New function.
+       (spu_address_class_type_flags_to_name): Likewise.
+       (spu_address_class_name_to_type_flags): Likewise.
+       (spu_pointer_to_address): Handle __ea pointers.
+       (spu_auto_flush_cache_p): New static variable.
+       (spu_objfile_from_frame): New function.
+       (flush_ea_cache, spu_attach_normal_stop): Likewise.
+       (show_spu_auto_flush_cache): Likewise.
+       (spu_gdbarch_init): Install address class handlers.
+       (_initialize_spu_tdep): Attach to normal_stop observer.
+       Install "set spu auto-flush-cache" / "show spu auto-flush-cache"
+       commands.
+
+       * NEWS: Mention "set/show spu auto-flush-cache" commands.
+
+2009-07-31  Ulrich Weigand  <uweigand@de.ibm.com>
+
        * spu-tdep.c: Include "block.h".
        (setspucmdlist, showspucmdlist): New static variables.
        (spu_stop_on_load_p): Likewise.
index db5a80b..970f4df 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -263,6 +263,11 @@ set spu stop-on-load
 show spu stop-on-load
   Control whether to stop for new SPE threads during Cell/B.E. debugging.
 
+set spu auto-flush-cache
+show spu auto-flush-cache
+  Control whether to automatically flush the software-managed cache
+  during Cell/B.E. debugging.
+
 set sh calling-convention
 show sh calling-convention
   Control the calling convention used when calling SH target functions.
index 360bbe0..dedf3fe 100644 (file)
@@ -1,6 +1,11 @@
 2009-07-31  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * gdb.texinfo (Cell Broadband Engine SPU architecture): Document the
+       "set spu auto-flush-cache" and "show spu auto-flush-cache" commands.
+
+2009-07-31  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * gdb.texinfo (Cell Broadband Engine SPU architecture): Document the
        "set spu stop-on-load" and "show spu stop-on-load" commands.
 
 2009-07-31  Ulrich Weigand  <uweigand@de.ibm.com>
index c06c6be..fab05fc 100644 (file)
@@ -17505,6 +17505,16 @@ function.  The default is @code{off}.
 @kindex show spu
 Show whether to stop for new SPE threads.
 
+@item set spu auto-flush-cache @var{arg}
+Set whether to automatically flush the software-managed cache.  When set to
+@code{on}, @value{GDBN} will automatically cause the SPE software-managed
+cache to be flushed whenever SPE execution stops.  This provides a consistent
+view of PowerPC memory that is accessed via the cache.  If an application
+does not use the software-managed cache, this option has no effect.
+
+@item show spu auto-flush-cache
+Show whether to automatically flush the software-managed cache.
+
 @end table
 
 @node PowerPC
index 1cc77ad..7e7ab9c 100644 (file)
@@ -42,6 +42,7 @@
 #include "floatformat.h"
 #include "block.h"
 #include "observer.h"
+#include "infcall.h"
 
 #include "spu-tdep.h"
 
@@ -52,6 +53,8 @@ static struct cmd_list_element *showspucmdlist = NULL;
 
 /* Whether to stop for new SPE contexts.  */
 static int spu_stop_on_load_p = 0;
+/* Whether to automatically flush the SW-managed cache.  */
+static int spu_auto_flush_cache_p = 1;
 
 
 /* The tdep structure.  */
@@ -340,7 +343,8 @@ spu_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   return default_register_reggroup_p (gdbarch, regnum, group);
 }
 
-/* Address conversion.  */
+
+/* Address handling.  */
 
 static int
 spu_gdbarch_id (struct gdbarch *gdbarch)
@@ -377,6 +381,37 @@ spu_lslr (int id)
   return strtoulst (buf, NULL, 16);
 }
 
+static int
+spu_address_class_type_flags (int byte_size, int dwarf2_addr_class)
+{
+  if (dwarf2_addr_class == 1)
+    return TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
+  else
+    return 0;
+}
+
+static const char *
+spu_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
+{
+  if (type_flags & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1)
+    return "__ea";
+  else
+    return NULL;
+}
+
+static int
+spu_address_class_name_to_type_flags (struct gdbarch *gdbarch,
+                                     const char *name, int *type_flags_ptr)
+{
+  if (strcmp (name, "__ea") == 0)
+    {
+      *type_flags_ptr = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
+      return 1;
+    }
+  else
+   return 0;
+}
+
 static void
 spu_address_to_pointer (struct gdbarch *gdbarch,
                        struct type *type, gdb_byte *buf, CORE_ADDR addr)
@@ -396,6 +431,10 @@ spu_pointer_to_address (struct gdbarch *gdbarch,
   ULONGEST addr
     = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
+  /* Do not convert __ea pointers.  */
+  if (TYPE_ADDRESS_CLASS_1 (type))
+    return addr;
+
   return addr? SPUADDR (id, addr & lslr) : 0;
 }
 
@@ -1820,6 +1859,73 @@ spu_catch_start (struct objfile *objfile)
 }
 
 
+/* Look up OBJFILE loaded into FRAME's SPU context.  */
+static struct objfile *
+spu_objfile_from_frame (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  struct objfile *obj;
+
+  if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
+    return NULL;
+
+  ALL_OBJFILES (obj)
+    {
+      if (obj->sections != obj->sections_end
+         && SPUADDR_SPU (obj_section_addr (obj->sections)) == tdep->id)
+       return obj;
+    }
+
+  return NULL;
+}
+
+/* Flush cache for ea pointer access if available.  */
+static void
+flush_ea_cache (void)
+{
+  struct minimal_symbol *msymbol;
+  struct objfile *obj;
+
+  if (!has_stack_frames ())
+    return;
+
+  obj = spu_objfile_from_frame (get_current_frame ());
+  if (obj == NULL)
+    return;
+
+  /* Lookup inferior function __cache_flush.  */
+  msymbol = lookup_minimal_symbol ("__cache_flush", NULL, obj);
+  if (msymbol != NULL)
+    {
+      struct type *type;
+      CORE_ADDR addr;
+
+      type = objfile_type (obj)->builtin_void;
+      type = lookup_function_type (type);
+      type = lookup_pointer_type (type);
+      addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+      call_function_by_hand (value_from_pointer (type, addr), 0, NULL);
+    }
+}
+
+/* This handler is called when the inferior has stopped.  If it is stopped in
+   SPU architecture then flush the ea cache if used.  */
+static void
+spu_attach_normal_stop (struct bpstats *bs, int print_frame)
+{
+  if (!spu_auto_flush_cache_p)
+    return;
+
+  /* Temporarily reset spu_auto_flush_cache_p to avoid recursively
+     re-entering this function when __cache_flush stops.  */
+  spu_auto_flush_cache_p = 0;
+  flush_ea_cache ();
+  spu_auto_flush_cache_p = 1;
+}
+
+
 /* "info spu" commands.  */
 
 static void
@@ -2411,6 +2517,14 @@ show_spu_stop_on_load (struct ui_file *file, int from_tty,
                     value);
 }
 
+static void
+show_spu_auto_flush_cache (struct ui_file *file, int from_tty,
+                          struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Automatic software-cache flush is %s.\n"),
+                    value);
+}
+
 
 /* Set up gdbarch struct.  */
 
@@ -2480,10 +2594,16 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
   set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
 
-  /* Address conversion.  */
+  /* Address handling.  */
   set_gdbarch_address_to_pointer (gdbarch, spu_address_to_pointer);
   set_gdbarch_pointer_to_address (gdbarch, spu_pointer_to_address);
   set_gdbarch_integer_to_address (gdbarch, spu_integer_to_address);
+  set_gdbarch_address_class_type_flags (gdbarch, spu_address_class_type_flags);
+  set_gdbarch_address_class_type_flags_to_name
+    (gdbarch, spu_address_class_type_flags_to_name);
+  set_gdbarch_address_class_name_to_type_flags
+    (gdbarch, spu_address_class_name_to_type_flags);
+
 
   /* Inferior function calls.  */
   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
@@ -2536,6 +2656,9 @@ _initialize_spu_tdep (void)
   /* Install spu stop-on-load handler.  */
   observer_attach_new_objfile (spu_catch_start);
 
+  /* Add ourselves to normal_stop event chain.  */
+  observer_attach_normal_stop (spu_attach_normal_stop);
+
   /* Add root prefix command for all "set spu"/"show spu" commands.  */
   add_prefix_cmd ("spu", no_class, set_spu_command,
                  _("Various SPU specific commands."),
@@ -2559,6 +2682,21 @@ Use \"off\" to disable stopping for new SPE threads."),
                           show_spu_stop_on_load,
                           &setspucmdlist, &showspucmdlist);
 
+  /* Toggle whether or not to automatically flush the software-managed
+     cache whenever SPE execution stops.  */
+  add_setshow_boolean_cmd ("auto-flush-cache", class_support,
+                          &spu_auto_flush_cache_p, _("\
+Set whether to automatically flush the software-managed cache."),
+                           _("\
+Show whether to automatically flush the software-managed cache."),
+                           _("\
+Use \"on\" to automatically flush the software-managed cache\n\
+whenever SPE execution stops.\n\
+Use \"off\" to never automatically flush the software-managed cache."),
+                          NULL,
+                          show_spu_auto_flush_cache,
+                          &setspucmdlist, &showspucmdlist);
+
   /* Add root prefix command for all "info spu" commands.  */
   add_prefix_cmd ("spu", class_info, info_spu_command,
                  _("Various SPU specific commands."),