cpu_features icon indicating copy to clipboard operation
cpu_features copied to clipboard

Add support for riscv64?

Open yuzibo opened this issue 2 years ago • 14 comments

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:)

yuzibo avatar Jul 11 '22 02:07 yuzibo

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

toor1245 avatar Jul 11 '22 17:07 toor1245

@yuzibo Which board have you used? I would need this information to add a test

DaniAffCH avatar Aug 15 '22 10:08 DaniAffCH

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

yuzibo avatar Aug 15 '22 12:08 yuzibo

More info about Unmatched board is here: https://www.sifive.com/boards/hifive-unmatched The machines from plct is the same

yuzibo avatar Aug 15 '22 14:08 yuzibo

Thanks a lot! @yuzibo

DaniAffCH avatar Aug 15 '22 14:08 DaniAffCH

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;
}

toor1245 avatar Aug 15 '22 15:08 toor1245

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 avatar Aug 15 '22 15:08 yuzibo

@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

toor1245 avatar Aug 15 '22 15:08 toor1245

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;
}

yuzibo avatar Aug 15 '22 15:08 yuzibo

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.

michael-roe avatar Aug 15 '22 19:08 michael-roe

@yuzibo thank you! This is the expected result, but it was necessary to check

toor1245 avatar Aug 15 '22 19:08 toor1245

@michael-roe, what advantages of using fdt compared with proc/cpuinfo or hwcap? Since we have stable functionality to parse via these features

toor1245 avatar Aug 15 '22 19:08 toor1245

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

michael-roe avatar Aug 16 '22 12:08 michael-roe

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.

michael-roe avatar Aug 18 '22 10:08 michael-roe