From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25001 invoked by alias); 22 Jul 2009 17:17:47 -0000 Received: (qmail 24985 invoked by uid 22791); 22 Jul 2009 17:17:45 -0000 X-SWARE-Spam-Status: No, hits=-0.6 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_37,KAM_STOCKGEN,MSGID_FROM_MTA_HEADER,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mtagate1.de.ibm.com (HELO mtagate1.de.ibm.com) (195.212.17.161) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 22 Jul 2009 17:17:38 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate1.de.ibm.com (8.13.1/8.13.1) with ESMTP id n6MHHZLX012760 for ; Wed, 22 Jul 2009 17:17:35 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v9.2) with ESMTP id n6MHHZHQ2441234 for ; Wed, 22 Jul 2009 19:17:35 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n6MHHZDl014889 for ; Wed, 22 Jul 2009 19:17:35 +0200 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id n6MHHYoe014875 for ; Wed, 22 Jul 2009 19:17:34 +0200 Message-Id: <200907221717.n6MHHYoe014875@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Wed, 22 Jul 2009 19:17:34 +0200 Subject: [rfc] [8/9] Cell multi-arch: Support PPU address space access To: gdb-patches@sourceware.org Date: Wed, 22 Jul 2009 17:22:00 -0000 From: "Ulrich Weigand" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-07/txt/msg00552.txt.bz2 Hello, this adds support for the __ea address space qualifier (the GCC patches to add this feature are currently being contributed to mainline). This feature adds support for pointers in SPU code that hold PowerPC addresses. These are marked using an address class of 1 in DWARF-2 debug info. The patch below uses GDB's existing support for address classes to recognize such pointers, and handle proper conversion in the pointer/integer to address routines. In addition, the __ea pointers 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_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. Bye, Ulrich 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. */ @@ -340,7 +343,8 @@ spu_register_reggroup_p (struct gdbarch 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 * 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 *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. */ @@ -2480,10 +2594,16 @@ spu_gdbarch_init (struct gdbarch_info in 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 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."), Index: src/gdb/doc/gdb.texinfo =================================================================== --- src.orig/gdb/doc/gdb.texinfo +++ src/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 Index: src/gdb/NEWS =================================================================== --- src.orig/gdb/NEWS +++ src/gdb/NEWS @@ -258,6 +258,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. -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com