svd2rust icon indicating copy to clipboard operation
svd2rust copied to clipboard

Support for atomic `Peripherals::take()`

Open VictorKoenders opened this issue 2 years ago • 2 comments

Hello,

I'm currently working on a toy kernel on a raspberry pi, and I'm using svd2rust to generate the bindings to the aarch64 BCM2837 chip that the raspberry pi 3b is running on.

When generating the peripherals I cannot select a Target because the aarch64 is multi-core and critical sections do not work. Therefor the Peripherals::take() -> Option<Self> method won't be generated.

Currently I inject the following code into the generated output:

use core::sync::atomic::{AtomicBool, Ordering};

static LOCKED: AtomicBool = AtomicBool::new(false);

impl Peripherals {
    pub fn take() -> Option<Self> {
        let was_locked = LOCKED.compare_exchange(false, true, Ordering::Acquire, Ordering::Acquire).is_ok();
        if was_locked {
            None
        } else {
            Some(unsafe { Self::steal() })
        }
    }
}

impl Drop for Peripherals {
    fn drop(&mut self) {
        LOCKED.store(false, Ordering::Relaxed);
    }
}

I was considering porting this to svd2rust but I'm not sure how to approach this. I could:

  • add a Target::Atomic
  • Add a Target::Custom(TargetOptions) and
#[non_exhaustive]
#[derive(Default)]
pub struct TargetOptions {
    pub atomic: bool,
    pub interrupt_free: bool,
    // other options
}

(This would make all the other Target an alias for a hard-coded TargetOptions implementation)

  • Add a new boolean field to svd2rust::utils::Config to overwrite Peripherals::take() with an atomic implementation when that field is set

Or maybe another approach is better. What do you think?

VictorKoenders avatar May 25 '22 10:05 VictorKoenders

I think it makes sense to do it the other way around, Target is the core thing, and TargetOptions is what is consumed, it has the target and its options

Emilgardis avatar May 25 '22 11:05 Emilgardis

@VictorKoenders, does https://github.com/rust-embedded/svd2rust/pull/651 fix this? You will need an implementation for critical_section that works correctly on multi-core of course.

reitermarkus avatar Aug 24 '22 02:08 reitermarkus

Closing as solved

burrbull avatar Nov 07 '22 18:11 burrbull