Add runtime tools and Red Bear service wiring

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-14 10:50:42 +01:00
parent fd60edc823
commit 51f3c21121
62 changed files with 9613 additions and 881 deletions
@@ -0,0 +1,135 @@
//! IOMMU daemon — provides scheme:iommu for DMA remapping.
use std::env;
use std::fs;
use std::process;
use iommu::amd_vi::AmdViUnit;
#[cfg(target_os = "redox")]
use iommu::IommuScheme;
use log::{error, info, LevelFilter, Metadata, Record};
#[cfg(target_os = "redox")]
use redox_scheme::{SignalBehavior, Socket};
struct StderrLogger {
level: LevelFilter,
}
impl log::Log for StderrLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
eprintln!("[{}] {}", record.level(), record.args());
}
}
fn flush(&self) {}
}
fn init_logging(level: LevelFilter) {
if log::set_boxed_logger(Box::new(StderrLogger { level })).is_err() {
return;
}
log::set_max_level(level);
}
fn detect_units_from_env() -> Result<Vec<AmdViUnit>, String> {
let Some(path) = env::var_os("IOMMU_IVRS_PATH") else {
return Ok(Vec::new());
};
let bytes = fs::read(&path).map_err(|err| {
format!(
"failed to read IVRS table from {}: {err}",
path.to_string_lossy()
)
})?;
let units = AmdViUnit::detect(&bytes).map_err(|err| format!("failed to parse IVRS: {err}"))?;
Ok(units)
}
#[cfg(target_os = "redox")]
fn run() -> Result<(), String> {
let mut units = detect_units_from_env()?;
info!("iommu: detected {} AMD-Vi unit(s)", units.len());
for (index, unit) in units.iter_mut().enumerate() {
match unit.init() {
Ok(()) => info!(
"iommu: initialized unit {} at MMIO {:#x}",
index,
unit.info().mmio_base
),
Err(err) => error!(
"iommu: failed to initialize unit {} at MMIO {:#x}: {}",
index,
unit.info().mmio_base,
err
),
}
}
let socket =
Socket::create("iommu").map_err(|e| format!("failed to register iommu scheme: {e}"))?;
info!("iommu: registered scheme:iommu");
let mut scheme = IommuScheme::with_units(units);
loop {
let request = match socket.next_request(SignalBehavior::Restart) {
Ok(Some(request)) => request,
Ok(None) => {
info!("iommu: scheme unmounted, exiting");
break;
}
Err(e) => {
error!("iommu: failed to read scheme request: {e}");
continue;
}
};
let response = match request.handle_scheme_block_mut(&mut scheme) {
Ok(response) => response,
Err(_request) => {
error!("iommu: failed to handle request");
continue;
}
};
if let Err(e) = socket.write_response(response, SignalBehavior::Restart) {
error!("iommu: failed to write response: {e}");
}
}
Ok(())
}
#[cfg(not(target_os = "redox"))]
fn run() -> Result<(), String> {
let units = detect_units_from_env()?;
info!(
"iommu: host build stub active; parsed {} AMD-Vi unit(s) from IOMMU_IVRS_PATH",
units.len()
);
Ok(())
}
fn main() {
let log_level = match env::var("IOMMU_LOG").as_deref() {
Ok("debug") => LevelFilter::Debug,
Ok("trace") => LevelFilter::Trace,
Ok("warn") => LevelFilter::Warn,
Ok("error") => LevelFilter::Error,
_ => LevelFilter::Info,
};
init_logging(log_level);
if let Err(e) = run() {
error!("iommu: fatal error: {e}");
process::exit(1);
}
}