qemu

Форк
0
/
cpuinfo-aarch64.c 
117 строк · 3.1 Кб
1
/*
2
 * SPDX-License-Identifier: GPL-2.0-or-later
3
 * Host specific cpu identification for AArch64.
4
 */
5

6
#include "qemu/osdep.h"
7
#include "host/cpuinfo.h"
8

9
#ifdef CONFIG_LINUX
10
# ifdef CONFIG_GETAUXVAL
11
#  include <sys/auxv.h>
12
# else
13
#  include <asm/hwcap.h>
14
#  include "elf.h"
15
# endif
16
# ifndef HWCAP2_BTI
17
#  define HWCAP2_BTI 0  /* added in glibc 2.32 */
18
# endif
19
#endif
20
#ifdef CONFIG_ELF_AUX_INFO
21
#include <sys/auxv.h>
22
#endif
23
#ifdef CONFIG_DARWIN
24
# include <sys/sysctl.h>
25
#endif
26
#if defined(__OpenBSD__) && !defined(CONFIG_ELF_AUX_INFO)
27
# include <machine/armreg.h>
28
# include <machine/cpu.h>
29
# include <sys/types.h>
30
# include <sys/sysctl.h>
31
#endif
32

33
unsigned cpuinfo;
34

35
#ifdef CONFIG_DARWIN
36
static bool sysctl_for_bool(const char *name)
37
{
38
    int val = 0;
39
    size_t len = sizeof(val);
40

41
    if (sysctlbyname(name, &val, &len, NULL, 0) == 0) {
42
        return val != 0;
43
    }
44

45
    /*
46
     * We might in the future ask for properties not present in older kernels,
47
     * but we're only asking about static properties, all of which should be
48
     * 'int'.  So we shouldn't see ENOMEM (val too small), or any of the other
49
     * more exotic errors.
50
     */
51
    assert(errno == ENOENT);
52
    return false;
53
}
54
#endif
55

56
/* Called both as constructor and (possibly) via other constructors. */
57
unsigned __attribute__((constructor)) cpuinfo_init(void)
58
{
59
    unsigned info = cpuinfo;
60

61
    if (info) {
62
        return info;
63
    }
64

65
    info = CPUINFO_ALWAYS;
66

67
#if defined(CONFIG_LINUX) || defined(CONFIG_ELF_AUX_INFO)
68
    unsigned long hwcap = qemu_getauxval(AT_HWCAP);
69
    info |= (hwcap & HWCAP_ATOMICS ? CPUINFO_LSE : 0);
70
    info |= (hwcap & HWCAP_USCAT ? CPUINFO_LSE2 : 0);
71
    info |= (hwcap & HWCAP_AES ? CPUINFO_AES : 0);
72
    info |= (hwcap & HWCAP_PMULL ? CPUINFO_PMULL : 0);
73

74
    unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2);
75
    info |= (hwcap2 & HWCAP2_BTI ? CPUINFO_BTI : 0);
76
#endif
77
#ifdef CONFIG_DARWIN
78
    info |= sysctl_for_bool("hw.optional.arm.FEAT_LSE") * CPUINFO_LSE;
79
    info |= sysctl_for_bool("hw.optional.arm.FEAT_LSE2") * CPUINFO_LSE2;
80
    info |= sysctl_for_bool("hw.optional.arm.FEAT_AES") * CPUINFO_AES;
81
    info |= sysctl_for_bool("hw.optional.arm.FEAT_PMULL") * CPUINFO_PMULL;
82
    info |= sysctl_for_bool("hw.optional.arm.FEAT_BTI") * CPUINFO_BTI;
83
#endif
84
#if defined(__OpenBSD__) && !defined(CONFIG_ELF_AUX_INFO)
85
    int mib[2];
86
    uint64_t isar0;
87
    uint64_t pfr1;
88
    size_t len;
89

90
    mib[0] = CTL_MACHDEP;
91
    mib[1] = CPU_ID_AA64ISAR0;
92
    len = sizeof(isar0);
93
    if (sysctl(mib, 2, &isar0, &len, NULL, 0) != -1) {
94
        if (ID_AA64ISAR0_ATOMIC(isar0) >= ID_AA64ISAR0_ATOMIC_IMPL) {
95
            info |= CPUINFO_LSE;
96
        }
97
        if (ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_BASE) {
98
            info |= CPUINFO_AES;
99
        }
100
        if (ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_PMULL) {
101
            info |= CPUINFO_PMULL;
102
        }
103
    }
104

105
    mib[0] = CTL_MACHDEP;
106
    mib[1] = CPU_ID_AA64PFR1;
107
    len = sizeof(pfr1);
108
    if (sysctl(mib, 2, &pfr1, &len, NULL, 0) != -1) {
109
        if (ID_AA64PFR1_BT(pfr1) >= ID_AA64PFR1_BT_IMPL) {
110
            info |= CPUINFO_BTI;
111
        }
112
    }
113
#endif
114

115
    cpuinfo = info;
116
    return info;
117
}
118

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.