Issues with volatile crate

I'm using the Volatile crate for volatile reads and writes to memory. When I attempt to read the value of a pointer into a variable, and then call .read() on it, I just get a copy of the Volatile<...> variable and not the item within. (Also, rust refers to the Volatile crate as 'my_crate_name::Volatile::...'. Any way to prevent this?).
Is there any way I can get access to the item contained within the Volatile structure without unsafe code? I can't exactly modify the volatile item without being able to extract what's inside the structure, and I'd rather not have tons of closures inside closures -- that would become way too messy.

this crate? If so, then Volatile::read should give you the value inside. Can you show the code where this isn't the case.

1 Like

This is the code:

                    let mem_ptr = {
let raw_ptr = bars[5] as *mut internal::HbaMem;
        raw_ptr as *mut Volatile<internal::HbaMem>
    };
                    let pi = mem_ptr.read().borrow().pi;

I've tried several other variants; the original code, before I tried this hack, was:

                    let mem_ptr = {
let raw_ptr = bars[5] as *mut internal::HbaMem;
        raw_ptr as *mut Volatile<internal::HbaMem>
    };
                    let mem = mem_ptr.read();
                    let pi = mem.pi;

The error I'm getting says:

error[E0609]: no field `pi` on type `vga::volatile::Volatile<drivers::storage::ahci::internal::HbaMem>`
   --> src\drivers\storage\ahci.rs:234:34
    |
234 |                     let pi = mem.pi;
    |                                  ^^ unknown field

This is ridiculously confusing. The vga part is a part of my main application. But its acting as though I embedded the Volatile crate into this little kernel -- which is definitely not the case. So I'm quite confused why Rust is making such an inference.

mem_ptr has type *mut Volatile<internal::HbaMem> so when you call read you're not calling Volatile::read but <*mut _>::read().

You then get a Volatile<internal::HbaMem> and the compiler complains when you try to access a pi field.

Your code seems a bit weird to me but I can't be sure without knowing what is the type of bars.

Anyway you should be able to get the value with:

let pi = (*mem_ptr).read().pi;
1 Like

I'm doing it the way the docs specify for handling volatile pointers. In this case the pointer is a struct I'm trying to build from memory accesses. Is this not the right way to do it?

Oh ok bars contains memory addresses, it makes sense.

Why not use read_volatile like other part of your codebase?

2 Likes

Because I don't think read_volatile() rads into structs....

The volatile crate is just using read_volatile under the hood, so you should probably just use read_volatile if you are already dealing with raw pointers.

1 Like

Ah, I will do that. Thanks.