To-date, ARM has defined around 1500 different system registers (see their downloadable Architecture Specification Language (ASL)). I have found it tedious to read these out in Linux. Specific code has to be written for each register, those for exception levels > 0 have to be done in a kernel module, and there is no graceful way to handle the not implemented case (your program crashes, or your entire kernel panics when using a module). This can be managed for digging into a small number, but won't scale if you want to read many (or all) of them.
Moreover, most of these registers will not be implemented on your processor, some only implemented on certain cores (e.g. big vs little), and some might be there in hardware but your firmware hasn't gotten around to adding support (or has done so incorrectly).
This repo contains my efforts towards making it possible to explore system registers. Currently, this only helps with being able to read all of them, without having to crash or kernel panic on each one that is not implemented.
This is a kernel module that creates root-readable sysfs nodes under /sys/kernel/sysreg/ for every system register defined in the ASL. The register value is returned as a 64-bit hex value.
# cat /sys/kernel/sysreg/midr_el1
0x00000000410fd811
# cat /sys/kernel/sysreg/id_aa64dfr0_el1
0x100f11f010305719
and illegal instruction exceptions are returned with errno EIO
# cat /sys/kernel/sysreg/actlr_el3
cat: /sys/kernel/sysreg/actlr_el3: Bad address
For more information about how to use the sysreg_sysfs module, see its README.
The ASL contains machine-interpretable descriptions of how to parse each register. The next step is to add a CLI tool that, given a register name, reads it (using the kernel module above), and parses it into human-readable form.
There is also a lot of constraint information in the ASL that could be used to validate that the register values are legal, assert that all required features are implemented and exposed by the hardware/firmware (e.g. to look for firmware bugs).