Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache
@ 2008-09-07 21:18 Ulrich Weigand
  2008-09-08  3:16 ` Eli Zaretskii
  0 siblings, 1 reply; 5+ messages in thread
From: Ulrich Weigand @ 2008-09-07 21:18 UTC (permalink / raw)
  To: gdb-patches

Hello,

the __ea pointers (see previous patch) are implemented in SPU code with the
help of a software-managed cache.  This causes some challenges for debugging,
because if you access a PowerPC variable via an __ea pointer from SPU code,
changes to that variable are not actually visible in PowerPC memory until
the SPU software-managed cache has written back the cache line.

This patch has GDB perform an inferior call to __cache_flush every time the
inferior stops in SPU code that uses the software-managed cache.  Thus,
the user is able to inspect PowerPC variables and see current values.

However, there are situations where this is counter-productive, e.g. when
you are actually trying to debug the cache manager itself.  Therefore,
the patch also adds a command to disable that feature.

Bye,
Ulrich


ChangeLog:

	* spu-tdep.c: Include "infcall.h".
	(spu_auto_flush_cache_p): New static variable.
	(spu_objfile_from_context): New function.
	(flush_ea_cache, spu_attach_normal_stop): Likewise.
	(show_spu_auto_flush_cache): Likewise.
	(_initialize_spu_tdep): Attach to normal_stop observer.
	Install "set spu auto-flush-cache" / "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.


Index: src/gdb/spu-tdep.c
===================================================================
--- src.orig/gdb/spu-tdep.c
+++ src/gdb/spu-tdep.c
@@ -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 *showspuc
 
 /* 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.  */
@@ -1772,6 +1775,76 @@ spu_catch_start (struct objfile *objfile
   tbreak_command (buf, 0);
 }
 
+/* Lookup OBJFILE corresponding to the current SPU context.  */
+static struct objfile *
+spu_objfile_from_context (void)
+{
+  struct frame_info *frame = get_current_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 and return 1.  Return 0 if
+   inferior call was not executed.  */
+static void
+flush_ea_cache (void)
+{
+  struct value *ea_flush_fn = NULL;
+  struct minimal_symbol *msymbol;
+  struct objfile *obj;
+
+  obj = spu_objfile_from_context ();
+  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 = builtin_type_void;
+      type = lookup_function_type (type);
+      type = lookup_pointer_type (type);
+      addr = SYMBOL_VALUE_ADDRESS (msymbol);
+      ea_flush_fn = value_from_pointer (type, addr);
+    }
+
+  if (ea_flush_fn)
+    call_function_by_hand (ea_flush_fn, 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)
+{
+  if (!spu_auto_flush_cache_p)
+    return;
+
+  if (!target_has_registers || !target_has_stack || !target_has_memory)
+    return;
+
+  /* Temporarily reset the 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.  */
 
@@ -2344,6 +2417,14 @@ show_spu_stop_on_load (struct ui_file *f
                     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.  */
 
@@ -2464,6 +2545,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."),
@@ -2486,6 +2570,20 @@ Use \"off\" to disable stopping for new 
                           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 SW-managed cache."),
+                           _("\
+Show whether to automatically flush SW-managed cache."),
+                           _("\
+Use \"on\" to automatically flush the software-managed cache 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."),
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo
+++ src/gdb/doc/gdb.texinfo
@@ -16446,6 +16446,16 @@ function.
 @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
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache
  2008-09-07 21:18 [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache Ulrich Weigand
@ 2008-09-08  3:16 ` Eli Zaretskii
  2008-09-08 11:48   ` Ulrich Weigand
  0 siblings, 1 reply; 5+ messages in thread
From: Eli Zaretskii @ 2008-09-08  3:16 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

> Date: Sun, 7 Sep 2008 23:17:16 +0200 (CEST)
> From: "Ulrich Weigand" <uweigand@de.ibm.com>
> 
> +Set whether to automatically flush SW-managed cache."),

Please say "software" instead of "SW".  I don't see a need for the
shorthand here, and it certainly obscures the meaning.

> +Use \"on\" to automatically flush the software-managed cache whenever SPE execution stops.\n\

This line is too long.

> Index: src/gdb/doc/gdb.texinfo

This part is fine.  Thanks.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache
  2008-09-08  3:16 ` Eli Zaretskii
@ 2008-09-08 11:48   ` Ulrich Weigand
  2008-09-08 19:29     ` Eli Zaretskii
  0 siblings, 1 reply; 5+ messages in thread
From: Ulrich Weigand @ 2008-09-08 11:48 UTC (permalink / raw)
  To: eliz; +Cc: gdb-patches

Eli Zaretskii wrote:
> > Date: Sun, 7 Sep 2008 23:17:16 +0200 (CEST)
> > From: "Ulrich Weigand" <uweigand@de.ibm.com>
> > 
> > +Set whether to automatically flush SW-managed cache."),
> 
> Please say "software" instead of "SW".  I don't see a need for the
> shorthand here, and it certainly obscures the meaning.
> 
> > +Use \"on\" to automatically flush the software-managed cache whenever SPE execution stops.\n\
> 
> This line is too long.

Both issues should be fixed in the patch below.

Thanks,
Ulrich


ChangeLog:

	* spu-tdep.c: Include "infcall.h".
	(spu_auto_flush_cache_p): New static variable.
	(spu_objfile_from_context): New function.
	(flush_ea_cache, spu_attach_normal_stop): Likewise.
	(show_spu_auto_flush_cache): Likewise.
	(_initialize_spu_tdep): Attach to normal_stop observer.
	Install "set spu auto-flush-cache" / "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.


Index: src/gdb/spu-tdep.c
===================================================================
--- src.orig/gdb/spu-tdep.c
+++ src/gdb/spu-tdep.c
@@ -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 *showspuc
 
 /* 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.  */
@@ -1772,6 +1775,76 @@ spu_catch_start (struct objfile *objfile
   tbreak_command (buf, 0);
 }
 
+/* Lookup OBJFILE corresponding to the current SPU context.  */
+static struct objfile *
+spu_objfile_from_context (void)
+{
+  struct frame_info *frame = get_current_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 and return 1.  Return 0 if
+   inferior call was not executed.  */
+static void
+flush_ea_cache (void)
+{
+  struct value *ea_flush_fn = NULL;
+  struct minimal_symbol *msymbol;
+  struct objfile *obj;
+
+  obj = spu_objfile_from_context ();
+  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 = builtin_type_void;
+      type = lookup_function_type (type);
+      type = lookup_pointer_type (type);
+      addr = SYMBOL_VALUE_ADDRESS (msymbol);
+      ea_flush_fn = value_from_pointer (type, addr);
+    }
+
+  if (ea_flush_fn)
+    call_function_by_hand (ea_flush_fn, 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)
+{
+  if (!spu_auto_flush_cache_p)
+    return;
+
+  if (!target_has_registers || !target_has_stack || !target_has_memory)
+    return;
+
+  /* Temporarily reset the 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.  */
 
@@ -2344,6 +2417,14 @@ show_spu_stop_on_load (struct ui_file *f
                     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.  */
 
@@ -2464,6 +2545,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."),
@@ -2487,6 +2571,21 @@ Use \"off\" to disable stopping for new 
                           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 \
+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."),
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo
+++ src/gdb/doc/gdb.texinfo
@@ -16446,6 +16446,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

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache
  2008-09-08 11:48   ` Ulrich Weigand
@ 2008-09-08 19:29     ` Eli Zaretskii
  2008-09-09 10:49       ` Ulrich Weigand
  0 siblings, 1 reply; 5+ messages in thread
From: Eli Zaretskii @ 2008-09-08 19:29 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

> Date: Mon, 8 Sep 2008 13:47:36 +0200 (CEST)
> From: "Ulrich Weigand" <uweigand@de.ibm.com>
> Cc: gdb-patches@sourceware.org
> 
> > > +Use \"on\" to automatically flush the software-managed cache whenever SPE execution stops.\n\
> > 
> > This line is too long.
> 
> Both issues should be fixed in the patch below.

The second one is not, I think:

> +Use \"on\" to automatically flush the software-managed cache \

The trailing backslash escapes the following newline, so the line will
be still too long when displayed by GDB; you want \n\, I think.

Thanks.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache
  2008-09-08 19:29     ` Eli Zaretskii
@ 2008-09-09 10:49       ` Ulrich Weigand
  0 siblings, 0 replies; 5+ messages in thread
From: Ulrich Weigand @ 2008-09-09 10:49 UTC (permalink / raw)
  To: eliz; +Cc: gdb-patches

Eli Zaretskii wrote:
> > Date: Mon, 8 Sep 2008 13:47:36 +0200 (CEST)
> > From: "Ulrich Weigand" <uweigand@de.ibm.com>
> > Cc: gdb-patches@sourceware.org
> > 
> > > > +Use \"on\" to automatically flush the software-managed cache whenever SPE execution stops.\n\
> > > 
> > > This line is too long.
> > 
> > Both issues should be fixed in the patch below.
> 
> The second one is not, I think:
> 
> > +Use \"on\" to automatically flush the software-managed cache \
> 
> The trailing backslash escapes the following newline, so the line will
> be still too long when displayed by GDB; you want \n\, I think.

Ah, I misunderstood.  I've now changed this to \n\ to ensure the
line as printed is no longer than 80 characters; same for the
stop-on-load command.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-09-09 10:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-07 21:18 [rfc] [18/18] Cell multi-arch: Automatically flush software-managed cache Ulrich Weigand
2008-09-08  3:16 ` Eli Zaretskii
2008-09-08 11:48   ` Ulrich Weigand
2008-09-08 19:29     ` Eli Zaretskii
2008-09-09 10:49       ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox