cpu_features
cpu_features copied to clipboard
Add support for riscv64?
Hi, Do we have a plan to support riscv64? I am willing to do it but maybe need your help. I am stuck on how to define RiscvFeatures struct:
cat /proc/cpuinfo
processor : 0
hart : 2
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
processor : 1
hart : 1
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
processor : 2
hart : 3
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
processor : 3
hart : 4
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
I have a real riscv64 hardware by hand:)
Since riscv cpu identification instructions can only be performed in M-mode. Machine level is the highest level and as far as I understand we can't even run it in userland so the best approach is to parse proc/cpuinfo see Linux implementation https://github.com/google/cpu_features/blob/main/src/impl_x86_linux_or_android.c and the same approach we can use for FreeBSD https://github.com/google/cpu_features/blob/main/src/impl_x86_freebsd.c. if I'm not mistaken macOS and Windows don't support riscv
@yuzibo Which board have you used? I would need this information to add a test
Hi, @DaniAffCH Thanks for working on that. My locally real riscv64 hardware is Unmatched boards.
Linux unmatched 5.18.0-2-riscv64 #1 SMP Debian 5.18.5-1 (2022-06-16) riscv64 GNU/Linux
So how can I help you to do test? Or: You can apply for access to Unmatched boards' resources from here: https://github.com/plctlab/riscv-lab-access Any issue please let me know, thanks
More info about Unmatched board is here: https://www.sifive.com/boards/hifive-unmatched The machines from plct is the same
Thanks a lot! @yuzibo
Hi @yuzibo, I'm wondering if we can run M-mode code in userspace as is the case with aarch64 for Linux.
Could you run the code under Linux riscv to see if you are getting an illegal instruction or some result, please?
#include <stdio.h>
static unsigned long cpuid()
{
unsigned long res;
asm ("csrr %0, mcpuid" : "=r"(res));
return res;
}
int main() {
unsigned long mcpuid = cpuid();
printf("mcpuid: %lu", mcpuid);
return 0;
}
Oops:
vimer@unmatched:~/build/cpu$ gcc -g get_cpuid.c -o test
get_cpuid.c: Assembler messages:
get_cpuid.c:12: Error: unknown CSR `mcpuid'
@yuzibo, probably mcpuid is deprecated, could you replace mcpuid
to misa
, please?
https://five-embeddev.com/riscv-isa-manual/latest/machine.html#machine
example:
https://github.com/five-embeddev/riscv-csr-access/blob/master/include/riscv-csr.h
It can be compiled but fail on runtime:
vimer@unmatched:~/build/cpu$ gcc -g get_cpuid.c -o test
vimer@unmatched:~/build/cpu$ ./test
Illegal instruction
vimer@unmatched:~/build/cpu$ cat get_cpuid.c
#include <stdio.h>
static unsigned long cpuid()
{
unsigned long res;
__asm__ volatile ("csrr %0, misa" : "=r"(res));
return res;
}
int main() {
unsigned long misa = cpuid();
printf("misa: %lu", misa);
return 0;
}
I think the right way to do this is that the kernel reads the FDT from the boot rom, and uses that to work out which extensions the CPU supports. Then userspace parses /proc/cpuinfo or uses hwcap.h.
There are extensions that aren't in CSR's, and have to be determined from the FDT.
@yuzibo thank you! This is the expected result, but it was necessary to check
@michael-roe, what advantages of using fdt compared with proc/cpuinfo
or hwcap
? Since we have stable functionality to parse via these features
User space programs (which includes cpu_features) ought to use proc/cpuinfo and/or hwcap.
But the part of the Linux kernel that creates /proc/cpuinfo (and, probably, hwcap) looks at the FDT to work out which options the CPU supports. Some of the information can't be derived just from cpu status registers.
So the basic flow is:
a) kernel reads the FDT from the boot rom, works out what options are supported and saves this info somewhere b) cpu_features tries to read /proc/cpuinfo c) kernel remembers the answer from step (a), and returns this in text form as the result of the read of /proc/cpuinfo d) cpu_features parses the text it got from /proc/cpuinfo
See https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/cpufeature.c for the part of the Linux kernel that works out which ISA features are supported.
What I think is happening here is that it's getting the information from the FDT.