Author: andrew
Date: Wed Oct 30 13:45:40 2019
New Revision: 354178
URL: https://svnweb.freebsd.org/changeset/base/354178

Log:
  Allow the userspace ID register fields to be read from the kernel
  
  To allow consistent values to be used in both the kernel and userspace
  create a function for these to be read from the kernel. They use a newly
  created macro with the name of the ID register to read. For now there is
  redundant information in the user_regs array as it still holds the CRm and
  Op2 values, however this will be fixed in a later change.
  
  This will be used by ptrace to allow hardware breakpoints in userspace.
  
  Sponsored by: DARPA, AFRL

Modified:
  head/sys/arm64/arm64/identcpu.c
  head/sys/arm64/include/armreg.h
  head/sys/arm64/include/undefined.h

Modified: head/sys/arm64/arm64/identcpu.c
==============================================================================
--- head/sys/arm64/arm64/identcpu.c     Wed Oct 30 12:47:00 2019        
(r354177)
+++ head/sys/arm64/arm64/identcpu.c     Wed Oct 30 13:45:40 2019        
(r354178)
@@ -710,6 +710,7 @@ static struct mrs_field id_aa64pfr1_fields[] = {
 };
 
 struct mrs_user_reg {
+       u_int           reg;
        u_int           CRm;
        u_int           Op2;
        size_t          offset;
@@ -718,24 +719,28 @@ struct mrs_user_reg {
 
 static struct mrs_user_reg user_regs[] = {
        {       /* id_aa64isar0_el1 */
+               .reg = ID_AA64ISAR0_EL1,
                .CRm = 6,
                .Op2 = 0,
                .offset = __offsetof(struct cpu_desc, id_aa64isar0),
                .fields = id_aa64isar0_fields,
        },
        {       /* id_aa64isar1_el1 */
+               .reg = ID_AA64ISAR1_EL1,
                .CRm = 6,
                .Op2 = 1,
                .offset = __offsetof(struct cpu_desc, id_aa64isar1),
                .fields = id_aa64isar1_fields,
        },
        {       /* id_aa64pfr0_el1 */
+               .reg = ID_AA64PFR0_EL1,
                .CRm = 4,
                .Op2 = 0,
                .offset = __offsetof(struct cpu_desc, id_aa64pfr0),
                .fields = id_aa64pfr0_fields,
        },
        {       /* id_aa64dfr0_el1 */
+               .reg = ID_AA64DFR0_EL1,
                .CRm = 5,
                .Op2 = 0,
                .offset = __offsetof(struct cpu_desc, id_aa64dfr0),
@@ -816,6 +821,23 @@ user_mrs_handler(vm_offset_t va, uint32_t insn, struct
                frame->tf_lr = value;
 
        return (1);
+}
+
+bool
+extract_user_id_field(u_int reg, u_int field_shift, uint8_t *val)
+{
+       uint64_t value;
+       int i;
+
+       for (i = 0; i < nitems(user_regs); i++) {
+               if (user_regs[i].reg == reg) {
+                       value = CPU_DESC_FIELD(user_cpu_desc, i);
+                       *val = value >> field_shift;
+                       return (true);
+               }
+       }
+
+       return (false);
 }
 
 static void

Modified: head/sys/arm64/include/armreg.h
==============================================================================
--- head/sys/arm64/include/armreg.h     Wed Oct 30 12:47:00 2019        
(r354177)
+++ head/sys/arm64/include/armreg.h     Wed Oct 30 13:45:40 2019        
(r354178)
@@ -51,6 +51,10 @@
 #define         MRS_Op2_MASK                   0x000000e0
 #define         MRS_Rt_SHIFT                   0
 #define         MRS_Rt_MASK                    0x0000001f
+#define        MRS_REG(op0, op1, crn, crm, op2)                                
\
+    (((op0) << MRS_Op0_SHIFT) | ((op1) << MRS_Op1_SHIFT) |             \
+     ((crn) << MRS_CRn_SHIFT) | ((crm) << MRS_CRm_SHIFT) |             \
+     ((op2) << MRS_Op2_SHIFT))
 
 #define        READ_SPECIALREG(reg)                                            
\
 ({     uint64_t _val;                                                  \
@@ -193,6 +197,7 @@
 #define        ICC_SRE_EL2_EN          (1U << 3)
 
 /* ID_AA64DFR0_EL1 */
+#define        ID_AA64DFR0_EL1                 MRS_REG(3, 0, 0, 5, 0)
 #define        ID_AA64DFR0_DebugVer_SHIFT      0
 #define        ID_AA64DFR0_DebugVer_MASK       (UL(0xf) << 
ID_AA64DFR0_DebugVer_SHIFT)
 #define        ID_AA64DFR0_DebugVer_VAL(x)     ((x) & 
ID_AA64DFR0_DebugVer_MASK)
@@ -230,6 +235,7 @@
 #define         ID_AA64DFR0_PMSVer_V1          (UL(0x1) << 
ID_AA64DFR0_PMSVer_SHIFT)
 
 /* ID_AA64ISAR0_EL1 */
+#define        ID_AA64ISAR0_EL1                MRS_REG(3, 0, 0, 6, 0)
 #define        ID_AA64ISAR0_AES_SHIFT          4
 #define        ID_AA64ISAR0_AES_MASK           (UL(0xf) << 
ID_AA64ISAR0_AES_SHIFT)
 #define        ID_AA64ISAR0_AES_VAL(x)         ((x) & ID_AA64ISAR0_AES_MASK)
@@ -284,6 +290,7 @@
 #define         ID_AA64ISAR0_DP_IMPL           (UL(0x1) << 
ID_AA64ISAR0_DP_SHIFT)
 
 /* ID_AA64ISAR1_EL1 */
+#define        ID_AA64ISAR1_EL1                MRS_REG(3, 0, 0, 6, 1)
 #define        ID_AA64ISAR1_DPB_SHIFT          0
 #define        ID_AA64ISAR1_DPB_MASK           (UL(0xf) << 
ID_AA64ISAR1_DPB_SHIFT)
 #define        ID_AA64ISAR1_DPB_VAL(x)         ((x) & ID_AA64ISAR1_DPB_MASK)
@@ -326,6 +333,7 @@
 #define         ID_AA64ISAR1_GPI_IMPL          (UL(0x1) << 
ID_AA64ISAR1_GPI_SHIFT)
 
 /* ID_AA64MMFR0_EL1 */
+#define        ID_AA64MMFR0_EL1                MRS_REG(3, 0, 0, 7, 0)
 #define        ID_AA64MMFR0_PARange_SHIFT      0
 #define        ID_AA64MMFR0_PARange_MASK       (UL(0xf) << 
ID_AA64MMFR0_PARange_SHIFT)
 #define        ID_AA64MMFR0_PARange_VAL(x)     ((x) & 
ID_AA64MMFR0_PARange_MASK)
@@ -373,6 +381,7 @@
 #define         ID_AA64MMFR0_TGran4_NONE       (UL(0xf) << 
ID_AA64MMFR0_TGran4_SHIFT)
 
 /* ID_AA64MMFR1_EL1 */
+#define        ID_AA64MMFR1_EL1                MRS_REG(3, 0, 0, 7, 1)
 #define        ID_AA64MMFR1_HAFDBS_SHIFT       0
 #define        ID_AA64MMFR1_HAFDBS_MASK        (UL(0xf) << 
ID_AA64MMFR1_HAFDBS_SHIFT)
 #define        ID_AA64MMFR1_HAFDBS_VAL(x)      ((x) & ID_AA64MMFR1_HAFDBS_MASK)
@@ -418,7 +427,7 @@
 #define         ID_AA64MMFR1_XNX_IMPL          (UL(0x1) << 
ID_AA64MMFR1_XNX_SHIFT)
 
 /* ID_AA64MMFR2_EL1 */
-#define        ID_AA64MMFR2_EL1                S3_0_C0_C7_2
+#define        ID_AA64MMFR2_EL1                MRS_REG(3, 0, 0, 7, 2)
 #define        ID_AA64MMFR2_CnP_SHIFT          0
 #define        ID_AA64MMFR2_CnP_MASK           (UL(0xf) << 
ID_AA64MMFR2_CnP_SHIFT)
 #define        ID_AA64MMFR2_CnP_VAL(x)         ((x) & ID_AA64MMFR2_CnP_MASK)
@@ -456,6 +465,7 @@
 #define         ID_AA64MMFR2_NV_IMPL           (UL(0x1) << 
ID_AA64MMFR2_NV_SHIFT)
 
 /* ID_AA64PFR0_EL1 */
+#define        ID_AA64PFR0_EL1                 MRS_REG(3, 0, 0, 4, 0)
 #define        ID_AA64PFR0_EL0_SHIFT           0
 #define        ID_AA64PFR0_EL0_MASK            (UL(0xf) << 
ID_AA64PFR0_EL0_SHIFT)
 #define        ID_AA64PFR0_EL0_VAL(x)          ((x) & ID_AA64PFR0_EL0_MASK)

Modified: head/sys/arm64/include/undefined.h
==============================================================================
--- head/sys/arm64/include/undefined.h  Wed Oct 30 12:47:00 2019        
(r354177)
+++ head/sys/arm64/include/undefined.h  Wed Oct 30 13:45:40 2019        
(r354178)
@@ -33,6 +33,8 @@
 #ifndef _MACHINE__UNDEFINED_H_
 #define        _MACHINE__UNDEFINED_H_
 
+#ifdef _KERNEL
+
 typedef int (*undef_handler_t)(vm_offset_t, uint32_t, struct trapframe *,
     uint32_t);
 
@@ -60,5 +62,8 @@ void undef_init(void);
 void *install_undef_handler(bool, undef_handler_t);
 void remove_undef_handler(void *);
 int undef_insn(u_int, struct trapframe *);
+bool extract_user_id_field(u_int, u_int, uint8_t *);
+
+#endif /* _KERNEL */
 
 #endif
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to