File Index
Files and directories
Sign in
FILE

cpufeature.h

File preview with syntax highlighting.

linux-6.19.14/arch/riscv/include/asm/cpufeature.h C
  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.