arch/riscv/include/asm/vendor_extensions.h

Source file repositories/reference/linux-study-clean/arch/riscv/include/asm/vendor_extensions.h

File Facts

System
Linux kernel
Corpus path
arch/riscv/include/asm/vendor_extensions.h
Extension
.h
Size
3247 bytes
Lines
105
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct riscv_isavendorinfo {
	DECLARE_BITMAP(isa, RISCV_ISA_VENDOR_EXT_MAX);
};

struct riscv_isa_vendor_ext_data_list {
	bool is_initialized;
	const size_t ext_data_count;
	const struct riscv_isa_ext_data *ext_data;
	struct riscv_isavendorinfo per_hart_isa_bitmap[NR_CPUS];
	struct riscv_isavendorinfo all_harts_isa_bitmap;
};

extern struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[];

extern const size_t riscv_isa_vendor_ext_list_size;

/*
 * The alternatives need some way of distinguishing between vendor extensions
 * and errata. Incrementing all of the vendor extension keys so they are at
 * least 0x8000 accomplishes that.
 */
#define RISCV_VENDOR_EXT_ALTERNATIVES_BASE	0x8000

#define VENDOR_EXT_ALL_CPUS			-1

bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit);
#define riscv_cpu_isa_vendor_extension_available(cpu, vendor, ext)	\
	__riscv_isa_vendor_extension_available(cpu, vendor, RISCV_ISA_VENDOR_EXT_##ext)
#define riscv_isa_vendor_extension_available(vendor, ext)	\
	__riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, \
					       RISCV_ISA_VENDOR_EXT_##ext)

static __always_inline bool riscv_has_vendor_extension_likely(const unsigned long vendor,
							      const unsigned long ext)
{
	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
		return false;

	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
		return __riscv_has_extension_likely(vendor,
						    ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE);

	return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext);
}

static __always_inline bool riscv_has_vendor_extension_unlikely(const unsigned long vendor,
								const unsigned long ext)
{
	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
		return false;

	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
		return __riscv_has_extension_unlikely(vendor,
						      ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE);

	return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext);
}

static __always_inline bool riscv_cpu_has_vendor_extension_likely(const unsigned long vendor,
								  int cpu, const unsigned long ext)
{
	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
		return false;

	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
	    __riscv_has_extension_likely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
		return true;

	return __riscv_isa_vendor_extension_available(cpu, vendor, ext);
}

static __always_inline bool riscv_cpu_has_vendor_extension_unlikely(const unsigned long vendor,
								    int cpu,
								    const unsigned long ext)
{
	if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
		return false;

	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
	    __riscv_has_extension_unlikely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
		return true;

	return __riscv_isa_vendor_extension_available(cpu, vendor, ext);
}

#endif /* _ASM_VENDOR_EXTENSIONS_H */

Annotation

Implementation Notes