Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arm processers support #96

Closed
topilski opened this issue May 24, 2017 · 22 comments
Closed

Arm processers support #96

topilski opened this issue May 24, 2017 · 22 comments

Comments

@topilski
Copy link
Contributor

topilski commented May 24, 2017

Hi, do you have some plans to support arm processors? Now i have some stubs for arm platform: https://github.com/fastogt/libcpuid

@anrieff
Copy link
Owner

anrieff commented May 24, 2017

Hi,
we should definitely add the basics that would allow people to use libcpuid on ARM and then rely on pull requests to fill up the CPU database. I only have one AArch-64-based computer, but I can try contributing at least that :)
I'll play with your fork today or tomorrow, and then maybe integrate it, or ask you to submit a pull request if all seems fine

@topilski
Copy link
Contributor Author

topilski commented May 24, 2017

Hi @anrieff you can integrate, but i using prebuilded config.h and cmake build system https://github.com/fastogt/common/tree/master/src/third-party/cpuid, some definitions i receive via cmake https://github.com/fastogt/cmake/blob/master/config.cmake , i have arm devices for testing, but i don't know which function need to implement, it will be cool if we will found how to integrate arm CPU's.

@anrieff
Copy link
Owner

anrieff commented May 24, 2017

OK, don't worry, I'll take care of the initial coding so that libcpuid successfully compiles on ARM with both autotools and CMake, and my AArch64 processor is recognized; you'll then be able to fork the ARM supported version and test on your machines and potentially produce pull requests with the additions for recognizing them properly. Details to follow here, when I make progress on this task.

@topilski
Copy link
Contributor Author

Hi @anrieff , sure will wait you, also it will be perfect have CMakeLists.txt to build/inegrate libcpuid via cmake.

@gnzlbg
Copy link

gnzlbg commented Sep 7, 2017

@anrieff any progress on this?

@anrieff
Copy link
Owner

anrieff commented Sep 8, 2017

Hey, sorry about the much delay. As you may have noted, I haven't been active here for the last few months and that's because of tremendous workload I have at my regular work. I'll be back to more regular schedule and writing new features around the end of November - sorry about overpromising and underdelivering on the ARM feature specifically :
In the interim, if anyone wants to tackle this feature request and issue PR's, I'll be happy to merge them.

@topilski
Copy link
Contributor Author

topilski commented Apr 9, 2018

Ping

@anrieff
Copy link
Owner

anrieff commented Apr 12, 2018

Haven't had time to look into this, sorry. I don't want to promise anything though, I may not be able to integrate ARM support anytime soon.

@topilski
Copy link
Contributor Author

I'm sorry, I thought we together will do this issue, in any case i will wait when you will be ready. Thank you.

@gnzlbg
Copy link

gnzlbg commented Apr 14, 2018

FYI stdsimd detect module implements run-time feature detection for ARM, AArch64, PowerPC/PPC64 and MIPS/MIPS64 on linux using getauxval with parsing /proc/self or parsing /proc/cpuinfo as fallbacks, so if you want to implement something like that here you might want to use that as inspiration. An alternative would be to have stdsimd as a dependency. You would need to wrap the macros into functions and export them, but then you can call them via C FFI.

@jeremy-rifkin
Copy link

It would be great to get an update on this

@anrieff
Copy link
Owner

anrieff commented Jan 11, 2021

Re: ways to implement this,
I'm definitely voting to do this without introducing further dependencies. After all it is just a set of #ifdefs that need not be too hard to test on Linux, Windows and OSX.
With Apple now going towards ARM it's probably the best time to push toward closing this issue.
I'm putting a calendar notification so I can look into what can be done for ARM this Saturday. Stay tuned!

@panda-saroj
Copy link

Hi, Is the ARM support integration available with the latest libcpuid?
I had built libcpuid from the current github source on AArch-64-based Raspberry Pi and Nvidia Jetson Nano.
I tried using CPU-X, which uses libcpuid and it throws the following errors on both the devices.

CPU-X:core.c:274: failed to call libcpuid (CPUID instruction is not supported)
CPU-X:core.c:1710: failed to retrieve motherboard information (fallback mode)
CPU-X:core.c:1794: failed to retrieve CPU temperature (fallback mode)
CPU-X:core.c:1820: failed to retrieve CPU voltage (fallback mode)

CPU-X works fine on Intel based computers.

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

Hello,

I am playing a little bit on my Raspberry Pi 4 Model B. I found following code: https://wiki.osdev.org/Detecting_Raspberry_Pi_Board

For information, Main ID Register, MIDR, provides identification information for the processor. Some useful links:

So I tried to build and run it:

Program received signal SIGILL, Illegal instruction.
_start () at test.c:15
15	    asm volatile ("mrc p15,0,%0,c0,c0,0" : "=r" (reg));

It does not work, because this instruction is accessible only in privileged modes.
Unlike x86, ARM does not allow to read CPU ID registers from user space.

Correct me if I am wrong, but I do not think we can provide CPU identification for the ARM architecture in libcpuid.
For x86, libcpuid relies on CPUID instruction then decodes data inside registers to identify the CPU. On ARM, if we cannot use MIDR, then we cannot implement the logic to identify CPU.
I mean, kernels can expose some information (like /proc/cpuinfo on Linux), but parsing such OS specific data is not identification IMHO.

@anrieff
Copy link
Owner

anrieff commented Nov 17, 2022

Have you tried the MRS instruction? This answer suggests they tried MRS in user-mode and it worked for some of the id registers.
It seems the CPUID procedure is different between ARMv7 and ARMv8; the former uses mrc, the later uses mrs.

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

I cannot use MRS instruction:

/tmp/ccmltbnK.s: Assembler messages:
/tmp/ccmltbnK.s:156: Error: selected processor does not support requested special purpose register -- `mrs r3,MIDR_EL1'
/tmp/ccmltbnK.s:184: Error: selected processor does not support requested special purpose register -- `mrs r3,VPIDR_EL2'
/tmp/ccmltbnK.s:212: Error: selected processor does not support requested special purpose register -- `mrs r3,REVIDR_EL1'
/tmp/ccmltbnK.s:240: Error: selected processor does not support requested special purpose register -- `mrs r3,ID_AA64ISAR0_EL1'
/tmp/ccmltbnK.s:268: Error: selected processor does not support requested special purpose register -- `mrs r3,ID_AA64ISAR1_EL1'
/tmp/ccmltbnK.s:296: Error: selected processor does not support requested special purpose register -- `mrs r3,MVFR0_EL1'
/tmp/ccmltbnK.s:324: Error: selected processor does not support requested special purpose register -- `mrs r3,MVFR1_EL1'
/tmp/ccmltbnK.s:352: Error: selected processor does not support requested special purpose register -- `mrs r3,MVFR2_EL1'

It is a ARMv7 Processor rev 3 (v7l).

I do not have ARMv8 available to me.

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

Hello, I have good and bad news.

The good new is despite having bare metal ARMv8 CPU running in AArch64 mode, I found that I can use QEMU's TCG to emulate some ARM CPUs. It works very well, I can emulate a Cortex A57 CPU to run Debian 12 and FreeBSD 14 (I cannot run Windows 11 though, VM stucks after "Press any key to boot...").
I started to play with MRS instruction on MIDR_EL1 register, I have good results:

CPU Info for type #0:
------------------
  arch       : ARM
  purpose    : general
  vendor_str : `ARM'
  vendor id  : 11
  brand_str  : `Cortex-A57'
  implementer: 65 (41h)
  arch_ver   : 15 (0Fh)
  variant    : 1 (01h)
  part_num   : 3335 (D07h)
  revision   : 0 (00h)
  num_cores  : 2
  num_logical: 2
  tot_logical: 2

What I learned about AArch64 is Exception levels: for short, libcpuid is running at EL0 while kernel is running at EL1, so in theory any software running at EL0 cannot access EL1/EL2/EL3 registers.
However, some kernels may export some EL1 registers to userspace (like MIDR_EL1), like Linux and FreeBSD (I have no idea for others OS).

And the bad new is still about EL1 registers: to decode information about caches, a cache level needs to be write in CSSELR-EL1, then CCSIDR-EL1 can be read to get current cache size, but Linux do not allow access to these registers. Some people will probably tell me that we can still harcode cache size for each CPU in the DB, but caches are optional on some CPUs (like Cortex M7) or the value can be in a range (see Arm Cortex-A Processor Comparison Table), so I do not think it is a great idea because it may reports wrong information to end users IMHO.

I hope I will be able to open a PR for review soon, I need to decode ARM CPUs features before.

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

I added initial support for ARM CPUs in c588569. Please note that only AArch64 mode (ARMv8+) is supported on OS where access to EL1 registers from userspace is trapped (Linux and FreeBSD as far as I know).
Support for AArch32 mode, older CPUs, caches information and other OS require more work. I will try to work on this, but it will require to implement kernel modules for that.

For volunteers who meet the prerequisites, feel free to build libcpuid from master, share RAW data (cpuid_tool --save=-) and provide feedback here!

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

caches information

About CCSIDR_EL1:

The parameters NumSets, Associativity, and LineSize in these registers define the architecturally visible parameters that are required for the cache maintenance by Set/Way instructions. They are not guaranteed to represent the actual microarchitectural features of a design. You cannot make any inference about the actual sizes of caches based on these parameters.

We, I guess it is explicit... Even Linux developers removed CCSIDR-based cache information probing.

TheTumultuousUnicornOfDarkness added a commit that referenced this issue Jul 7, 2024
Related to #96
Kernel modules to access AArch32 registers will be added in a separate commit.
@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

Support for AArch32 mode and older CPUs is in progress: ea9ada7.
Kernel modules are still required to extract RAW data, but I have work in progress for a Linux kernel module.

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

I updated the cpuid_get_raw_data_core() function and added an interface to interact with kernel modules in 0f0b1e6.
Also, I added the Linux kernel module in 371a964 and the FreeBSD kernel module in 0d71be9.
I updated the READMEs, you can check the ARM CPUID column in the Operating systems section to find instruction about how to build and use these modules. Please note that access to kernel devices requires privileges.

macOS and Windows are not supported yet. If someone is interested to work on this support, I will be happy to leave this task to him. The arm-cpusysregs repository provides an example with modules for macOS and Windows, it should not be that complicated to adapt the code. The tricky part is to create one dedicated device that runs on a dedicated CPU core (the MPIDR register contains the core ID, e.g. 0000000180000000 for core 0, 0000000180000001 for core 1, 0000000180000002 for core 2 and so on). Running on dedicated core is important to properly detect big.LITTLE system.
The userspace interface is in the rdcpuid.c file.
I won't be available for a few weeks, I can take a look when I get back if no one has taken care of it.

@TheTumultuousUnicornOfDarkness
Copy link
Collaborator

About macOS: it looks painful to load a kernel extension according to this. The System Integrity Protection (SIP) must be disabled if we are not registered "Apple developers".

Also, I found this deprecation notice:

Starting with macOS Big Sur, macOS releases no longer load kernel extensions that use deprecated kernel programming interfaces (KPIs) by default.

Apple is promoting system extensions as an alternative to kernel extensions, but it requires an entitlement from Apple, meaning an developer ID is required.
I do not have the motivation to dig inside the Apple ecosystem, I do not plan to invest time in a kernel/system extension for macOS.


About Windows: it tried to install Windows Insider Preview ARM64 on a QEMU VM by using CPU emulation, but I was not able to configure the system, so I cannot progress on this topic.

Anyway, Windows ARM64 runners for GitHub Actions are still not publicly available.


Since libcpuid is supporting ARM CPUs, I am closing this issue. I plan to release v0.7.0 as is, we will see if people are requesting raw data extraction on macOS/Windows systems running on ARM CPUs. Any contributors are welcome to work on such support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants