]> git.karo-electronics.de Git - linux-beck.git/blobdiff - drivers/misc/sgi-gru/gru_instructions.h
X86: uv: implement a gru_read_gpa kernel function
[linux-beck.git] / drivers / misc / sgi-gru / gru_instructions.h
index 3fde33c1e8f3b64e10192194974ec0016ea95f00..e033b6ce4a3f637e1f928507841269e2756bfa48 100644 (file)
@@ -81,6 +81,8 @@ struct control_block_extended_exc_detail {
        int             exopc;
        long            exceptdet0;
        int             exceptdet1;
+       int             cbrstate;
+       int             cbrexecstatus;
 };
 
 /*
@@ -107,7 +109,8 @@ struct gru_instruction_bits {
     unsigned char              reserved2: 2;
     unsigned char              istatus:   2;
     unsigned char              isubstatus:4;
-    unsigned char              reserved3: 2;
+    unsigned char              reserved3: 1;
+    unsigned char              tlb_fault_color: 1;
     /* DW 1 */
     unsigned long              idef4;          /* 42 bits: TRi1, BufSize */
     /* DW 2-6 */
@@ -250,17 +253,37 @@ struct gru_instruction {
 #define CBE_CAUSE_HA_RESPONSE_FATAL            (1 << 13)
 #define CBE_CAUSE_HA_RESPONSE_NON_FATAL                (1 << 14)
 #define CBE_CAUSE_ADDRESS_SPACE_DECODE_ERROR   (1 << 15)
-#define CBE_CAUSE_RESPONSE_DATA_ERROR          (1 << 16)
-#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR    (1 << 17)
+#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR    (1 << 16)
+#define CBE_CAUSE_RA_RESPONSE_DATA_ERROR       (1 << 17)
+#define CBE_CAUSE_HA_RESPONSE_DATA_ERROR       (1 << 18)
+
+/* CBE cbrexecstatus bits */
+#define CBR_EXS_ABORT_OCC_BIT                  0
+#define CBR_EXS_INT_OCC_BIT                    1
+#define CBR_EXS_PENDING_BIT                    2
+#define CBR_EXS_QUEUED_BIT                     3
+#define CBR_EXS_TLB_INVAL_BIT                  4
+#define CBR_EXS_EXCEPTION_BIT                  5
+
+#define CBR_EXS_ABORT_OCC                      (1 << CBR_EXS_ABORT_OCC_BIT)
+#define CBR_EXS_INT_OCC                                (1 << CBR_EXS_INT_OCC_BIT)
+#define CBR_EXS_PENDING                                (1 << CBR_EXS_PENDING_BIT)
+#define CBR_EXS_QUEUED                         (1 << CBR_EXS_QUEUED_BIT)
+#define CBR_TLB_INVAL                          (1 << CBR_EXS_TLB_INVAL_BIT)
+#define CBR_EXS_EXCEPTION                      (1 << CBR_EXS_EXCEPTION_BIT)
 
 /*
  * Exceptions are retried for the following cases. If any OTHER bits are set
  * in ecause, the exception is not retryable.
  */
-#define EXCEPTION_RETRY_BITS (CBE_CAUSE_RESPONSE_DATA_ERROR |          \
-                             CBE_CAUSE_RA_REQUEST_TIMEOUT |            \
+#define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR |           \
                              CBE_CAUSE_TLBHW_ERROR |                   \
-                             CBE_CAUSE_HA_REQUEST_TIMEOUT)
+                             CBE_CAUSE_RA_REQUEST_TIMEOUT |            \
+                             CBE_CAUSE_RA_RESPONSE_NON_FATAL |         \
+                             CBE_CAUSE_HA_RESPONSE_NON_FATAL |         \
+                             CBE_CAUSE_RA_RESPONSE_DATA_ERROR |        \
+                             CBE_CAUSE_HA_RESPONSE_DATA_ERROR          \
+                             )
 
 /* Message queue head structure */
 union gru_mesqhead {
@@ -317,6 +340,19 @@ static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
  *             - nelem and stride are in elements
  *             - tri0/tri1 is in bytes for the beginning of the data segment.
  */
+static inline void gru_vload_phys(void *cb, unsigned long gpa,
+               unsigned int tri0, int iaa, unsigned long hints)
+{
+       struct gru_instruction *ins = (struct gru_instruction *)cb;
+
+       ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
+       ins->nelem = 1;
+       ins->tri0 = tri0;
+       ins->op1_stride = 1;
+       gru_start_instruction(ins, __opword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
+                                       CB_IMA(hints)));
+}
+
 static inline void gru_vload(void *cb, unsigned long mem_addr,
                unsigned int tri0, unsigned char xtype, unsigned long nelem,
                unsigned long stride, unsigned long hints)
@@ -600,9 +636,11 @@ static inline int gru_get_cb_substatus(void *cb)
        return cbs->isubstatus;
 }
 
-/* Check the status of a CB. If the CB is in UPM mode, call the
- * OS to handle the UPM status.
- * Returns the CB status field value (0 for normal completion)
+/*
+ * User interface to check an instruction status. UPM and exceptions
+ * are handled automatically. However, this function does NOT wait
+ * for an active instruction to complete.
+ *
  */
 static inline int gru_check_status(void *cb)
 {
@@ -610,34 +648,31 @@ static inline int gru_check_status(void *cb)
        int ret;
 
        ret = cbs->istatus;
-       if (ret == CBS_CALL_OS)
+       if (ret != CBS_ACTIVE)
                ret = gru_check_status_proc(cb);
        return ret;
 }
 
-/* Wait for CB to complete.
- * Returns the CB status field value (0 for normal completion)
+/*
+ * User interface (via inline function) to wait for an instruction
+ * to complete. Completion status (IDLE or EXCEPTION is returned
+ * to the user. Exception due to hardware errors are automatically
+ * retried before returning an exception.
+ *
  */
 static inline int gru_wait(void *cb)
 {
-       struct gru_control_block_status *cbs = (void *)cb;
-       int ret = cbs->istatus;
-
-       if (ret != CBS_IDLE)
-               ret = gru_wait_proc(cb);
-       return ret;
+       return gru_wait_proc(cb);
 }
 
-/* Wait for CB to complete. Aborts program if error. (Note: error does NOT
+/*
+ * Wait for CB to complete. Aborts program if error. (Note: error does NOT
  * mean TLB mis - only fatal errors such as memory parity error or user
  * bugs will cause termination.
  */
 static inline void gru_wait_abort(void *cb)
 {
-       struct gru_control_block_status *cbs = (void *)cb;
-
-       if (cbs->istatus != CBS_IDLE)
-               gru_wait_abort_proc(cb);
+       gru_wait_abort_proc(cb);
 }