From 45f6a1e6aa4141a565e38a800f677f9e352425ba Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Tue, 4 Apr 2023 17:28:51 +0100 Subject: sme2: Enable SME2 support in gdbserver This patch teaches gdbserver about the SME2 and the ZT0 register. Since most of the code used by gdbserver for SME2 is shared with gdb, this is a rather small patch that reuses most of the code put in place for native AArch64 Linux. Validated under Fast Models. Reviewed-by: Thiago Jung Bauermann --- gdbserver/linux-aarch64-low.cc | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'gdbserver') diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index e887e39..fcbe7bb 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -797,6 +797,46 @@ aarch64_za_regs_copy_from_regcache (struct regcache *regcache, void *buf) memcpy (buf, za_state.data (), za_state.size ()); } +/* Wrapper for aarch64_zt_regs_copy_to_reg_buf, to help copying NT_ARM_ZT + state from the thread (BUF) to the register cache. */ + +static void +aarch64_zt_regs_copy_to_regcache (struct regcache *regcache, + ATTRIBUTE_UNUSED const void *buf) +{ + /* BUF is unused here since we collect the data straight from a ptrace + request, therefore bypassing gdbserver's own call to ptrace. */ + int tid = lwpid_of (current_thread); + + int zt_regnum = find_regno (regcache->tdesc, "zt0"); + + /* Update the register cache. aarch64_zt_regs_copy_to_reg_buf handles + fetching the NT_ARM_ZT state from thread TID. */ + aarch64_zt_regs_copy_to_reg_buf (tid, regcache, zt_regnum); +} + +/* Wrapper for aarch64_zt_regs_copy_from_reg_buf, to help copying NT_ARM_ZT + state from the register cache to the thread (BUF). */ + +static void +aarch64_zt_regs_copy_from_regcache (struct regcache *regcache, void *buf) +{ + int tid = lwpid_of (current_thread); + + int zt_regnum = find_regno (regcache->tdesc, "zt0"); + + /* Update the thread NT_ARM_ZT state. aarch64_zt_regs_copy_from_reg_buf + handles writing the ZT state back to thread TID. */ + aarch64_zt_regs_copy_from_reg_buf (tid, regcache, zt_regnum); + + /* We need to return the expected data in BUF, so copy whatever the kernel + already has to BUF. */ + + /* Obtain a dump of NT_ARM_ZT from ptrace. */ + gdb::byte_vector zt_state = aarch64_fetch_zt_regset (tid); + memcpy (buf, zt_state.data (), zt_state.size ()); +} + /* Array containing all the possible register sets for AArch64/Linux. During architecture setup, these will be checked against the HWCAP/HWCAP2 bits for validity and enabled/disabled accordingly. @@ -824,6 +864,11 @@ static struct regset_info aarch64_regsets[] = 0, EXTENDED_REGS, aarch64_za_regs_copy_from_regcache, aarch64_za_regs_copy_to_regcache }, + /* Scalable Matrix Extension 2 (SME2) ZT registers. */ + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_ZT, + 0, EXTENDED_REGS, + aarch64_zt_regs_copy_from_regcache, aarch64_zt_regs_copy_to_regcache + }, /* PAC registers. */ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK, 0, OPTIONAL_REGS, @@ -895,6 +940,10 @@ aarch64_adjust_register_sets (const struct aarch64_features &features) if (features.svq > 0) regset->size = ZA_PT_SIZE (features.svq); break; + case NT_ARM_ZT: + if (features.sme2) + regset->size = AARCH64_SME2_ZT0_SIZE; + break; default: gdb_assert_not_reached ("Unknown register set found."); } @@ -933,6 +982,14 @@ aarch64_target::low_arch_setup () if (linux_get_hwcap2 (pid, 8) & HWCAP2_SME) features.svq = aarch64_za_get_svq (tid); + /* Scalable Matrix Extension 2 feature check. */ + CORE_ADDR hwcap2 = linux_get_hwcap2 (pid, 8); + if ((hwcap2 & HWCAP2_SME2) || (hwcap2 & HWCAP2_SME2P1)) + { + /* Make sure ptrace supports NT_ARM_ZT. */ + features.sme2 = supports_zt_registers (tid); + } + current_process ()->tdesc = aarch64_linux_read_description (features); /* Adjust the register sets we should use for this particular set of -- cgit v1.1