0

This is a follow-up question for this answer.

I'm trying to read the content of ID_AA64MMFR1_EL1 register into the 64-bit variable using inline assembly:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    uint64_t foo;
    __asm volatile("mov %0, ID_AA64MMFR1_EL1" : "=r"(foo) ::);
    printf("%"PRIx64"\n", foo);
}

Note: I need to read ID_AA64MMFR1_EL1 in order to know the value of AFP field.

However, assembler rejects this code:

$ gcc t1b.c
/tmp/ccTDGH7d.s: Assembler messages:
/tmp/ccTDGH7d.s:22: Error: undefined symbol ID_AA64MMFR1_EL1 used as an immediate value

A simple question: how to do it correctly?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
pmor
  • 5,392
  • 4
  • 17
  • 36

2 Answers2

2

The mov mnemonic is only used for moves between general-purpose and/or FP/SIMD registers (x0-x30, xzr, sp, q0-q31), and for moving immediate values into general-purpose registers. Moves to and from system registers use msr and mrs respectively. So here you want mrs instead of mov.

Note that from your headers, it appears that you're doing this from a normal user-space C program. On a typical operating system, user space runs at exception level 0 (EL0). But the EL1 tag on the name of ID_AA64MMFR1_EL1 indicates that it can only be read at EL1 and higher (i.e. kernel mode). So executing this instruction will trap.

Some operating systems might handle the trap by emulating the instruction. I know Linux does this for some of the feature ID registers, but can't recall if this is one of them. However, in such a case, the value returned to your program does not necessarily equal the value actually returned by the hardware. The OS could for instance mask off bits for features that it doesn't want you to know about.

On other operating systems (e.g. MacOS if I recall correctly), your program will simply die with SIGILL.

Normally, the operating system will provide other mechanisms for querying CPU features like this. For example, Linux has /proc/cpuinfo and MacOS has sysctl.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • Re: `/proc/cpuinfo`: In the `Features` list what would be the acronym / short text for the AFP feature? Peprahs `afp`? – pmor Jun 01 '23 at 12:54
  • 1
    @pmor: Yes, looks like `afp`. https://github.com/torvalds/linux/blob/929ed21dfdb6ee94391db51c9eedb63314ef6847/arch/arm64/kernel/cpuinfo.c#L105 – Nate Eldredge Jun 01 '23 at 16:32
2

If your program is running at EL0, you should rather use the HWCAP_CPUID API available in hwcaps - more details in this article, ARM64 CPU Feature Registers. See here for a working example code.

Frant
  • 5,382
  • 1
  • 16
  • 22