1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/* RISC-V architecture probe interface
Copyright (C) 2024-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#ifndef _SYS_HWPROBE_H
#define _SYS_HWPROBE_H 1
#include <features.h>
#include <sched.h>
#include <stddef.h>
#include <errno.h>
#ifdef __has_include
# if __has_include (<asm/hwprobe.h>)
# include <asm/hwprobe.h>
# endif
#endif
/* Define a (probably stale) version of the interface if the Linux headers
aren't present. */
#ifndef RISCV_HWPROBE_KEY_MVENDORID
struct riscv_hwprobe {
signed long long int key;
unsigned long long int value;
};
#define RISCV_HWPROBE_KEY_MVENDORID 0
#define RISCV_HWPROBE_KEY_MARCHID 1
#define RISCV_HWPROBE_KEY_MIMPID 2
#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
#define RISCV_HWPROBE_IMA_FD (1 << 0)
#define RISCV_HWPROBE_IMA_C (1 << 1)
#define RISCV_HWPROBE_IMA_V (1 << 2)
#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
#define RISCV_HWPROBE_EXT_ZICBOZ (1 << 6)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
#endif /* RISCV_HWPROBE_KEY_MVENDORID */
__BEGIN_DECLS
#if defined __cplusplus || !__GNUC_PREREQ (2, 7)
# define __RISCV_HWPROBE_CPUS_TYPE cpu_set_t *
#else
/* The fourth argument to __riscv_hwprobe should be a null pointer or a
pointer to a cpu_set_t (either the fixed-size type or allocated with
CPU_ALLOC). However, early versions of this header file used the
argument type unsigned long int *. The transparent union allows
the argument to be either cpu_set_t * or unsigned long int * for
compatibility. The older header file requiring unsigned long int *
can be identified by the lack of the __RISCV_HWPROBE_CPUS_TYPE macro.
In C++ and with compilers that do not support transparent unions, the
argument type must be cpu_set_t *. */
typedef union {
cpu_set_t *__cs;
unsigned long int *__ul;
} __RISCV_HWPROBE_CPUS_TYPE __attribute__ ((__transparent_union__));
# define __RISCV_HWPROBE_CPUS_TYPE __RISCV_HWPROBE_CPUS_TYPE
#endif
extern int __riscv_hwprobe (struct riscv_hwprobe *__pairs,
size_t __pair_count, size_t __cpusetsize,
__RISCV_HWPROBE_CPUS_TYPE __cpus,
unsigned int __flags)
__THROW __nonnull ((1)) __attr_access ((__read_write__, 1, 2));
/* A pointer to the __riscv_hwprobe function is passed as the second
argument to ifunc selector routines. Include a function pointer type for
convenience in calling the function in those settings. */
typedef int (*__riscv_hwprobe_t) (struct riscv_hwprobe *__pairs,
size_t __pair_count, size_t __cpusetsize,
__RISCV_HWPROBE_CPUS_TYPE __cpus,
unsigned int __flags)
__nonnull ((1)) __attr_access ((__read_write__, 1, 2));
/* Helper function usable from ifunc selectors that probes a single key. */
static __inline int
__riscv_hwprobe_one(__riscv_hwprobe_t hwprobe_func,
long long int key,
unsigned long long int *value)
{
struct riscv_hwprobe pair;
int rc;
/* Earlier versions of glibc pass NULL as the second ifunc parameter. Other C
libraries on non-Linux systems may pass +1 as this function pointer to
indicate no support. Users copying this function to exotic worlds
(non-Linux non-glibc) may want to do additional validity checks here. */
if (hwprobe_func == NULL)
return ENOSYS;
pair.key = key;
rc = hwprobe_func (&pair, 1, 0, NULL, 0);
if (rc != 0)
return rc;
if (pair.key < 0)
return ENOENT;
*value = pair.value;
return 0;
}
__END_DECLS
#endif /* sys/hwprobe.h */
|