From patchwork Fri Jul 13 13:52:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Franco de Carvalho X-Patchwork-Id: 28377 Received: (qmail 100768 invoked by alias); 13 Jul 2018 13:53:44 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 100539 invoked by uid 89); 13 Jul 2018 13:53:42 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=dirty X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 13 Jul 2018 13:53:39 +0000 Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w6DDnQsq033682 for ; Fri, 13 Jul 2018 09:53:38 -0400 Received: from e16.ny.us.ibm.com (e16.ny.us.ibm.com [129.33.205.206]) by mx0a-001b2d01.pphosted.com with ESMTP id 2k6twv6eeg-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 13 Jul 2018 09:53:37 -0400 Received: from localhost by e16.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 13 Jul 2018 09:53:36 -0400 Received: from b01cxnp22033.gho.pok.ibm.com (9.57.198.23) by e16.ny.us.ibm.com (146.89.104.203) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Fri, 13 Jul 2018 09:53:32 -0400 Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w6DDrUCS9372054 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 13 Jul 2018 13:53:30 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 14C5AAC062; Fri, 13 Jul 2018 09:54:26 -0400 (EDT) Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B581BAC05F; Fri, 13 Jul 2018 09:54:25 -0400 (EDT) Received: from pedro.localdomain (unknown [9.85.180.127]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP; Fri, 13 Jul 2018 09:54:25 -0400 (EDT) Received: by pedro.localdomain (Postfix, from userid 1000) id 268883C04BD; Fri, 13 Jul 2018 10:53:25 -0300 (-03) From: Pedro Franco de Carvalho To: gdb-patches@sourceware.org Cc: uweigand@de.ibm.com, edjunior@gmail.com Subject: [PATCH 14/17] [PowerPC] Add gdbserver support for HTM registers Date: Fri, 13 Jul 2018 10:52:23 -0300 In-Reply-To: <20180713135226.2321-1-pedromfc@linux.ibm.com> References: <20180713135226.2321-1-pedromfc@linux.ibm.com> x-cbid: 18071313-0072-0000-0000-0000037F8CC5 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009363; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000266; SDB=6.01060763; UDB=6.00544525; IPR=6.00838682; MB=3.00022128; MTD=3.00000008; XFM=3.00000015; UTC=2018-07-13 13:53:34 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18071313-0073-0000-0000-000048B35E00 Message-Id: <20180713135226.2321-15-pedromfc@linux.ibm.com> This patch extends suport for the HTM registers to the powerpc linux gdbserver stub. The "fill" functions for checkpointed register sets are not implemented, because ptrace can return ENODATA for these regsets whenever the inferior is not in a transaction. Since gdbserver writes all registers in one go before resuming the inferior, this error would not be detected at the time the user tries to write to one of the registers on the client side, and gdbserver would print out warnings every time it resumes the inferior when it is not in a transaction, so there is currently no straightforward way to handle this case. This means the checkpointed registers in the client-side regcache can become dirty when the user tries to write to them, until the inferior is resumed and stopped again. Another limitation for the checkpointed registers is that traceframes don't record if registers are available or not, so if these registers are collected when a tracepoint is hit and the inferior is not in a transaction, the user will see zero values for all of them, instead of the usual . gdb/gdbserver/ChangeLog: 2018-07-05 Pedro Franco de Carvalho * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) : New enum value. (init_registers_powerpc_isa207_htm_vsx32l) (init_registers_powerpc_isa207_htm_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) (ppc_store_tm_ctarregset): New functions. (ppc_regsets): Add entries for HTM regsets. (ppc_arch_setup): Set htm in features struct when needed. Set sizes for the HTM regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_HTM_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. --- gdb/gdbserver/linux-ppc-ipa.c | 6 ++ gdb/gdbserver/linux-ppc-low.c | 187 ++++++++++++++++++++++++++++++++++- gdb/gdbserver/linux-ppc-tdesc-init.h | 7 ++ 3 files changed, 199 insertions(+), 1 deletion(-) diff --git a/gdb/gdbserver/linux-ppc-ipa.c b/gdb/gdbserver/linux-ppc-ipa.c index b543dceba5..348d455193 100644 --- a/gdb/gdbserver/linux-ppc-ipa.c +++ b/gdb/gdbserver/linux-ppc-ipa.c @@ -195,6 +195,8 @@ get_ipa_tdesc (int idx) return tdesc_powerpc_isa205_ppr_dscr_vsx64l; case PPC_TDESC_ISA207_VSX: return tdesc_powerpc_isa207_vsx64l; + case PPC_TDESC_ISA207_HTM_VSX: + return tdesc_powerpc_isa207_htm_vsx64l; #else case PPC_TDESC_BASE: return tdesc_powerpc_32l; @@ -214,6 +216,8 @@ get_ipa_tdesc (int idx) return tdesc_powerpc_isa205_ppr_dscr_vsx32l; case PPC_TDESC_ISA207_VSX: return tdesc_powerpc_isa207_vsx32l; + case PPC_TDESC_ISA207_HTM_VSX: + return tdesc_powerpc_isa207_htm_vsx32l; case PPC_TDESC_E500: return tdesc_powerpc_e500l; #endif @@ -244,6 +248,7 @@ initialize_low_tracepoint (void) init_registers_powerpc_isa205_vsx64l (); init_registers_powerpc_isa205_ppr_dscr_vsx64l (); init_registers_powerpc_isa207_vsx64l (); + init_registers_powerpc_isa207_htm_vsx64l (); #else init_registers_powerpc_32l (); init_registers_powerpc_altivec32l (); @@ -254,6 +259,7 @@ initialize_low_tracepoint (void) init_registers_powerpc_isa205_vsx32l (); init_registers_powerpc_isa205_ppr_dscr_vsx32l (); init_registers_powerpc_isa207_vsx32l (); + init_registers_powerpc_isa207_htm_vsx32l (); init_registers_powerpc_e500l (); #endif } diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index 6c27368a36..2c830d638a 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -526,6 +526,127 @@ ppc_store_tarregset (struct regcache *regcache, const void *buf) } static void +ppc_fill_tm_sprregset (struct regcache *regcache, void *buf) +{ + int i, base; + char *regset = (char *) buf; + + base = find_regno (regcache->tdesc, "tfhar"); + for (i = 0; i < 3; i++) + collect_register (regcache, base + i, ®set[i*8]); +} + +static void +ppc_store_tm_sprregset (struct regcache *regcache, const void *buf) +{ + int i, base; + char *regset = (char *) buf; + + base = find_regno (regcache->tdesc, "tfhar"); + for (i = 0; i < 3; i++) + supply_register (regcache, base + i, ®set[i*8]); +} + +static void +ppc_store_tm_cgprregset (struct regcache *regcache, const void *buf) +{ + int i, base, size, endian_offset; + char *regset = (char *) buf; + + base = find_regno (regcache->tdesc, "cr0"); + size = register_size (regcache->tdesc, base); + + gdb_assert (size == 4 || size == 8); + + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i*size]); + + endian_offset = 0; + + if ((size == 8) && (__BYTE_ORDER == __BIG_ENDIAN)) + endian_offset = 4; + + supply_register_by_name (regcache, "ccr", + ®set[PT_CCR * size + endian_offset]); + + supply_register_by_name (regcache, "cxer", + ®set[PT_XER * size + endian_offset]); + + supply_register_by_name (regcache, "clr", ®set[PT_LNK * size]); + supply_register_by_name (regcache, "cctr", ®set[PT_CTR * size]); +} + +static void +ppc_store_tm_cfprregset (struct regcache *regcache, const void *buf) +{ + int i, base; + char *regset = (char *) buf; + + base = find_regno (regcache->tdesc, "cf0"); + + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i*8]); + + supply_register_by_name (regcache, "cfpscr", ®set[32*8]); +} + +static void +ppc_store_tm_cvrregset (struct regcache *regcache, const void *buf) +{ + int i, base; + char *regset = (char *) buf; + int vscr_offset = 0; + + base = find_regno (regcache->tdesc, "cvr0"); + + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i*16]); + + if (__BYTE_ORDER == __BIG_ENDIAN) + vscr_offset = 12; + + supply_register_by_name (regcache, "cvscr", + ®set[32 * 16 + vscr_offset]); + + supply_register_by_name (regcache, "cvrsave", ®set[33 * 16]); +} + +static void +ppc_store_tm_cvsxregset (struct regcache *regcache, const void *buf) +{ + int i, base; + const char *regset = (const char *) buf; + + base = find_regno (regcache->tdesc, "cvs0h"); + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i * 8]); +} + +static void +ppc_store_tm_cpprregset (struct regcache *regcache, const void *buf) +{ + const char *cppr = (const char *) buf; + + supply_register_by_name (regcache, "cppr", cppr); +} + +static void +ppc_store_tm_cdscrregset (struct regcache *regcache, const void *buf) +{ + const char *cdscr = (const char *) buf; + + supply_register_by_name (regcache, "cdscr", cdscr); +} + +static void +ppc_store_tm_ctarregset (struct regcache *regcache, const void *buf) +{ + const char *ctar = (const char *) buf; + + supply_register_by_name (regcache, "ctar", ctar); +} + +static void ppc_fill_vsxregset (struct regcache *regcache, void *buf) { int i, base; @@ -638,6 +759,22 @@ 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_TM_CTAR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_ctarregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CDSCR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cdscrregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CPPR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cpprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVSX, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cvsxregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVMX, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cvrregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CFPR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cfprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CGPR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cgprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_SPR, 0, EXTENDED_REGS, + ppc_fill_tm_sprregset, ppc_store_tm_sprregset }, { 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, @@ -720,7 +857,13 @@ ppc_arch_setup (void) && (ppc_hwcap2 & PPC_FEATURE2_TAR) && ppc_check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)) - features.isa207 = true; + { + features.isa207 = true; + if ((ppc_hwcap2 & PPC_FEATURE2_HTM) + && ppc_check_regset (tid, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET)) + features.htm = true; + } } if (ppc_hwcap & PPC_FEATURE_CELL) @@ -782,6 +925,42 @@ ppc_arch_setup (void) regset->size = (features.isa207 ? PPC_LINUX_SIZEOF_TARREGSET : 0); break; + case NT_PPC_TM_SPR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_TM_SPRREGSET : 0); + break; + case NT_PPC_TM_CGPR: + if (features.wordsize == 4) + regset->size = (features.htm ? + PPC32_LINUX_SIZEOF_CGPRREGSET : 0); + else + regset->size = (features.htm ? + PPC64_LINUX_SIZEOF_CGPRREGSET : 0); + break; + case NT_PPC_TM_CFPR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CFPRREGSET : 0); + break; + case NT_PPC_TM_CVMX: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CVMXREGSET : 0); + break; + case NT_PPC_TM_CVSX: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CVSXREGSET : 0); + break; + case NT_PPC_TM_CPPR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CPPRREGSET : 0); + break; + case NT_PPC_TM_CDSCR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CDSCRREGSET : 0); + break; + case NT_PPC_TM_CTAR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CTARREGSET : 0); + break; default: break; } @@ -3165,6 +3344,8 @@ ppc_get_ipa_tdesc_idx (void) return PPC_TDESC_ISA205_PPR_DSCR_VSX; if (tdesc == tdesc_powerpc_isa207_vsx64l) return PPC_TDESC_ISA207_VSX; + if (tdesc == tdesc_powerpc_isa207_htm_vsx64l) + return PPC_TDESC_ISA207_HTM_VSX; #endif if (tdesc == tdesc_powerpc_32l) @@ -3185,6 +3366,8 @@ ppc_get_ipa_tdesc_idx (void) return PPC_TDESC_ISA205_PPR_DSCR_VSX; if (tdesc == tdesc_powerpc_isa207_vsx32l) return PPC_TDESC_ISA207_VSX; + if (tdesc == tdesc_powerpc_isa207_htm_vsx32l) + return PPC_TDESC_ISA207_HTM_VSX; if (tdesc == tdesc_powerpc_e500l) return PPC_TDESC_E500; @@ -3245,6 +3428,7 @@ initialize_low_arch (void) init_registers_powerpc_isa205_vsx32l (); init_registers_powerpc_isa205_ppr_dscr_vsx32l (); init_registers_powerpc_isa207_vsx32l (); + init_registers_powerpc_isa207_htm_vsx32l (); init_registers_powerpc_e500l (); #if __powerpc64__ init_registers_powerpc_64l (); @@ -3256,6 +3440,7 @@ initialize_low_arch (void) init_registers_powerpc_isa205_vsx64l (); init_registers_powerpc_isa205_ppr_dscr_vsx64l (); init_registers_powerpc_isa207_vsx64l (); + init_registers_powerpc_isa207_htm_vsx64l (); #endif initialize_regsets_info (&ppc_regsets_info); diff --git a/gdb/gdbserver/linux-ppc-tdesc-init.h b/gdb/gdbserver/linux-ppc-tdesc-init.h index 29b8122886..d1dfdad571 100644 --- a/gdb/gdbserver/linux-ppc-tdesc-init.h +++ b/gdb/gdbserver/linux-ppc-tdesc-init.h @@ -31,6 +31,7 @@ enum ppc_linux_tdesc { PPC_TDESC_ISA205_VSX, PPC_TDESC_ISA205_PPR_DSCR_VSX, PPC_TDESC_ISA207_VSX, + PPC_TDESC_ISA207_HTM_VSX, PPC_TDESC_E500, }; @@ -63,6 +64,9 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx32l (void); /* Defined in auto-generated file powerpc-isa207-vsx32l.c. */ void init_registers_powerpc_isa207_vsx32l (void); +/* Defined in auto-generated file powerpc-isa207-htm-vsx32l.c. */ +void init_registers_powerpc_isa207_htm_vsx32l (void); + /* Defined in auto-generated file powerpc-e500l.c. */ void init_registers_powerpc_e500l (void); @@ -97,4 +101,7 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx64l (void); /* Defined in auto-generated file powerpc-isa207-vsx64l.c. */ void init_registers_powerpc_isa207_vsx64l (void); +/* Defined in auto-generated file powerpc-isa207-htm-vsx64l.c. */ +void init_registers_powerpc_isa207_htm_vsx64l (void); + #endif