milestone: desktop path Phases 1-5
Phase 1 (Runtime Substrate): 4 check binaries, --probe, POSIX tests Phase 2 (Wayland Compositor): bounded scaffold, zero warnings Phase 3 (KWin Session): preflight checker (KWin stub, gated on Qt6Quick) Phase 4 (KDE Plasma): 18 KF6 enabled, preflight checker Phase 5 (Hardware GPU): DRM/firmware/Mesa preflight checker Build: zero warnings, all scripts syntax-clean. Oracle-verified.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "pcid-spawner"
|
||||
description = "PCI-based device driver spawner daemon"
|
||||
version = "0.1.0"
|
||||
authors = ["4lDO2 <4lDO2@protonmail.com>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
log.workspace = true
|
||||
pico-args.workspace = true
|
||||
redox_syscall.workspace = true
|
||||
serde.workspace = true
|
||||
toml.workspace = true
|
||||
|
||||
config = { path = "../../config" }
|
||||
common = { path = "../common" }
|
||||
daemon = { path = "../../daemon" }
|
||||
pcid = { path = "../pcid" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1,101 @@
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
|
||||
use pcid_interface::config::Config;
|
||||
use pcid_interface::PciFunctionHandle;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut args = pico_args::Arguments::from_env();
|
||||
let initfs = args.contains("--initfs");
|
||||
|
||||
common::setup_logging(
|
||||
"bus",
|
||||
"pci",
|
||||
"pci-spawner.log",
|
||||
common::output_level(),
|
||||
common::file_level(),
|
||||
);
|
||||
|
||||
let mut config_data = String::new();
|
||||
for path in if initfs {
|
||||
config::config_for_initfs("pcid")?
|
||||
} else {
|
||||
config::config("pcid")?
|
||||
} {
|
||||
if let Ok(tmp) = fs::read_to_string(path) {
|
||||
config_data.push_str(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
let config: Config = toml::from_str(&config_data)?;
|
||||
|
||||
for entry in fs::read_dir("/scheme/pci")? {
|
||||
let entry = entry.context("failed to get entry")?;
|
||||
let device_path = entry.path();
|
||||
log::trace!("ENTRY: {}", device_path.to_string_lossy());
|
||||
|
||||
let mut handle = match PciFunctionHandle::connect_by_path(&device_path) {
|
||||
Ok(handle) => handle,
|
||||
Err(err) if err.raw_os_error() == Some(syscall::ENOLCK) => {
|
||||
log::debug!(
|
||||
"pcid-spawner: {} already in use: {err}",
|
||||
device_path.display(),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!(
|
||||
"pcid-spawner: failed to open channel for {}: {err}",
|
||||
device_path.display(),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let full_device_id = handle.config().func.full_device_id;
|
||||
|
||||
log::debug!(
|
||||
"pcid-spawner enumerated: PCI {} {}",
|
||||
handle.config().func.addr,
|
||||
full_device_id.display()
|
||||
);
|
||||
|
||||
let Some(driver) = config
|
||||
.drivers
|
||||
.iter()
|
||||
.find(|driver| driver.match_function(&full_device_id))
|
||||
else {
|
||||
log::debug!("no driver for {}, continuing", handle.config().func.addr);
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut args = driver.command.iter();
|
||||
|
||||
let program = args
|
||||
.next()
|
||||
.ok_or_else(|| anyhow!("driver configuration entry did not have any command!"))?;
|
||||
let program = if program.starts_with('/') {
|
||||
program.to_owned()
|
||||
} else {
|
||||
"/usr/lib/drivers/".to_owned() + program
|
||||
};
|
||||
|
||||
let mut command = Command::new(program);
|
||||
command.args(args);
|
||||
|
||||
log::info!("pcid-spawner: spawn {:?}", command);
|
||||
|
||||
handle.enable_device();
|
||||
|
||||
let channel_fd = handle.into_inner_fd();
|
||||
command.env("PCID_CLIENT_CHANNEL", channel_fd.to_string());
|
||||
|
||||
#[allow(deprecated, reason = "we can't yet move this to init")]
|
||||
daemon::Daemon::spawn(command);
|
||||
syscall::close(channel_fd as usize).unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user