From 98399b030fed7678c61e3c00930462c6f5e3cf9a Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 25 Sep 2016 16:59:25 -0600 Subject: [PATCH] Launch commands for each device found if specified --- drivers/pcid/Cargo.toml | 7 ++ drivers/pcid/src/config.rs | 14 +++ drivers/pcid/src/main.rs | 171 +++++++++++++++++++++++++------------ initfs/etc/init.rc | 6 +- initfs/etc/pcid.toml | 5 ++ 5 files changed, 147 insertions(+), 56 deletions(-) create mode 100644 drivers/pcid/src/config.rs create mode 100644 initfs/etc/pcid.toml diff --git a/drivers/pcid/Cargo.toml b/drivers/pcid/Cargo.toml index e6b6318..222032c 100644 --- a/drivers/pcid/Cargo.toml +++ b/drivers/pcid/Cargo.toml @@ -2,5 +2,12 @@ name = "pcid" version = "0.1.0" +[dependencies] +rustc-serialize = { git = "https://github.com/redox-os/rustc-serialize.git" } +toml = "*" + [dependencies.syscall] path = "../../syscall/" + +[replace] +"rustc-serialize:0.3.19" = { git = "https://github.com/redox-os/rustc-serialize.git" } diff --git a/drivers/pcid/src/config.rs b/drivers/pcid/src/config.rs new file mode 100644 index 0000000..3bc4dba --- /dev/null +++ b/drivers/pcid/src/config.rs @@ -0,0 +1,14 @@ +#[derive(Debug, Default, RustcDecodable)] +pub struct Config { + pub drivers: Vec +} + +#[derive(Debug, Default, RustcDecodable)] +pub struct DriverConfig { + pub name: Option, + pub class: Option, + pub subclass: Option, + pub vendor: Option, + pub device: Option, + pub command: Option> +} diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs index 0886bef..9eb0889 100644 --- a/drivers/pcid/src/main.rs +++ b/drivers/pcid/src/main.rs @@ -1,79 +1,144 @@ #![feature(asm)] +extern crate rustc_serialize; extern crate syscall; +extern crate toml; +use std::env; +use std::fs::File; +use std::io::Read; +use std::process::Command; use std::thread; use syscall::iopl; +use config::Config; use pci::{Pci, PciBar, PciClass}; +mod config; mod pci; -fn enumerate_pci() { - println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); +fn main() { + thread::spawn(|| { + let mut config = Config::default(); - let pci = Pci::new(); - for bus in pci.buses() { - for dev in bus.devs() { - for func in dev.funcs() { - if let Some(header) = func.header() { - print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", - bus.num, dev.num, func.num, - header.vendor_id, header.device_id, - header.class, header.subclass, header.interface, header.revision); + let mut args = env::args().skip(1); + if let Some(config_path) = args.next() { + if let Ok(mut config_file) = File::open(&config_path) { + let mut config_data = String::new(); + if let Ok(_) = config_file.read_to_string(&mut config_data) { + config = toml::decode_str(&config_data).unwrap_or(Config::default()); + } + } + } - let pci_class = PciClass::from(header.class); - print!(" {:?}", pci_class); - match pci_class { - PciClass::Storage => match header.subclass { - 0x01 => { - print!(" IDE"); + println!("{:?}", config); + + unsafe { iopl(3).unwrap() }; + + println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); + + let pci = Pci::new(); + for bus in pci.buses() { + for dev in bus.devs() { + for func in dev.funcs() { + if let Some(header) = func.header() { + print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", + bus.num, dev.num, func.num, + header.vendor_id, header.device_id, + header.class, header.subclass, header.interface, header.revision); + + let pci_class = PciClass::from(header.class); + print!(" {:?}", pci_class); + match pci_class { + PciClass::Storage => match header.subclass { + 0x01 => { + print!(" IDE"); + }, + 0x06 => { + print!(" SATA"); + }, + _ => () }, - 0x06 => { - print!(" SATA"); - }, - _ => () - }, - PciClass::SerialBus => match header.subclass { - 0x03 => match header.interface { - 0x00 => { - print!(" UHCI"); - }, - 0x10 => { - print!(" OHCI"); - }, - 0x20 => { - print!(" EHCI"); - }, - 0x30 => { - print!(" XHCI"); + PciClass::SerialBus => match header.subclass { + 0x03 => match header.interface { + 0x00 => { + print!(" UHCI"); + }, + 0x10 => { + print!(" OHCI"); + }, + 0x20 => { + print!(" EHCI"); + }, + 0x30 => { + print!(" XHCI"); + }, + _ => () }, _ => () }, _ => () - }, - _ => () - } + } - for i in 0..header.bars.len() { - match PciBar::from(header.bars[i]) { - PciBar::None => (), - PciBar::Memory(address) => print!(" {}={:>08X}", i, address), - PciBar::Port(address) => print!(" {}={:>04X}", i, address) + for i in 0..header.bars.len() { + match PciBar::from(header.bars[i]) { + PciBar::None => (), + PciBar::Memory(address) => print!(" {}={:>08X}", i, address), + PciBar::Port(address) => print!(" {}={:>04X}", i, address) + } + } + + print!("\n"); + + for driver in config.drivers.iter() { + if let Some(class) = driver.class { + if class != header.class { continue; } + } + + if let Some(subclass) = driver.subclass { + if subclass != header.subclass { continue; } + } + + if let Some(vendor) = driver.vendor { + if vendor != header.vendor_id { continue; } + } + + if let Some(device) = driver.device { + if device != header.device_id { continue; } + } + + if let Some(ref args) = driver.command { + let mut args = args.iter(); + if let Some(program) = args.next() { + let mut command = Command::new(program); + for arg in args { + let bar_arg = |i| -> String { + match PciBar::from(header.bars[i]) { + PciBar::None => String::new(), + PciBar::Memory(address) => format!("{:>08X}", address), + PciBar::Port(address) => format!("{:>04X}", address) + } + }; + let arg = match arg.as_str() { + "$0" => bar_arg(0), + "$1" => bar_arg(1), + "$2" => bar_arg(2), + "$3" => bar_arg(3), + "$4" => bar_arg(4), + "$5" => bar_arg(5), + _ => arg.clone() + }; + command.arg(&arg); + } + println!("{:?}", command); + } + } + + println!("Driver: {:?}", driver); } } - - print!("\n"); } } } - } -} - -fn main() { - thread::spawn(||{ - unsafe { iopl(3).unwrap() }; - - enumerate_pci(); }); } diff --git a/initfs/etc/init.rc b/initfs/etc/init.rc index 27af7d0..e46d40d 100644 --- a/initfs/etc/init.rc +++ b/initfs/etc/init.rc @@ -1,5 +1,5 @@ initfs:bin/vesad initfs:bin/ps2d -#initfs:bin/pcid -initfs:bin/example -#initfs:bin/login display: initfs:bin/ion +initfs:bin/pcid initfs:etc/pcid.toml +#initfs:bin/example +initfs:bin/login display: initfs:bin/ion diff --git a/initfs/etc/pcid.toml b/initfs/etc/pcid.toml new file mode 100644 index 0000000..ec6c838 --- /dev/null +++ b/initfs/etc/pcid.toml @@ -0,0 +1,5 @@ +[[drivers]] +name = "AHCI storage" +class = 1 +subclass = 6 +command = ["ahcid", "$5"]