evaloop has quit [Remote host closed the connection]
evaloop has joined #rust-embedded
<M9names[m]>
yaoxingpu: yes, all discussions here are in English. I hope there are places to discuss Embedded Rust in Chinese, but this room is not one of them.
<ithinuel[m]>
(I have no clue if google introduced some offensive language in that or not 🤷)
<ithinuel[m]>
s/🤷/🤷, but that’s 9names ’s message gone through it/
<jannic[m]>
<ithinuel[m]> " * yaoxingpu: 是的,这里所有的讨论都是英文的。 我..." <- According to a different translator I used to translate it back to English, the only language Google added was "Translations are supported by Google Translate."
evaloop has quit [Read error: Connection reset by peer]
evaloop has joined #rust-embedded
IlPalazzo-ojiisa has joined #rust-embedded
qzl[m] has joined #rust-embedded
<qzl[m]>
I wanted to develop a simple dw-mshc driver, but I was unable to download Synopsys SD/eMMC Host Controller IP Datasheet pdf. I want to develop a simple dw-mshc driver, but I cannot download Synopsys SD/eMMC Host Controller IP Datasheet pdf. I use SDIO 3.0. Is there such a driver in the community
ryan-summers[m] has joined #rust-embedded
<ryan-summers[m]>
eMMC standards are notorious for being protected IP. In the past, I've had to use the JEDEC standard to communicate with them
<ryan-summers[m]>
* eMMC data sheets are notorious for being protected IP. In the past, I've had to use the JEDEC standard to communicate with them
<Kaspar[m]>
<dirbaio[m]> "what does the "magic" do" <- "magic" basically stores `uc.get()` somewhere as usize, then triggers PendSV, which in turn switches to another thread. The other thread eventually calls the `send<T>(something: T)` brother, which in a similar critical section, takes the usize addr and uses `core::ptr::write()` to copy over `something`, then triggers PendSV again.
<Kaspar[m]>
So the thread that calls `recv()`, at the end of it's critical section when it re-enables interrupts, PendSV triggers, switches away, ..., and when that thread gets restored eventually, an object has been written to `uc.ptr()`.
<Kaspar[m]>
So now I'm trying to figure out how to force the Rust compiler to re-read from memory. blackbox() does the trick but "should not be relied on".
<JamesMunns[m]>
you probably want compiler_fence
<JamesMunns[m]>
you probably want your kernel to use compiler_fence(Ordering::Release), and you userspace to use complier_fence(Ordering::Acquire)
<dirbaio[m]>
Yep it's probably that
<JamesMunns[m]>
but the critical section will prevent PendSV from executing?
<dirbaio[m]>
pendsv is a volatile register write, so the compiler is allowed to assume the rest of memory doesn't magically change due to that write. So it sees you are creating a MaybeUninit then immediately reading from it which is UB
<JamesMunns[m]>
like, PendSV triggers an interrupt, and CS disables interrupts. Maybe it's not disableable if you are using the protected mode for the kernel, but idk how our CS handles that
<dirbaio[m]>
The critical section already has fences though, I think?
<JamesMunns[m]>
oh and Kaspar if you expect to work on targets that have dcache, you probably want to use `fence` not `compiler_fence`.
<JamesMunns[m]>
The former also instructs the cpu to do cache/out of order flushes AND prevents the optimizer from reordering, compiler_fence just stops the optimizer
<JamesMunns[m]>
I think modern C versions will have equivalents of all of these functions as well, if your kernel side should be doing equivalent steps.
IlPalazzo-ojiisa has quit [Remote host closed the connection]
<JamesMunns[m]>
uhhh, I don't think nrf52840 has dcache
<JamesMunns[m]>
I would be very suspicious of that
<JamesMunns[m]>
it has icache kinda
<JamesMunns[m]>
but no reordering or anythin
<JamesMunns[m]>
did you use compiler_fence(Release) in your kernel before returning from the ISR, and compiler_fence(Acquire) in the function you shared, before reading from the variable?
<dirbaio[m]>
Also you might want to not cast through usize
<JamesMunns[m]>
you're saying "at this point the function releases exclusive access to the preceeding data (`uc`), and then at this point the function acquires exclusive access to the preceeding data"
<JamesMunns[m]>
fence might have been a red herring as it actually emits dsb/isb, but afaik the nrf52840 should never require fence
<JamesMunns[m]>
can you share the actual magic?
<JamesMunns[m]>
you might be doing some other undefined behavior
<Kaspar[m]>
dirbaio[m]: boy was this easy when memory addresses where memory addresses. :smirk:
<Kaspar[m]>
in this case, that usize is part of the thread state, I can't easily put an address to a T there. I hope I can get this to work as is.
<JamesMunns[m]>
Kaspar[m]: > <@kaspar:schleiser.de> boy was this easy when memory addresses where memory addresses. :smirk:
<JamesMunns[m]>
> in this case, that usize is part of the thread state, I can't easily put an address to a T there. I hope I can get this to work as is.
<JamesMunns[m]>
this hasn't been the case since the PDP-11
<Kaspar[m]>
JamesMunns[m]: Is that UB also if it is guaranteed "elsewhere" that the memory has been written to? (it is in every case, just not inside the recv() cs)
<JamesMunns[m]>
does put_current do a context switch?
<Kaspar[m]>
dirbaio[m]: > <@dirbaio:matrix.org> The reason I'm saying this is because currently it's very underspecified when it's allowed to cast from usize to ptr and write to that. I think currently the compiler is conservative so it's likely to work, but it's best avoided. If the issue is generics you can cast through `*... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/FJPLiklxmveguOJvMwAUWjsG>)
<JamesMunns[m]>
*mut () is basically void*
<JamesMunns[m]>
sorta, not exactly
<Kaspar[m]>
JamesMunns[m]: well, it pends PendSV, which would do the context switch after the cs.
<Kaspar[m]>
The "memory model is unspecified" doesn't make it any easyer. In my current issue, the T is an u8, which fits snugly into a register. In C I'm pretty sure getting the address of a variable forces it to be on stack. In Rust, I'm not so sure :)
<JamesMunns[m]>
it should, you're likely escaping the pointer, where is put_current defined?
<Kaspar[m]>
I'd also not be surprised if dancing with critical sections which switch context is hard approaching corner cases around what the llvm should be allowed to optimize away...
<Kaspar[m]>
It is certainly approaching the corner cases of the abstract machine in my head. :)
<JamesMunns[m]>
AFAIK the compiler doesn't "understand" context switches, fences should inform the compiler "spooky shit is allowed to have happened hereish"
<JamesMunns[m]>
it's possible there is OTHER UB going on with your queue or context switch stuff, and this function is being messed with despite being locally correct. that's why seqcst can mask other problems, it makes "global" synchronization claims, rather than local ones
<JamesMunns[m]>
I'd prefer "AcqRel" as a default over "SeqCst"
<JamesMunns[m]>
oh
<JamesMunns[m]>
your operations with self/state are a little sis
<JamesMunns[m]>
* your operations with self/state are a little sus
<JamesMunns[m]>
like, you have no synchronization that changes to `self`/`self.state` might happen "out of band"
<JamesMunns[m]>
not certain. there's certainly some spooky things you are doing here :)
<JamesMunns[m]>
if at all possible, it might be worth figuring out how to build an analog of this on desktop so you can use miri
Foxyloxy has quit [Read error: Connection reset by peer]
<JamesMunns[m]>
Maybe CC dirbaio, it looks like you did the cortex-m cs impl, any idea if this was an oversight?
<jannic[m]>
I know :-) But I wonder if the wording "It must provide ordering guarantees at least equivalent to a [core::sync::atomic::Ordering::Acquire]" could be interpreted in a way that excludes single-core systems. Are the atomic operations NOPs in that case, and don't provide any compiler fences?
<JamesMunns[m]>
no, because the compiler might reorder the ops across that point
<JamesMunns[m]>
ahhhh
<JamesMunns[m]>
interrupt enable/disable have a fence in them