aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2026-06-18 13:34:04 +0000
committerAndrew Turner <andrew@FreeBSD.org>2026-06-18 14:56:52 +0000
commita9e12d3ec8bde29e97227757bc08cb1a0a93afa9 (patch)
tree9ad3155675de788a78af33b76e92778299dc9932
parentfd1ee28bd01429aa8c38199d5fc069e8b0b75442 (diff)
arm64: Support building sys/sysl instructions
Add support to build system instructions from a macro. These are based on the existing support for msr/mrs instructions with adjustments for the different instruction format. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D57017
-rw-r--r--sys/arm64/include/_armreg.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/arm64/include/_armreg.h b/sys/arm64/include/_armreg.h
index 0f5134e5a978..0ade9e6168c9 100644
--- a/sys/arm64/include/_armreg.h
+++ b/sys/arm64/include/_armreg.h
@@ -52,6 +52,34 @@
#define WRITE_SPECIALREG(reg, _val) \
__asm __volatile("msr " __STRING(reg) ", %0" : : "r"((uint64_t)_val))
+
+#define __SYS_ALT_NAME(op1, crn, crm, op2) \
+ "#" #op1 ", C" #crn ", C" #crm ", #" #op2
+#define _SYS_ALT_NAME(op1, crn, crm, op2) \
+ __SYS_ALT_NAME(op1, crn, crm, op2)
+#define SYS_ALT_NAME(insn) \
+ _SYS_ALT_NAME(insn##_op1, insn##_CRn, insn##_CRm, insn##_op2)
+
+#define SYS(insn) do { \
+ _Static_assert(insn##_op0 == 1, "Invalid SYS instruction"); \
+ __asm __volatile("sys " SYS_ALT_NAME(insn)); \
+} while (0)
+
+#define SYS_ARG(insn, _val) do { \
+ _Static_assert(insn##_op0 == 1, "Invalid SYS instruction"); \
+ __asm __volatile("sys " SYS_ALT_NAME(insn) ", %0" \
+ : : "r"((uint64_t)_val)); \
+} while (0)
+
+#define SYSL(insn) \
+({ \
+ uint64_t _val; \
+ _Static_assert(insn##_op0 == 1, "Invalid SYS instruction"); \
+ __asm __volatile("sysl %0, " SYS_ALT_NAME(insn) \
+ : "=&r"(_val)); \
+ _val; \
+})
+
#define UL(x) UINT64_C(x)
#endif /* !_MACHINE__ARMREG_H_ */