Merge tag 'riscv-for-linus-6.3-mw1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-block.git] / arch / riscv / include / asm / hwcap.h
index 64ad1937e71494b17389697549fcec5cade84939..e3021b2590de0a04e5ebd9ed936b464e09ce9b47 100644 (file)
@@ -8,24 +8,11 @@
 #ifndef _ASM_RISCV_HWCAP_H
 #define _ASM_RISCV_HWCAP_H
 
+#include <asm/alternative-macros.h>
 #include <asm/errno.h>
 #include <linux/bits.h>
 #include <uapi/asm/hwcap.h>
 
-#ifndef __ASSEMBLY__
-#include <linux/jump_label.h>
-/*
- * This yields a mask that user programs can use to figure out what
- * instruction set this cpu supports.
- */
-#define ELF_HWCAP              (elf_hwcap)
-
-enum {
-       CAP_HWCAP = 1,
-};
-
-extern unsigned long elf_hwcap;
-
 #define RISCV_ISA_EXT_a                ('a' - 'a')
 #define RISCV_ISA_EXT_c                ('c' - 'a')
 #define RISCV_ISA_EXT_d                ('d' - 'a')
@@ -37,42 +24,31 @@ extern unsigned long elf_hwcap;
 #define RISCV_ISA_EXT_u                ('u' - 'a')
 
 /*
- * Increse this to higher value as kernel support more ISA extensions.
+ * These macros represent the logical IDs of each multi-letter RISC-V ISA
+ * extension and are used in the ISA bitmap. The logical IDs start from
+ * RISCV_ISA_EXT_BASE, which allows the 0-25 range to be reserved for single
+ * letter extensions. The maximum, RISCV_ISA_EXT_MAX, is defined in order
+ * to allocate the bitmap and may be increased when necessary.
+ *
+ * New extensions should just be added to the bottom, rather than added
+ * alphabetically, in order to avoid unnecessary shuffling.
  */
-#define RISCV_ISA_EXT_MAX      64
-#define RISCV_ISA_EXT_NAME_LEN_MAX 32
+#define RISCV_ISA_EXT_BASE             26
 
-/* The base ID for multi-letter ISA extensions */
-#define RISCV_ISA_EXT_BASE 26
+#define RISCV_ISA_EXT_SSCOFPMF         26
+#define RISCV_ISA_EXT_SSTC             27
+#define RISCV_ISA_EXT_SVINVAL          28
+#define RISCV_ISA_EXT_SVPBMT           29
+#define RISCV_ISA_EXT_ZBB              30
+#define RISCV_ISA_EXT_ZICBOM           31
+#define RISCV_ISA_EXT_ZIHINTPAUSE      32
 
-/*
- * This enum represent the logical ID for each multi-letter RISC-V ISA extension.
- * The logical ID should start from RISCV_ISA_EXT_BASE and must not exceed
- * RISCV_ISA_EXT_MAX. 0-25 range is reserved for single letter
- * extensions while all the multi-letter extensions should define the next
- * available logical extension id.
- */
-enum riscv_isa_ext_id {
-       RISCV_ISA_EXT_SSCOFPMF = RISCV_ISA_EXT_BASE,
-       RISCV_ISA_EXT_SVPBMT,
-       RISCV_ISA_EXT_ZICBOM,
-       RISCV_ISA_EXT_ZIHINTPAUSE,
-       RISCV_ISA_EXT_SSTC,
-       RISCV_ISA_EXT_SVINVAL,
-       RISCV_ISA_EXT_ID_MAX
-};
-static_assert(RISCV_ISA_EXT_ID_MAX <= RISCV_ISA_EXT_MAX);
+#define RISCV_ISA_EXT_MAX              64
+#define RISCV_ISA_EXT_NAME_LEN_MAX     32
 
-/*
- * This enum represents the logical ID for each RISC-V ISA extension static
- * keys. We can use static key to optimize code path if some ISA extensions
- * are available.
- */
-enum riscv_isa_ext_key {
-       RISCV_ISA_EXT_KEY_FPU,          /* For 'F' and 'D' */
-       RISCV_ISA_EXT_KEY_SVINVAL,
-       RISCV_ISA_EXT_KEY_MAX,
-};
+#ifndef __ASSEMBLY__
+
+#include <linux/jump_label.h>
 
 struct riscv_isa_ext_data {
        /* Name of the extension displayed to userspace via /proc/cpuinfo */
@@ -81,20 +57,40 @@ struct riscv_isa_ext_data {
        unsigned int isa_ext_id;
 };
 
-extern struct static_key_false riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_MAX];
+static __always_inline bool
+riscv_has_extension_likely(const unsigned long ext)
+{
+       compiletime_assert(ext < RISCV_ISA_EXT_MAX,
+                          "ext must be < RISCV_ISA_EXT_MAX");
+
+       asm_volatile_goto(
+       ALTERNATIVE("j  %l[l_no]", "nop", 0, %[ext], 1)
+       :
+       : [ext] "i" (ext)
+       :
+       : l_no);
+
+       return true;
+l_no:
+       return false;
+}
 
-static __always_inline int riscv_isa_ext2key(int num)
+static __always_inline bool
+riscv_has_extension_unlikely(const unsigned long ext)
 {
-       switch (num) {
-       case RISCV_ISA_EXT_f:
-               return RISCV_ISA_EXT_KEY_FPU;
-       case RISCV_ISA_EXT_d:
-               return RISCV_ISA_EXT_KEY_FPU;
-       case RISCV_ISA_EXT_SVINVAL:
-               return RISCV_ISA_EXT_KEY_SVINVAL;
-       default:
-               return -EINVAL;
-       }
+       compiletime_assert(ext < RISCV_ISA_EXT_MAX,
+                          "ext must be < RISCV_ISA_EXT_MAX");
+
+       asm_volatile_goto(
+       ALTERNATIVE("nop", "j   %l[l_yes]", 0, %[ext], 1)
+       :
+       : [ext] "i" (ext)
+       :
+       : l_yes);
+
+       return false;
+l_yes:
+       return true;
 }
 
 unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);