diff options
-rw-r--r-- | gdb/ChangeLog | 42 | ||||
-rw-r--r-- | gdb/arch/ppc-linux-common.h | 2 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 9 | ||||
-rw-r--r-- | gdb/features/rs6000/power-ebb.xml | 14 | ||||
-rw-r--r-- | gdb/features/rs6000/power-linux-pmu.xml | 17 | ||||
-rw-r--r-- | gdb/features/rs6000/powerpc-isa207-vsx32l.c | 12 | ||||
-rw-r--r-- | gdb/features/rs6000/powerpc-isa207-vsx32l.xml | 2 | ||||
-rw-r--r-- | gdb/features/rs6000/powerpc-isa207-vsx64l.c | 12 | ||||
-rw-r--r-- | gdb/features/rs6000/powerpc-isa207-vsx64l.xml | 2 | ||||
-rw-r--r-- | gdb/gdbserver/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/gdbserver/configure.srv | 2 | ||||
-rw-r--r-- | gdb/gdbserver/linux-ppc-low.c | 74 | ||||
-rw-r--r-- | gdb/nat/ppc-linux.h | 13 | ||||
-rw-r--r-- | gdb/ppc-linux-nat.c | 58 | ||||
-rw-r--r-- | gdb/ppc-linux-tdep.c | 62 | ||||
-rw-r--r-- | gdb/ppc-linux-tdep.h | 2 | ||||
-rw-r--r-- | gdb/ppc-tdep.h | 28 | ||||
-rw-r--r-- | gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat | 8 | ||||
-rw-r--r-- | gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat | 8 | ||||
-rw-r--r-- | gdb/rs6000-tdep.c | 74 |
21 files changed, 452 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 029c675..e07af9d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,6 +1,48 @@ 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET) + (PPC_LINUX_SIZEOF_PMUREGSET): Declare. + * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU): + Define if not already defined. + * features/rs6000/power-ebb.xml: New file. + * features/rs6000/power-linux-pmu.xml: New file. + * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu + features. + * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise. + * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate. + * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate. + * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate. + * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate. + * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call + fetch_regset with ebb and pmu regsets. + (store_register, store_ppc_registers): Call store_regset with ebb + and pmu regsets. + (ppc_linux_nat_target::read_description): Set isa207 field in the + features struct if ebb and pmu are avaiable. + * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu) + (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals. + (ppc_linux_iterate_over_regset_sections): Call back with the ebb + and pmu regsets. + (ppc_linux_core_read_description): Check if the pmu section is + present and set isa207 in the features struct. + * ppc-linux-tdep.h (ppc32_linux_ebbregset) + (ppc32_linux_pmuregset): Declare. + * ppc-tdep.h (struct gdbarch_tdep) <ppc_mmcr0_regnum>: New field. + <ppc_mmcr2_regnum, ppc_siar_regnum, ppc_sdar_regnum>: New fields. + <ppc_sier_regnum>: New field. + (enum): <PPC_BESCR_REGNUM, PPC_EBBHR_REGNUM, PPC_EBBRR_REGNUM>: + New enum values. + <PPC_MMCR0_REGNUM, PPC_MMCR2_REGNUM, PPC_SIAR_REGNUM>: New enum + values. + <PPC_SDAR_REGNUM, PPC_SIER_REGNUM>: New enum values. + (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define. + * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the + ebb and pmu features. + +2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> + Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_vsx32l) (tdesc_powerpc_isa207_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TARREGSET): Define. diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h index f0e4a42..50e9e06 100644 --- a/gdb/arch/ppc-linux-common.h +++ b/gdb/arch/ppc-linux-common.h @@ -33,6 +33,8 @@ struct target_desc; #define PPC_LINUX_SIZEOF_PPRREGSET 8 #define PPC_LINUX_SIZEOF_DSCRREGSET 8 #define PPC_LINUX_SIZEOF_TARREGSET 8 +#define PPC_LINUX_SIZEOF_EBBREGSET (3*8) +#define PPC_LINUX_SIZEOF_PMUREGSET (5*8) /* Check if the hwcap auxv entry indicates that isa205 is supported. */ bool ppc_linux_has_isa205 (CORE_ADDR hwcap); diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 5d67972..ee5d23f 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,10 @@ 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * gdb.texinfo (PowerPC Features): Describe new features + "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu". + +2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * gdb.texinfo (PowerPC Features): Describe new feature "org.gnu.gdb.power.tar". diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d970608..e8130ce 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -43201,6 +43201,15 @@ contain the 64-bit register @samp{dscr}. The @samp{org.gnu.gdb.power.tar} feature is optional. It should contain the 64-bit register @samp{tar}. +The @samp{org.gnu.gdb.power.ebb} feature is optional. It should +contain registers @samp{bescr}, @samp{ebbhr} and @samp{ebbrr}, all +64-bit wide. + +The @samp{org.gnu.gdb.power.linux.pmu} feature is optional. It should +contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar} +and @samp{sier}, all 64-bit wide. This is the subset of the isa 2.07 +server PMU registers provided by @sc{gnu}/Linux. + @node S/390 and System z Features @subsection S/390 and System z Features @cindex target descriptions, S/390 features diff --git a/gdb/features/rs6000/power-ebb.xml b/gdb/features/rs6000/power-ebb.xml new file mode 100644 index 0000000..7bec21f --- /dev/null +++ b/gdb/features/rs6000/power-ebb.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2018 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!-- POWER8 Event-based Branching Registers. --> +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.power.ebb"> + <reg name="bescr" bitsize="64" type="uint64" save-restore="no"/> + <reg name="ebbhr" bitsize="64" type="uint64" save-restore="no"/> + <reg name="ebbrr" bitsize="64" type="uint64" save-restore="no"/> +</feature> diff --git a/gdb/features/rs6000/power-linux-pmu.xml b/gdb/features/rs6000/power-linux-pmu.xml new file mode 100644 index 0000000..c60b444 --- /dev/null +++ b/gdb/features/rs6000/power-linux-pmu.xml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2018 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!-- Subset of the POWER8 ISA 2.07 Performance Monitor Registers + provided by Linux. --> +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.power.linux.pmu"> + <reg name="mmcr0" bitsize="64" type="uint64" save-restore="no"/> + <reg name="mmcr2" bitsize="64" type="uint64" save-restore="no"/> + <reg name="siar" bitsize="64" type="uint64" save-restore="no"/> + <reg name="sdar" bitsize="64" type="uint64" save-restore="no"/> + <reg name="sier" bitsize="64" type="uint64" save-restore="no"/> +</feature> diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-vsx32l.c index 73c7a01..8fe0f5e 100644 --- a/gdb/features/rs6000/powerpc-isa207-vsx32l.c +++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.c @@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx32l (void) feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); + feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); + tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); + tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); + tdesc_powerpc_isa207_vsx32l = result; } diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml index 599e6a2..635eef5 100644 --- a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml +++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml @@ -16,4 +16,6 @@ <xi:include href="power-ppr.xml"/> <xi:include href="power-dscr.xml"/> <xi:include href="power-tar.xml"/> + <xi:include href="power-ebb.xml"/> + <xi:include href="power-linux-pmu.xml"/> </target> diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-vsx64l.c index 9c73552..0af1879 100644 --- a/gdb/features/rs6000/powerpc-isa207-vsx64l.c +++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.c @@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx64l (void) feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); + feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); + tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); + tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); + tdesc_powerpc_isa207_vsx64l = result; } diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml index 42a23cc..67dff71 100644 --- a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml +++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml @@ -16,4 +16,6 @@ <xi:include href="power-ppr.xml"/> <xi:include href="power-dscr.xml"/> <xi:include href="power-tar.xml"/> + <xi:include href="power-ebb.xml"/> + <xi:include href="power-linux-pmu.xml"/> </target> diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 7699bf8..56e724d 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,15 @@ 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and + rs6000/power-linux-pmu.xml to srv_xmlfiles. + * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset) + (ppc_store_pmuregset): New functions. + (ppc_regsets): Add entries for ebb and pmu regsets. + (ppc_arch_setup): Set isa207 in features struct if the ebb and + pmu regsets are available. Set sizes for these regsets. + +2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-vsx64l-ipa.o and powerpc-isa207-vsx32l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-vsx32l.o and diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 7cf7cac..eb5f208 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -249,6 +249,8 @@ case "${target}" in srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml" diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index eeba724..e328151 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -545,6 +545,61 @@ ppc_store_tarregset (struct regcache *regcache, const void *buf) supply_register_by_name (regcache, "tar", tar); } +/* Event-Based Branching regset store function. Unless the inferior + has a perf event open, ptrace can return in error when reading and + writing to the regset, with ENODATA. For reading, the registers + will correctly show as unavailable. For writing, gdbserver + currently only caches any register writes from P and G packets and + the stub always tries to write all the regsets when resuming the + inferior, which would result in frequent warnings. For this + reason, we don't define a fill function. This also means that the + client-side regcache will be dirty if the user tries to write to + the EBB registers. G packets that the client sends to write to + unrelated registers will also include data for EBB registers, even + if they are unavailable. */ + +static void +ppc_store_ebbregset (struct regcache *regcache, const void *buf) +{ + const char *regset = (const char *) buf; + + /* The order in the kernel regset is: EBBRR, EBBHR, BESCR. In the + .dat file is BESCR, EBBHR, EBBRR. */ + supply_register_by_name (regcache, "ebbrr", ®set[0]); + supply_register_by_name (regcache, "ebbhr", ®set[8]); + supply_register_by_name (regcache, "bescr", ®set[16]); +} + +/* Performance Monitoring Unit regset fill function. */ + +static void +ppc_fill_pmuregset (struct regcache *regcache, void *buf) +{ + char *regset = (char *) buf; + + /* The order in the kernel regset is SIAR, SDAR, SIER, MMCR2, MMCR0. + In the .dat file is MMCR0, MMCR2, SIAR, SDAR, SIER. */ + collect_register_by_name (regcache, "siar", ®set[0]); + collect_register_by_name (regcache, "sdar", ®set[8]); + collect_register_by_name (regcache, "sier", ®set[16]); + collect_register_by_name (regcache, "mmcr2", ®set[24]); + collect_register_by_name (regcache, "mmcr0", ®set[32]); +} + +/* Performance Monitoring Unit regset store function. */ + +static void +ppc_store_pmuregset (struct regcache *regcache, const void *buf) +{ + const char *regset = (const char *) buf; + + supply_register_by_name (regcache, "siar", ®set[0]); + supply_register_by_name (regcache, "sdar", ®set[8]); + supply_register_by_name (regcache, "sier", ®set[16]); + supply_register_by_name (regcache, "mmcr2", ®set[24]); + supply_register_by_name (regcache, "mmcr0", ®set[32]); +} + static void ppc_fill_vsxregset (struct regcache *regcache, void *buf) { @@ -654,6 +709,10 @@ static struct regset_info ppc_regsets[] = { fetch them every time, but still fall back to PTRACE_PEEKUSER for the general registers. Some kernels support these, but not the newer PPC_PTRACE_GETREGS. */ + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS, + NULL, ppc_store_ebbregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS, + ppc_fill_pmuregset, ppc_store_pmuregset }, { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TAR, 0, EXTENDED_REGS, ppc_fill_tarregset, ppc_store_tarregset }, { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS, @@ -734,8 +793,13 @@ ppc_arch_setup (void) features.ppr_dscr = true; if ((ppc_hwcap2 & PPC_FEATURE2_ARCH_2_07) && (ppc_hwcap2 & PPC_FEATURE2_TAR) + && (ppc_hwcap2 & PPC_FEATURE2_EBB) && ppc_check_regset (tid, NT_PPC_TAR, - PPC_LINUX_SIZEOF_TARREGSET)) + PPC_LINUX_SIZEOF_TARREGSET) + && ppc_check_regset (tid, NT_PPC_EBB, + PPC_LINUX_SIZEOF_EBBREGSET) + && ppc_check_regset (tid, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET)) features.isa207 = true; } @@ -798,6 +862,14 @@ ppc_arch_setup (void) regset->size = (features.isa207 ? PPC_LINUX_SIZEOF_TARREGSET : 0); break; + case NT_PPC_EBB: + regset->size = (features.isa207 ? + PPC_LINUX_SIZEOF_EBBREGSET : 0); + break; + case NT_PPC_PMU: + regset->size = (features.isa207 ? + PPC_LINUX_SIZEOF_PMUREGSET : 0); + break; default: break; } diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h index 913a9e0..c965030 100644 --- a/gdb/nat/ppc-linux.h +++ b/gdb/nat/ppc-linux.h @@ -60,6 +60,9 @@ #ifndef PPC_FEATURE2_TAR #define PPC_FEATURE2_TAR 0x04000000 #endif +#ifndef PPC_FEATURE2_EBB +#define PPC_FEATURE2_EBB 0x10000000 +#endif /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a configure time check. Some older glibc's (for instance 2.2.1) @@ -106,6 +109,16 @@ #define NT_PPC_DSCR 0x105 #endif +/* Event Based Branch Registers. */ +#ifndef NT_PPC_EBB +#define NT_PPC_EBB 0x106 +#endif + +/* Performance Monitor Registers. */ +#ifndef NT_PPC_PMU +#define NT_PPC_PMU 0x107 +#endif + /* Return the wordsize of the target, either 4 or 8 bytes. */ int ppc_linux_target_wordsize (int tid); diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 850d229..0bbdcdc 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -666,6 +666,24 @@ fetch_register (struct regcache *regcache, int tid, int regno) &ppc32_linux_tarregset); return; } + else if (PPC_IS_EBB_REGNUM (regno)) + { + gdb_assert (tdep->have_ebb); + + fetch_regset (regcache, tid, NT_PPC_EBB, + PPC_LINUX_SIZEOF_EBBREGSET, + &ppc32_linux_ebbregset); + return; + } + else if (PPC_IS_PMU_REGNUM (regno)) + { + gdb_assert (tdep->ppc_mmcr0_regnum != -1); + + fetch_regset (regcache, tid, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset); + return; + } if (regaddr == -1) { @@ -871,6 +889,14 @@ fetch_ppc_registers (struct regcache *regcache, int tid) fetch_regset (regcache, tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET, &ppc32_linux_tarregset); + if (tdep->have_ebb) + fetch_regset (regcache, tid, NT_PPC_EBB, + PPC_LINUX_SIZEOF_EBBREGSET, + &ppc32_linux_ebbregset); + if (tdep->ppc_mmcr0_regnum != -1) + fetch_regset (regcache, tid, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset); } /* Fetch registers from the child process. Fetch all registers if @@ -1078,6 +1104,24 @@ store_register (const struct regcache *regcache, int tid, int regno) &ppc32_linux_tarregset); return; } + else if (PPC_IS_EBB_REGNUM (regno)) + { + gdb_assert (tdep->have_ebb); + + store_regset (regcache, tid, regno, NT_PPC_EBB, + PPC_LINUX_SIZEOF_EBBREGSET, + &ppc32_linux_ebbregset); + return; + } + else if (PPC_IS_PMU_REGNUM (regno)) + { + gdb_assert (tdep->ppc_mmcr0_regnum != -1); + + store_regset (regcache, tid, regno, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset); + return; + } if (regaddr == -1) return; @@ -1301,6 +1345,15 @@ store_ppc_registers (const struct regcache *regcache, int tid) store_regset (regcache, tid, -1, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET, &ppc32_linux_tarregset); + + if (tdep->ppc_mmcr0_regnum != -1) + store_regset (regcache, tid, -1, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset); + + /* Because the EBB registers can be unavailable, attempts to store + them here would cause this function to fail most of the time, so + we ignore them. */ } /* Fetch the AT_HWCAP entry from the aux vector. */ @@ -2429,7 +2482,10 @@ ppc_linux_nat_target::read_description () features.ppr_dscr = true; if ((hwcap2 & PPC_FEATURE2_ARCH_2_07) && (hwcap2 & PPC_FEATURE2_TAR) - && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)) + && (hwcap2 & PPC_FEATURE2_EBB) + && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET) + && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET) + && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) features.isa207 = true; } diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 1d070dd..337ba67 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -599,6 +599,44 @@ const struct regset ppc32_linux_tarregset = { regcache_collect_regset }; +/* Event-Based Branching regmap. */ + +static const struct regcache_map_entry ppc32_regmap_ebb[] = + { + { 1, PPC_EBBRR_REGNUM, 8 }, + { 1, PPC_EBBHR_REGNUM, 8 }, + { 1, PPC_BESCR_REGNUM, 8 }, + { 0 } + }; + +/* Event-Based Branching regset. */ + +const struct regset ppc32_linux_ebbregset = { + ppc32_regmap_ebb, + regcache_supply_regset, + regcache_collect_regset +}; + +/* Performance Monitoring Unit regmap. */ + +static const struct regcache_map_entry ppc32_regmap_pmu[] = + { + { 1, PPC_SIAR_REGNUM, 8 }, + { 1, PPC_SDAR_REGNUM, 8 }, + { 1, PPC_SIER_REGNUM, 8 }, + { 1, PPC_MMCR2_REGNUM, 8 }, + { 1, PPC_MMCR0_REGNUM, 8 }, + { 0 } + }; + +/* Performance Monitoring Unit regset. */ + +const struct regset ppc32_linux_pmuregset = { + ppc32_regmap_pmu, + regcache_supply_regset, + regcache_collect_regset +}; + const struct regset * ppc_linux_gregset (int wordsize) { @@ -674,6 +712,22 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, cb (".reg-ppc-tar", PPC_LINUX_SIZEOF_TARREGSET, PPC_LINUX_SIZEOF_TARREGSET, &ppc32_linux_tarregset, "Target Address Register", cb_data); + + /* EBB registers are unavailable when ptrace returns ENODATA. Check + availability when generating a core file (regcache != NULL). */ + if (tdep->have_ebb) + if (regcache == NULL + || REG_VALID == regcache->get_register_status (PPC_BESCR_REGNUM)) + cb (".reg-ppc-ebb", PPC_LINUX_SIZEOF_EBBREGSET, + PPC_LINUX_SIZEOF_EBBREGSET, + &ppc32_linux_ebbregset, "Event-based Branching Registers", + cb_data); + + if (tdep->ppc_mmcr0_regnum != -1) + cb (".reg-ppc-pmu", PPC_LINUX_SIZEOF_PMUREGSET, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset, "Performance Monitor Registers", + cb_data); } static void @@ -1088,6 +1142,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr"); asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr"); asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar"); + asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu"); if (! section) return NULL; @@ -1123,7 +1178,12 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, if (ppr && dscr) { features.ppr_dscr = true; - if (tar) + + /* We don't require the EBB note section to be present in the + core file to select isa207 because these registers could have + been unavailable when the core file was created. They will + be in the tdep but will show as unavailable. */ + if (tar && pmu) features.isa207 = true; } diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h index d6ddf69..cce1ddd 100644 --- a/gdb/ppc-linux-tdep.h +++ b/gdb/ppc-linux-tdep.h @@ -48,5 +48,7 @@ int ppc_linux_trap_reg_p (struct gdbarch *gdbarch); extern const struct regset ppc32_linux_pprregset; extern const struct regset ppc32_linux_dscrregset; extern const struct regset ppc32_linux_tarregset; +extern const struct regset ppc32_linux_ebbregset; +extern const struct regset ppc32_linux_pmuregset; #endif /* PPC_LINUX_TDEP_H */ diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index e2b9681..cfe32c9 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -265,6 +265,15 @@ struct gdbarch_tdep /* Decimal 128 registers. */ int ppc_dl0_regnum; /* First Decimal128 argument register pair. */ + int have_ebb; + + /* PMU registers. */ + int ppc_mmcr0_regnum; + int ppc_mmcr2_regnum; + int ppc_siar_regnum; + int ppc_sdar_regnum; + int ppc_sier_regnum; + /* Offset to ABI specific location where link register is saved. */ int lr_frame_offset; @@ -321,12 +330,31 @@ enum { PPC_PPR_REGNUM = 172, PPC_DSCR_REGNUM = 173, PPC_TAR_REGNUM = 174, + + /* EBB registers. */ + PPC_BESCR_REGNUM = 175, + PPC_EBBHR_REGNUM = 176, + PPC_EBBRR_REGNUM = 177, + + /* PMU registers. */ + PPC_MMCR0_REGNUM = 178, + PPC_MMCR2_REGNUM = 179, + PPC_SIAR_REGNUM = 180, + PPC_SDAR_REGNUM = 181, + PPC_SIER_REGNUM = 182, + PPC_NUM_REGS }; /* Big enough to hold the size of the largest register in bytes. */ #define PPC_MAX_REGISTER_SIZE 64 +#define PPC_IS_EBB_REGNUM(i) \ + ((i) >= PPC_BESCR_REGNUM && (i) <= PPC_EBBRR_REGNUM) + +#define PPC_IS_PMU_REGNUM(i) \ + ((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM) + /* An instruction to match. */ struct ppc_insn_pattern diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat index 2b6e0a9..0718d72 100644 --- a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat +++ b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat @@ -145,3 +145,11 @@ expedite:r1,pc 64:ppr 64:dscr 64:tar +64:bescr +64:ebbhr +64:ebbrr +64:mmcr0 +64:mmcr2 +64:siar +64:sdar +64:sier diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat index 095bd7f..510c6c8 100644 --- a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat +++ b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat @@ -145,3 +145,11 @@ expedite:r1,pc 64:ppr 64:dscr 64:tar +64:bescr +64:ebbhr +64:ebbrr +64:mmcr0 +64:mmcr2 +64:siar +64:sdar +64:sier diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 00145f2..54591db 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -5817,7 +5817,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0; - int have_tar = 0; + int have_tar = 0, have_ebb = 0, have_pmu = 0; int tdesc_wordsize = -1; const struct target_desc *tdesc = info.target_desc; struct tdesc_arch_data *tdesc_data = NULL; @@ -6157,6 +6157,64 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } else have_tar = 0; + + /* Event-based Branching Registers. */ + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.ebb"); + if (feature != NULL) + { + static const char *const ebb_regs[] = { + "bescr", "ebbhr", "ebbrr" + }; + + valid_p = 1; + for (i = 0; i < ARRAY_SIZE (ebb_regs); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_BESCR_REGNUM + i, + ebb_regs[i]); + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_ebb = 1; + } + else + have_ebb = 0; + + /* Subset of the ISA 2.07 Performance Monitor Registers provided + by Linux. */ + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.linux.pmu"); + if (feature != NULL) + { + valid_p = 1; + + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_MMCR0_REGNUM, + "mmcr0"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_MMCR2_REGNUM, + "mmcr2"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_SIAR_REGNUM, + "siar"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_SDAR_REGNUM, + "sdar"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_SIER_REGNUM, + "sier"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_pmu = 1; + } + else + have_pmu = 0; } /* If we have a 64-bit binary on a 32-bit target, complain. Also @@ -6354,6 +6412,20 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1; tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1; tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1; + tdep->have_ebb = have_ebb; + + /* If additional pmu registers are added, care must be taken when + setting new fields in the tdep below, to maintain compatibility + with features that only provide some of the registers. Currently + gdb access to the pmu registers is only supported in linux, and + linux only provides a subset of the pmu registers defined in the + architecture. */ + + tdep->ppc_mmcr0_regnum = have_pmu ? PPC_MMCR0_REGNUM : -1; + tdep->ppc_mmcr2_regnum = have_pmu ? PPC_MMCR2_REGNUM : -1; + tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1; + tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1; + tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1; set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); |