Skip to content

Commit

Permalink
Implement pass through device
Browse files Browse the repository at this point in the history
The number of PMP (Physical Memory Protection) registers is limited on any RISC-V platform. Currently, each memory-mapped virtual device requires a separate PMP entry. This commit introduces a solution that allows grouping all virtual devices under a single PMP entry by implementing a pass-through module in front of them.
  • Loading branch information
francois141 committed Aug 31, 2024
1 parent 8308af0 commit d3cddb1
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/device/empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::device::{DeviceAccess, VirtDevice, Width};

// ———————————————————————————— Empty device ————————————————————————————— //

pub struct EmptyDevice {}

impl DeviceAccess for EmptyDevice {
fn read_device(&self, _: usize, _: Width) -> Result<usize, &'static str> {
panic!("Trying to read the empty device!");
}

fn write_device(&self, _: usize, _: Width, _: usize) -> Result<(), &'static str> {
panic!("Trying to write the empty device!");
}
}

impl EmptyDevice {
pub const fn new() -> VirtDevice {
VirtDevice {
start_addr: 0,
size: 0,
name: "",
device_interface: &EmptyDevice {},
}
}
}
48 changes: 48 additions & 0 deletions src/device/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! Base device classes

use crate::device::empty::EmptyDevice;
use crate::platform::{Plat, Platform};

pub mod clint;
pub mod empty;
pub mod tester;

// ———————————————————————————— Virtual Devices ————————————————————————————— //
Expand Down Expand Up @@ -63,3 +67,47 @@ pub trait DeviceAccess: Sync + Send {
fn write_device(&self, offset: usize, w_width: Width, value: usize)
-> Result<(), &'static str>;
}

// ———————————————————————————— Pass Through module ————————————————————————————— //

pub struct PassThroughModule {
devices: [VirtDevice; 2],
base_address: usize,
}

impl DeviceAccess for PassThroughModule {
fn read_device(&self, offset: usize, r_width: Width) -> Result<usize, &'static str> {
match find_matching_device(self.base_address + offset, &self.devices) {
Some(device) => device.device_interface.read_device(offset, r_width),
_ => Err("Mapping to non existent device"),
}
}

fn write_device(
&self,
offset: usize,
w_width: Width,
value: usize,
) -> Result<(), &'static str> {
match find_matching_device(self.base_address + offset, &self.devices) {
Some(device) => device.device_interface.write_device(offset, w_width, value),
_ => Err("Mapping to non existent device"),
}
}
}

impl PassThroughModule {
pub const fn new(base_address: usize) -> PassThroughModule {
let empty_clint_device = EmptyDevice::new();
let empty_test_device = EmptyDevice::new();

PassThroughModule {
devices: [empty_clint_device, empty_test_device],
base_address: base_address,
}
}

pub fn attach_devices(&mut self) {
self.devices = Plat::create_virtual_devices()
}
}

0 comments on commit d3cddb1

Please sign in to comment.