1*cb14a3feSDimitry Andric#include <zircon/features.h>
2*cb14a3feSDimitry Andric#include <zircon/syscalls.h>
3*cb14a3feSDimitry Andric
4*cb14a3feSDimitry Andricvoid __init_cpu_features_resolver() {
5*cb14a3feSDimitry Andric  if (__aarch64_cpu_features.features)
6*cb14a3feSDimitry Andric    return;
7*cb14a3feSDimitry Andric
8*cb14a3feSDimitry Andric    // This ensures the vDSO is a direct link-time dependency of anything that
9*cb14a3feSDimitry Andric    // needs this initializer code.
10*cb14a3feSDimitry Andric#pragma comment(lib, "zircon")
11*cb14a3feSDimitry Andric  uint32_t features;
12*cb14a3feSDimitry Andric  zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features);
13*cb14a3feSDimitry Andric  if (status != ZX_OK)
14*cb14a3feSDimitry Andric    return;
15*cb14a3feSDimitry Andric
16*cb14a3feSDimitry Andric#define setCPUFeature(cpu_feature)                                             \
17*cb14a3feSDimitry Andric  __aarch64_cpu_features.features |= 1ULL << cpu_feature
18*cb14a3feSDimitry Andric
19*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_FP)
20*cb14a3feSDimitry Andric    setCPUFeature(FEAT_FP);
21*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_ASIMD)
22*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SIMD);
23*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_AES)
24*cb14a3feSDimitry Andric    setCPUFeature(FEAT_AES);
25*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_PMULL)
26*cb14a3feSDimitry Andric    setCPUFeature(FEAT_PMULL);
27*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_SHA1)
28*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SHA1);
29*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_SHA256)
30*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SHA2);
31*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_CRC32)
32*cb14a3feSDimitry Andric    setCPUFeature(FEAT_CRC);
33*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_RDM)
34*cb14a3feSDimitry Andric    setCPUFeature(FEAT_RDM);
35*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_SHA3)
36*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SHA3);
37*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_SM4)
38*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SM4);
39*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_DP)
40*cb14a3feSDimitry Andric    setCPUFeature(FEAT_DOTPROD);
41*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_FHM)
42*cb14a3feSDimitry Andric    setCPUFeature(FEAT_FP16FML);
43*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_SHA512)
44*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SHA3);
45*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_I8MM)
46*cb14a3feSDimitry Andric    setCPUFeature(FEAT_I8MM);
47*cb14a3feSDimitry Andric  if (features & ZX_ARM64_FEATURE_ISA_SVE)
48*cb14a3feSDimitry Andric    setCPUFeature(FEAT_SVE);
49*cb14a3feSDimitry Andric
50*cb14a3feSDimitry Andric  setCPUFeature(FEAT_INIT);
51*cb14a3feSDimitry Andric}
52