Closed alistair23 closed 4 years ago
The CSR is encoded as an immediate, so it must be a value statically known at compile-time. Thus, closing as expected behavior.
So the plan is to never allow accessing them without hard coding the assembly?
Well, "hard coding the assembly" is what a compiler does. Otherwise this would require generating or modifying machine code at runtime, which is something much more complex than inline assembly (IIRC GCC does it for a GNU C extension, breaking non-executable stacks in the process).
I was hoping we could have something like:
fn read_csr(csr_num: usize) -> u32 {
let r: u32;
unsafe { asm!("csrr {rd}, {csr}", rd = out(reg) r, csr = csr_num) }
r
}
Then the calls to the function would produce assembly like this:
read_csr(0x10)
which generates: csrr a0, 0x10
read_csr(0x20)
which generates: csrr a0, 0x20
I see what you mean though that it would then be possible to have: read_csr(user_input * 10)
which would require run-time generating of the instruction. Is it possible to force the input to be known at compile time?
Otherwise we would have to handwrite something like this:
fn read_csr(csr_num: usize) -> u32 {
let r: u32;
if csr_num == 0x10 {
unsafe { asm!("csrr {rd}, {csr}", rd = out(reg) r, csr = 0x10) }
} else if csr_num == 0x20 {
unsafe { asm!("csrr {rd}, {csr}", rd = out(reg) r, csr = 0x20) }
}
r
}
I'm not sure, but I can suggest asking questions on https://users.rust-lang.org/. Maybe using a trait with an associated const works?
@alistair23 I've got a proposal somewhere for LLVM and Clang builtins which would support this (as long as you can get LLVM to compile down the csr identifier to a constant). The path to upstreaming them probably involves a proper proposal to sw-dev though, and agreement on the intrinsic names.
With the new inline assembly it would be nice to be able to read/write from a RISC-V CSR, where the CSR value is passed in via a function argument (or some other means).
Currently there is no way to access the CSR without hard coding the address in the assembly.
const
I tried this code:
Which results in this error:
in(reg)
I have tried this code:
Which results in this error:
in(csr)
and I have tried this code:
Which results in this error:
Obviously all of the above are incorrect as defined in the RFC, so that is fine.
It would be great if there is either a
in(csr)
option or theconst
option is expanded to allow non-consts (maybe anum
option or something).This seems like a common usecase to have a
read_csr(csr_num: usize) -> u32
function that can read a CSR value from a number passed in.Meta
rustc --version --verbose
:Backtrace
```
```