The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=18af5a180b29f425b8427263be5517d3573ca220

commit 18af5a180b29f425b8427263be5517d3573ca220
Author:     Sarah Walker <[email protected]>
AuthorDate: 2026-02-09 20:39:53 +0000
Commit:     Andrew Turner <[email protected]>
CommitDate: 2026-02-10 15:39:56 +0000

    arm64: Enable MOPS usage in the kernel
    
    Support handling kernel-side MOE exceptions.
    
    Reported by:    andrew
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D54943
---
 sys/arm64/arm64/trap.c | 123 +++++++++++++++++++++++++------------------------
 1 file changed, 63 insertions(+), 60 deletions(-)

diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 3de56187657c..b3c68fa4826f 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -480,6 +480,66 @@ fpe_trap(struct thread *td, void *addr, uint32_t exception)
 }
 #endif
 
+static void
+handle_moe(struct thread *td, struct trapframe *frame, uint64_t esr)
+{
+       uint64_t src;
+       uint64_t dest;
+       uint64_t size;
+       int src_reg;
+       int dest_reg;
+       int size_reg;
+       int format_option;
+
+       format_option = esr & ISS_MOE_FORMAT_OPTION_MASK;
+       dest_reg = (esr & ISS_MOE_DESTREG_MASK) >> ISS_MOE_DESTREG_SHIFT;
+       size_reg = (esr & ISS_MOE_SIZEREG_MASK) >> ISS_MOE_SIZEREG_SHIFT;
+       dest = frame->tf_x[dest_reg];
+       size = frame->tf_x[size_reg];
+
+       /*
+        * Put the registers back in the original format suitable for a
+        * prologue instruction, using the generic return routine from the
+        * Arm ARM (DDI 0487I.a) rules CNTMJ and MWFQH.
+        */
+       if (esr & ISS_MOE_MEMINST) {
+               /* SET* instruction */
+               if (format_option == ISS_MOE_FORMAT_OPTION_A ||
+                   format_option == ISS_MOE_FORMAT_OPTION_A2) {
+                       /* Format is from Option A; forward set */
+                       frame->tf_x[dest_reg] = dest + size;
+                       frame->tf_x[size_reg] = -size;
+               }
+       } else {
+               /* CPY* instruction */
+               src_reg = (esr & ISS_MOE_SRCREG_MASK) >> ISS_MOE_SRCREG_SHIFT;
+               src = frame->tf_x[src_reg];
+
+               if (format_option == ISS_MOE_FORMAT_OPTION_B ||
+                   format_option == ISS_MOE_FORMAT_OPTION_B2) {
+                       /* Format is from Option B */
+                       if (frame->tf_spsr & PSR_N) {
+                               /* Backward copy */
+                               frame->tf_x[dest_reg] = dest - size;
+                               frame->tf_x[src_reg] = src + size;
+                       }
+               } else {
+                       /* Format is from Option A */
+                       if (frame->tf_x[size_reg] & (1UL << 63)) {
+                               /* Forward copy */
+                               frame->tf_x[dest_reg] = dest + size;
+                               frame->tf_x[src_reg] = src + size;
+                               frame->tf_x[size_reg] = -size;
+                       }
+               }
+       }
+
+       if (esr & ISS_MOE_FROM_EPILOGUE)
+               frame->tf_elr -= 8;
+       else
+               frame->tf_elr -= 4;
+}
+
 /*
  * See the comment above data_abort().
  */
@@ -589,6 +649,9 @@ do_el1h_sync(struct thread *td, struct trapframe *frame)
                print_gp_register("far", far);
                panic("Branch Target exception");
                break;
+       case EXCP_MOE:
+               handle_moe(td, frame, esr);
+               break;
        default:
                print_registers(frame);
                print_gp_register("far", far);
@@ -597,66 +660,6 @@ do_el1h_sync(struct thread *td, struct trapframe *frame)
        }
 }
 
-static void
-handle_moe(struct thread *td, struct trapframe *frame, uint64_t esr)
-{
-       uint64_t src;
-       uint64_t dest;
-       uint64_t size;
-       int src_reg;
-       int dest_reg;
-       int size_reg;
-       int format_option;
-
-       format_option = esr & ISS_MOE_FORMAT_OPTION_MASK;
-       dest_reg = (esr & ISS_MOE_DESTREG_MASK) >> ISS_MOE_DESTREG_SHIFT;
-       size_reg = (esr & ISS_MOE_SIZEREG_MASK) >> ISS_MOE_SIZEREG_SHIFT;
-       dest = frame->tf_x[dest_reg];
-       size = frame->tf_x[size_reg];
-
-       /*
-        * Put the registers back in the original format suitable for a
-        * prologue instruction, using the generic return routine from the
-        * Arm ARM (DDI 0487I.a) rules CNTMJ and MWFQH.
-        */
-       if (esr & ISS_MOE_MEMINST) {
-               /* SET* instruction */
-               if (format_option == ISS_MOE_FORMAT_OPTION_A ||
-                   format_option == ISS_MOE_FORMAT_OPTION_A2) {
-                       /* Format is from Option A; forward set */
-                       frame->tf_x[dest_reg] = dest + size;
-                       frame->tf_x[size_reg] = -size;
-               }
-       } else {
-               /* CPY* instruction */
-               src_reg = (esr & ISS_MOE_SRCREG_MASK) >> ISS_MOE_SRCREG_SHIFT;
-               src = frame->tf_x[src_reg];
-
-               if (format_option == ISS_MOE_FORMAT_OPTION_B ||
-                   format_option == ISS_MOE_FORMAT_OPTION_B2) {
-                       /* Format is from Option B */
-                       if (frame->tf_spsr & PSR_N) {
-                               /* Backward copy */
-                               frame->tf_x[dest_reg] = dest - size;
-                               frame->tf_x[src_reg] = src + size;
-                       }
-               } else {
-                       /* Format is from Option A */
-                       if (frame->tf_x[size_reg] & (1UL << 63)) {
-                               /* Forward copy */
-                               frame->tf_x[dest_reg] = dest + size;
-                               frame->tf_x[src_reg] = src + size;
-                               frame->tf_x[size_reg] = -size;
-                       }
-               }
-       }
-
-       if (esr & ISS_MOE_FROM_EPILOGUE)
-               frame->tf_elr -= 8;
-       else
-               frame->tf_elr -= 4;
-}
-
 void
 do_el0_sync(struct thread *td, struct trapframe *frame)
 {

Reply via email to