File Index
Files and directories
Sign in
FILE

vendor_extensions.h

File preview with syntax highlighting.

linux-6.19.14/arch/riscv/include/asm/vendor_extensions.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright 2024 Rivos, Inc
  4 */
  5
  6#ifndef _ASM_VENDOR_EXTENSIONS_H
  7#define _ASM_VENDOR_EXTENSIONS_H
  8
  9#include <asm/cpufeature.h>
 10
 11#include <linux/array_size.h>
 12#include <linux/types.h>
 13
 14/*
 15 * The extension keys of each vendor must be strictly less than this value.
 16 */
 17#define RISCV_ISA_VENDOR_EXT_MAX 32
 18
 19struct riscv_isavendorinfo {
 20	DECLARE_BITMAP(isa, RISCV_ISA_VENDOR_EXT_MAX);
 21};
 22
 23struct riscv_isa_vendor_ext_data_list {
 24	bool is_initialized;
 25	const size_t ext_data_count;
 26	const struct riscv_isa_ext_data *ext_data;
 27	struct riscv_isavendorinfo per_hart_isa_bitmap[NR_CPUS];
 28	struct riscv_isavendorinfo all_harts_isa_bitmap;
 29};
 30
 31extern struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[];
 32
 33extern const size_t riscv_isa_vendor_ext_list_size;
 34
 35/*
 36 * The alternatives need some way of distinguishing between vendor extensions
 37 * and errata. Incrementing all of the vendor extension keys so they are at
 38 * least 0x8000 accomplishes that.
 39 */
 40#define RISCV_VENDOR_EXT_ALTERNATIVES_BASE	0x8000
 41
 42#define VENDOR_EXT_ALL_CPUS			-1
 43
 44bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit);
 45#define riscv_cpu_isa_vendor_extension_available(cpu, vendor, ext)	\
 46	__riscv_isa_vendor_extension_available(cpu, vendor, RISCV_ISA_VENDOR_EXT_##ext)
 47#define riscv_isa_vendor_extension_available(vendor, ext)	\
 48	__riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, \
 49					       RISCV_ISA_VENDOR_EXT_##ext)
 50
 51static __always_inline bool riscv_has_vendor_extension_likely(const unsigned long vendor,
 52							      const unsigned long ext)
 53{
 54	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
 55		return false;
 56
 57	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
 58		return __riscv_has_extension_likely(vendor,
 59						    ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
 60
 61	return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext);
 62}
 63
 64static __always_inline bool riscv_has_vendor_extension_unlikely(const unsigned long vendor,
 65								const unsigned long ext)
 66{
 67	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
 68		return false;
 69
 70	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
 71		return __riscv_has_extension_unlikely(vendor,
 72						      ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
 73
 74	return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext);
 75}
 76
 77static __always_inline bool riscv_cpu_has_vendor_extension_likely(const unsigned long vendor,
 78								  int cpu, const unsigned long ext)
 79{
 80	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
 81		return false;
 82
 83	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
 84	    __riscv_has_extension_likely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
 85		return true;
 86
 87	return __riscv_isa_vendor_extension_available(cpu, vendor, ext);
 88}
 89
 90static __always_inline bool riscv_cpu_has_vendor_extension_unlikely(const unsigned long vendor,
 91								    int cpu,
 92								    const unsigned long ext)
 93{
 94	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
 95		return false;
 96
 97	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
 98	    __riscv_has_extension_unlikely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
 99		return true;
100
101	return __riscv_isa_vendor_extension_available(cpu, vendor, ext);
102}
103
104#endif /* _ASM_VENDOR_EXTENSIONS_H */
~/ Read-only file preview.