#include "gdb_proc_service.h"
#include "arch/aarch64.h"
#include "arch/aarch64-mte-linux.h"
+#include "arch/aarch64-scalable-linux.h"
#include "linux-aarch32-tdesc.h"
#include "linux-aarch64-tdesc.h"
#include "nat/aarch64-mte-linux-ptrace.h"
memcpy (buf, sve_state.data (), sve_state.size ());
}
+/* Wrapper for aarch64_za_regs_copy_to_reg_buf, to help copying NT_ARM_ZA
+ state from the thread (BUF) to the register cache. */
+
+static void
+aarch64_za_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 za_regnum = find_regno (regcache->tdesc, "za");
+ int svg_regnum = find_regno (regcache->tdesc, "svg");
+ int svcr_regnum = find_regno (regcache->tdesc, "svcr");
+
+ /* Update the register cache. aarch64_za_regs_copy_to_reg_buf handles
+ fetching the NT_ARM_ZA state from thread TID. */
+ aarch64_za_regs_copy_to_reg_buf (tid, regcache, za_regnum, svg_regnum,
+ svcr_regnum);
+}
+
+/* Wrapper for aarch64_za_regs_copy_from_reg_buf, to help copying NT_ARM_ZA
+ state from the register cache to the thread (BUF). */
+
+static void
+aarch64_za_regs_copy_from_regcache (struct regcache *regcache, void *buf)
+{
+ int tid = lwpid_of (current_thread);
+
+ int za_regnum = find_regno (regcache->tdesc, "za");
+ int svg_regnum = find_regno (regcache->tdesc, "svg");
+ int svcr_regnum = find_regno (regcache->tdesc, "svcr");
+
+ /* Update the thread NT_ARM_ZA state. aarch64_za_regs_copy_from_reg_buf
+ handles writing the ZA state back to thread TID. */
+ aarch64_za_regs_copy_from_reg_buf (tid, regcache, za_regnum, svg_regnum,
+ svcr_regnum);
+
+ /* We need to return the expected data in BUF, so copy whatever the kernel
+ already has to BUF. */
+
+ /* Obtain a dump of ZA from ptrace. */
+ gdb::byte_vector za_state = aarch64_fetch_za_regset (tid);
+ memcpy (buf, za_state.data (), za_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.
0, EXTENDED_REGS,
aarch64_sve_regs_copy_from_regcache, aarch64_sve_regs_copy_to_regcache
},
+ /* Scalable Matrix Extension (SME) ZA register. */
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_ZA,
+ 0, EXTENDED_REGS,
+ aarch64_za_regs_copy_from_regcache, aarch64_za_regs_copy_to_regcache
+ },
/* PAC registers. */
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK,
0, OPTIONAL_REGS,
if (features.tls > 0)
regset->size = AARCH64_TLS_REGISTER_SIZE * features.tls;
break;
+ case NT_ARM_ZA:
+ if (features.svq > 0)
+ regset->size = ZA_PT_SIZE (features.svq);
+ break;
default:
gdb_assert_not_reached ("Unknown register set found.");
}
features.mte = linux_get_hwcap2 (pid, 8) & HWCAP2_MTE;
features.tls = aarch64_tls_register_count (tid);
+ /* Scalable Matrix Extension feature and size check. */
+ if (linux_get_hwcap2 (pid, 8) & HWCAP2_SME)
+ features.svq = aarch64_za_get_svq (tid);
+
current_process ()->tdesc = aarch64_linux_read_description (features);
/* Adjust the register sets we should use for this particular set of