On Sat, 2012-12-22 at 01:00 +0100, Franck Jullien wrote: 
> This patch adds target support to or32.
> 
> Registers names and groups are dynamically created from the tdesc remote
> file. Groups names are taken from the last string of the feature name.
> For example, we could have:
> 
>   <feature name="org.gnu.gdb.or32.timer">
>     <reg name="ttmr"           bitsize="32" regnum="2216"/>
>     <reg name="ttcr"           bitsize="32" regnum="2217"/>
>   </feature>
> 
> and timer registers would be accessible using "info registers timer" and
> "set $ttmr ..."
> 
> While receiving the tdesc file, found registers and groups are
> displayed. For example:
> 
> (gdb) target remote :50001
> Remote debugging using :50001
> Found   93 registers in group group0
> Found 1035 registers in group group1
> Found 1035 registers in group group2
> Found    6 registers in group group3
> Found    4 registers in group group4
> Found    2 registers in group group5
> Found   22 registers in group group6
> Found   16 registers in group group7
> Found    1 registers in group group8
> Found    1 registers in group pic
> Found    1 registers in group timer
> Found    2 registers in group nogroup
> Found 2218 registers in the tdesc file

Hi Franck,

This description needs to go partly in the Doxygen comments and party in
the updated user documentation.

As before you need ChangeLog.or32 entries.

I haven't looked in detail at this patch - it's quite substantial, but
the general approach seems good.

Best wishes,


Jeremy

> Signed-off-by: Franck Jullien <[email protected]>
> ---
>  gdb/or32-tdep.c |  154 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 152 insertions(+), 2 deletions(-)
> 
> diff --git a/gdb/or32-tdep.c b/gdb/or32-tdep.c
> index aa0e953..f02fefe 100644
> --- a/gdb/or32-tdep.c
> +++ b/gdb/or32-tdep.c
> @@ -7,6 +7,8 @@
>     and by Per Bothner([email protected]) at U.Wisconsin.
>     Contributor Jeremy Bennett <[email protected]>
>  
> +   Contributor Franck Jullien <[email protected]>
> +
>     This file is part of GDB.
>  
>     This program is free software; you can redistribute it and/or modify it
> @@ -101,6 +103,8 @@
>  #include "dwarf2-frame.h"
>  #include "trad-frame.h"
>  #include "regset.h"
> +#include "remote.h"
> +#include "target-descriptions.h"
>  
>  #include <inttypes.h>
>  
> @@ -654,7 +658,15 @@ or32_register_name (struct gdbarch *gdbarch,
>        the future. */
>      };
>  
> -  return or32_gdb_reg_names[regnum];
> +  /* If we have a target description, use it */
> +  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
> +    return tdesc_register_name (gdbarch, regnum);
> +  else {
> +    if (0 <= regnum && regnum < OR32_NUM_REGS_CACHED) {
> +      return or32_gdb_reg_names[regnum];
> +    } else
> +      return NULL;
> +  }
>  
>  }    /* or32_register_name() */
>  
> @@ -736,6 +748,8 @@ or32_registers_info (struct gdbarch    *gdbarch,
>                    int                regnum,
>                    int                all) 
>  {
> +  struct regcache *regcache = get_current_regcache ();
> +
>    if (-1 == regnum)
>      {
>        /* Do all (valid) registers */
> @@ -751,12 +765,18 @@ or32_registers_info (struct gdbarch    *gdbarch,
>    else
>      {
>        /* Do one specified register - if it is part of this architecture */
> -      if ('\0' == *(or32_register_name (gdbarch, regnum)))
> +      if ((regnum < OR32_NUM_REGS_CACHED) && ('\0' == *(or32_register_name 
> (gdbarch, regnum))))
>       {
>         error ("Not a valid register for the current processor type");
>       }
>        else
>       {
> +       /* If the register is not in the g/G packet, fetch it from the
> +        * target with a p/P packet.
> +        */
> +       if (regnum >= OR32_NUM_REGS_CACHED)
> +         target_fetch_registers(regcache, regnum);
> +
>         default_print_registers_info (gdbarch, file, frame, regnum, all);
>       }
>      }
> @@ -815,6 +835,9 @@ or32_register_reggroup_p (struct gdbarch  *gdbarch,
>        return 0;                      /* No vector regs.  */
>      }
>  
> +  if (!strcmp(tdesc_register_group(gdbarch, regnum), reggroup_name(group)))
> +      return 1;
> +
>    /* For any that are not handled above.  */
>    return default_register_reggroup_p (gdbarch, regnum, group);
>  
> @@ -1752,6 +1775,67 @@ or32_regset_from_core_section (struct gdbarch *gdbarch,
>  
>  }    /* or32_regset_from_core_section () */
>  
> +/* 
> -------------------------------------------------------------------------- */
> +/*!Register all reg found in a feature section and set the register group 
> equal to feature name
> +
> +   @param[in]  feature    The feature to search for registers.
> +   @param[in]  group      Group name for this feature.
> +   @param[out] tdesc_data The target descriptor data to fill.
> +   @param[out] reg_index  Register index in tdesc_data.
> +
> +   @return  Number of registers found, -1 if error.                          
>  */
> +/* 
> -------------------------------------------------------------------------- */
> +static int get_feature_registers(const struct tdesc_feature *feature,
> +                          struct tdesc_arch_data *tdesc_data, int 
> *reg_index, const char *group)
> +{
> +  int valid_p;
> +  int i;
> +  char *name;
> +
> +  if (feature) {
> +    valid_p = 1;
> +    i = 0;
> +    while (1) {
> +      name = tdesc_find_register_name(feature, i++);
> +      if (name) {
> +        tdesc_set_register_group_early (feature, name, group);
> +        valid_p &= tdesc_numbered_register (feature, tdesc_data, 
> (*reg_index)++, name);
> +      } else
> +        break;
> +    }
> +
> +    if (!valid_p) {
> +      tdesc_data_cleanup (tdesc_data);
> +      return -1;
> +    }
> +
> +    return (i-1);
> +  }
> +
> +  return 0;
> +}
> +
> +/* 
> -------------------------------------------------------------------------- */
> +/*!Return the feature "short" name.
> +
> +   @param[in]  feature_name    The feature name (org.gnu.gdb.or32.xxxx)
> +
> +   @return  String after last "." (xxxx)                                     
>  */
> +/* 
> -------------------------------------------------------------------------- */
> +static char *get_feature_short_name(const char *feature_name)
> +{
> +  int i;
> +  int last_dot = -1;
> +
> +  for (i = 0; i < strlen(feature_name); i++)
> +    if (feature_name[i] == '.')
> +      last_dot = i;
> +
> +  if (last_dot > 0)
> +    return (char *)&feature_name[last_dot + 1];
> +  else
> +    return NULL;
> +}
>  
>  /* 
> -------------------------------------------------------------------------- */
>  /*!Architecture initialization for OpenRISC 1000
> @@ -1772,6 +1856,12 @@ or32_gdbarch_init (struct gdbarch_info  info,
>    struct        gdbarch       *gdbarch;
>    struct        gdbarch_tdep  *tdep;
>    const struct  bfd_arch_info *binfo;
> +  struct tdesc_arch_data      *tdesc_data = NULL;
> +
> +  int i;
> +  int reg_index = 0;
> +  int retval;
> +  int group;
>  
>    /* Find a candidate among the list of pre-declared architectures.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
> @@ -1874,6 +1964,63 @@ or32_gdbarch_init (struct gdbarch_info  info,
>    dwarf2_append_unwinders (gdbarch);
>    frame_unwind_append_unwinder (gdbarch, &or32_frame_unwind);
>  
> +  /* Check any target description for validity.  */
> +  if (tdesc_has_registers (info.target_desc)) {
> +
> +    const struct tdesc_feature *feature;
> +    int total_regs = 0;
> +    int nb_features;
> +    char *short_name;
> +
> +    tdesc_data = tdesc_data_alloc ();
> +
> +    /* Get the number of feature in tdesc file */
> +    nb_features = tdesc_nb_feature (info.target_desc);
> +
> +    /* For each feature/group, create a register group with the feature
> +     * "short" name and declare all feature registers to the tdesc_data
> +     */
> +    for (group = 0; group < nb_features; group++) {
> +      feature = tdesc_find_feature (info.target_desc,
> +                                    tdesc_feature_idx_name(info.target_desc, 
> group));
> +
> +      short_name = 
> get_feature_short_name(tdesc_feature_idx_name(info.target_desc, group));
> +
> +      reggroup_add (gdbarch, reggroup_new (short_name, USER_REGGROUP));
> +
> +      retval = get_feature_registers(feature, tdesc_data, &reg_index, 
> short_name);
> +
> +      if (retval < 0) {
> +        tdesc_data_cleanup (tdesc_data);
> +        return NULL;
> +      } else {
> +        total_regs += retval;
> +        printf("Found %4d registers in group %s\n", retval, short_name);
> +      }
> +    }
> +
> +    printf("Found %4d registers in the tdesc file\n", total_regs);
> +
> +    if (!total_regs) {
> +      tdesc_data_cleanup (tdesc_data);
> +      return NULL;
> +    }
> +  }
> +
> +  if (tdesc_data) {
> +      tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);
> +
> +      /* Override the normal target description methods to handle our
> +         dual real and pseudo registers.  */
> +      set_gdbarch_register_name         (gdbarch, or32_register_name);
> +      set_gdbarch_register_reggroup_p   (gdbarch, or32_register_reggroup_p);
> +
> +      set_gdbarch_register_name         (gdbarch, or32_register_name);
> +      set_gdbarch_sp_regnum             (gdbarch, OR32_SP_REGNUM);
> +      set_gdbarch_pc_regnum             (gdbarch, OR32_NPC_REGNUM);
> +      set_gdbarch_num_pseudo_regs       (gdbarch, OR32_NUM_PSEUDO_REGS);
> +  }
> +
>    return gdbarch;
>  
>  }    /* or32_gdbarch_init() */
> @@ -2921,6 +3068,9 @@ _initialize_or32_tdep (void)
>    /* Initialize the automata for the assembler */
>    build_automata();
>  
> +  /* Tell remote stub that we support XML target description.  */
> +  register_remote_support_xml ("or32");
> +
>    /* Commands to show and set special purpose registers */
>    add_info ("spr", or32_info_spr_command,
>           "Show the value of a special purpose register");

-- 
Tel:      +44 (1590) 610184
Cell:     +44 (7970) 676050
SkypeID: jeremybennett
Email:   [email protected]
Web:     www.embecosm.com

_______________________________________________
OpenRISC mailing list
[email protected]
http://lists.openrisc.net/listinfo/openrisc

Reply via email to