From: Ulrich Weigand Date: Fri, 31 Jul 2009 15:35:38 +0000 (+0000) Subject: ChangeLog: X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ff1a52c620029dc07c557feb21eb84550a7968ed;p=binutils-gdb.git ChangeLog: * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cff32f05248..1ef086092bf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2009-07-31 Ulrich Weigand + + * 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 * spu-tdep.c: Include "block.h". diff --git a/gdb/NEWS b/gdb/NEWS index db5a80bc4c4..970f4df615f 100644 --- 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. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 360bbe00f4a..dedf3fe11f4 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2009-07-31 Ulrich Weigand + + * 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 * gdb.texinfo (Cell Broadband Engine SPU architecture): Document the diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index c06c6be51af..fab05fced0e 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index 1cc77add548..7e7ab9cc3dd 100644 --- a/gdb/spu-tdep.c +++ b/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 *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."),