From db8dacb578b687574ba900298a4159c887dd18d0 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Mon, 15 Apr 2024 12:01:47 +0300 Subject: aarch64: Add thread state types Notes: * TPIDR_EL0, the TLS pointer, is included in the generic state directly. * TPIDR2_EL0, part of the SME extension, is not included in the generic state. If we add SME support, it will be a part of something like aarch64_sme_state. * CPSR is not a real register in AArch64 (unlike in AArch32), but a collection of individually accessible bits and pieces from PSTATE. Due to how the kernel accesses user mode's PSTATE (via SPSR), it's convenient to represent PSTATE as a pseudo-register in the same format as SPSR. This is also what QEMU and XNU do. * There is no hardware-enforced 'natural' order to place the registers in, since no registers get pushed onto the stack on exception entry. Saving and restoring registers from an instance of struct aarch64_thread_state is implemented entirely in software, and the format is essentially arbitrary. * aarch64_float_state includes registers of a 128-bit type; this may create issues for compilers other than GCC. * fp_reserved is not a register, but a placeholder. If and when Arm adds another floating-point meta-register, this will be changed to represent it, and that would not be considered a compatibility break, so don't access fp_reserved by name, or its value, from userland. Instead, memset the whole structure to 0 if starting from scratch, or memcpy an existing structure. More thread state types could be added in the future, such as aarch64_debug_state, aarch64_virt_state (for hardware-accelerated virtualization), potentially ones for PAC, SVE/SME, etc. Message-ID: <20240415090149.38358-8-bugaevc@gmail.com> --- aarch64/Makefrag.am | 1 + aarch64/include/mach/aarch64/thread_status.h | 43 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 aarch64/include/mach/aarch64/thread_status.h (limited to 'aarch64') diff --git a/aarch64/Makefrag.am b/aarch64/Makefrag.am index 13c9439a..dd1837d4 100644 --- a/aarch64/Makefrag.am +++ b/aarch64/Makefrag.am @@ -36,6 +36,7 @@ include_mach_aarch64_HEADERS = \ aarch64/include/mach/aarch64/mach_aarch64_types.h \ aarch64/include/mach/aarch64/machine_types.defs \ aarch64/include/mach/aarch64/syscall_sw.h \ + aarch64/include/mach/aarch64/thread_status.h \ aarch64/include/mach/aarch64/vm_param.h \ aarch64/include/mach/aarch64/vm_types.h diff --git a/aarch64/include/mach/aarch64/thread_status.h b/aarch64/include/mach/aarch64/thread_status.h new file mode 100644 index 00000000..c0c7773e --- /dev/null +++ b/aarch64/include/mach/aarch64/thread_status.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2024 Free Software Foundation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _MACH_AARCH64_THREAD_STATUS_H_ +#define _MACH_AARCH64_THREAD_STATUS_H_ + +#define AARCH64_THREAD_STATE 1 +#define AARCH64_FLOAT_STATE 2 + +struct aarch64_thread_state { + uint64_t x[31]; + uint64_t sp; + uint64_t pc; + uint64_t tpidr_el0; + uint64_t cpsr; /* in SPSR format */ +}; +#define AARCH64_THREAD_STATE_COUNT (sizeof(struct aarch64_thread_state) / sizeof(unsigned int)) + +struct aarch64_float_state { + __int128 v[32]; + uint64_t fpsr; + uint64_t fpcr; + uint64_t fpmr; + uint64_t fp_reserved; /* for when ARM adds another FP register */ +}; +#define AARCH64_FLOAT_STATE_COUNT (sizeof(struct aarch64_float_state) / sizeof(unsigned int)) + +#endif /* _MACH_AARHC64_THREAD_STATUS_H_ */ -- cgit v1.2.3