Skip to content

Commit

Permalink
Updating CPU features detection for AArch64 processors
Browse files Browse the repository at this point in the history
  • Loading branch information
sadko4u committed Nov 30, 2024
1 parent f767848 commit 6d98611
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 36 deletions.
3 changes: 2 additions & 1 deletion include/private/dsp/arch/aarch64/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#ifdef ARCH_AARCH64

#if defined(PLATFORM_MACOSX)
// TODO: add another method to detect hardware features
#define HWCAP_ASIMD (1 << 0)
#elif defined(PLATFORM_POSIX)
#include <sys/auxv.h>
#endif /* PLATFORM_POSIX */
Expand Down Expand Up @@ -187,6 +187,7 @@
size_t part;
size_t revision;
uint64_t hwcap;
char cpu_name[64];
} cpu_features_t;

void detect_cpu_features(cpu_features_t *f);
Expand Down
1 change: 1 addition & 0 deletions include/private/dsp/arch/arm/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
size_t part;
size_t revision;
uint64_t hwcap;
char cpu_name[64];
} cpu_features_t;

void detect_cpu_features(cpu_features_t *f);
Expand Down
117 changes: 82 additions & 35 deletions src/main/aarch64/aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,43 +154,33 @@ namespace lsp
return "Generic ARM processor";
}

void detect_cpu_features(cpu_features_t *f) // must be at least 13 bytes
#ifdef PLATFORM_LINUX
static void read_cpu_info(cpu_features_t *f)
{
f->implementer = 0;
f->architecture = 0;
IF_ARCH_ARM6(f->architecture = 6);
IF_ARCH_ARM7(f->architecture = 7);
IF_ARCH_ARM8(f->architecture = 8);
f->variant = 0;
f->part = 0;
f->revision = 0;

#if defined(PLATFORM_LINUX)
f->hwcap = getauxval(AT_HWCAP);
#elif defined(PLATFORM_BSD)
unsigned long __hwcap = 0;
if (elf_aux_info(AT_HWCAP, &__hwcap, sizeof(__hwcap)) == 0)
f->hwcap = __hwcap;
#else
f->hwcap = 0;
#endif

// processor : 0
// BogoMIPS : 38.40
// Features : fp asimd evtstrm crc32 cpuid
// CPU implementer : 0x41
// CPU architecture: 8
// CPU variant : 0x0
// CPU part : 0xd03
// CPU revision : 4
// Example contents:
// processor : 0
// BogoMIPS : 38.40
// Features : fp asimd evtstrm crc32 cpuid
// CPU implementer : 0x41
// CPU architecture: 8
// CPU variant : 0x0
// CPU part : 0xd03
// CPU revision : 4

// Read /proc/cpuinfo
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
if (cpuinfo == NULL)
return; // handle error
lsp_finally {
fclose(cpuinfo);
};

size_t size = 0;
char *line = NULL;
lsp_finally {
if (line != NULL)
free(line);
};

while (getline(&line, &size, cpuinfo) >= 0)
{
Expand Down Expand Up @@ -238,11 +228,69 @@ namespace lsp
// Store parsed value
*field = value;
}
}
#endif /* PLATFORM_LINUX */

// if we got here, handle error
if (line != NULL)
free(line);
fclose(cpuinfo);
#ifdef PLATFORM_MACOSX
static void read_hwcap(cpu_features_t *f)
{
int val = 0;
size_t len = sizeof(val);
if (sysctlbyname("hw.optional.AdvSIMD", &val, &len, nullptr, 0) == 0)
{
if (val != 0)
f->hwcap |= HWCAP_AARCH64_ASIMD;
}
}

static void read_cpu_name(cpu_features_t *f)
{
int val = 0;
size_t len = sizeof(val);
sysctlbyname("machdep.cpu.brand_string", f->cpu_name, sizeof(f->cpu_name), nullptr, 0);
}
#endif /* PLATFORM_MACOSX */

#ifdef PLATFORM_FREEBSD
static void read_cpu_name(cpu_features_t *f)
{
int val = 0;
size_t len = sizeof(val);
sysctlbyname("hw.model", f->cpu_name, sizeof(f->cpu_name), nullptr, 0);
}
#endif /* PLATFORM_FREEBSD */

void detect_cpu_features(cpu_features_t *f) // must be at least 13 bytes
{
f->implementer = 0;
f->architecture = 0;
IF_ARCH_ARM6(f->architecture = 6);
IF_ARCH_ARM7(f->architecture = 7);
IF_ARCH_ARM8(f->architecture = 8);
f->variant = 0;
f->part = 0;
f->revision = 0;
f->hwcap = 0;
strncpy(f->cpu_name, "Generic ARM processor", sizeof(f->cpu_name));

#if defined(PLATFORM_LINUX)
f->hwcap = getauxval(AT_HWCAP);
read_cpu_info(f);
const char *cpu_name = find_cpu_name(f->part);
if (cpu_name != NULL)
strncpy(f->cpu_name, cpu_name, sizeof(f->cpu_name));

#elif defined(PLATFORM_BSD)
unsigned long __hwcap = 0;
if (elf_aux_info(AT_HWCAP, &__hwcap, sizeof(__hwcap)) == 0)
f->hwcap = __hwcap;
read_cpu_name(f);

#elif defined(PLATFORM_MACOSX)
read_hwcap(f);
read_cpu_name(f);

#endif
}

static size_t estimate_features_size(const cpu_features_t *f)
Expand Down Expand Up @@ -284,7 +332,6 @@ namespace lsp
cpu_features_t f;
detect_cpu_features(&f);

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

size_t size = sizeof(dsp::info_t);
size += strlen(ARCH_STRING) + 1;
size += strlen(cpu) + 1;
size += strlen(f.cpu_name) + 1;
size += strlen(model) + 1;
size += estimate_features_size(&f);

Expand All @@ -308,7 +355,7 @@ namespace lsp
res->arch = text;
text = stpcpy(text, ARCH_STRING) + 1;
res->cpu = text;
text = stpcpy(text, cpu) + 1;
text = stpcpy(text, f.cpu_name) + 1;
res->model = text;
text = stpcpy(text, model) + 1;
res->features = text;
Expand Down

0 comments on commit 6d98611

Please sign in to comment.