riscv: implement Zicbom-based CMO instructions + the t-head variant
[linux-block.git] / arch / riscv / include / asm / errata_list.h
index 398e351e7002e784d2af00c5c544514813dfb2ce..19a771085781a69da552b1daaa31b6b325a17a9a 100644 (file)
 
 #ifdef CONFIG_ERRATA_THEAD
 #define        ERRATA_THEAD_PBMT 0
-#define        ERRATA_THEAD_NUMBER 1
+#define        ERRATA_THEAD_CMO 1
+#define        ERRATA_THEAD_NUMBER 2
 #endif
 
 #define        CPUFEATURE_SVPBMT 0
-#define        CPUFEATURE_NUMBER 1
+#define        CPUFEATURE_ZICBOM 1
+#define        CPUFEATURE_NUMBER 2
 
 #ifdef __ASSEMBLY__
 
@@ -87,6 +89,59 @@ asm volatile(ALTERNATIVE(                                            \
 #define ALT_THEAD_PMA(_val)
 #endif
 
+/*
+ * dcache.ipa rs1 (invalidate, physical address)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ *   0000001    01010      rs1       000      00000  0001011
+ * dache.iva rs1 (invalida, virtual address)
+ *   0000001    00110      rs1       000      00000  0001011
+ *
+ * dcache.cpa rs1 (clean, physical address)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ *   0000001    01001      rs1       000      00000  0001011
+ * dcache.cva rs1 (clean, virtual address)
+ *   0000001    00100      rs1       000      00000  0001011
+ *
+ * dcache.cipa rs1 (clean then invalidate, physical address)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ *   0000001    01011      rs1       000      00000  0001011
+ * dcache.civa rs1 (... virtual address)
+ *   0000001    00111      rs1       000      00000  0001011
+ *
+ * sync.s (make sure all cache operations finished)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ *   0000000    11001     00000      000      00000  0001011
+ */
+#define THEAD_inval_A0 ".long 0x0265000b"
+#define THEAD_clean_A0 ".long 0x0245000b"
+#define THEAD_flush_A0 ".long 0x0275000b"
+#define THEAD_SYNC_S   ".long 0x0190000b"
+
+#define ALT_CMO_OP(_op, _start, _size, _cachesize)                     \
+asm volatile(ALTERNATIVE_2(                                            \
+       __nops(6),                                                      \
+       "mv a0, %1\n\t"                                                 \
+       "j 2f\n\t"                                                      \
+       "3:\n\t"                                                        \
+       "cbo." __stringify(_op) " (a0)\n\t"                             \
+       "add a0, a0, %0\n\t"                                            \
+       "2:\n\t"                                                        \
+       "bltu a0, %2, 3b\n\t"                                           \
+       "nop", 0, CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM,           \
+       "mv a0, %1\n\t"                                                 \
+       "j 2f\n\t"                                                      \
+       "3:\n\t"                                                        \
+       THEAD_##_op##_A0 "\n\t"                                         \
+       "add a0, a0, %0\n\t"                                            \
+       "2:\n\t"                                                        \
+       "bltu a0, %2, 3b\n\t"                                           \
+       THEAD_SYNC_S, THEAD_VENDOR_ID,                                  \
+                       ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO)      \
+       : : "r"(_cachesize),                                            \
+           "r"((unsigned long)(_start) & ~((_cachesize) - 1UL)),       \
+           "r"((unsigned long)(_start) + (_size))                      \
+       : "a0")
+
 #endif /* __ASSEMBLY__ */
 
 #endif