Skip to content

Commit 8a0ce07

Browse files
committed
Updating CPU features detection for AArch64 processors
1 parent f767848 commit 8a0ce07

File tree

3 files changed

+93
-37
lines changed

3 files changed

+93
-37
lines changed

include/private/dsp/arch/aarch64/features.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#ifdef ARCH_AARCH64
2828

2929
#if defined(PLATFORM_MACOSX)
30-
// TODO: add another method to detect hardware features
30+
#define HWCAP_ASIMD (1 << 0)
3131
#elif defined(PLATFORM_POSIX)
3232
#include <sys/auxv.h>
3333
#endif /* PLATFORM_POSIX */
@@ -187,6 +187,7 @@
187187
size_t part;
188188
size_t revision;
189189
uint64_t hwcap;
190+
char cpu_name[64];
190191
} cpu_features_t;
191192

192193
void detect_cpu_features(cpu_features_t *f);

include/private/dsp/arch/arm/features.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
size_t part;
114114
size_t revision;
115115
uint64_t hwcap;
116+
char cpu_name[64];
116117
} cpu_features_t;
117118

118119
void detect_cpu_features(cpu_features_t *f);

src/main/aarch64/aarch64.cpp

Lines changed: 90 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
#include <errno.h>
3939
#include <stdlib.h>
4040

41+
// Platform-specific includes
42+
#if defined(PLATFORM_FREEBSD)
43+
#include <sys/sysctl.h>
44+
#elif defined(PLATFORM_MACOSX)
45+
#include <sys/sysctl.h>
46+
#endif
47+
4148
// Include common architectural definitions
4249
#define PRIVATE_DSP_ARCH_AARCH64_IMPL
4350
#include <private/dsp/arch/aarch64/features.h>
@@ -151,46 +158,36 @@ namespace lsp
151158
else
152159
return cpu_parts[mid].name;
153160
}
154-
return "Generic ARM processor";
161+
return "Generic AArch64 processor";
155162
}
156163

157-
void detect_cpu_features(cpu_features_t *f) // must be at least 13 bytes
164+
#ifdef PLATFORM_LINUX
165+
static void read_cpu_info(cpu_features_t *f)
158166
{
159-
f->implementer = 0;
160-
f->architecture = 0;
161-
IF_ARCH_ARM6(f->architecture = 6);
162-
IF_ARCH_ARM7(f->architecture = 7);
163-
IF_ARCH_ARM8(f->architecture = 8);
164-
f->variant = 0;
165-
f->part = 0;
166-
f->revision = 0;
167-
168-
#if defined(PLATFORM_LINUX)
169-
f->hwcap = getauxval(AT_HWCAP);
170-
#elif defined(PLATFORM_BSD)
171-
unsigned long __hwcap = 0;
172-
if (elf_aux_info(AT_HWCAP, &__hwcap, sizeof(__hwcap)) == 0)
173-
f->hwcap = __hwcap;
174-
#else
175-
f->hwcap = 0;
176-
#endif
177-
178-
// processor : 0
179-
// BogoMIPS : 38.40
180-
// Features : fp asimd evtstrm crc32 cpuid
181-
// CPU implementer : 0x41
182-
// CPU architecture: 8
183-
// CPU variant : 0x0
184-
// CPU part : 0xd03
185-
// CPU revision : 4
167+
// Example contents:
168+
// processor : 0
169+
// BogoMIPS : 38.40
170+
// Features : fp asimd evtstrm crc32 cpuid
171+
// CPU implementer : 0x41
172+
// CPU architecture: 8
173+
// CPU variant : 0x0
174+
// CPU part : 0xd03
175+
// CPU revision : 4
186176

187177
// Read /proc/cpuinfo
188178
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
189179
if (cpuinfo == NULL)
190180
return; // handle error
181+
lsp_finally {
182+
fclose(cpuinfo);
183+
};
191184

192185
size_t size = 0;
193186
char *line = NULL;
187+
lsp_finally {
188+
if (line != NULL)
189+
free(line);
190+
};
194191

195192
while (getline(&line, &size, cpuinfo) >= 0)
196193
{
@@ -238,11 +235,69 @@ namespace lsp
238235
// Store parsed value
239236
*field = value;
240237
}
238+
}
239+
#endif /* PLATFORM_LINUX */
240+
241+
#ifdef PLATFORM_MACOSX
242+
static void read_hwcap(cpu_features_t *f)
243+
{
244+
int val = 0;
245+
size_t len = sizeof(val);
246+
if (sysctlbyname("hw.optional.AdvSIMD", &val, &len, NULL, 0) == 0)
247+
{
248+
if (val != 0)
249+
f->hwcap |= HWCAP_AARCH64_ASIMD;
250+
}
251+
}
252+
253+
static void read_cpu_name(cpu_features_t *f)
254+
{
255+
size_t len = sizeof(f->cpu_name);
256+
sysctlbyname("machdep.cpu.brand_string", f->cpu_name, &len, nullptr, 0);
257+
}
258+
#endif /* PLATFORM_MACOSX */
259+
260+
#ifdef PLATFORM_FREEBSD
261+
static void read_cpu_name(cpu_features_t *f)
262+
{
263+
size_t len = sizeof(f->cpu_name);
264+
sysctlbyname("hw.model", f->cpu_name, &len, nullptr, 0);
265+
}
266+
#endif /* PLATFORM_FREEBSD */
267+
268+
void detect_cpu_features(cpu_features_t *f) // must be at least 13 bytes
269+
{
270+
f->implementer = 0;
271+
f->architecture = 0;
272+
IF_ARCH_ARM6(f->architecture = 6);
273+
IF_ARCH_ARM7(f->architecture = 7);
274+
IF_ARCH_ARM8(f->architecture = 8);
275+
f->variant = 0;
276+
f->part = 0;
277+
f->revision = 0;
278+
f->hwcap = 0;
279+
strncpy(f->cpu_name, "Generic AArch64 processor", sizeof(f->cpu_name) - 1);
280+
281+
#if defined(PLATFORM_LINUX)
282+
f->hwcap = getauxval(AT_HWCAP);
283+
read_cpu_info(f);
284+
const char *cpu_name = find_cpu_name(f->part);
285+
if (cpu_name != NULL)
286+
strncpy(f->cpu_name, cpu_name, sizeof(f->cpu_name));
287+
288+
#elif defined(PLATFORM_BSD)
289+
unsigned long __hwcap = 0;
290+
if (elf_aux_info(AT_HWCAP, &__hwcap, sizeof(__hwcap)) == 0)
291+
f->hwcap = __hwcap;
292+
read_cpu_name(f);
293+
294+
#elif defined(PLATFORM_MACOSX)
295+
read_hwcap(f);
296+
read_cpu_name(f);
297+
298+
#endif
241299

242-
// if we got here, handle error
243-
if (line != NULL)
244-
free(line);
245-
fclose(cpuinfo);
300+
f->cpu_name[sizeof(f->cpu_name) - 1] = '\0';
246301
}
247302

248303
static size_t estimate_features_size(const cpu_features_t *f)
@@ -284,7 +339,6 @@ namespace lsp
284339
cpu_features_t f;
285340
detect_cpu_features(&f);
286341

287-
const char *cpu = find_cpu_name(f.part);
288342
char *model = NULL;
289343
int n = asprintf(&model, "vendor=0x%x, architecture=%d, variant=%d, part=0x%x, revision=%d",
290344
int(f.implementer), int(f.architecture), int(f.variant), int(f.part), int(f.revision));
@@ -293,7 +347,7 @@ namespace lsp
293347

294348
size_t size = sizeof(dsp::info_t);
295349
size += strlen(ARCH_STRING) + 1;
296-
size += strlen(cpu) + 1;
350+
size += strlen(f.cpu_name) + 1;
297351
size += strlen(model) + 1;
298352
size += estimate_features_size(&f);
299353

@@ -308,7 +362,7 @@ namespace lsp
308362
res->arch = text;
309363
text = stpcpy(text, ARCH_STRING) + 1;
310364
res->cpu = text;
311-
text = stpcpy(text, cpu) + 1;
365+
text = stpcpy(text, f.cpu_name) + 1;
312366
res->model = text;
313367
text = stpcpy(text, model) + 1;
314368
res->features = text;

0 commit comments

Comments
 (0)