Skip to content

Commit

Permalink
expose aarch64 CPU identifiers from midr_el1
Browse files Browse the repository at this point in the history
Summary:
This uses the official table from [Arm themselves](https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/MIDR-EL1--Main-ID-Register) to translate implementer names.

However, since variant & partnum are implementation-defined, we don't have a standard human-readable string for them. Instead, expose the raw value and let higher layers deal with it.

Reviewed By: ricklavoie

Differential Revision: D57508976

fbshipit-source-id: 844f17d5812a49d7bb10a8bd318b6eacf7c5408c
  • Loading branch information
rahulg authored and facebook-github-bot committed May 18, 2024
1 parent 9001bd2 commit 13c9e6f
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions hphp/util/process-cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <assert.h>
#include <cstring>

#include <folly/Format.h>
#include <sys/wait.h>
#include <unistd.h>

Expand Down Expand Up @@ -50,6 +51,43 @@ static ALWAYS_INLINE void do_cpuid(int func, uint32_t* p) {
}
#endif

#ifdef __aarch64__
std::string aarch64ImplementerName(uint8_t implementer) {
switch (implementer) {
case 0x00:
return "Reserved";
case 0x41:
return "Arm Limited";
case 0x42:
return "Broadcom Corporation";
case 0x43:
return "Cavium Inc";
case 0x44:
return "Digital Equipment Corporation";
case 0x46:
return "Fujitsu Ltd";
case 0x49:
return "Infineon Technologies AG";
case 0x4D:
return "Motorola or Freescale Semiconductor Inc";
case 0x4E:
return "NVIDIA Corporation";
case 0x50:
return "Applied Micro Circuits Corporation";
case 0x51:
return "Qualcomm Inc";
case 0x56:
return "Marvell International Ltd";
case 0x69:
return "Intel Corporation";
case 0xC0:
return "Ampere Computing";
default:
return folly::sformat("Unknown aarch64 0x{:02X}", implementer);
}
}
#endif

std::string Process::GetCPUModel() {
#if defined(__x86_64__) || defined(_M_X64)
uint32_t regs[4];
Expand Down Expand Up @@ -77,6 +115,24 @@ std::string Process::GetCPUModel() {
assert(brand - cpu_brand < sizeof(cpu_brand));
return cpu_brand;

#elif defined(__aarch64__)

uint64_t midr_el1;
asm volatile ("mrs %0, midr_el1" : "=r" (midr_el1) : : );

// top 32 bits are reserved
uint8_t implementer = (midr_el1 >> 24) & 0xFF;
uint8_t variant = (midr_el1 >> 20) & 0x0F;
uint16_t partnum = (midr_el1 >> 4) & 0x0FFF;
uint8_t revision = midr_el1 & 0x0F;

std::string model = folly::sformat("{} 0x{:01X} 0x{:03X} 0x{:01X}",
aarch64ImplementerName(implementer),
variant,
partnum,
revision);
return model;

#else
// On non-x64, fall back to calling uname
std::string model = "Unknown ";
Expand Down

0 comments on commit 13c9e6f

Please sign in to comment.