| 372 | } |
| 373 | |
| 374 | CpuInfo CpuInfo::build() |
| 375 | { |
| 376 | #if !defined(_WIN64) && !defined(BARE_METAL) && !defined(__APPLE__) && !defined(__OpenBSD__) && \ |
| 377 | !defined(__FreeBSD__) && !defined(__QNX__) && (defined(__arm__) || defined(__aarch64__)) |
| 378 | const uint64_t hwcaps = getauxval(AT_HWCAP); |
| 379 | const uint64_t hwcaps2 = getauxval(AT_HWCAP2); |
| 380 | const uint32_t max_cpus = get_max_cpus(); |
| 381 | |
| 382 | // Populate midr values |
| 383 | std::vector<uint32_t> cpus_midr; |
| 384 | if (hwcaps & ARM_COMPUTE_CPU_FEATURE_HWCAP_CPUID) |
| 385 | { |
| 386 | cpus_midr = midr_from_cpuid(max_cpus); |
| 387 | } |
| 388 | if (cpus_midr.empty()) |
| 389 | { |
| 390 | cpus_midr = midr_from_proc_cpuinfo(max_cpus); |
| 391 | } |
| 392 | if (cpus_midr.empty()) |
| 393 | { |
| 394 | cpus_midr.resize(max_cpus, 0); |
| 395 | } |
| 396 | |
| 397 | // Populate isa (Assume homogeneous ISA specification) |
| 398 | CpuIsaInfo isa = init_cpu_isa_from_hwcaps(hwcaps, hwcaps2, cpus_midr.back()); |
| 399 | |
| 400 | // Convert midr to models |
| 401 | std::vector<CpuModel> cpus_model; |
| 402 | std::transform(std::begin(cpus_midr), std::end(cpus_midr), std::back_inserter(cpus_model), |
| 403 | [](uint32_t midr) -> CpuModel { return midr_to_model(midr); }); |
| 404 | |
| 405 | CpuInfo info(isa, cpus_model); |
| 406 | return info; |
| 407 | #elif defined(__arm__) && \ |
| 408 | (defined(__OpenBSD__) || \ |
| 409 | defined( \ |
| 410 | __FreeBSD__)) /* if !defined(_WIN64) && !defined(BARE_METAL) && !defined(__APPLE__) && !defined(__OpenBSD__) && |
| 411 | !defined(__FreeBSD__) && !defined(__QNX__) && (defined(__arm__) || defined(__aarch64__)) */ |
| 412 | int mib[2] = {0, 0}; |
| 413 | int ncpu = {1}; |
| 414 | size_t len = sizeof(ncpu); |
| 415 | mib[0] = CTL_HW; |
| 416 | mib[1] = HW_NCPU; |
| 417 | if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) |
| 418 | { |
| 419 | // if the system call fails we set number of cpus to 1 |
| 420 | ncpu = 1; |
| 421 | } |
| 422 | CpuIsaInfo isainfo; |
| 423 | std::vector<CpuModel> cpus_model(ncpu); |
| 424 | isainfo.neon = true; |
| 425 | CpuInfo info(isainfo, cpus_model); |
| 426 | return info; |
| 427 | #elif (BARE_METAL) && \ |
| 428 | defined(__aarch64__) /* #elif defined(__arm__) && (defined(__OpenBSD__) || defined(__FreeBSD__)) */ |
| 429 | |
| 430 | // Assume single CPU in bare metal mode. Just read the ID register and feature bits directly. |
| 431 | uint64_t isar0 = 0, isar1 = 0, pfr0 = 0, pfr1 = 0, svefr0 = 0, smefr0 = 0, midr = 0; |
no test coverage detected