FILE
cpufeature.h
File preview with syntax highlighting.
linux-6.19.14/arch/riscv/include/asm/cpufeature.h
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright 2022-2024 Rivos, Inc 4 */ 5 6#ifndef _ASM_CPUFEATURE_H 7#define _ASM_CPUFEATURE_H 8 9#include <linux/bitmap.h> 10#include <linux/jump_label.h> 11#include <linux/workqueue.h> 12#include <linux/kconfig.h> 13#include <linux/percpu-defs.h> 14#include <linux/threads.h> 15#include <asm/hwcap.h> 16#include <asm/cpufeature-macros.h> 17 18/* 19 * These are probed via a device_initcall(), via either the SBI or directly 20 * from the corresponding CSRs. 21 */ 22struct riscv_cpuinfo { 23 unsigned long mvendorid; 24 unsigned long marchid; 25 unsigned long mimpid; 26}; 27 28struct riscv_isainfo { 29 DECLARE_BITMAP(isa, RISCV_ISA_EXT_MAX); 30}; 31 32DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); 33 34extern const struct seq_operations cpuinfo_op; 35 36/* Per-cpu ISA extensions. */ 37extern struct riscv_isainfo hart_isa[NR_CPUS]; 38 39extern u32 thead_vlenb_of; 40 41void __init riscv_user_isa_enable(void); 42 43#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \ 44 .name = #_name, \ 45 .property = #_name, \ 46 .id = _id, \ 47 .subset_ext_ids = _subset_exts, \ 48 .subset_ext_size = _subset_exts_size, \ 49 .validate = _validate \ 50} 51 52#define __RISCV_ISA_EXT_DATA(_name, _id) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, NULL) 53 54#define __RISCV_ISA_EXT_DATA_VALIDATE(_name, _id, _validate) \ 55 _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, _validate) 56 57/* Used to declare pure "lasso" extension (Zk for instance) */ 58#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \ 59 _RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \ 60 ARRAY_SIZE(_bundled_exts), NULL) 61#define __RISCV_ISA_EXT_BUNDLE_VALIDATE(_name, _bundled_exts, _validate) \ 62 _RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \ 63 ARRAY_SIZE(_bundled_exts), _validate) 64 65/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */ 66#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \ 67 _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), NULL) 68#define __RISCV_ISA_EXT_SUPERSET_VALIDATE(_name, _id, _sub_exts, _validate) \ 69 _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate) 70 71bool __init check_unaligned_access_emulated_all_cpus(void); 72void unaligned_access_init(void); 73int cpu_online_unaligned_access_init(unsigned int cpu); 74#if defined(CONFIG_RISCV_SCALAR_MISALIGNED) 75void unaligned_emulation_finish(void); 76bool unaligned_ctl_available(void); 77#else 78static inline bool unaligned_ctl_available(void) 79{ 80 return false; 81} 82#endif 83 84#if defined(CONFIG_RISCV_MISALIGNED) 85DECLARE_PER_CPU(long, misaligned_access_speed); 86bool misaligned_traps_can_delegate(void); 87#else 88static inline bool misaligned_traps_can_delegate(void) 89{ 90 return false; 91} 92#endif 93 94bool __init check_vector_unaligned_access_emulated_all_cpus(void); 95#if defined(CONFIG_RISCV_VECTOR_MISALIGNED) 96void check_vector_unaligned_access_emulated(struct work_struct *work __always_unused); 97DECLARE_PER_CPU(long, vector_misaligned_access); 98#endif 99 100#if defined(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS) 101DECLARE_STATIC_KEY_FALSE(fast_unaligned_access_speed_key); 102 103static __always_inline bool has_fast_unaligned_accesses(void) 104{ 105 return static_branch_likely(&fast_unaligned_access_speed_key); 106} 107#else 108static __always_inline bool has_fast_unaligned_accesses(void) 109{ 110 if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) 111 return true; 112 else 113 return false; 114} 115#endif 116 117unsigned long riscv_get_elf_hwcap(void); 118 119struct riscv_isa_ext_data { 120 const unsigned int id; 121 const char *name; 122 const char *property; 123 const unsigned int *subset_ext_ids; 124 const unsigned int subset_ext_size; 125 int (*validate)(const struct riscv_isa_ext_data *data, const unsigned long *isa_bitmap); 126}; 127 128extern const struct riscv_isa_ext_data riscv_isa_ext[]; 129extern const size_t riscv_isa_ext_count; 130extern bool riscv_isa_fallback; 131 132unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap); 133static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext) 134{ 135 compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX"); 136 137 if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && 138 __riscv_has_extension_likely(STANDARD_EXT, ext)) 139 return true; 140 141 return __riscv_isa_extension_available(hart_isa[cpu].isa, ext); 142} 143 144static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsigned long ext) 145{ 146 compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX"); 147 148 if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && 149 __riscv_has_extension_unlikely(STANDARD_EXT, ext)) 150 return true; 151 152 return __riscv_isa_extension_available(hart_isa[cpu].isa, ext); 153} 154 155#endif
~/
Read-only file preview.