host_cpu_feature_supported() is the generic method which
dispatch to the host accelerator implementation, taking
care to cache supported features.

Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
---
 target/arm/cpu.h          | 11 +++++++++++
 target/arm/arm_hw_accel.c | 27 +++++++++++++++++++++++++++
 target/arm/meson.build    |  2 +-
 3 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 target/arm/arm_hw_accel.c

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 5136c4caabf..aff60cef6da 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2508,6 +2508,16 @@ static inline ARMSecuritySpace arm_secure_to_space(bool 
secure)
 
 #if !defined(CONFIG_USER_ONLY)
 
+/**
+ * host_cpu_feature_supported:
+ * @feat: Feature to test for support
+ * @can_emulate: Whether Allow to fall back to emulation if @feat is not
+ *               supported by hardware accelerator
+ *
+ * Hardware accelerator implementation of cpu_feature_supported().
+ */
+bool host_cpu_feature_supported(enum arm_features feature, bool can_emulate);
+
 /**
  * arm_hw_accel_cpu_feature_supported:
  * @feat: Feature to test for support
@@ -2515,6 +2525,7 @@ static inline ARMSecuritySpace arm_secure_to_space(bool 
secure)
  *               supported by hardware accelerator
  *
  * Hardware accelerator implementation of cpu_feature_supported().
+ * Common code should use the generic host_cpu_feature_supported() equivalent.
  */
 bool arm_hw_accel_cpu_feature_supported(enum arm_features feat,
                                         bool can_emulate);
diff --git a/target/arm/arm_hw_accel.c b/target/arm/arm_hw_accel.c
new file mode 100644
index 00000000000..3a8ff007599
--- /dev/null
+++ b/target/arm/arm_hw_accel.c
@@ -0,0 +1,27 @@
+/*
+ * QEMU helpers for ARM hardware accelerators
+ *
+ *  Copyright (c) Linaro
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+bool host_cpu_feature_supported(enum arm_features feat, bool can_emulate)
+{
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
+    static enum { F_UNKN, F_SUPP, F_UNSUPP } supported[64] = { };
+
+    assert(feat < ARRAY_SIZE(supported));
+    if (supported[feat] == F_UNKN) {
+        supported[feat] = arm_hw_accel_cpu_feature_supported(feat, 
can_emulate);
+    }
+    return supported[feat] == F_SUPP;
+#elif defined(CONFIG_TCG)
+    return can_emulate;
+#else
+#error
+#endif
+}
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 07d9271aa4d..37718c85666 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -11,7 +11,7 @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
 arm_system_ss = ss.source_set()
 arm_common_system_ss = ss.source_set()
 arm_system_ss.add(files(
-  'arm-qmp-cmds.c',
+  'arm-qmp-cmds.c', 'arm_hw_accel.c',
 ))
 arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
 arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
-- 
2.49.0


Reply via email to