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

riscv-rt: Implement FPU initialization #157

Closed
Disasm opened this issue Mar 5, 2019 · 14 comments · Fixed by #166
Closed

riscv-rt: Implement FPU initialization #157

Disasm opened this issue Mar 5, 2019 · 14 comments · Fixed by #166

Comments

@Disasm
Copy link
Member

Disasm commented Mar 5, 2019

No description provided.

@laanwj
Copy link
Contributor

laanwj commented Jul 27, 2019

What kind of FPU initialization would be expected on RISC-V?

@Disasm
Copy link
Member Author

Disasm commented Jul 27, 2019

Something like this: rust-embedded/riscv-rt@3a76c3b (and optionally zeroing all of the FPU registers).
The problem is that fcsr::clear_flags(); part doesn't work on K210, that's why I reverted that commit. IIRC instead of accessing the FPU CSRs they use single instruction to clear CSR.

@laanwj
Copy link
Contributor

laanwj commented Jul 29, 2019

This is what lib/bsp/crt.S does:

  li t0, MSTATUS_FS
  csrs mstatus, t0

  fssr    x0
  fmv.w.x f0, x0
  fmv.w.x f1, x0
  fmv.w.x f2, x0
  fmv.w.x f3, x0
  fmv.w.x f4, x0
  fmv.w.x f5, x0
  fmv.w.x f6, x0
  fmv.w.x f7, x0
  fmv.w.x f8, x0
  fmv.w.x f9, x0
  fmv.w.x f10,x0
  fmv.w.x f11,x0
  fmv.w.x f12,x0
  fmv.w.x f13,x0
  fmv.w.x f14,x0
  fmv.w.x f15,x0
  fmv.w.x f16,x0
  fmv.w.x f17,x0
  fmv.w.x f18,x0
  fmv.w.x f19,x0
  fmv.w.x f20,x0
  fmv.w.x f21,x0
  fmv.w.x f22,x0
  fmv.w.x f23,x0
  fmv.w.x f24,x0
  fmv.w.x f25,x0
  fmv.w.x f26,x0
  fmv.w.x f27,x0
  fmv.w.x f28,x0
  fmv.w.x f29,x0
  fmv.w.x f30,x0
  fmv.w.x f31,x0

So as I understand:

  • This enabled the floating point registers by enabling the FS bit in MSTATUS
  • I was not able to find the fssr instruction in any of the spec documents, but I know it sets the control word. By setting it to zero this selects the default rounding mode of RNE Round to Nearest, ties to Even.
  • Afer that, it zeros all the floating point registers

So yes, they use an instruction instead of CSR access. Interesting (but annoying) that accessing the control word through csr instructions doesn't work on K210.

Looks like this is going to need a function implemented in a .s file, then, especially to clear the registers. And/or inline assembly.

I've wondered at times: why is inline assembly an optional feature?

@Disasm
Copy link
Member Author

Disasm commented Jul 29, 2019

Looks like this is going to need a function implemented in a .s file, then, especially to clear the registers. And/or inline assembly.

Yes, something like that.

I've wondered at times: why is inline assembly an optional feature?

Inline assembly unstable AFAIK, so if you want to build this on stable, you have to use a different approach (such as pre-compiled asm functions or ThinLTO)

@laanwj
Copy link
Contributor

laanwj commented Jul 29, 2019

Inline assembly unstable AFAIK, so if you want to build this on stable, you have to use a different approach (such as pre-compiled asm functions or ThinLTO)

Oh right (rust-lang/rust#29722), thanks, had thought it would be stable by now, but even the syntax is still under discussion.

@laanwj
Copy link
Contributor

laanwj commented Jul 29, 2019

Okay, I didn't know this, but apparentlyfssr and friends are simply pseudo-instructions that map to CSR access: riscv/riscv-isa-manual#419

00301073          fssr    zero
00301073          fscsr         zero,zero
00301073          csrrw         zero,fcsr,zero
00301073          csrrw         zero,0x003,zero

I really wonder what causes the K210 issue now.

@Disasm
Copy link
Member Author

Disasm commented Jul 29, 2019

I don't remember exactly, but I think I accessed only one half of the CSR (there are frm and fflag CSRs for this), maybe this was a problem.

@kristate
Copy link

kristate commented Feb 7, 2020

Hello from the future, did this ever get cleared-up?

@laanwj
Copy link
Contributor

laanwj commented Feb 7, 2020

Well you are from the future, you should know! 😄

But no—it's still an open issue.
It seems on Kendryte K210, floating point works without this kind of initialization (maybe because the bootrom takes care of it). I don't think we have Rust on any other RISC-V SoCs with floating point to compare.

@luojia65
Copy link
Contributor

@romancardenas
Copy link
Contributor

Hi from the future! inline assembly is already stable and I opened a PR (#118). So thanks to inline assembly we can start to attend to these old issues :)

@romancardenas romancardenas transferred this issue from rust-embedded/riscv-rt Nov 28, 2023
@romancardenas romancardenas changed the title Implement FPU initialization riscv-rt: Implement FPU initialization Nov 28, 2023
@mini-ninja-64
Copy link
Contributor

mini-ninja-64 commented Dec 6, 2023

I am happy to have a go at implementing this, what would be the preferred approach for setting FPU as enabled?

a piece of config similar to the m-mode / s-mode switch that the crate currently uses, or something more like if in m-mode use misa to auto detect FPU presence?

I feel like I read somewhere before misa should be avoided in favour of device tree for most things so maybe it would not make sense to use it for this 🤔, especially as in s-mode we would have to call opensbi or something wierd like that for reading misa before setting the fs bit in sstatus.

@romancardenas
Copy link
Contributor

If your target supports the f extension, you could use a configuration gate like #[cfg(riscvf)] (check this).

We do something similar here for targets supporting integer multiplication.

@mini-ninja-64
Copy link
Contributor

Perfect thankyou!!! ❤️

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

Successfully merging a pull request may close this issue.

6 participants