[FFmpeg-devel] [PATCH 2/2] riscv: add hwprobe() for CPU detection
Rémi Denis-Courmont
remi at remlab.net
Sat Nov 18 22:16:18 EET 2023
This adds the Linux-specific system call to detect CPU features. Unlike
the auxillary vector, this supports extension other than single lettered
ones. (The API is kind of a mess though.)
At the moment, we need this to detect Zba and Zbb at run-time.
---
configure | 5 +++++
libavutil/riscv/cpu.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/configure b/configure
index 6be849fc08..a6039c1476 100755
--- a/configure
+++ b/configure
@@ -2202,6 +2202,7 @@ HAVE_LIST_PUB="
HEADERS_LIST="
arpa_inet_h
+ asm_hwprobe_h
asm_types_h
cdio_paranoia_h
cdio_paranoia_paranoia_h
@@ -2227,6 +2228,7 @@ HEADERS_LIST="
opencv2_core_core_c_h
OpenGL_gl3_h
poll_h
+ sys_hwprobe_h
sys_param_h
sys_resource_h
sys_select_h
@@ -5410,6 +5412,9 @@ elif enabled ppc; then
elif enabled riscv; then
+ check_headers asm/hwprobe.h
+ check_headers sys/hwprobe.h
+
if test_cpp_condition stddef.h "__riscv_zbb"; then
enable fast_clz
fi
diff --git a/libavutil/riscv/cpu.c b/libavutil/riscv/cpu.c
index 984293aef0..23e49767c2 100644
--- a/libavutil/riscv/cpu.c
+++ b/libavutil/riscv/cpu.c
@@ -18,8 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define _GNU_SOURCE
#include "libavutil/cpu.h"
#include "libavutil/cpu_internal.h"
+#include "libavutil/macros.h"
#include "libavutil/log.h"
#include "config.h"
@@ -27,10 +29,51 @@
#include <sys/auxv.h>
#define HWCAP_RV(letter) (1ul << ((letter) - 'A'))
#endif
+#if defined (HAVE_SYS_HWPROBE_H)
+#include <sys/hwprobe.h>
+#elif defined (HAVE_ASM_HWPROBE_H)
+#include <asm/hwprobe.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static int __riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
+ size_t cpu_count, unsigned long *cpus,
+ unsigned int flags)
+{
+ return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus,
+ flags);
+}
+#endif
int ff_get_cpu_flags_riscv(void)
{
int ret = 0;
+#if defined (HAVE_SYS_HWPROBE_H) || defined (HAVE_ASM_HWPROBE_H)
+ struct riscv_hwprobe pairs[] = {
+ { RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0 },
+ { RISCV_HWPROBE_KEY_IMA_EXT_0, 0 },
+ };
+
+ if (__riscv_hwprobe(pairs, FF_ARRAY_ELEMS(pairs), 0, NULL, 0) == 0) {
+ if (pairs[0].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA)
+ ret |= AV_CPU_FLAG_RVI;
+ if (pairs[1].value & RISCV_HWPROBE_IMA_FD)
+ ret |= AV_CPU_FLAG_RVF | AV_CPU_FLAG_RVD;
+# ifdef RISCV_HWPROBE_IMA_V
+ if (pairs[1].value & RISCV_HWPROBE_IMA_V)
+ ret |= AV_CPU_FLAG_RVV_I32 | AV_CPU_FLAG_RVV_I64
+ | AV_CPU_FLAG_RVV_F32 | AV_CPU_FLAG_RVV_F64;
+# endif
+# ifdef RISCV_HWPROBE_EXT_ZBA
+ if (pairs[1].value & RISCV_HWPROBE_EXT_ZBA)
+ ret |= AV_CPU_FLAG_RVB_ADDR;
+# endif
+# ifdef RISCV_HWPROBE_EXT_ZBB
+ if (pairs[1].value & RISCV_HWPROBE_EXT_ZBB)
+ ret |= AV_CPU_FLAG_RVB_BASIC;
+# endif
+ } else
+#endif
#if HAVE_GETAUXVAL
{
const unsigned long hwcap = getauxval(AT_HWCAP);
--
2.42.0
More information about the ffmpeg-devel
mailing list