50 }
51
52 void VM_Version::get_os_cpu_info() {
53 size_t sysctllen;
54
55 // cpu_has() uses sysctlbyname function to check the existence of CPU
56 // features. References: Apple developer document [1] and XNU kernel [2].
57 // [1] https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
58 // [2] https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/kern_mib.c
59 //
60 // Note that for some features (e.g., LSE, SHA512 and SHA3) there are two
61 // parameters for sysctlbyname, which are invented at different times.
62 // Considering backward compatibility, we check both here.
63 //
64 // Floating-point and Advance SIMD features are standard in Apple processors
65 // beginning with M1 and A7, and don't need to be checked [1].
66 // 1) hw.optional.floatingpoint always returns 1 [2].
67 // 2) ID_AA64PFR0_EL1 describes AdvSIMD always equals to FP field.
68 // See the Arm ARM, section "ID_AA64PFR0_EL1, AArch64 Processor Feature
69 // Register 0".
70 _features = CPU_FP | CPU_ASIMD;
71
72 // All Apple-darwin Arm processors have AES, PMULL, SHA1 and SHA2.
73 // See https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/arm/commpage/commpage.c#L412
74 // Note that we ought to add assertions to check sysctlbyname parameters for
75 // these four CPU features, e.g., "hw.optional.arm.FEAT_AES", but the
76 // corresponding string names are not available before xnu-8019 version.
77 // Hence, assertions are omitted considering backward compatibility.
78 _features |= CPU_AES | CPU_PMULL | CPU_SHA1 | CPU_SHA2;
79
80 if (cpu_has("hw.optional.armv8_crc32")) {
81 _features |= CPU_CRC32;
82 }
83 if (cpu_has("hw.optional.arm.FEAT_LSE") ||
84 cpu_has("hw.optional.armv8_1_atomics")) {
85 _features |= CPU_LSE;
86 }
87 if (cpu_has("hw.optional.arm.FEAT_SHA512") ||
88 cpu_has("hw.optional.armv8_2_sha512")) {
89 _features |= CPU_SHA512;
90 }
91 if (cpu_has("hw.optional.arm.FEAT_SHA3") ||
92 cpu_has("hw.optional.armv8_2_sha3")) {
93 _features |= CPU_SHA3;
94 }
95
96 int cache_line_size;
97 int hw_conf_cache_line[] = { CTL_HW, HW_CACHELINE };
98 sysctllen = sizeof(cache_line_size);
99 if (sysctl(hw_conf_cache_line, 2, &cache_line_size, &sysctllen, nullptr, 0)) {
100 cache_line_size = 16;
101 }
102 _icache_line_size = 16; // minimal line length CCSIDR_EL1 can hold
103 _dcache_line_size = cache_line_size;
104
105 uint64_t dczid_el0;
106 __asm__ (
107 "mrs %0, DCZID_EL0\n"
108 : "=r"(dczid_el0)
109 );
110 if (!(dczid_el0 & 0x10)) {
111 _zva_length = 4 << (dczid_el0 & 0xf);
112 }
113
|
50 }
51
52 void VM_Version::get_os_cpu_info() {
53 size_t sysctllen;
54
55 // cpu_has() uses sysctlbyname function to check the existence of CPU
56 // features. References: Apple developer document [1] and XNU kernel [2].
57 // [1] https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
58 // [2] https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/kern_mib.c
59 //
60 // Note that for some features (e.g., LSE, SHA512 and SHA3) there are two
61 // parameters for sysctlbyname, which are invented at different times.
62 // Considering backward compatibility, we check both here.
63 //
64 // Floating-point and Advance SIMD features are standard in Apple processors
65 // beginning with M1 and A7, and don't need to be checked [1].
66 // 1) hw.optional.floatingpoint always returns 1 [2].
67 // 2) ID_AA64PFR0_EL1 describes AdvSIMD always equals to FP field.
68 // See the Arm ARM, section "ID_AA64PFR0_EL1, AArch64 Processor Feature
69 // Register 0".
70 set_feature(CPU_FP);
71 set_feature(CPU_ASIMD);
72
73 // All Apple-darwin Arm processors have AES, PMULL, SHA1 and SHA2.
74 // See https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/arm/commpage/commpage.c#L412
75 // Note that we ought to add assertions to check sysctlbyname parameters for
76 // these four CPU features, e.g., "hw.optional.arm.FEAT_AES", but the
77 // corresponding string names are not available before xnu-8019 version.
78 // Hence, assertions are omitted considering backward compatibility.
79 set_feature(CPU_AES);
80 set_feature(CPU_PMULL);
81 set_feature(CPU_SHA1);
82 set_feature(CPU_SHA2);
83
84 if (cpu_has("hw.optional.armv8_crc32")) {
85 set_feature(CPU_CRC32);
86 }
87 if (cpu_has("hw.optional.arm.FEAT_LSE") ||
88 cpu_has("hw.optional.armv8_1_atomics")) {
89 set_feature(CPU_LSE);
90 }
91 if (cpu_has("hw.optional.arm.FEAT_SHA512") ||
92 cpu_has("hw.optional.armv8_2_sha512")) {
93 set_feature(CPU_SHA512);
94 }
95 if (cpu_has("hw.optional.arm.FEAT_SHA3") ||
96 cpu_has("hw.optional.armv8_2_sha3")) {
97 set_feature(CPU_SHA3);
98 }
99
100 int cache_line_size;
101 int hw_conf_cache_line[] = { CTL_HW, HW_CACHELINE };
102 sysctllen = sizeof(cache_line_size);
103 if (sysctl(hw_conf_cache_line, 2, &cache_line_size, &sysctllen, nullptr, 0)) {
104 cache_line_size = 16;
105 }
106 _icache_line_size = 16; // minimal line length CCSIDR_EL1 can hold
107 _dcache_line_size = cache_line_size;
108
109 uint64_t dczid_el0;
110 __asm__ (
111 "mrs %0, DCZID_EL0\n"
112 : "=r"(dczid_el0)
113 );
114 if (!(dczid_el0 & 0x10)) {
115 _zva_length = 4 << (dczid_el0 & 0xf);
116 }
117
|