From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 127412 invoked by alias); 23 Nov 2016 22:11:25 -0000 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 Received: (qmail 121913 invoked by uid 89); 23 Nov 2016 22:11:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=no version=3.3.2 spammy=70118, sk:_initia, sk:gdbarch, *regcache X-HELO: mail-pg0-f65.google.com Received: from mail-pg0-f65.google.com (HELO mail-pg0-f65.google.com) (74.125.83.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Nov 2016 22:11:13 +0000 Received: by mail-pg0-f65.google.com with SMTP id p66so1926842pga.2 for ; Wed, 23 Nov 2016 14:11:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=npGHsjahjGxJLKaPWhS5agtnf5d6u033nI8OFkw3H+Q=; b=K/9CDI69UerFqYrZHH0nGKplpccaHE9dJI+6gX+vJfdSBx8B7SgFhxJR41du3cGOiS QwSnpaplKzA4qW67vqDvGygfzqaeG0YLAnISbNNBvCUUdNuZki5eumwKq0lzDPIjPPio OuAAtpMDeNlhHfsNEUcLUClUXTI9JonssEbd/pvtieSGQ4OQhaqlp80jB7dvFTgdIBH4 eGMKw0oo3V0JkaVffxPz4kp3w7mLPD3kUGzMnoWRpIXcmuobo6D52pdH1tjKY8j/IMDR JFDNQbezXeu+YnwJHuowOtlSMLlzZlelECZNUg17im7/uBy7e3S87cxKMBGtwa9aDB3z o9Kg== X-Gm-Message-State: AKaTC026NLphIYc4JCf9XaCQi6d1otMTeSVQDN/3FpYaEdfAtuQ2C8A+lJtYcBKkvML7MQ== X-Received: by 10.98.33.133 with SMTP id o5mr5010665pfj.32.1479939071453; Wed, 23 Nov 2016 14:11:11 -0800 (PST) Received: from lianli.shorne-pla.net (z14.124-44-185.ppp.wakwak.ne.jp. [124.44.185.14]) by smtp.gmail.com with ESMTPSA id q145sm54970183pfq.22.2016.11.23.14.11.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Nov 2016 14:11:10 -0800 (PST) Received: from lianli.shorne-pla.net (localhost [127.0.0.1]) by lianli.shorne-pla.net (8.15.2/8.15.2) with ESMTPS id uANMB7FK001459 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 24 Nov 2016 07:11:08 +0900 Received: (from shorne@localhost) by lianli.shorne-pla.net (8.15.2/8.15.2/Submit) id uANMB7oe001458; Thu, 24 Nov 2016 07:11:07 +0900 From: Stafford Horne To: gdb-patches@sourceware.org Cc: openrisc@lists.librecores.org, Franck Jullien Subject: [PATCH 07/18] gdb: or1k: add target descriptor support Date: Wed, 23 Nov 2016 22:14:00 -0000 Message-Id: <1479939044-1341-8-git-send-email-shorne@gmail.com> In-Reply-To: <1479939044-1341-1-git-send-email-shorne@gmail.com> References: <1479939044-1341-1-git-send-email-shorne@gmail.com> X-IsSubscribed: yes X-SW-Source: 2016-11/txt/msg00713.txt.bz2 From: Franck Jullien This patch adds target support to or1k. Registers names and groups are dynamically created from the tdesc remote file. For example, we could have: Then, a group "timer" would be created and timer registers would be accessible using "info registers timer" and "set $ttmr ..." While receiving a tdesc file from the remote, found registers and corresponding groups can displayed using "set debug arch 1" before setting the target to remote. For example: Remote debugging using :50001 Found 93 registers in feature org.gnu.gdb.or1k.group0 Found 1035 registers in feature org.gnu.gdb.or1k.group1 Found 1035 registers in feature org.gnu.gdb.or1k.group2 Found 6 registers in feature org.gnu.gdb.or1k.group3 Found 4 registers in feature org.gnu.gdb.or1k.group4 Found 2 registers in feature org.gnu.gdb.or1k.group5 Found 22 registers in feature org.gnu.gdb.or1k.group6 Found 16 registers in feature org.gnu.gdb.or1k.group7 Found 1 registers in feature org.gnu.gdb.or1k.group8 Found 2 registers in feature org.gnu.gdb.or1k.group9 Found 2 registers in feature org.gnu.gdb.or1k.group10 Found 2218 registers in the tdesc file Available groups can be displayed with: (gdb) maintenance print reggroups Group Type system user dmmu user immu user dcache user icache user mac user debug user perf user power user pic user timer user gdb/ChangeLog: * or1k-tdep.c: changes --- gdb/or1k-tdep.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 214 insertions(+), 4 deletions(-) diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c index 1a3c16b..cb0871f 100644 --- a/gdb/or1k-tdep.c +++ b/gdb/or1k-tdep.c @@ -115,6 +115,8 @@ #include "dwarf2-frame.h" #include "trad-frame.h" #include "regset.h" +#include "remote.h" +#include "target-descriptions.h" #include @@ -699,7 +701,18 @@ or1k_register_name (struct gdbarch *gdbarch, the future. */ }; - return or1k_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 < OR1K_NUM_REGS_CACHED) + { + return or1k_gdb_reg_names[regnum]; + } + else + return NULL; + } } /* or1k_register_name() */ @@ -781,6 +794,8 @@ or1k_registers_info (struct gdbarch *gdbarch, int regnum, int all) { + struct regcache *regcache = get_current_regcache (); + if (-1 == regnum) { /* Do all (valid) registers */ @@ -796,12 +811,19 @@ or1k_registers_info (struct gdbarch *gdbarch, else { /* Do one specified register - if it is part of this architecture */ - if ('\0' == *(or1k_register_name (gdbarch, regnum))) + if ((regnum < OR1K_NUM_REGS_CACHED) + && ('\0' == *(or1k_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 >= OR1K_NUM_REGS_CACHED) + target_fetch_registers (regcache, regnum); + default_print_registers_info (gdbarch, file, frame, regnum, all); } } @@ -860,8 +882,16 @@ or1k_register_reggroup_p (struct gdbarch *gdbarch, return 0; /* No vector regs. */ } - /* For any that are not handled above. */ - return default_register_reggroup_p (gdbarch, regnum, group); + if (tdesc_has_registers (gdbarch_target_desc (gdbarch))) + { + if ((tdesc_register_in_reggroup_p (gdbarch, regnum, group)) != 1) + return 0; + else + return 1; + } + else + /* For any that are not handled above. */ + return default_register_reggroup_p (gdbarch, regnum, group); } /* or1k_register_reggroup_p() */ @@ -1839,6 +1869,115 @@ or1k_regset_from_core_section (struct gdbarch *gdbarch, } /* or1k_regset_from_core_section () */ +/* -------------------------------------------------------------------------- */ +/*!Create a register group based on a group name. + + We create a group only if group_name is not already a register group name. + + @param[in] gdbarch The GDB architecture we are using. + @param[in] group_name Name of the new register group. + + @return 1 if the group has been created, 0 otherwise. */ +/* -------------------------------------------------------------------------- */ +static int +create_register_group (struct gdbarch *gdbarch, const char *group_name) +{ + struct reggroup *group; + static int first = 1; + int group_exist = 0; + + if (group_name == NULL) + return 0; + + if (!first) + { + for (group = reggroup_next (gdbarch, NULL); + group != NULL; group = reggroup_next (gdbarch, group)) + { + if (strcmp (group_name, reggroup_name (group)) == 0) + group_exist = 1; + } + + if (!group_exist) + { + /* If the group doesn't exist, create it */ + reggroup_add (gdbarch, reggroup_new (group_name, USER_REGGROUP)); + return 1; + } + } + else + { + /* reggroup_next cannot be called during architecture. However, + * a first call to reggroup_add execute reggroups_init and then + * reggroup_next can be use. We assume the first group name we + * create does not exist. + */ + reggroup_add (gdbarch, reggroup_new (group_name, USER_REGGROUP)); + first = 0; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/*!Register all reg found in a feature section. + + Register all reg found in a feature section and create a group for each + new register group name found in the tdesc file. + + @param[in] feature The feature to search for registers. + @param[out] tdesc_data The target descriptor data to fill. + @param[out] reg_index Register index in tdesc_data. + @param[in] gdbarch The GDB architecture we are using. + + @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, + struct gdbarch *gdbarch) +{ + int valid_p; + int i; + char *name; + char *group_name; + + if (feature) + { + valid_p = 1; + i = 0; + while (1) + { + name = tdesc_find_register_name (feature, i); + if (name) + { + valid_p &= + tdesc_numbered_register (feature, tdesc_data, (*reg_index)++, + name); + if (valid_p) + { + group_name = tdesc_find_register_group_name (feature, i); + if (group_name) + create_register_group (gdbarch, group_name); + } + i++; + } + else + break; + } + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return -1; + } + + return i; + + } + + return 0; +} /* -------------------------------------------------------------------------- */ /*!Architecture initialization for OpenRISC 1000 @@ -1859,6 +1998,12 @@ or1k_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); @@ -1971,6 +2116,68 @@ or1k_gdbarch_init (struct gdbarch_info info, (gdbarch, or1k_single_step_through_delay); } + /* 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 feature_name[30]; + + tdesc_data = tdesc_data_alloc (); + + /* OpenRisc architecture manual define a maximum of 32 registers groups */ + for (group = 0; group < 32; group++) + { + + sprintf (feature_name, "org.gnu.gdb.or1k.group%d", group); + feature = tdesc_find_feature (info.target_desc, feature_name); + + retval = + get_feature_registers (feature, tdesc_data, ®_index, gdbarch); + + if (retval < 0) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + else + { + total_regs += retval; + if (retval && gdbarch_debug) + fprintf_unfiltered (gdb_stdout, + "Found %4d registers in feature %s\n", + retval, feature_name); + } + } + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdout, + "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, or1k_register_name); + set_gdbarch_register_reggroup_p (gdbarch, or1k_register_reggroup_p); + + set_gdbarch_register_name (gdbarch, or1k_register_name); + set_gdbarch_sp_regnum (gdbarch, OR1K_SP_REGNUM); + set_gdbarch_pc_regnum (gdbarch, OR1K_NPC_REGNUM); + set_gdbarch_num_pseudo_regs (gdbarch, OR1K_NUM_PSEUDO_REGS); + } + return gdbarch; } /* or1k_gdbarch_init() */ @@ -3017,6 +3224,9 @@ _initialize_or1k_tdep (void) they have their BFD defined. */ gdbarch_register (bfd_arch_or1k, or1k_gdbarch_init, or1k_dump_tdep); + /* Tell remote stub that we support XML target description. */ + register_remote_support_xml ("or1k"); + /* Commands to show and set special purpose registers */ add_info ("spr", or1k_info_spr_command, "Show the value of a special purpose register"); -- 2.7.4