Add boot_argument(), returns the value an a* register had at boot time#94
Add boot_argument(), returns the value an a* register had at boot time#94SimonSapin wants to merge 4 commits into
a* register had at boot time#94Conversation
|
This unconditionally reserves 8 * XLEN in |
Disasm
left a comment
There was a problem hiding this comment.
This will not work well in multi-core environments since multiple cores will execute the same code at the same time. If different argument values are passed on different cores, we will get garbage in the end.
|
I checked binary sizes and this PR adds 44 bytes of code for |
This avoids a data race on multicore
|
I’d added a branch on hartid that I believe should fix the multicore issue. What does the source code look like for passing to main in your comparison? |
|
I created a draft PR for this: #95. |
| STORE a5, 5*REGBYTES(t1) | ||
| STORE a6, 6*REGBYTES(t1) | ||
| STORE a7, 7*REGBYTES(t1) | ||
| fence rw, rw |
There was a problem hiding this comment.
I’m not confident about this (single) fence, or about using plain reads in fn boot_arguments.
At first I started emulating the behavior of AtomicUsize: https://rust.godbolt.org/z/3djWjhPcG. But why is the fence instruction placed before stores and after loads? I’d expected fences to be between things in order to separate them.
On the Rust size I ended up with this, since AtomicUsize is disabled on targets without the A extension. The portable-atomic crate would be another option for doing the same.
/// Simulate AtomicUsize::load(Ordering::Acquire)
unsafe fn atomic_load(ptr: *const usize) -> usize {
let value;
// Only lw v.s. ld changes but asm! wants a string literal
#[cfg(target_pointer_width = "32")]
core::arch::asm!(
"fence r, rw",
"lw {value}, 0({ptr})",
ptr = in(reg) ptr,
value = out(reg) value,
);
#[cfg(not(target_pointer_width = "32"))]
core::arch::asm!(
"fence r, rw",
"ld {value}, 0({ptr})",
ptr = in(reg) ptr,
value = out(reg) value,
);
value
}There was a problem hiding this comment.
Position of fence instructions depends on the ordering. With SeqCst you get fences before and after the load.
|
Closing in favor of #95 |
Fixes #92
With this PR, the code below succeeds in QEMU and
Fdtcan be used to find the address of the simulated UART that prints to stdout on the host.